Skip to content

Commit 93d7e47

Browse files
authored
Merge pull request #2 from libsigcplusplus/master
Updating from the source repo.
2 parents 63045b9 + 5a95388 commit 93d7e47

File tree

4 files changed

+109
-160
lines changed

4 files changed

+109
-160
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

sigc++/tuple-utils/tuple_transform_each.h

Lines changed: 49 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -18,88 +18,57 @@
1818
#ifndef SIGC_TUPLE_UTILS_TUPLE_TRANSFORM_EACH_H
1919
#define SIGC_TUPLE_UTILS_TUPLE_TRANSFORM_EACH_H
2020

21+
// #include <sigc++/tuple-utils/tuple_cat.h>
2122
#include <sigc++/tuple-utils/tuple_cdr.h>
2223
#include <sigc++/tuple-utils/tuple_end.h>
2324
#include <sigc++/tuple-utils/tuple_start.h>
2425
#include <type_traits>
2526

26-
namespace sigc
27-
{
27+
namespace sigc::internal {
2828

29-
namespace internal
30-
{
31-
32-
namespace detail
33-
{
29+
namespace detail {
3430

3531
template <template <typename> class T_transformer, std::size_t size_from_index>
36-
struct tuple_transform_each_impl
37-
{
32+
struct tuple_transform_each_impl {
3833
// TODO: Avoid the need to pass t_original all the way into the recursion?
3934
template <typename T_current, typename T_original>
40-
constexpr static decltype(auto) tuple_transform_each(T_current&& t, T_original& t_original)
41-
{
42-
// We use std::decay_t<> because tuple_size is not defined for references.
43-
constexpr auto size = std::tuple_size<std::decay_t<T_current>>::value;
44-
static_assert(size > 1, "size must be more than 0.");
45-
46-
constexpr auto index = size - size_from_index;
47-
static_assert(index >= 0, "unexpected index.");
48-
49-
using from_element_type = typename std::tuple_element<index, std::decay_t<T_original>>::type;
50-
using to_element_type = typename std::result_of<decltype (
51-
&T_transformer<from_element_type>::transform)(from_element_type&)>::type;
52-
const auto t_element = std::tuple<to_element_type>(
53-
T_transformer<from_element_type>::transform(std::get<index>(t_original)));
54-
55-
const auto t_start = tuple_start<index>(std::forward<T_current>(t));
56-
57-
// t_end's elements will be copies of the elements in t, so this method's
58-
// caller won't see the changes made in the subsequent call of
59-
// tuple_transform_each() on those copies. That's why we pass t_original
60-
// through too, so we can modify that directly.
61-
// the const version (tuple_transform_each_const()) doesn't have to worry
62-
// about this, though avoiding copying would be more efficient.
63-
const auto t_end = tuple_end<size - index - 1>(t);
64-
65-
auto t_with_transformed_element = std::tuple_cat(t_start, t_element, t_end);
66-
return tuple_transform_each_impl<T_transformer, size_from_index - 1>::tuple_transform_each(
67-
t_with_transformed_element, t_original);
68-
}
69-
};
70-
71-
template <template <typename> class T_transformer>
72-
struct tuple_transform_each_impl<T_transformer, 1>
73-
{
74-
template <typename T_current, typename T_original>
75-
constexpr static decltype(auto) tuple_transform_each(T_current&& t, T_original& t_original)
76-
{
77-
// We use std::decay_t<> because tuple_size is not defined for references.
78-
constexpr auto size = std::tuple_size<std::decay_t<T_current>>::value;
79-
static_assert(size > 0, "size must be more than 0.");
80-
81-
constexpr auto index = size - 1;
82-
static_assert(index >= 0, "unexpected index.");
83-
84-
using from_element_type = typename std::tuple_element<index, T_original>::type;
85-
using to_element_type = typename std::result_of<decltype (
86-
&T_transformer<from_element_type>::transform)(from_element_type&)>::type;
87-
const auto tuple_element = std::tuple<to_element_type>(
88-
T_transformer<from_element_type>::transform(std::get<index>(t_original)));
89-
90-
const auto tuple_rest = tuple_start<size - 1>(std::forward<T_current>(t));
91-
return std::tuple_cat(tuple_rest, tuple_element);
92-
}
93-
};
94-
95-
template <template <typename> class T_transformer>
96-
struct tuple_transform_each_impl<T_transformer, 0>
97-
{
98-
template <typename T_current, typename T_original>
99-
constexpr static decltype(auto) tuple_transform_each(T_current&& t, T_original& /* t_original */)
100-
{
101-
// Do nothing because the tuple has no elements.
102-
return std::forward<T_current>(t);
35+
constexpr
36+
static decltype(auto)
37+
tuple_transform_each(T_current&& t, T_original& t_original) {
38+
if constexpr(size_from_index == 0) {
39+
//Do nothing because the tuple has no elements.
40+
return std::forward<T_current>(t);
41+
} else { //TODO: Should this compile without using else to contain the alternative code?
42+
//We use std::decay_t<> because tuple_size is not defined for references.
43+
constexpr auto size = std::tuple_size<std::decay_t<T_current>>::value;
44+
constexpr auto index = size - size_from_index;
45+
static_assert(index >= 0, "unexpected index.");
46+
47+
using from_element_type = typename std::tuple_element<index, std::decay_t<T_original>>::type;
48+
using to_element_type = typename std::result_of<decltype (
49+
&T_transformer<from_element_type>::transform)(from_element_type&)>::type;
50+
const auto t_element =
51+
std::tuple<to_element_type>(T_transformer<from_element_type>::transform(std::get<index>(t_original)));
52+
53+
if constexpr(size_from_index == 1) {
54+
const auto tuple_rest = tuple_start<size - 1>(std::forward<T_current>(t));
55+
return std::tuple_cat(tuple_rest, t_element);
56+
} else {
57+
const auto t_start = tuple_start<index>(std::forward<T_current>(t));
58+
59+
// t_end's elements will be copies of the elements in t, so this method's
60+
// caller won't see the changes made in the subsequent call of
61+
// tuple_transform_each() on those copies. That's why we pass t_original
62+
// through too, so we can modify that directly.
63+
// the const version (tuple_transform_each_const()) doesn't have to worry
64+
// about this, though avoiding copying would be more efficient.
65+
const auto t_end = tuple_end<size - index - 1>(t);
66+
67+
auto t_with_transformed_element = std::tuple_cat(t_start, t_element, t_end);
68+
return tuple_transform_each_impl<T_transformer,
69+
size_from_index - 1>::tuple_transform_each(t_with_transformed_element, t_original);
70+
}
71+
}
10372
}
10473
};
10574

@@ -110,18 +79,16 @@ struct tuple_transform_each_impl<T_transformer, 0>
11079
* in the original tuple.
11180
*/
11281
template <template <typename> class T_transformer, typename T>
113-
constexpr decltype(auto)
114-
tuple_transform_each(T&& t)
115-
{
116-
// We use std::decay_t<> because tuple_size is not defined for references.
82+
constexpr
83+
decltype(auto)
84+
tuple_transform_each(T&& t) {
85+
//We use std::decay_t<> because tuple_size is not defined for references.
11786
constexpr auto size = std::tuple_size<std::decay_t<T>>::value;
11887

119-
return detail::tuple_transform_each_impl<T_transformer, size>::tuple_transform_each(
120-
std::forward<T>(t), t);
88+
return detail::tuple_transform_each_impl<T_transformer,
89+
size>::tuple_transform_each(std::forward<T>(t), t);
12190
}
12291

123-
} // namespace internal
124-
125-
} // namespace sigc
92+
} // namespace sigc::internal
12693

127-
#endif // SIGC_TUPLE_UTILS_TUPLE_TRANSFORM_EACH_H
94+
#endif //SIGC_TUPLE_UTILS_TUPLE_TRANSFORM_EACH_H

0 commit comments

Comments
 (0)