1 
2 // Copyright 2015, 2017 Peter Dimov.
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 //
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 
9 
10 #if defined(_MSC_VER)
11 #pragma warning( disable: 4244 ) // 'initializing': conversion from 'int' to 'char', possible loss of data
12 #endif
13 
14 #include <boost/mp11/tuple.hpp>
15 #include <boost/mp11/detail/config.hpp>
16 #include <boost/core/lightweight_test.hpp>
17 #include <tuple>
18 #include <memory>
19 #include <utility>
20 #include <array>
21 
22 struct T1
23 {
24     int x, y, z;
25 
T1T126     T1( int x = 0, int y = 0, int z = 0 ): x(x), y(y), z(z) {}
27 };
28 
29 struct T2
30 {
31     std::unique_ptr<int> x, y, z;
32 
T2T233     T2( std::unique_ptr<int> x, std::unique_ptr<int> y, std::unique_ptr<int> z ): x(std::move(x)), y(std::move(y)), z(std::move(z)) {}
34 
35 #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
36 
T2T237     T2( T2&& r ): x( std::move(r.x) ), y( std::move(r.y) ), z( std::move(r.z) ) {}
38 
39 #endif
40 };
41 
main()42 int main()
43 {
44     using boost::mp11::construct_from_tuple;
45 
46     {
47         std::tuple<int, short, char> tp{ 1, 2, 3 };
48 
49         {
50             T1 t1 = construct_from_tuple<T1>( tp );
51 
52             BOOST_TEST_EQ( t1.x, 1 );
53             BOOST_TEST_EQ( t1.y, 2 );
54             BOOST_TEST_EQ( t1.z, 3 );
55         }
56 
57         {
58             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
59 
60             BOOST_TEST_EQ( t1.x, 1 );
61             BOOST_TEST_EQ( t1.y, 2 );
62             BOOST_TEST_EQ( t1.z, 3 );
63         }
64     }
65 
66     {
67         std::tuple<int, short, char> const tp{ 1, 2, 3 };
68 
69         {
70             T1 t1 = construct_from_tuple<T1>( tp );
71 
72             BOOST_TEST_EQ( t1.x, 1 );
73             BOOST_TEST_EQ( t1.y, 2 );
74             BOOST_TEST_EQ( t1.z, 3 );
75         }
76 
77         {
78             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
79 
80             BOOST_TEST_EQ( t1.x, 1 );
81             BOOST_TEST_EQ( t1.y, 2 );
82             BOOST_TEST_EQ( t1.z, 3 );
83         }
84     }
85 
86 #if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 8
87 #else
88 
89     {
90         std::tuple<std::unique_ptr<int>, std::unique_ptr<int>, std::unique_ptr<int>> tp{ std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2)), std::unique_ptr<int>(new int(3)) };
91 
92             T2 t2 = construct_from_tuple<T2>( std::move(tp) );
93 
94             BOOST_TEST_EQ( *t2.x, 1 );
95             BOOST_TEST_EQ( *t2.y, 2 );
96             BOOST_TEST_EQ( *t2.z, 3 );
97     }
98 
99 #endif
100 
101     {
102         std::pair<int, short> tp{ 1, 2 };
103 
104         {
105             T1 t1 = construct_from_tuple<T1>( tp );
106 
107             BOOST_TEST_EQ( t1.x, 1 );
108             BOOST_TEST_EQ( t1.y, 2 );
109             BOOST_TEST_EQ( t1.z, 0 );
110         }
111 
112         {
113             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
114 
115             BOOST_TEST_EQ( t1.x, 1 );
116             BOOST_TEST_EQ( t1.y, 2 );
117             BOOST_TEST_EQ( t1.z, 0 );
118         }
119     }
120 
121     {
122         std::pair<int, short> const tp{ 1, 2 };
123 
124         {
125             T1 t1 = construct_from_tuple<T1>( tp );
126 
127             BOOST_TEST_EQ( t1.x, 1 );
128             BOOST_TEST_EQ( t1.y, 2 );
129             BOOST_TEST_EQ( t1.z, 0 );
130         }
131 
132         {
133             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
134 
135             BOOST_TEST_EQ( t1.x, 1 );
136             BOOST_TEST_EQ( t1.y, 2 );
137             BOOST_TEST_EQ( t1.z, 0 );
138         }
139     }
140 
141     {
142         std::array<int, 3> tp{{ 1, 2, 3 }};
143 
144         {
145             T1 t1 = construct_from_tuple<T1>( tp );
146 
147             BOOST_TEST_EQ( t1.x, 1 );
148             BOOST_TEST_EQ( t1.y, 2 );
149             BOOST_TEST_EQ( t1.z, 3 );
150         }
151 
152         {
153             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
154 
155             BOOST_TEST_EQ( t1.x, 1 );
156             BOOST_TEST_EQ( t1.y, 2 );
157             BOOST_TEST_EQ( t1.z, 3 );
158         }
159     }
160 
161     {
162         std::array<int, 3> const tp{{ 1, 2, 3 }};
163 
164         {
165             T1 t1 = construct_from_tuple<T1>( tp );
166 
167             BOOST_TEST_EQ( t1.x, 1 );
168             BOOST_TEST_EQ( t1.y, 2 );
169             BOOST_TEST_EQ( t1.z, 3 );
170         }
171 
172         {
173             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
174 
175             BOOST_TEST_EQ( t1.x, 1 );
176             BOOST_TEST_EQ( t1.y, 2 );
177             BOOST_TEST_EQ( t1.z, 3 );
178         }
179     }
180 
181     {
182         std::tuple<> tp;
183 
184         {
185             T1 t1 = construct_from_tuple<T1>( tp );
186 
187             BOOST_TEST_EQ( t1.x, 0 );
188             BOOST_TEST_EQ( t1.y, 0 );
189             BOOST_TEST_EQ( t1.z, 0 );
190         }
191 
192         {
193             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
194 
195             BOOST_TEST_EQ( t1.x, 0 );
196             BOOST_TEST_EQ( t1.y, 0 );
197             BOOST_TEST_EQ( t1.z, 0 );
198         }
199     }
200 
201     {
202         std::array<int, 0> tp;
203 
204         {
205             T1 t1 = construct_from_tuple<T1>( tp );
206 
207             BOOST_TEST_EQ( t1.x, 0 );
208             BOOST_TEST_EQ( t1.y, 0 );
209             BOOST_TEST_EQ( t1.z, 0 );
210         }
211 
212         {
213             T1 t1 = construct_from_tuple<T1>( std::move(tp) );
214 
215             BOOST_TEST_EQ( t1.x, 0 );
216             BOOST_TEST_EQ( t1.y, 0 );
217             BOOST_TEST_EQ( t1.z, 0 );
218         }
219     }
220 
221     return boost::report_errors();
222 }
223