summaryrefslogtreecommitdiff
path: root/sigc++/tuple-utils
diff options
context:
space:
mode:
authorMurray Cumming <murrayc@murrayc.com>2018-04-15 11:10:45 +0200
committerMurray Cumming <murrayc@murrayc.com>2018-04-15 11:15:23 +0200
commit1759faf552248373714acc573b55421e86cb94cc (patch)
tree8cdb2c9a71514db3682b496bcff9c25ef6103e1f /sigc++/tuple-utils
parent12ad173361ce3f8fe2a3cee8c53397891e33abd1 (diff)
downloadsigc++-1759faf552248373714acc573b55421e86cb94cc.tar.gz
C++17: Update from murrayc-tuple-utils.
From https://github.com/murraycu/murrayc-tuple-utils/commits/master This also uses the C++17 nested namespace syntax. Apart from tuple_transform_each, which seems to have a memory access problem, with both g++ and clang++, in its C++17 version.
Diffstat (limited to 'sigc++/tuple-utils')
-rw-r--r--sigc++/tuple-utils/tuple_cdr.h26
-rw-r--r--sigc++/tuple-utils/tuple_end.h69
-rw-r--r--sigc++/tuple-utils/tuple_start.h43
3 files changed, 60 insertions, 78 deletions
diff --git a/sigc++/tuple-utils/tuple_cdr.h b/sigc++/tuple-utils/tuple_cdr.h
index e0c17f7..8577fef 100644
--- a/sigc++/tuple-utils/tuple_cdr.h
+++ b/sigc++/tuple-utils/tuple_cdr.h
@@ -22,11 +22,7 @@
#include <type_traits>
#include <utility>
-namespace sigc
-{
-
-namespace internal
-{
+namespace sigc::internal {
/**
* Get the type of a tuple without the first item.
@@ -41,11 +37,11 @@ struct tuple_type_cdr<std::tuple<H, T...>>
using type = std::tuple<T...>;
};
-namespace detail
-{
+namespace detail {
template <typename T, std::size_t... I>
-constexpr decltype(auto)
+constexpr
+decltype(auto)
tuple_cdr_impl(T&& t, std::index_sequence<0, I...>)
{
using cdr = typename tuple_type_cdr<std::decay_t<T>>::type;
@@ -59,10 +55,10 @@ tuple_cdr_impl(T&& t, std::index_sequence<0, I...>)
* This is analogous to std::tuple_cat().
*/
template <typename T>
-constexpr decltype(auto)
-tuple_cdr(T&& t)
-{
- // We use std::decay_t<> because tuple_size is not defined for references.
+constexpr
+decltype(auto)
+tuple_cdr(T&& t) {
+ //We use std::decay_t<> because tuple_size is not defined for references.
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
static_assert(size != 0, "tuple size must be non-zero");
@@ -70,8 +66,6 @@ tuple_cdr(T&& t)
return detail::tuple_cdr_impl(std::forward<T>(t), seq{});
}
-} // namespace internal
-
-} // namespace sigc
+} // namespace sigc::internal
-#endif // SIGC_TUPLE_UTILS_TUPLE_CDR_H
+#endif //SIGC_TUPLE_UTILS_TUPLE_CDR_H
diff --git a/sigc++/tuple-utils/tuple_end.h b/sigc++/tuple-utils/tuple_end.h
index 6eeac12..2f3572e 100644
--- a/sigc++/tuple-utils/tuple_end.h
+++ b/sigc++/tuple-utils/tuple_end.h
@@ -20,58 +20,55 @@
#include <sigc++/tuple-utils/tuple_cdr.h>
-namespace sigc
-{
+namespace sigc::internal {
-namespace internal
-{
-
-namespace detail
-{
+namespace detail {
template <typename T, std::size_t remove_from_start>
-struct tuple_end_impl
-{
- constexpr static decltype(auto) // typename tuple_type_end<T, size - remove_from_start>::type
- tuple_end(T&& t)
- {
- static_assert(remove_from_start > 0, "remove_from_start must be more than zero.");
-
- using cdr = typename tuple_type_cdr<std::decay_t<T>>::type;
- return tuple_end_impl<cdr, remove_from_start - 1>::tuple_end(tuple_cdr(std::forward<T>(t)));
- }
-};
-
-template <typename T>
-struct tuple_end_impl<T, 1>
-{
- constexpr static decltype(auto) tuple_end(T&& t) { return tuple_cdr(std::forward<T>(t)); }
+struct tuple_type_end_impl {
+ using type = typename tuple_type_end_impl<typename tuple_type_cdr<std::decay_t<T>>::type,
+ remove_from_start - 1>::type;
};
template <typename T>
-struct tuple_end_impl<T, 0>
-{
- constexpr static decltype(auto) tuple_end(T&& t) { return std::forward<T>(t); }
+struct tuple_type_end_impl<T, 0> {
+ using type = T;
};
} // detail namespace
/**
+ * Get the type of a tuple with the last @a len types of the original.
+ */
+template <typename T, std::size_t len>
+struct tuple_type_end
+ : detail::tuple_type_end_impl<T, std::tuple_size<T>::value - len> {};
+
+/**
* Get the tuple with the last @a len items of the original.
*/
template <std::size_t len, typename T>
-constexpr decltype(auto) // typename tuple_type_end<T, len>::type
- tuple_end(T&& t)
-{
- // We use std::decay_t<> because tuple_size is not defined for references.
+constexpr
+decltype(auto) // typename tuple_type_end<T, len>::type
+tuple_end(T&& t) {
+ //We use std::decay_t<> because tuple_size is not defined for references.
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
static_assert(len <= size, "The tuple size must be less than or equal to the length.");
- constexpr auto size_start = size - len;
- return detail::tuple_end_impl<T, size_start>::tuple_end(std::forward<T>(t));
-}
-} // namespace internal
+ if constexpr(len == 0) {
+ // Recursive calls to tuple_cdr() would result in this eventually,
+ // but this avoids the extra work:
+ return std::tuple<>();
+ } else if constexpr(size - len == 0) {
+ return std::forward<T>(t);
+ } else if constexpr(size - len == 1) {
+ return tuple_cdr(std::forward<T>(t));
+ } else {
+ return tuple_end<len>(
+ tuple_cdr(std::forward<T>(t)));
+ }
+}
-} // namespace sigc
+} // namespace sigc::internal;
-#endif // SIGC_TUPLE_UTILS_TUPLE_END_H
+#endif //SIGC_TUPLE_UTILS_TUPLE_END_H
diff --git a/sigc++/tuple-utils/tuple_start.h b/sigc++/tuple-utils/tuple_start.h
index 06491ce..c220a92 100644
--- a/sigc++/tuple-utils/tuple_start.h
+++ b/sigc++/tuple-utils/tuple_start.h
@@ -21,21 +21,15 @@
#include <tuple>
#include <utility>
-namespace sigc
-{
+namespace sigc::internal {
-namespace internal
-{
-
-namespace detail
-{
+namespace detail {
template <typename T, typename Seq>
struct tuple_type_start_impl;
template <typename T, std::size_t... I>
-struct tuple_type_start_impl<T, std::index_sequence<I...>>
-{
+struct tuple_type_start_impl<T, std::index_sequence<I...>> {
using type = std::tuple<typename std::tuple_element<I, T>::type...>;
};
@@ -45,21 +39,20 @@ struct tuple_type_start_impl<T, std::index_sequence<I...>>
* Get the type of a tuple with just the first @len items.
*/
template <typename T, std::size_t len>
-struct tuple_type_start : detail::tuple_type_start_impl<T, std::make_index_sequence<len>>
-{
-};
+struct tuple_type_start
+ : detail::tuple_type_start_impl<T, std::make_index_sequence<len>> {};
-namespace detail
-{
+namespace detail {
template <typename T, typename Seq>
struct tuple_start_impl;
template <typename T, std::size_t... I>
-struct tuple_start_impl<T, std::index_sequence<I...>>
-{
- static constexpr decltype(auto) tuple_start(T&& t)
- {
+struct tuple_start_impl<T, std::index_sequence<I...>> {
+ static
+ constexpr
+ decltype(auto)
+ tuple_start(T&& t) {
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
constexpr auto len = sizeof...(I);
static_assert(len <= size, "The tuple size must be less than or equal to the length.");
@@ -75,10 +68,10 @@ struct tuple_start_impl<T, std::index_sequence<I...>>
* Get the tuple with the last @a len items of the original.
*/
template <std::size_t len, typename T>
-constexpr decltype(auto) // typename tuple_type_end<T, len>::type
- tuple_start(T&& t)
-{
- // We use std::decay_t<> because tuple_size is not defined for references.
+constexpr
+decltype(auto) // typename tuple_type_end<T, len>::type
+tuple_start(T&& t) {
+ //We use std::decay_t<> because tuple_size is not defined for references.
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
static_assert(len <= size, "The tuple size must be less than or equal to the length.");
@@ -86,8 +79,6 @@ constexpr decltype(auto) // typename tuple_type_end<T, len>::type
std::forward<T>(t));
}
-} // namespace internal
-
-} // namespace sigc
+} // namespace sigc::internal;
-#endif // SIGC_TUPLE_UTILS_TUPLE_START_H
+#endif //SIGC_TUPLE_UTILS_TUPLE_START_H