• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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