forked from SGSSGene/StandardCplusplus
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtuple
145 lines (116 loc) · 3.4 KB
/
tuple
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#pragma once
#include <functional>
#include <type_traits>
#include <utility>
namespace std
{
template <typename First, typename... Rest>
struct tuple : public tuple<Rest...>
{
tuple() = default;
tuple(First first, Rest... rest) : tuple<Rest...>(rest...), _item(first) {}
First _item;
};
template <typename First>
struct tuple<First>
{
tuple() = default;
tuple(First first) : _item(first) {}
First _item;
};
template<size_t I, class T>
struct tuple_element;
// recursive case
template <size_t I, class Head, class... Tail>
struct tuple_element<I, tuple<Head, Tail...>>
: tuple_element<I - 1, tuple<Tail...>>
{
};
// base case
template <class Head, class... Tail>
struct tuple_element<0, tuple<Head, Tail...>>
{
typedef Head type;
};
template<size_t I, typename... Ts>
using tuple_element_t = typename tuple_element<I, Ts...>::type;
namespace detail {
template <int index, typename First, typename... Rest>
struct tuple_getter
{
static auto value(const tuple<First, Rest...> *t) -> decltype(tuple_getter<index - 1, Rest...>::value(t))
{
return tuple_getter<index - 1, Rest...>::value(t);
}
static auto value(tuple<First, Rest...> *t) -> decltype(tuple_getter<index - 1, Rest...>::value(t))
{
return tuple_getter<index - 1, Rest...>::value(t);
}
};
template <typename First, typename... Rest>
struct tuple_getter<0, First, Rest...>
{
static const First& value(const tuple<First, Rest...> *t)
{
return t->_item;
}
static First& value(tuple<First, Rest...> *t)
{
return t->_item;
}
};
}
template <size_t index, typename First, typename... Rest>
auto get(const tuple<First, Rest...> &t) -> decltype(detail::tuple_getter<index, First, Rest...>::value(&t))
{
return detail::tuple_getter<index, First, Rest...>::value(&t);
}
template <size_t index, typename First, typename... Rest>
auto get(tuple<First, Rest...> &t) -> decltype(detail::tuple_getter<index, First, Rest...>::value(&t))
{
return detail::tuple_getter<index, First, Rest...>::value(&t);
}
template< class T >
class tuple_size; /*undefined*/
template< class... Types >
class tuple_size< tuple<Types...> >
: public integral_constant<size_t, sizeof...(Types)> { };
template< class T >
class tuple_size<const T>
: public integral_constant<size_t, tuple_size<T>::value> { };
template< class T >
class tuple_size< volatile T >
: public integral_constant<size_t, tuple_size<T>::value> { };
template< class T >
class tuple_size< const volatile T >
: public integral_constant<size_t, tuple_size<T>::value> { };
#if __cplusplus >= 201703L // c++17
template< class T >
inline constexpr size_t tuple_size_v = tuple_size<T>::value;
#endif
template <typename... Elements>
constexpr
tuple<Elements &&...> forward_as_tuple(Elements &&...args) noexcept
{
return tuple<Elements &&...>(forward<Elements>(args)...);
}
namespace detail {
template <class T>
struct unwrap_refwrapper
{
using type = T;
};
template <class T>
struct unwrap_refwrapper<reference_wrapper<T>>
{
using type = T&;
};
template <class T>
using special_decay_t = typename unwrap_refwrapper<typename decay<T>::type>::type;
}
template <typename... Types>
auto make_tuple(Types&&... args)
{
return tuple<detail::special_decay_t<Types>...>(forward<Types>(args)...);
}
} // namespace std