Skip to content

Commit

Permalink
C++17: Update from murrayc-tuple-utils.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
murraycu committed Apr 15, 2018
1 parent 12ad173 commit 1759faf
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 78 deletions.
26 changes: 10 additions & 16 deletions sigc++/tuple-utils/tuple_cdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand All @@ -59,19 +55,17 @@ 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");
using seq = std::make_index_sequence<size>;
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
69 changes: 33 additions & 36 deletions sigc++/tuple-utils/tuple_end.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
43 changes: 17 additions & 26 deletions sigc++/tuple-utils/tuple_start.h
Original file line number Diff line number Diff line change
Expand Up @@ -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...>;
};

Expand All @@ -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.");
Expand All @@ -75,19 +68,17 @@ 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.");

return detail::tuple_start_impl<T, std::make_index_sequence<len>>::tuple_start(
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

0 comments on commit 1759faf

Please sign in to comment.