123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- //-----------------------------------------------------------------------------
- // boost-libs variant/test/variant_get_test.cpp source file
- // See http://www.boost.org for updates, documentation, and revision history.
- //-----------------------------------------------------------------------------
- //
- // Copyright (c) 2016-2019 Antony Polukhin
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // This test suite was created to cover issues reported in:
- // https://svn.boost.org/trac/boost/ticket/5871
- // https://svn.boost.org/trac/boost/ticket/11602
- #include "boost/variant/variant.hpp"
- #include "boost/variant/recursive_variant.hpp"
- #include "boost/core/lightweight_test.hpp"
- #include <string>
- #include <list>
- struct A{};
- struct B{};
- struct C{};
- struct D{};
- bool foo(const boost::variant<A, B>& ) {
- return false;
- }
- bool foo(const boost::variant<C, D>& ) {
- return true;
- }
- void test_overload_selection_variant_constructor() {
- D d;
- BOOST_TEST(foo(d));
- boost::variant<B, A> v;
- BOOST_TEST(!foo(v));
- }
- // Pre msvc-14.0 could not dustinguish between multiple assignment operators:
- // warning C4522: 'assignment_tester' : multiple assignment operators specified
- // error C2666: variant::operator =' : 3 overloads have similar conversions
- // Old versions of GCC have same issue:
- // error: variant::operator=(const T&) cannot be overloaded
- #if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_MSC_VER) && _MSC_VER < 1900)
- void test_overload_selection_variant_assignment() {
- BOOST_TEST(true);
- }
- #else
- struct assignment_tester: boost::variant<C, D>, boost::variant<B, A> {
- using boost::variant<B, A>::operator=;
- using boost::variant<C, D>::operator=;
- };
- void test_overload_selection_variant_assignment() {
- A a;
- assignment_tester tester;
- tester = a;
- const int which0 = static_cast< boost::variant<B, A>& >(tester).which();
- BOOST_TEST(which0 == 1);
- boost::variant<A, B> b;
- b = B();
- tester = b;
- const int which1 = static_cast< boost::variant<B, A>& >(tester).which();
- BOOST_TEST(which1 == 0);
- }
- #endif
- typedef boost::variant<int> my_variant;
- struct convertible {
- operator my_variant() const {
- return my_variant();
- }
- };
- void test_implicit_conversion_operator() {
- // https://svn.boost.org/trac/boost/ticket/8555
- my_variant y = convertible();
- BOOST_TEST(y.which() == 0);
- }
- struct X: boost::variant< int > {};
- class V1: public boost::variant<float,double> {};
- struct AB: boost::variant<A, B> {};
- void test_derived_from_variant_construction() {
- // https://svn.boost.org/trac/boost/ticket/7120
- X x;
- boost::variant<X> y(x);
- BOOST_TEST(y.which() == 0);
- // https://svn.boost.org/trac/boost/ticket/10278
- boost::variant<V1, std::string> v2 = V1();
- BOOST_TEST(v2.which() == 0);
- // https://svn.boost.org/trac/boost/ticket/12155
- AB ab;
- boost::variant<AB, C> ab_c(ab);
- BOOST_TEST(ab_c.which() == 0);
- boost::variant<A, B> a_b(ab);
- BOOST_TEST(a_b.which() == 0);
- boost::variant<B, C, A> b_c_a1(static_cast<boost::variant<A, B>& >(ab));
- BOOST_TEST(b_c_a1.which() == 2);
- // Following conversion seems harmful as it may lead to slicing:
- // boost::variant<B, C, A> b_c_a(ab);
- // BOOST_TEST(b_c_a.which() == 2);
- }
- void test_derived_from_variant_assignment() {
- // https://svn.boost.org/trac/boost/ticket/7120
- X x;
- boost::variant<X> y;
- y = x;
- BOOST_TEST(y.which() == 0);
- // https://svn.boost.org/trac/boost/ticket/10278
- boost::variant<V1, std::string> v2;
- v2 = V1();
- BOOST_TEST(v2.which() == 0);
- // https://svn.boost.org/trac/boost/ticket/12155
- AB ab;
- boost::variant<AB, C> ab_c;
- ab_c = ab;
- BOOST_TEST(ab_c.which() == 0);
- boost::variant<A, B> a_b;
- a_b = ab;
- BOOST_TEST(a_b.which() == 0);
- boost::variant<B, C, A> b_c_a1;
- b_c_a1 = static_cast<boost::variant<A, B>& >(ab);
- BOOST_TEST(b_c_a1.which() == 2);
- // Following conversion seems harmful as it may lead to slicing:
- // boost::variant<B, C, A> b_c_a;
- // b_c_a = ab;
- // BOOST_TEST(b_c_a.which() == 2);
- }
- // http://thread.gmane.org/gmane.comp.lib.boost.devel/267757
- struct info {
- struct nil_ {};
- typedef
- boost::variant<
- nil_
- , std::string
- , boost::recursive_wrapper<info>
- , boost::recursive_wrapper<std::pair<info, info> >
- , boost::recursive_wrapper<std::list<info> >
- >
- value_type;
- value_type v;
- inline void test_on_incomplete_types() {
- info i0;
- i0.v = "Hello";
- BOOST_TEST(i0.v.which() == 1);
- info::value_type v0 = "Hello";
- BOOST_TEST(v0.which() == 1);
- info::value_type v1("Hello");
- BOOST_TEST(v1.which() == 1);
- info::value_type v2 = i0;
- BOOST_TEST(v2.which() == 2);
- info::value_type v3(i0);
- BOOST_TEST(v3.which() == 2);
- v0 = v3;
- BOOST_TEST(v0.which() == 2);
- v3 = v1;
- BOOST_TEST(v3.which() == 1);
- v3 = nil_();
- BOOST_TEST(v3.which() == 0);
- }
- };
- int main()
- {
- test_overload_selection_variant_constructor();
- test_overload_selection_variant_assignment();
- test_implicit_conversion_operator();
- test_derived_from_variant_construction();
- test_derived_from_variant_assignment();
- info().test_on_incomplete_types();
- return boost::report_errors();
- }
|