summaryrefslogtreecommitdiff
path: root/libs/variant/test/variant_get_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/variant/test/variant_get_test.cpp')
-rw-r--r--libs/variant/test/variant_get_test.cpp323
1 files changed, 323 insertions, 0 deletions
diff --git a/libs/variant/test/variant_get_test.cpp b/libs/variant/test/variant_get_test.cpp
new file mode 100644
index 000000000..69b613729
--- /dev/null
+++ b/libs/variant/test/variant_get_test.cpp
@@ -0,0 +1,323 @@
+//-----------------------------------------------------------------------------
+// boost-libs variant/test/variant_get_test.cpp source file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2014 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)
+
+#include "boost/variant/variant.hpp"
+#include "boost/variant/get.hpp"
+#include "boost/variant/polymorphic_get.hpp"
+#include "boost/variant/recursive_wrapper.hpp"
+#include "boost/test/minimal.hpp"
+
+struct base {
+ int trash;
+
+ base() : trash(123) {}
+ base(const base& b) : trash(b.trash) { int i = 100; (void)i; }
+ const base& operator=(const base& b) {
+ trash = b.trash;
+ int i = 100; (void)i;
+
+ return *this;
+ }
+
+ virtual ~base(){}
+};
+
+struct derived1 : base{};
+struct derived2 : base{};
+
+struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
+struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
+struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
+struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
+
+typedef boost::variant<int, base, derived1, derived2, std::string> var_t;
+typedef boost::variant<int, derived1, derived2, std::string> var_t_shortened;
+typedef boost::variant<base, derived1, derived2> var_t_no_fallback;
+typedef boost::variant<int&, base&, derived1&, derived2&, std::string&> var_ref_t;
+typedef boost::variant<const int&, const base&, const derived1&, const derived2&, const std::string&> var_cref_t;
+
+struct recursive_structure;
+typedef boost::variant<
+ int, base, derived1, derived2, std::string, boost::recursive_wrapper<recursive_structure>
+> var_req_t;
+struct recursive_structure { var_req_t var; };
+
+template <class T, class V, class TestType>
+inline void check_polymorphic_get_on_types_impl_single_type(V* v)
+{
+ if (!!boost::is_same<T, TestType>::value) {
+ BOOST_CHECK(boost::polymorphic_get<TestType>(v));
+ BOOST_CHECK(boost::polymorphic_get<const TestType>(v));
+ BOOST_CHECK(boost::polymorphic_strict_get<TestType>(v));
+ BOOST_CHECK(boost::polymorphic_strict_get<const TestType>(v));
+ BOOST_CHECK(boost::polymorphic_relaxed_get<TestType>(v));
+ BOOST_CHECK(boost::polymorphic_relaxed_get<const TestType>(v));
+ } else {
+ BOOST_CHECK(!boost::polymorphic_get<TestType>(v));
+ BOOST_CHECK(!boost::polymorphic_get<const TestType>(v));
+ BOOST_CHECK(!boost::polymorphic_strict_get<TestType>(v));
+ BOOST_CHECK(!boost::polymorphic_strict_get<const TestType>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<TestType>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<const TestType>(v));
+ }
+}
+
+template <class T, class V, class TestType>
+inline void check_get_on_types_impl_single_type(V* v)
+{
+ if (!!boost::is_same<T, TestType>::value) {
+ BOOST_CHECK(boost::get<TestType>(v));
+ BOOST_CHECK(boost::get<const TestType>(v));
+ BOOST_CHECK(boost::strict_get<TestType>(v));
+ BOOST_CHECK(boost::strict_get<const TestType>(v));
+ BOOST_CHECK(boost::relaxed_get<TestType>(v));
+ BOOST_CHECK(boost::relaxed_get<const TestType>(v));
+ } else {
+ BOOST_CHECK(!boost::get<TestType>(v));
+ BOOST_CHECK(!boost::get<const TestType>(v));
+ BOOST_CHECK(!boost::strict_get<TestType>(v));
+ BOOST_CHECK(!boost::strict_get<const TestType>(v));
+ BOOST_CHECK(!boost::relaxed_get<TestType>(v));
+ BOOST_CHECK(!boost::relaxed_get<const TestType>(v));
+ }
+}
+
+template <class T, class V>
+inline void check_get_on_types_impl(V* v)
+{
+ check_get_on_types_impl_single_type<T, V, int>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, int>(v);
+
+ check_get_on_types_impl_single_type<T, V, base>(v);
+
+ check_get_on_types_impl_single_type<T, V, derived1>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, derived1>(v);
+
+ check_get_on_types_impl_single_type<T, V, derived2>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, derived2>(v);
+
+ check_get_on_types_impl_single_type<T, V, std::string>(v);
+ check_polymorphic_get_on_types_impl_single_type<T, V, std::string>(v);
+
+ // Never exist in here
+ BOOST_CHECK(!boost::relaxed_get<short>(v));
+ BOOST_CHECK(!boost::relaxed_get<const short>(v));
+ BOOST_CHECK(!boost::relaxed_get<char>(v));
+ BOOST_CHECK(!boost::relaxed_get<char*>(v));
+ BOOST_CHECK(!boost::relaxed_get<bool>(v));
+ BOOST_CHECK(!boost::relaxed_get<const bool>(v));
+
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<short>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<const short>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<char>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<char*>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<bool>(v));
+ BOOST_CHECK(!boost::polymorphic_relaxed_get<const bool>(v));
+
+ boost::get<T>(*v); // Must compile
+ boost::get<const T>(*v); // Must compile
+ boost::strict_get<T>(*v); // Must compile
+ boost::strict_get<const T>(*v); // Must compile
+
+ boost::polymorphic_get<T>(*v); // Must compile
+ boost::polymorphic_get<const T>(*v); // Must compile
+ boost::polymorphic_strict_get<T>(*v); // Must compile
+ boost::polymorphic_strict_get<const T>(*v); // Must compile
+}
+
+template <class T, class V>
+inline void check_get_on_types(V* v)
+{
+ check_get_on_types_impl<T, V>(v);
+ check_get_on_types_impl<T, const V>(v);
+}
+
+inline void get_test()
+{
+ var_t v;
+ check_get_on_types<int>(&v);
+
+ var_t(base()).swap(v);
+ check_get_on_types<base>(&v);
+
+ var_t(derived1()).swap(v);
+ check_get_on_types<derived1>(&v);
+
+ var_t(derived2()).swap(v);
+ check_get_on_types<derived2>(&v);
+
+ var_t(std::string("Hello")).swap(v);
+ check_get_on_types<std::string>(&v);
+
+ var_t_shortened vs = derived2();
+ check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
+ // Checking that Base is really determinated
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
+
+ vs = derived1();
+ check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
+ // Checking that Base is really determinated
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
+}
+
+inline void get_test_no_fallback()
+{
+ var_t_no_fallback v;
+ var_t_no_fallback(base()).swap(v);
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+
+ var_t_no_fallback(derived1()).swap(v);
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<derived1, var_t_no_fallback, derived1>(&v);
+ check_get_on_types_impl_single_type<derived1, const var_t_no_fallback, derived1>(&v);
+
+ var_t_no_fallback(derived2()).swap(v);
+ check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
+ check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
+ check_get_on_types_impl_single_type<derived2, var_t_no_fallback, derived2>(&v);
+ check_get_on_types_impl_single_type<derived2, const var_t_no_fallback, derived2>(&v);
+}
+
+inline void get_ref_test()
+{
+ int i = 0;
+ var_ref_t v(i);
+ check_get_on_types<int>(&v);
+
+ base b;
+ var_ref_t v1(b);
+ check_get_on_types<base>(&v1);
+
+ derived1 d1;
+ var_ref_t v2(d1);
+ check_get_on_types<derived1>(&v2);
+
+ derived2 d2;
+ var_ref_t v3(d2);
+ check_get_on_types<derived2>(&v3);
+
+ std::string s("Hello");
+ var_ref_t v4(s);
+ check_get_on_types<std::string>(&v4);
+}
+
+
+inline void get_cref_test()
+{
+ int i = 0;
+ var_cref_t v(i);
+ BOOST_CHECK(boost::get<const int>(&v));
+ BOOST_CHECK(!boost::get<const base>(&v));
+
+ base b;
+ var_cref_t v1(b);
+ BOOST_CHECK(boost::get<const base>(&v1));
+ BOOST_CHECK(!boost::get<const derived1>(&v1));
+ BOOST_CHECK(!boost::get<const int>(&v1));
+
+ std::string s("Hello");
+ const var_cref_t v4 = s;
+ BOOST_CHECK(boost::get<const std::string>(&v4));
+ BOOST_CHECK(!boost::get<const int>(&v4));
+}
+
+inline void get_recursive_test()
+{
+ var_req_t v;
+ check_get_on_types<int>(&v);
+
+ var_req_t(base()).swap(v);
+ check_get_on_types<base>(&v);
+
+ var_req_t(derived1()).swap(v);
+ check_get_on_types<derived1>(&v);
+
+ var_req_t(derived2()).swap(v);
+ check_get_on_types<derived2>(&v);
+
+ var_req_t(std::string("Hello")).swap(v);
+ check_get_on_types<std::string>(&v);
+
+ recursive_structure s = { v }; // copying "v"
+ v = s;
+ check_get_on_types<recursive_structure>(&v);
+}
+
+template <class T>
+inline void check_that_does_not_exist_impl()
+{
+ using namespace boost::detail::variant;
+
+ BOOST_CHECK((holds_element<T, const int>::value));
+ BOOST_CHECK((!holds_element<T, short>::value));
+ BOOST_CHECK((!holds_element<T, short>::value));
+ BOOST_CHECK((!holds_element<T, const short>::value));
+ BOOST_CHECK((!holds_element<T, char*>::value));
+ BOOST_CHECK((!holds_element<T, const char*>::value));
+ BOOST_CHECK((!holds_element<T, char[5]>::value));
+ BOOST_CHECK((!holds_element<T, const char[5]>::value));
+ BOOST_CHECK((!holds_element<T, bool>::value));
+ BOOST_CHECK((!holds_element<T, const bool>::value));
+
+ BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<int> >::value));
+ BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<short> >::value));
+ BOOST_CHECK((!holds_element<T, boost::detail::reference_content<short> >::value));
+
+
+ BOOST_CHECK((holds_element_polymorphic<T, const int>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, const short>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, char*>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, const char*>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, char[5]>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, const char[5]>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, bool>::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, const bool>::value));
+
+ BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<int> >::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<short> >::value));
+ BOOST_CHECK((!holds_element_polymorphic<T, boost::detail::reference_content<short> >::value));
+}
+
+inline void check_that_does_not_exist()
+{
+ using namespace boost::detail::variant;
+
+ BOOST_CHECK((holds_element<var_t, int>::value));
+ BOOST_CHECK((holds_element<var_ref_t, int>::value));
+ BOOST_CHECK((!holds_element<var_cref_t, int>::value));
+
+ check_that_does_not_exist_impl<var_t>();
+ check_that_does_not_exist_impl<var_ref_t>();
+ check_that_does_not_exist_impl<var_cref_t>();
+ check_that_does_not_exist_impl<var_req_t>();
+}
+
+int test_main(int , char* [])
+{
+ get_test();
+ get_test_no_fallback();
+ get_ref_test();
+ get_cref_test();
+ get_recursive_test();
+ check_that_does_not_exist();
+
+ return boost::exit_success;
+}