]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | //----------------------------------------------------------------------------- |
2 | // boost-libs variant/test/variant_get_test.cpp source file | |
3 | // See http://www.boost.org for updates, documentation, and revision history. | |
4 | //----------------------------------------------------------------------------- | |
5 | // | |
f67539c2 | 6 | // Copyright (c) 2016-2020 Antony Polukhin |
7c673cae FG |
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 | ||
13 | // This test suite was created to cover issues reported in: | |
14 | // https://svn.boost.org/trac/boost/ticket/5871 | |
15 | // https://svn.boost.org/trac/boost/ticket/11602 | |
16 | ||
17 | #include "boost/variant/variant.hpp" | |
18 | #include "boost/variant/recursive_variant.hpp" | |
92f5a8d4 | 19 | #include "boost/core/lightweight_test.hpp" |
7c673cae FG |
20 | |
21 | #include <string> | |
22 | #include <list> | |
23 | ||
24 | struct A{}; | |
25 | struct B{}; | |
26 | struct C{}; | |
27 | struct D{}; | |
28 | ||
29 | ||
30 | bool foo(const boost::variant<A, B>& ) { | |
31 | return false; | |
32 | } | |
33 | ||
34 | bool foo(const boost::variant<C, D>& ) { | |
35 | return true; | |
36 | } | |
37 | ||
38 | void test_overload_selection_variant_constructor() { | |
39 | D d; | |
92f5a8d4 | 40 | BOOST_TEST(foo(d)); |
7c673cae FG |
41 | |
42 | boost::variant<B, A> v; | |
92f5a8d4 | 43 | BOOST_TEST(!foo(v)); |
7c673cae FG |
44 | } |
45 | ||
46 | // Pre msvc-14.0 could not dustinguish between multiple assignment operators: | |
47 | // warning C4522: 'assignment_tester' : multiple assignment operators specified | |
48 | // error C2666: variant::operator =' : 3 overloads have similar conversions | |
49 | // Old versions of GCC have same issue: | |
50 | // error: variant::operator=(const T&) cannot be overloaded | |
51 | #if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_MSC_VER) && _MSC_VER < 1900) | |
52 | ||
53 | void test_overload_selection_variant_assignment() { | |
92f5a8d4 | 54 | BOOST_TEST(true); |
7c673cae FG |
55 | } |
56 | ||
57 | #else | |
58 | ||
59 | struct assignment_tester: boost::variant<C, D>, boost::variant<B, A> { | |
60 | using boost::variant<B, A>::operator=; | |
61 | using boost::variant<C, D>::operator=; | |
62 | }; | |
63 | ||
64 | void test_overload_selection_variant_assignment() { | |
65 | A a; | |
66 | assignment_tester tester; | |
67 | tester = a; | |
68 | const int which0 = static_cast< boost::variant<B, A>& >(tester).which(); | |
92f5a8d4 | 69 | BOOST_TEST(which0 == 1); |
7c673cae FG |
70 | |
71 | boost::variant<A, B> b; | |
72 | b = B(); | |
73 | tester = b; | |
74 | const int which1 = static_cast< boost::variant<B, A>& >(tester).which(); | |
92f5a8d4 | 75 | BOOST_TEST(which1 == 0); |
7c673cae FG |
76 | } |
77 | ||
78 | #endif | |
79 | ||
80 | typedef boost::variant<int> my_variant; | |
81 | ||
82 | struct convertible { | |
83 | operator my_variant() const { | |
84 | return my_variant(); | |
85 | } | |
86 | }; | |
87 | ||
88 | void test_implicit_conversion_operator() { | |
89 | // https://svn.boost.org/trac/boost/ticket/8555 | |
90 | my_variant y = convertible(); | |
92f5a8d4 | 91 | BOOST_TEST(y.which() == 0); |
7c673cae FG |
92 | } |
93 | ||
94 | struct X: boost::variant< int > {}; | |
95 | class V1: public boost::variant<float,double> {}; | |
96 | ||
97 | struct AB: boost::variant<A, B> {}; | |
98 | ||
99 | void test_derived_from_variant_construction() { | |
100 | // https://svn.boost.org/trac/boost/ticket/7120 | |
101 | X x; | |
102 | boost::variant<X> y(x); | |
92f5a8d4 | 103 | BOOST_TEST(y.which() == 0); |
7c673cae FG |
104 | |
105 | // https://svn.boost.org/trac/boost/ticket/10278 | |
106 | boost::variant<V1, std::string> v2 = V1(); | |
92f5a8d4 | 107 | BOOST_TEST(v2.which() == 0); |
7c673cae FG |
108 | |
109 | // https://svn.boost.org/trac/boost/ticket/12155 | |
110 | AB ab; | |
111 | boost::variant<AB, C> ab_c(ab); | |
92f5a8d4 | 112 | BOOST_TEST(ab_c.which() == 0); |
7c673cae FG |
113 | |
114 | boost::variant<A, B> a_b(ab); | |
92f5a8d4 | 115 | BOOST_TEST(a_b.which() == 0); |
7c673cae FG |
116 | |
117 | boost::variant<B, C, A> b_c_a1(static_cast<boost::variant<A, B>& >(ab)); | |
92f5a8d4 | 118 | BOOST_TEST(b_c_a1.which() == 2); |
7c673cae FG |
119 | |
120 | ||
121 | // Following conversion seems harmful as it may lead to slicing: | |
122 | // boost::variant<B, C, A> b_c_a(ab); | |
92f5a8d4 | 123 | // BOOST_TEST(b_c_a.which() == 2); |
7c673cae FG |
124 | } |
125 | ||
126 | void test_derived_from_variant_assignment() { | |
127 | // https://svn.boost.org/trac/boost/ticket/7120 | |
128 | X x; | |
129 | boost::variant<X> y; | |
130 | y = x; | |
92f5a8d4 | 131 | BOOST_TEST(y.which() == 0); |
7c673cae FG |
132 | |
133 | // https://svn.boost.org/trac/boost/ticket/10278 | |
134 | boost::variant<V1, std::string> v2; | |
135 | v2 = V1(); | |
92f5a8d4 | 136 | BOOST_TEST(v2.which() == 0); |
7c673cae FG |
137 | |
138 | // https://svn.boost.org/trac/boost/ticket/12155 | |
139 | AB ab; | |
140 | boost::variant<AB, C> ab_c; | |
141 | ab_c = ab; | |
92f5a8d4 | 142 | BOOST_TEST(ab_c.which() == 0); |
7c673cae FG |
143 | |
144 | boost::variant<A, B> a_b; | |
145 | a_b = ab; | |
92f5a8d4 | 146 | BOOST_TEST(a_b.which() == 0); |
7c673cae FG |
147 | |
148 | boost::variant<B, C, A> b_c_a1; | |
149 | b_c_a1 = static_cast<boost::variant<A, B>& >(ab); | |
92f5a8d4 | 150 | BOOST_TEST(b_c_a1.which() == 2); |
7c673cae FG |
151 | |
152 | ||
153 | // Following conversion seems harmful as it may lead to slicing: | |
154 | // boost::variant<B, C, A> b_c_a; | |
155 | // b_c_a = ab; | |
92f5a8d4 | 156 | // BOOST_TEST(b_c_a.which() == 2); |
7c673cae FG |
157 | } |
158 | ||
159 | ||
160 | // http://thread.gmane.org/gmane.comp.lib.boost.devel/267757 | |
161 | struct info { | |
162 | struct nil_ {}; | |
163 | ||
164 | typedef | |
165 | boost::variant< | |
166 | nil_ | |
167 | , std::string | |
168 | , boost::recursive_wrapper<info> | |
169 | , boost::recursive_wrapper<std::pair<info, info> > | |
170 | , boost::recursive_wrapper<std::list<info> > | |
171 | > | |
172 | value_type; | |
173 | value_type v; | |
174 | ||
175 | inline void test_on_incomplete_types() { | |
176 | info i0; | |
177 | i0.v = "Hello"; | |
92f5a8d4 | 178 | BOOST_TEST(i0.v.which() == 1); |
7c673cae FG |
179 | |
180 | info::value_type v0 = "Hello"; | |
92f5a8d4 | 181 | BOOST_TEST(v0.which() == 1); |
7c673cae FG |
182 | |
183 | info::value_type v1("Hello"); | |
92f5a8d4 | 184 | BOOST_TEST(v1.which() == 1); |
7c673cae FG |
185 | |
186 | info::value_type v2 = i0; | |
92f5a8d4 | 187 | BOOST_TEST(v2.which() == 2); |
7c673cae FG |
188 | |
189 | info::value_type v3(i0); | |
92f5a8d4 | 190 | BOOST_TEST(v3.which() == 2); |
7c673cae FG |
191 | |
192 | v0 = v3; | |
92f5a8d4 | 193 | BOOST_TEST(v0.which() == 2); |
7c673cae FG |
194 | |
195 | v3 = v1; | |
92f5a8d4 | 196 | BOOST_TEST(v3.which() == 1); |
7c673cae FG |
197 | |
198 | v3 = nil_(); | |
92f5a8d4 | 199 | BOOST_TEST(v3.which() == 0); |
7c673cae FG |
200 | } |
201 | }; | |
202 | ||
203 | ||
204 | ||
92f5a8d4 | 205 | int main() |
7c673cae FG |
206 | { |
207 | test_overload_selection_variant_constructor(); | |
208 | test_overload_selection_variant_assignment(); | |
209 | test_implicit_conversion_operator(); | |
210 | test_derived_from_variant_construction(); | |
211 | test_derived_from_variant_assignment(); | |
212 | info().test_on_incomplete_types(); | |
213 | ||
92f5a8d4 | 214 | return boost::report_errors(); |
7c673cae | 215 | } |