• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if defined(_MSC_VER)
10 # pragma warning( disable: 4702 ) // unreachable code
11 #endif
12 
13 #include <boost/variant2/variant.hpp>
14 #include <boost/core/lightweight_test.hpp>
15 #include <boost/core/lightweight_test_trait.hpp>
16 #include <type_traits>
17 #include <utility>
18 #include <string>
19 
20 using namespace boost::variant2;
21 
22 #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
23 
24 struct X1
25 {
26     int v;
27 
X1X128     X1(): v(0) {}
X1X129     explicit X1(int v): v(v) {}
X1X130     X1(X1 const& r): v(r.v) {}
X1X131     X1(X1&& r): v(r.v) {}
operator =X132     X1& operator=( X1 const& r ) { v = r.v; return *this; }
operator =X133     X1& operator=( X1&& r ) { v = r.v; return *this; }
34 };
35 
operator ==(X1 const & a,X1 const & b)36 inline bool operator==( X1 const& a, X1 const& b ) { return a.v == b.v; }
37 
38 STATIC_ASSERT( !std::is_nothrow_default_constructible<X1>::value );
39 STATIC_ASSERT( !std::is_nothrow_copy_constructible<X1>::value );
40 STATIC_ASSERT( !std::is_nothrow_move_constructible<X1>::value );
41 STATIC_ASSERT( !std::is_nothrow_copy_assignable<X1>::value );
42 STATIC_ASSERT( !std::is_nothrow_move_assignable<X1>::value );
43 
44 struct X2
45 {
46     int v;
47 
X2X248     X2(): v(0) {}
X2X249     explicit X2(int v): v(v) {}
X2X250     X2(X2 const& r): v(r.v) {}
X2X251     X2(X2&& r): v(r.v) {}
operator =X252     X2& operator=( X2 const& r ) { v = r.v; return *this; }
operator =X253     X2& operator=( X2&& r ) { v = r.v; return *this; }
54 };
55 
operator ==(X2 const & a,X2 const & b)56 inline bool operator==( X2 const& a, X2 const& b ) { return a.v == b.v; }
57 
58 STATIC_ASSERT( !std::is_nothrow_default_constructible<X2>::value );
59 STATIC_ASSERT( !std::is_nothrow_copy_constructible<X2>::value );
60 STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
61 STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
62 STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
63 
main()64 int main()
65 {
66     {
67         variant<int, float> v1( 1 );
68 
69         variant<int> v2 = v1.subset<int>();
70 
71         BOOST_TEST( holds_alternative<int>( v2 ) );
72         BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
73 
74         BOOST_TEST_THROWS( v1.subset<float>(), bad_variant_access );
75 
76         variant<int> v3 = std::move(v1).subset<int>();
77 
78         BOOST_TEST( holds_alternative<int>( v3 ) );
79         BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
80 
81         BOOST_TEST_THROWS( std::move(v1).subset<float>(), bad_variant_access );
82     }
83 
84     {
85         variant<int, float> const v1( 1 );
86 
87         variant<int> v2 = v1.subset<int>();
88 
89         BOOST_TEST( holds_alternative<int>( v2 ) );
90         BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
91 
92         BOOST_TEST_THROWS( v1.subset<float>(), bad_variant_access );
93 
94         variant<int> v3 = std::move(v1).subset<int>();
95 
96         BOOST_TEST( holds_alternative<int>( v3 ) );
97         BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
98 
99         BOOST_TEST_THROWS( std::move(v1).subset<float>(), bad_variant_access );
100     }
101 
102     {
103         variant<int, float> v1( 1 );
104 
105         variant<int, float> v2 = v1.subset<int, float>();
106 
107         BOOST_TEST( holds_alternative<int>( v2 ) );
108         BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
109 
110         variant<int, float> v3 = std::move(v1).subset<int, float>();
111 
112         BOOST_TEST( holds_alternative<int>( v3 ) );
113         BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
114     }
115 
116     {
117         variant<int, float> v1( 1 );
118 
119         variant<float, int> v2 = v1.subset<float, int>();
120 
121         BOOST_TEST( holds_alternative<int>( v2 ) );
122         BOOST_TEST_EQ( get<int>( v1 ), get<int>( v2 ) );
123 
124         variant<float, int> v3 = std::move(v1).subset<float, int>();
125 
126         BOOST_TEST( holds_alternative<int>( v3 ) );
127         BOOST_TEST_EQ( get<int>( v2 ), get<int>( v3 ) );
128     }
129 
130     {
131         variant<int, float, std::string> v1( "s1" );
132 
133         variant<int, std::string> v2 = v1.subset<int, std::string>();
134 
135         BOOST_TEST( holds_alternative<std::string>( v2 ) );
136         BOOST_TEST_EQ( get<std::string>( v1 ), get<std::string>( v2 ) );
137 
138         variant<float, std::string> v3 = std::move(v1).subset<float, std::string>();
139 
140         BOOST_TEST( holds_alternative<std::string>( v3 ) );
141         BOOST_TEST_EQ( get<std::string>( v2 ), get<std::string>( v3 ) );
142     }
143 
144     {
145         variant<int, int, float, float, X1, X2> v1{ X1{1} };
146 
147         variant<X1, X2> v2 = v1.subset<X1, X2>();
148 
149         BOOST_TEST( holds_alternative<X1>( v2 ) );
150         BOOST_TEST_EQ( get<X1>( v1 ).v, get<X1>( v2 ).v );
151 
152         variant<X1, X2> v3 = std::move( v1 ).subset<X1, X2>();
153 
154         BOOST_TEST( holds_alternative<X1>( v3 ) );
155         BOOST_TEST_EQ( get<X1>( v2 ).v, get<X1>( v3 ).v );
156     }
157 
158     return boost::report_errors();
159 }
160