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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy