forked from VioletGiraffe/StandardCplusplus
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtuple
More file actions
135 lines (108 loc) · 3.2 KB
/
tuple
File metadata and controls
135 lines (108 loc) · 3.2 KB
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
#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<std::size_t I, class T>
struct tuple_element;
// recursive case
template <std::size_t I, class Head, class... Tail>
struct tuple_element<I, std::tuple<Head, Tail...>>
: std::tuple_element<I - 1, std::tuple<Tail...>>
{
};
// base case
template <class Head, class... Tail>
struct tuple_element<0, std::tuple<Head, Tail...>>
{
typedef Head 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< std::tuple<Types...> >
: public std::integral_constant<std::size_t, sizeof...(Types)> { };
template< class T >
class tuple_size<const T>
: public std::integral_constant<std::size_t, tuple_size<T>::value> { };
template< class T >
class tuple_size< volatile T >
: public std::integral_constant<std::size_t, tuple_size<T>::value> { };
template< class T >
class tuple_size< const volatile T >
: public std::integral_constant<std::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
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 std::decay<T>::type>::type;
}
template <typename... Types>
auto make_tuple(Types&&... args)
{
return std::tuple<detail::special_decay_t<Types>...>(std::forward<Types>(args)...);
}
}