• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //-----------------------------------------------------------------------------
2 // boost-libs variant/test/variant_multivisit_test.cpp source file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2013-2020 Antony Polukhin
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See
9 // accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 
12 #include "boost/config.hpp"
13 #include "boost/noncopyable.hpp"
14 #define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 5
15 #include "boost/variant/multivisitors.hpp"
16 #include "boost/variant.hpp"
17 
18 #include "boost/core/lightweight_test.hpp"
19 
20 struct my_noncopyable : boost::noncopyable {
my_noncopyablemy_noncopyable21     my_noncopyable(){}
~my_noncopyablemy_noncopyable22     ~my_noncopyable(){}
23 };
24 
25 typedef boost::variant<my_noncopyable, int>         variant_noncopy_t;
26 
27 
28 typedef boost::variant<char, unsigned char, signed char, unsigned short, int, unsigned int>         variant6_t;
29 
30 struct test_visitor: boost::static_visitor<> {
31     // operators that shall not be called
32     template <class  T1, class  T2, class  T3>
operator ()test_visitor33     void operator()(T1&, T2&, T3&) const
34     {
35         BOOST_TEST(false);
36     }
37 
38     template <class  T1, class  T2, class  T3, class  T4>
operator ()test_visitor39     void operator()(T1&, T2&, T3&, T4&) const
40     {
41         BOOST_TEST(false);
42     }
43 
44     template <class  T1, class  T2, class  T3, class  T4, class  T5>
operator ()test_visitor45     void operator()(T1&, T2&, T3&, T4&, T5&) const
46     {
47         BOOST_TEST(false);
48     }
49 
50     // operators that are OK to call
operator ()test_visitor51     void operator()(char v0, unsigned char v1, signed char v2) const
52     {
53         BOOST_TEST(v0 == 0);
54         BOOST_TEST(v1 == 1);
55         BOOST_TEST(v2 == 2);
56     }
57 
operator ()test_visitor58     void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3) const
59     {
60         BOOST_TEST(v0 == 0);
61         BOOST_TEST(v1 == 1);
62         BOOST_TEST(v2 == 2);
63         BOOST_TEST(v3 == 3);
64     }
65 
operator ()test_visitor66     void operator()(char v0, unsigned char v1, signed char v2, unsigned short v3, int v4) const
67     {
68         BOOST_TEST(v0 == 0);
69         BOOST_TEST(v1 == 1);
70         BOOST_TEST(v2 == 2);
71         BOOST_TEST(v3 == 3);
72         BOOST_TEST(v4 == 4);
73     }
74 
75 
76     // Noncopyables
operator ()test_visitor77     void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
78         BOOST_TEST(true);
79     }
operator ()test_visitor80     void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
81         BOOST_TEST(true);
82     }
operator ()test_visitor83     void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
84         BOOST_TEST(true);
85     }
operator ()test_visitor86     void operator()(my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&, my_noncopyable&) const {
87         BOOST_TEST(true);
88     }
89 };
90 
91 typedef boost::variant<int, double, bool> bool_like_t;
92 typedef boost::variant<int, double> arithmetics_t;
93 
94 struct if_visitor: public boost::static_visitor<arithmetics_t> {
95     template <class T0, class T1, class T2>
operator ()if_visitor96     arithmetics_t operator()(T0 b, T1 v1, T2 v2) const {
97         if (!!b) {
98             return v1;
99         } else {
100             return v2;
101         }
102     }
103 };
104 
105 
main()106 int main()
107 {
108     test_visitor v;
109 
110     variant6_t v_array6[6];
111     v_array6[0] = char(0);
112     v_array6[1] = static_cast<unsigned char>(1);
113     v_array6[2] = static_cast<signed char>(2);
114     v_array6[3] = static_cast<unsigned short>(3);
115     v_array6[4] = static_cast<int>(4);
116     v_array6[5] = static_cast<unsigned int>(5);
117 
118     boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2]);
119     boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2]);
120 
121 // Following test also pass, but requires many Gigabytes of RAM for compilation and compile for about 15 minutes
122 //#define BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
123 #ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
124     boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
125     boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3]);
126 
127     boost::apply_visitor(v, v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
128     boost::apply_visitor(test_visitor(), v_array6[0], v_array6[1], v_array6[2], v_array6[3], v_array6[4]);
129 #endif
130 
131     bool_like_t v0(1), v1(true), v2(1.0);
132 
133     BOOST_TEST(
134         boost::apply_visitor(if_visitor(), v0, v1, v2)
135         ==
136         arithmetics_t(true)
137     );
138 
139 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
140     if_visitor if_vis;
141     BOOST_TEST(
142         boost::apply_visitor(if_vis)(v0, v1, v2)
143         ==
144         arithmetics_t(true)
145     );
146 #endif
147 
148 
149     variant_noncopy_t vnonc[6];
150     boost::apply_visitor(v, vnonc[0], vnonc[1], vnonc[2]);
151     boost::apply_visitor(test_visitor(), vnonc[0], vnonc[1], vnonc[2], vnonc[3]);
152 
153 #ifdef BOOST_VARIANT_MULTIVISITORS_TEST_VERY_EXTREME
154     boost::apply_visitor(v, vnonc[0], vnonc[1], vnonc[2], vnonc[3], vnonc[4]);
155     boost::apply_visitor(test_visitor(), vnonc[0], vnonc[1], vnonc[2], vnonc[3], vnonc[4], vnonc[5]);
156 #endif
157 
158     return boost::report_errors();
159 }
160