diff options
author | Murray Cumming <murrayc@murrayc.com> | 2018-04-15 11:10:45 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2018-04-15 11:15:23 +0200 |
commit | 1759faf552248373714acc573b55421e86cb94cc (patch) | |
tree | 8cdb2c9a71514db3682b496bcff9c25ef6103e1f /sigc++/tuple-utils | |
parent | 12ad173361ce3f8fe2a3cee8c53397891e33abd1 (diff) | |
download | sigc++-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.h | 26 | ||||
-rw-r--r-- | sigc++/tuple-utils/tuple_end.h | 69 | ||||
-rw-r--r-- | sigc++/tuple-utils/tuple_start.h | 43 |
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 |