summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/variant/test/overload_selection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/variant/test/overload_selection.cpp')
-rw-r--r--src/boost/libs/variant/test/overload_selection.cpp215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/boost/libs/variant/test/overload_selection.cpp b/src/boost/libs/variant/test/overload_selection.cpp
new file mode 100644
index 000000000..e00487ca6
--- /dev/null
+++ b/src/boost/libs/variant/test/overload_selection.cpp
@@ -0,0 +1,215 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_get_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2016-2020 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();
+}