-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest.cpp
More file actions
112 lines (87 loc) · 2.42 KB
/
test.cpp
File metadata and controls
112 lines (87 loc) · 2.42 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
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
template < typename T, T... Is >
struct integer_sequence {};
// Populate integer_sequence recursively
template < typename T, typename N, typename... Is >
struct make_integer_sequence_impl
{
using type = typename make_integer_sequence_impl<
T,
std::integral_constant<T,N::value-1>,
std::integral_constant<T,N::value>,
std::integral_constant<T,Is::value>...
>::type;
};
template < typename T, typename... Is >
struct make_integer_sequence_impl<T,std::integral_constant<T,0>,Is...>
{
using type = integer_sequence<T,0,Is::value...>;
};
// Interface
template < typename T, typename N >
struct make_integer_sequence_t
{
using type = typename make_integer_sequence_impl<
T,
std::integral_constant<T,N::value-2>,
std::integral_constant<T,N::value-1>
>::type;
};
template < typename T >
struct make_integer_sequence_t<T,std::integral_constant<T,0>>
{
using type = integer_sequence<T>;
};
template < typename T >
struct make_integer_sequence_t<T,std::integral_constant<T,1>>
{
using type = integer_sequence<T,0>;
};
// Handy typedef
template < typename T, T N >
using make_integer_sequence =
typename make_integer_sequence_t<T,std::integral_constant<T,N>>::type;
// From that derive index_sequence
template < size_t... Is >
using index_sequence = integer_sequence<size_t,Is...>;
template < size_t N >
using make_index_sequence = make_integer_sequence<size_t,N>;
// Call a function for each element in a tuple
template < typename T, typename F, size_t ... Is >
void for_each_impl(T&& t, F&& f, index_sequence<Is...>)
{
using expand_type = int[];
(void) expand_type { 0, ( (void) f(std::get<Is>(t)), 0) ... };
}
template < typename... Args, typename F >
void for_each(std::tuple<Args...> const& t, F&& f)
{
for_each_impl(t, f, make_index_sequence<sizeof...(Args)>{});
}
// "Byte array" emulation
struct Bytes {
std::string str;
Bytes(char const * c) : str(c) {};
Bytes(int i) : str(std::to_string(i)) {};
Bytes(char c) : str(1, c) {};
};
// Surrogate template lambda
struct Visitor
{
std::vector<Bytes>& v;
Visitor(std::vector<Bytes>& vb) : v(vb) {};
template < typename T >
void operator() (T&& x) { v.push_back(x); }
};
int main()
{
auto t = std::make_tuple(12, "abc", 10, 'c', 1);
std::vector<Bytes> v;
for_each(t, Visitor(v));
for (auto const& e : v)
std::cout << e.str << ' ';
std::cout << '\n';
}