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/config.hpp>
11 #include <boost/config/workaround.hpp>
12 
13 using namespace boost::variant2;
14 
15 struct X
16 {
17     constexpr X() = default;
XX18     constexpr explicit X(int, int) {}
19     template<class T> X( in_place_type_t<T> ) = delete;
20 };
21 
22 #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
23 
main()24 int main()
25 {
26     {
27         constexpr variant<int> v( in_place_type_t<int>{} );
28 
29         STATIC_ASSERT( v.index() == 0 );
30         STATIC_ASSERT( get<0>(v) == 0 );
31 
32         STATIC_ASSERT( holds_alternative<int>(v) );
33     }
34 
35     {
36         constexpr variant<X> v( in_place_type_t<X>{} );
37 
38         STATIC_ASSERT( v.index() == 0 );
39 
40         STATIC_ASSERT( holds_alternative<X>(v) );
41     }
42 
43     {
44         constexpr variant<int> v( in_place_type_t<int>{}, 1 );
45 
46         STATIC_ASSERT( v.index() == 0 );
47         STATIC_ASSERT( get<0>(v) == 1 );
48 
49         STATIC_ASSERT( holds_alternative<int>(v) );
50     }
51 
52     {
53         constexpr variant<int, float> v( in_place_type_t<int>{} );
54 
55         STATIC_ASSERT( v.index() == 0 );
56         STATIC_ASSERT( get<0>(v) == 0 );
57 
58         STATIC_ASSERT( holds_alternative<int>(v) );
59     }
60 
61     {
62         constexpr variant<int, float> v( in_place_type_t<int>{}, 1 );
63 
64         STATIC_ASSERT( v.index() == 0 );
65         STATIC_ASSERT( get<0>(v) == 1 );
66 
67         STATIC_ASSERT( holds_alternative<int>(v) );
68     }
69 
70     {
71         constexpr variant<int, float> v( in_place_type_t<float>{} );
72 
73         STATIC_ASSERT( v.index() == 1 );
74         STATIC_ASSERT( get<1>(v) == 0 );
75 
76         STATIC_ASSERT( holds_alternative<float>(v) );
77     }
78 
79     {
80         constexpr variant<int, float> v( in_place_type_t<float>{}, 3.14f );
81 
82         STATIC_ASSERT( v.index() == 1 );
83         STATIC_ASSERT( get<1>(v) == 3.14f );
84 
85         STATIC_ASSERT( holds_alternative<float>(v) );
86     }
87 
88     {
89         constexpr variant<int, int, float, X> v( in_place_type_t<float>{}, 3.14f );
90 
91         STATIC_ASSERT( v.index() == 2 );
92         STATIC_ASSERT( get<2>(v) == 3.14f );
93 
94         STATIC_ASSERT( holds_alternative<float>(v) );
95     }
96 
97     {
98         constexpr variant<int, int, float, float, X> v( in_place_type_t<X>{} );
99 
100         STATIC_ASSERT( v.index() == 4 );
101 
102         STATIC_ASSERT( holds_alternative<X>(v) );
103     }
104 
105 #if BOOST_WORKAROUND(BOOST_GCC, >= 100000 && BOOST_GCC < 100200)
106 
107     // no idea why this fails on g++ 10
108 
109 #else
110 
111     {
112         constexpr variant<int, int, float, float, X> v( in_place_type_t<X>{}, 0, 0 );
113 
114         STATIC_ASSERT( v.index() == 4 );
115 
116         STATIC_ASSERT( holds_alternative<X>(v) );
117     }
118 
119 #endif
120 }
121