Skip to content

Commit 1759faf

Browse files
committed
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.
1 parent 12ad173 commit 1759faf

File tree

3 files changed

+60
-78
lines changed

3 files changed

+60
-78
lines changed

sigc++/tuple-utils/tuple_cdr.h

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@
2222
#include <type_traits>
2323
#include <utility>
2424

25-
namespace sigc
26-
{
27-
28-
namespace internal
29-
{
25+
namespace sigc::internal {
3026

3127
/**
3228
* Get the type of a tuple without the first item.
@@ -41,11 +37,11 @@ struct tuple_type_cdr<std::tuple<H, T...>>
4137
using type = std::tuple<T...>;
4238
};
4339

44-
namespace detail
45-
{
40+
namespace detail {
4641

4742
template <typename T, std::size_t... I>
48-
constexpr decltype(auto)
43+
constexpr
44+
decltype(auto)
4945
tuple_cdr_impl(T&& t, std::index_sequence<0, I...>)
5046
{
5147
using cdr = typename tuple_type_cdr<std::decay_t<T>>::type;
@@ -59,19 +55,17 @@ tuple_cdr_impl(T&& t, std::index_sequence<0, I...>)
5955
* This is analogous to std::tuple_cat().
6056
*/
6157
template <typename T>
62-
constexpr decltype(auto)
63-
tuple_cdr(T&& t)
64-
{
65-
// We use std::decay_t<> because tuple_size is not defined for references.
58+
constexpr
59+
decltype(auto)
60+
tuple_cdr(T&& t) {
61+
//We use std::decay_t<> because tuple_size is not defined for references.
6662
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
6763

6864
static_assert(size != 0, "tuple size must be non-zero");
6965
using seq = std::make_index_sequence<size>;
7066
return detail::tuple_cdr_impl(std::forward<T>(t), seq{});
7167
}
7268

73-
} // namespace internal
74-
75-
} // namespace sigc
69+
} // namespace sigc::internal
7670

77-
#endif // SIGC_TUPLE_UTILS_TUPLE_CDR_H
71+
#endif //SIGC_TUPLE_UTILS_TUPLE_CDR_H

sigc++/tuple-utils/tuple_end.h

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,58 +20,55 @@
2020

2121
#include <sigc++/tuple-utils/tuple_cdr.h>
2222

23-
namespace sigc
24-
{
23+
namespace sigc::internal {
2524

26-
namespace internal
27-
{
28-
29-
namespace detail
30-
{
25+
namespace detail {
3126

3227
template <typename T, std::size_t remove_from_start>
33-
struct tuple_end_impl
34-
{
35-
constexpr static decltype(auto) // typename tuple_type_end<T, size - remove_from_start>::type
36-
tuple_end(T&& t)
37-
{
38-
static_assert(remove_from_start > 0, "remove_from_start must be more than zero.");
39-
40-
using cdr = typename tuple_type_cdr<std::decay_t<T>>::type;
41-
return tuple_end_impl<cdr, remove_from_start - 1>::tuple_end(tuple_cdr(std::forward<T>(t)));
42-
}
43-
};
44-
45-
template <typename T>
46-
struct tuple_end_impl<T, 1>
47-
{
48-
constexpr static decltype(auto) tuple_end(T&& t) { return tuple_cdr(std::forward<T>(t)); }
28+
struct tuple_type_end_impl {
29+
using type = typename tuple_type_end_impl<typename tuple_type_cdr<std::decay_t<T>>::type,
30+
remove_from_start - 1>::type;
4931
};
5032

5133
template <typename T>
52-
struct tuple_end_impl<T, 0>
53-
{
54-
constexpr static decltype(auto) tuple_end(T&& t) { return std::forward<T>(t); }
34+
struct tuple_type_end_impl<T, 0> {
35+
using type = T;
5536
};
5637

5738
} // detail namespace
5839

40+
/**
41+
* Get the type of a tuple with the last @a len types of the original.
42+
*/
43+
template <typename T, std::size_t len>
44+
struct tuple_type_end
45+
: detail::tuple_type_end_impl<T, std::tuple_size<T>::value - len> {};
46+
5947
/**
6048
* Get the tuple with the last @a len items of the original.
6149
*/
6250
template <std::size_t len, typename T>
63-
constexpr decltype(auto) // typename tuple_type_end<T, len>::type
64-
tuple_end(T&& t)
65-
{
66-
// We use std::decay_t<> because tuple_size is not defined for references.
51+
constexpr
52+
decltype(auto) // typename tuple_type_end<T, len>::type
53+
tuple_end(T&& t) {
54+
//We use std::decay_t<> because tuple_size is not defined for references.
6755
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
6856
static_assert(len <= size, "The tuple size must be less than or equal to the length.");
69-
constexpr auto size_start = size - len;
70-
return detail::tuple_end_impl<T, size_start>::tuple_end(std::forward<T>(t));
71-
}
7257

73-
} // namespace internal
58+
if constexpr(len == 0) {
59+
// Recursive calls to tuple_cdr() would result in this eventually,
60+
// but this avoids the extra work:
61+
return std::tuple<>();
62+
} else if constexpr(size - len == 0) {
63+
return std::forward<T>(t);
64+
} else if constexpr(size - len == 1) {
65+
return tuple_cdr(std::forward<T>(t));
66+
} else {
67+
return tuple_end<len>(
68+
tuple_cdr(std::forward<T>(t)));
69+
}
70+
}
7471

75-
} // namespace sigc
72+
} // namespace sigc::internal;
7673

77-
#endif // SIGC_TUPLE_UTILS_TUPLE_END_H
74+
#endif //SIGC_TUPLE_UTILS_TUPLE_END_H

sigc++/tuple-utils/tuple_start.h

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,15 @@
2121
#include <tuple>
2222
#include <utility>
2323

24-
namespace sigc
25-
{
24+
namespace sigc::internal {
2625

27-
namespace internal
28-
{
29-
30-
namespace detail
31-
{
26+
namespace detail {
3227

3328
template <typename T, typename Seq>
3429
struct tuple_type_start_impl;
3530

3631
template <typename T, std::size_t... I>
37-
struct tuple_type_start_impl<T, std::index_sequence<I...>>
38-
{
32+
struct tuple_type_start_impl<T, std::index_sequence<I...>> {
3933
using type = std::tuple<typename std::tuple_element<I, T>::type...>;
4034
};
4135

@@ -45,21 +39,20 @@ struct tuple_type_start_impl<T, std::index_sequence<I...>>
4539
* Get the type of a tuple with just the first @len items.
4640
*/
4741
template <typename T, std::size_t len>
48-
struct tuple_type_start : detail::tuple_type_start_impl<T, std::make_index_sequence<len>>
49-
{
50-
};
42+
struct tuple_type_start
43+
: detail::tuple_type_start_impl<T, std::make_index_sequence<len>> {};
5144

52-
namespace detail
53-
{
45+
namespace detail {
5446

5547
template <typename T, typename Seq>
5648
struct tuple_start_impl;
5749

5850
template <typename T, std::size_t... I>
59-
struct tuple_start_impl<T, std::index_sequence<I...>>
60-
{
61-
static constexpr decltype(auto) tuple_start(T&& t)
62-
{
51+
struct tuple_start_impl<T, std::index_sequence<I...>> {
52+
static
53+
constexpr
54+
decltype(auto)
55+
tuple_start(T&& t) {
6356
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
6457
constexpr auto len = sizeof...(I);
6558
static_assert(len <= size, "The tuple size must be less than or equal to the length.");
@@ -75,19 +68,17 @@ struct tuple_start_impl<T, std::index_sequence<I...>>
7568
* Get the tuple with the last @a len items of the original.
7669
*/
7770
template <std::size_t len, typename T>
78-
constexpr decltype(auto) // typename tuple_type_end<T, len>::type
79-
tuple_start(T&& t)
80-
{
81-
// We use std::decay_t<> because tuple_size is not defined for references.
71+
constexpr
72+
decltype(auto) // typename tuple_type_end<T, len>::type
73+
tuple_start(T&& t) {
74+
//We use std::decay_t<> because tuple_size is not defined for references.
8275
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
8376
static_assert(len <= size, "The tuple size must be less than or equal to the length.");
8477

8578
return detail::tuple_start_impl<T, std::make_index_sequence<len>>::tuple_start(
8679
std::forward<T>(t));
8780
}
8881

89-
} // namespace internal
90-
91-
} // namespace sigc
82+
} // namespace sigc::internal;
9283

93-
#endif // SIGC_TUPLE_UTILS_TUPLE_START_H
84+
#endif //SIGC_TUPLE_UTILS_TUPLE_START_H

0 commit comments

Comments
 (0)