1
2 // Copyright 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 #include <boost/variant2/variant.hpp>
10 #include <boost/core/lightweight_test.hpp>
11 #include <boost/core/lightweight_test_trait.hpp>
12 #include <type_traits>
13 #include <utility>
14 #include <string>
15
16 using namespace boost::variant2;
17
18 #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
19
20 struct X1
21 {
22 int v;
23
X1X124 X1(): v(0) {}
X1X125 explicit X1(int v): v(v) {}
X1X126 X1(X1 const& r): v(r.v) {}
X1X127 X1(X1&& r): v(r.v) {}
operator =X128 X1& operator=( X1 const& r ) { v = r.v; return *this; }
operator =X129 X1& operator=( X1&& r ) { v = r.v; return *this; }
30 };
31
operator ==(X1 const & a,X1 const & b)32 inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
33
34 STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
35 STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
36 STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
37 STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
38 STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
39
40 struct X2
41 {
42 int v;
43
X2X244 X2(): v(0) {}
X2X245 explicit X2(int v): v(v) {}
X2X246 X2(X2 const& r): v(r.v) {}
X2X247 X2(X2&& r): v(r.v) {}
operator =X248 X2& operator=( X2 const& r ) { v = r.v; return *this; }
operator =X249 X2& operator=( X2&& r ) { v = r.v; return *this; }
50 };
51
operator ==(X2 const & a,X2 const & b)52 inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
53
54 STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
55 STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
56 STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
57 STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
58 STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
59
main()60 int main()
61 {
62 {
63 variant<int> v( 1 );
64
65 variant<int, float> v2( v );
66
67 BOOST_TEST( holds_alternative<int>( v2 ) );
68 BOOST_TEST_EQ( get<int>( v ), get<int>( v2 ) );
69
70 variant<int, float> v3( std::move(v) );
71
72 BOOST_TEST( holds_alternative<int>( v3 ) );
73 BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
74 }
75
76 {
77 variant<int> const v( 1 );
78
79 variant<int, float> v2( v );
80
81 BOOST_TEST( holds_alternative<int>( v2 ) );
82 BOOST_TEST_EQ( get<int>( v ), get<int>( v2 ) );
83
84 variant<int, float> v3( std::move(v) );
85
86 BOOST_TEST( holds_alternative<int>( v3 ) );
87 BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
88 }
89
90 {
91 variant<int const> v( 1 );
92
93 variant<int const, float> v2( v );
94
95 BOOST_TEST( holds_alternative<int const>( v2 ) );
96 BOOST_TEST_EQ( get<int const>( v ), get<int const>( v2 ) );
97
98 variant<int const, float> v3( std::move(v) );
99
100 BOOST_TEST( holds_alternative<int const>( v3 ) );
101 BOOST_TEST_EQ( get<int const>( v2 ), get<int const>( v3 ) );
102 }
103
104 {
105 variant<int const> const v( 1 );
106
107 variant<int const, float> v2( v );
108
109 BOOST_TEST( holds_alternative<int const>( v2 ) );
110 BOOST_TEST_EQ( get<int const>( v ), get<int const>( v2 ) );
111
112 variant<int const, float> v3( std::move(v) );
113
114 BOOST_TEST( holds_alternative<int const>( v3 ) );
115 BOOST_TEST_EQ( get<int const>( v2 ), get<int const>( v3 ) );
116 }
117
118 {
119 variant<float> v( 3.14f );
120
121 variant<int, float> v2( v );
122
123 BOOST_TEST( holds_alternative<float>( v2 ) );
124 BOOST_TEST_EQ( get<float>( v ), get<float>( v2 ) );
125
126 variant<int, float> v3( std::move(v) );
127
128 BOOST_TEST( holds_alternative<float>( v3 ) );
129 BOOST_TEST_EQ( get<float>( v2 ), get<float>( v3 ) );
130 }
131
132 {
133 variant<float> v( 3.15f );
134
135 variant<int, int, float> v2( v );
136
137 BOOST_TEST( holds_alternative<float>( v2 ) );
138 BOOST_TEST_EQ( get<float>( v ), get<float>( v2 ) );
139
140 variant<int, int, float> v3( std::move(v) );
141
142 BOOST_TEST( holds_alternative<float>( v3 ) );
143 BOOST_TEST_EQ( get<float>( v2 ), get<float>( v3 ) );
144 }
145
146 {
147 variant<float, std::string> v( "s1" );
148
149 variant<int, int, float, std::string> v2( v );
150
151 BOOST_TEST( holds_alternative<std::string>( v2 ) );
152 BOOST_TEST_EQ( get<std::string>( v ), get<std::string>( v2 ) );
153
154 variant<int, int, float, std::string> v3( std::move(v) );
155
156 BOOST_TEST( holds_alternative<std::string>( v3 ) );
157 BOOST_TEST_EQ( get<std::string>( v2 ), get<std::string>( v3 ) );
158 }
159
160 {
161 variant<X1, X2> v{ X1{1} };
162
163 variant<int, int, float, float, X1, X2> v2( v );
164
165 BOOST_TEST( holds_alternative<X1>( v2 ) );
166 BOOST_TEST_EQ( get<X1>( v ).v, get<X1>( v2 ).v );
167
168 variant<int, int, float, float, X1, X2> v3( std::move(v) );
169
170 BOOST_TEST( holds_alternative<X1>( v3 ) );
171 BOOST_TEST_EQ( get<X1>( v2 ).v, get<X1>( v3 ).v );
172 }
173
174 return boost::report_errors();
175 }
176