| 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 | f: []( int& x ){ BOOST_TEST_EQ( x, 0 ); }, |
| 41 | f: []( int& ){ BOOST_ERROR( "incorrect alternative" ); }, |
| 42 | f: []( 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 | f: []( int const& x ){ BOOST_TEST_EQ( x, 1 ); }, |
| 50 | f: []( int& ){ BOOST_ERROR( "incorrect alternative" ); }, |
| 51 | f: []( 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 | f: []( int const& ){ BOOST_ERROR( "incorrect alternative" ); }, |
| 59 | f: []( int const& x ){ BOOST_TEST_EQ( x, 2 ); }, |
| 60 | f: []( 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 | f: []( int const& ){ BOOST_ERROR( "incorrect alternative" ); }, |
| 68 | f: []( int const& ){ BOOST_ERROR( "incorrect alternative" ); }, |
| 69 | f: []( 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 | f: []( int const& x ) -> double { return x; }, |
| 77 | f: []( 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 | f: []( int const& x ) { return x + 0.0; }, |
| 88 | f: []( 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 | f: []( int const& x ) { return x; }, |
| 99 | f: []( float const& x ) { return x; }, |
| 100 | f: []( 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 | } |
| 127 | |