1 // Copyright 2020 Peter Dimov
2 // Distributed under the Boost Software License, Version 1.0.
3 // https://www.boost.org/LICENSE_1_0.txt
4
5 #include <boost/mp11/tuple.hpp>
6 #include <boost/mp11/algorithm.hpp>
7 #include <boost/core/lightweight_test.hpp>
8 #include <tuple>
9 #include <utility>
10 #include <array>
11 #include <cstddef>
12
f(int x)13 int f( int x )
14 {
15 return x + 1;
16 }
17
g(int x,int y)18 int g( int x, int y )
19 {
20 return x + y;
21 }
22
h(int x,int y,int z)23 int h( int x, int y, int z )
24 {
25 return x + y + z;
26 }
27
q(int x,int y,int z,int v)28 int q( int x, int y, int z, int v )
29 {
30 return x + y + z + v;
31 }
32
make_array(T1 t1,T...t)33 template<class T1, class... T> std::array<T1, 1 + sizeof...(T)> make_array( T1 t1, T... t )
34 {
35 return { { t1, t... } };
36 }
37
38 template<class Tp> struct test_element
39 {
40 Tp& tp;
41
operator ()test_element42 template<int I> void operator()( boost::mp11::mp_int<I> ) const
43 {
44 BOOST_TEST_EQ( std::get<I>( tp ), q( I, I, I, I ) );
45 }
46 };
47
main()48 int main()
49 {
50 using boost::mp11::tuple_transform;
51
52 //
53
54 {
55 std::tuple<int> r = tuple_transform( f, std::make_tuple( 1 ) );
56
57 BOOST_TEST_EQ( std::get<0>( r ), 2 );
58 }
59
60 {
61 std::tuple<int> r = tuple_transform( f, ::make_array( 1 ) );
62
63 BOOST_TEST_EQ( std::get<0>( r ), 2 );
64 }
65
66 {
67 std::tuple<int> r = tuple_transform( g, ::make_array( 1 ), std::make_tuple( 2 ) );
68
69 BOOST_TEST_EQ( std::get<0>( r ), 3 );
70 }
71
72 {
73 std::tuple<int> r = tuple_transform( h, ::make_array( 1 ), std::make_tuple( 2 ), ::make_array( 3 ) );
74
75 BOOST_TEST_EQ( std::get<0>( r ), 6 );
76 }
77
78 //
79
80 {
81 std::tuple<int, int> r = tuple_transform( f, std::make_tuple( 1, 2 ) );
82
83 BOOST_TEST_EQ( std::get<0>( r ), 2 );
84 BOOST_TEST_EQ( std::get<1>( r ), 3 );
85 }
86
87 {
88 std::tuple<int, int> r = tuple_transform( f, std::make_pair( 1, 2 ) );
89
90 BOOST_TEST_EQ( std::get<0>( r ), 2 );
91 BOOST_TEST_EQ( std::get<1>( r ), 3 );
92 }
93
94 {
95 std::tuple<int, int> r = tuple_transform( f, ::make_array( 1, 2 ) );
96
97 BOOST_TEST_EQ( std::get<0>( r ), 2 );
98 BOOST_TEST_EQ( std::get<1>( r ), 3 );
99 }
100
101 {
102 std::tuple<int, int> r = tuple_transform( g, ::make_array( 1, 2 ), std::make_pair( 3, 4 ) );
103
104 BOOST_TEST_EQ( std::get<0>( r ), 4 );
105 BOOST_TEST_EQ( std::get<1>( r ), 6 );
106 }
107
108 {
109 std::tuple<int, int> r = tuple_transform( h, ::make_array( 1, 2 ), std::make_pair( 3, 4 ), std::make_tuple( 5, 6 ) );
110
111 BOOST_TEST_EQ( std::get<0>( r ), 9 );
112 BOOST_TEST_EQ( std::get<1>( r ), 12 );
113 }
114
115 //
116
117 {
118 std::tuple<int, int, int> r = tuple_transform( f, std::make_tuple( 1, 2, 3 ) );
119
120 BOOST_TEST_EQ( std::get<0>( r ), 2 );
121 BOOST_TEST_EQ( std::get<1>( r ), 3 );
122 BOOST_TEST_EQ( std::get<2>( r ), 4 );
123 }
124
125 {
126 std::tuple<int, int, int> r = tuple_transform( f, ::make_array( 1, 2, 3 ) );
127
128 BOOST_TEST_EQ( std::get<0>( r ), 2 );
129 BOOST_TEST_EQ( std::get<1>( r ), 3 );
130 BOOST_TEST_EQ( std::get<2>( r ), 4 );
131 }
132
133 {
134 std::tuple<int, int, int> r = tuple_transform( g, ::make_array( 1, 2, 3 ), std::make_tuple( 4, 5, 6 ) );
135
136 BOOST_TEST_EQ( std::get<0>( r ), 5 );
137 BOOST_TEST_EQ( std::get<1>( r ), 7 );
138 BOOST_TEST_EQ( std::get<2>( r ), 9 );
139 }
140
141 {
142 std::tuple<int, int, int> r = tuple_transform( h, ::make_array( 1, 2, 3 ), std::make_tuple( 4, 5, 6 ), ::make_array( 7, 8, 9 ) );
143
144 BOOST_TEST_EQ( std::get<0>( r ), 12 );
145 BOOST_TEST_EQ( std::get<1>( r ), 15 );
146 BOOST_TEST_EQ( std::get<2>( r ), 18 );
147 }
148
149 #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
150
151 {
152 using namespace boost::mp11;
153
154 int const N = 12;
155
156 using Tp = mp_rename<mp_iota< mp_int<N> >, std::tuple>;
157
158 auto const r = tuple_transform( q, Tp(), Tp(), Tp(), Tp() );
159
160 mp_for_each<Tp>( test_element<decltype(r)>{ r } );
161 }
162
163 #endif
164
165 return boost::report_errors();
166 }
167