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 <boost/config.hpp>
13 #include <boost/config/workaround.hpp>
14 #include <type_traits>
15 #include <utility>
16 #include <string>
17
18 using namespace boost::variant2;
19
20 #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
21
22 struct X1
23 {
X1X124 X1() {}
X1X125 X1(X1 const&) {}
X1X126 X1(X1&&) {}
27 };
28
operator ==(X1,X1)29 inline bool operator==( X1, X1 ) { return true; }
30
31 STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
32 STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
33 STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
34
35 struct X2
36 {
X2X237 X2() {}
X2X238 X2(X2 const&) {}
X2X239 X2(X2&&) {}
40 };
41
operator ==(X2,X2)42 inline bool operator==( X2, X2 ) { return true; }
43
44 STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
45 STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
46 STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
47
48 struct Y
49 {
50 Y( Y const& ) = delete;
51 };
52
53 struct D
54 {
~DD55 ~D() {}
56 };
57
operator ==(D,D)58 inline bool operator==( D, D ) { return true; }
59
test(V const & v)60 template<class V> static void test( V const & v )
61 {
62 V v2( v );
63
64 BOOST_TEST_EQ( v.index(), v2.index() );
65 BOOST_TEST( v == v2 );
66
67 BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<V>));
68 }
69
main()70 int main()
71 {
72 test( variant<int>() );
73 test( variant<int>(1) );
74
75 test( variant<int const>() );
76 test( variant<int const>(1) );
77
78 test( variant<int, float>() );
79 test( variant<int, float>(1) );
80 test( variant<int, float>(3.14f) );
81
82 test( variant<int const, float const>() );
83 test( variant<int const, float const>(1) );
84 test( variant<int const, float const>(3.14f) );
85
86 test( variant<std::string>() );
87 test( variant<std::string>("test") );
88
89 test( variant<std::string const>() );
90 test( variant<std::string const>("test") );
91
92 test( variant<int, float, std::string>() );
93 test( variant<int, float, std::string>(1) );
94 test( variant<int, float, std::string>(3.14f) );
95 test( variant<int, float, std::string>("test") );
96
97 test( variant<int, int>() );
98
99 test( variant<int, int, float>() );
100 test( variant<int, int, float>(3.14f) );
101
102 test( variant<int, int, float, float>() );
103
104 test( variant<int, int, float, float, std::string>("test") );
105
106 test( variant<std::string, std::string, float>() );
107
108 test( variant<X1 const>() );
109
110 test( variant<X1, X2>() );
111 test( variant<X1, X2, int>() );
112 test( variant<X1, X2, X2>() );
113 test( variant<X1, X1, X2, X2>() );
114
115 {
116 variant<X1, X2> v;
117 v.emplace<X2>();
118
119 test( v );
120 }
121
122 {
123 variant<X1, X1, X2> v;
124 v.emplace<X2>();
125
126 test( v );
127 }
128
129 #if !BOOST_WORKAROUND( __GNUC__, < 5 )
130
131 test( variant<D>() );
132
133 #endif
134
135 {
136 BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int>>));
137 BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int const>>));
138 BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int>>));
139 BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, float>>));
140 BOOST_TEST_TRAIT_TRUE((std::is_nothrow_copy_constructible<variant<int, int, float, float>>));
141
142 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1>>));
143 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int>>));
144 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, int, float>>));
145
146 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, X1>>));
147 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<int, int, X1>>));
148
149 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2>>));
150 BOOST_TEST_TRAIT_FALSE((std::is_nothrow_copy_constructible<variant<X1, X2, int, int>>));
151
152 BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<variant<X1, X2>>));
153
154 #if !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
155
156 BOOST_TEST_TRAIT_FALSE((std::is_copy_constructible<variant<int, float, Y>>));
157
158 #endif
159 }
160
161 return boost::report_errors();
162 }
163