]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | // Copyright 2017, 2021 Peter Dimov. |
2 | // Distributed under the Boost Software License, Version 1.0. | |
3 | // https://www.boost.org/LICENSE_1_0.txt | |
4 | ||
5 | #include <boost/variant2/variant.hpp> | |
6 | #include <boost/core/lightweight_test.hpp> | |
7 | #include <boost/core/lightweight_test_trait.hpp> | |
8 | #include <boost/mp11.hpp> | |
9 | #include <boost/config.hpp> | |
10 | ||
11 | using namespace boost::variant2; | |
12 | using boost::mp11::mp_int; | |
13 | ||
14 | struct X | |
15 | { | |
16 | }; | |
17 | ||
18 | struct F1 | |
19 | { | |
20 | int operator()( X& ) const { return 1; } | |
21 | int operator()( X const& ) const { return 2; } | |
22 | int operator()( X&& ) const { return 3; } | |
23 | int operator()( X const&& ) const { return 4; } | |
24 | }; | |
25 | ||
26 | struct F2 | |
27 | { | |
28 | mp_int<1> operator()( X& ) const { return {}; } | |
29 | mp_int<2> operator()( X const& ) const { return {}; } | |
30 | mp_int<3> operator()( X&& ) const { return {}; } | |
31 | mp_int<4> operator()( X const&& ) const { return {}; } | |
32 | }; | |
33 | ||
34 | int main() | |
35 | { | |
36 | { | |
37 | variant<int, int, float> v; | |
38 | ||
39 | visit_by_index( v, | |
40 | []( int& x ){ BOOST_TEST_EQ( x, 0 ); }, | |
41 | []( int& ){ BOOST_ERROR( "incorrect alternative" ); }, | |
42 | []( float& ){ BOOST_ERROR( "incorrect alternative" ); } ); | |
43 | } | |
44 | ||
45 | { | |
46 | variant<int const, int, float const> v( in_place_index_t<0>(), 1 ); | |
47 | ||
48 | visit_by_index( v, | |
49 | []( int const& x ){ BOOST_TEST_EQ( x, 1 ); }, | |
50 | []( int& ){ BOOST_ERROR( "incorrect alternative" ); }, | |
51 | []( float const& ){ BOOST_ERROR( "incorrect alternative" ); } ); | |
52 | } | |
53 | ||
54 | { | |
55 | variant<int, int, float> const v( in_place_index_t<1>(), 2 ); | |
56 | ||
57 | visit_by_index( v, | |
58 | []( int const& ){ BOOST_ERROR( "incorrect alternative" ); }, | |
59 | []( int const& x ){ BOOST_TEST_EQ( x, 2 ); }, | |
60 | []( float const& ){ BOOST_ERROR( "incorrect alternative" ); } ); | |
61 | } | |
62 | ||
63 | { | |
64 | variant<int const, int, float const> const v( 3.14f ); | |
65 | ||
66 | visit_by_index( v, | |
67 | []( int const& ){ BOOST_ERROR( "incorrect alternative" ); }, | |
68 | []( int const& ){ BOOST_ERROR( "incorrect alternative" ); }, | |
69 | []( float const& x ){ BOOST_TEST_EQ( x, 3.14f ); } ); | |
70 | } | |
71 | ||
72 | { | |
73 | variant<int, float> const v( 7 ); | |
74 | ||
75 | auto r = visit_by_index( v, | |
76 | []( int const& x ) -> double { return x; }, | |
77 | []( float const& x ) -> double { return x; } ); | |
78 | ||
79 | BOOST_TEST_TRAIT_SAME( decltype(r), double ); | |
80 | BOOST_TEST_EQ( r, 7.0 ); | |
81 | } | |
82 | ||
83 | { | |
84 | variant<int, float> const v( 2.0f ); | |
85 | ||
86 | auto r = visit_by_index( v, | |
87 | []( int const& x ) { return x + 0.0; }, | |
88 | []( float const& x ) { return x + 0.0; } ); | |
89 | ||
90 | BOOST_TEST_TRAIT_SAME( decltype(r), double ); | |
91 | BOOST_TEST_EQ( r, 2.0 ); | |
92 | } | |
93 | ||
94 | { | |
95 | variant<int, float, double> const v( 3.0 ); | |
96 | ||
97 | auto r = visit_by_index<double>( v, | |
98 | []( int const& x ) { return x; }, | |
99 | []( float const& x ) { return x; }, | |
100 | []( double const& x ) { return x; } ); | |
101 | ||
102 | BOOST_TEST_TRAIT_SAME( decltype(r), double ); | |
103 | BOOST_TEST_EQ( r, 3.0 ); | |
104 | } | |
105 | ||
106 | { | |
107 | variant<X> v; | |
108 | variant<X> const cv; | |
109 | ||
110 | F1 f1; | |
111 | ||
112 | BOOST_TEST_EQ( visit_by_index( v, f1 ), 1 ); | |
113 | BOOST_TEST_EQ( visit_by_index( cv, f1 ), 2 ); | |
114 | BOOST_TEST_EQ( visit_by_index( std::move( v ), f1 ), 3 ); | |
115 | BOOST_TEST_EQ( visit_by_index( std::move( cv ), f1 ), 4 ); | |
116 | ||
117 | F2 f2; | |
118 | ||
119 | BOOST_TEST_EQ( visit_by_index<int>( v, f2 ), 1 ); | |
120 | BOOST_TEST_EQ( visit_by_index<int>( cv, f2 ), 2 ); | |
121 | BOOST_TEST_EQ( visit_by_index<int>( std::move( v ), f2 ), 3 ); | |
122 | BOOST_TEST_EQ( visit_by_index<int>( std::move( cv ), f2 ), 4 ); | |
123 | } | |
124 | ||
125 | return boost::report_errors(); | |
126 | } |