• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //-----------------------------------------------------------------------------
2 // boost-libs variant/test/variant_plymorphic_get_test.cpp source file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2003 Eric Friedman
7 // Copyright (c) 2013-2020 Antony Polukhin
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 
13 #include "boost/variant/variant.hpp"
14 #include "boost/variant/apply_visitor.hpp"
15 #include "boost/variant/static_visitor.hpp"
16 #include "boost/variant/polymorphic_get.hpp"
17 #include "boost/core/lightweight_test.hpp"
18 
19 struct base {int trash;};
20 struct derived1 : base{};
21 struct derived2 : base{};
22 
~vbasevbase23 struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; }  };
foovderived124 struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
foovderived225 struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
foovderived326 struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
27 
28 template <class T, class Variant>
check_throws(Variant & v)29 inline void check_throws(Variant& v) {
30     try {
31         boost::polymorphic_get<T>(v);
32         BOOST_TEST(false);
33     } catch (const boost::bad_polymorphic_get& e) {
34         BOOST_TEST(!!e.what());
35         BOOST_TEST(std::string(e.what()) != boost::bad_get().what());
36     }
37 }
38 
main()39 int main()
40 {
41     typedef boost::variant<int, base, derived1, derived2> var_t;
42 
43     var_t var1;
44     BOOST_TEST(!boost::polymorphic_get<base>(&var1));
45     check_throws<base>(var1);
46     BOOST_TEST(!boost::polymorphic_get<const base>(&var1));
47     check_throws<base, const var_t>(var1);
48 
49     var1 = derived1();
50     BOOST_TEST(boost::polymorphic_get<base>(&var1));
51     BOOST_TEST(boost::polymorphic_get<const base>(&var1));
52 
53     derived2 d;
54     d.trash = 777;
55     var_t var2 = d;
56     BOOST_TEST(boost::polymorphic_get<base>(var2).trash == 777);
57     BOOST_TEST(boost::polymorphic_get<const base>(var2).trash == 777);
58 
59     var2 = 777;
60     BOOST_TEST(!boost::polymorphic_get<base>(&var2));
61     check_throws<base>(var2);
62     BOOST_TEST(!boost::polymorphic_get<const base>(&var2));
63     check_throws<base, const var_t>(var2);
64     BOOST_TEST(boost::polymorphic_get<int>(var2) == 777);
65     BOOST_TEST(boost::polymorphic_get<const int>(var2) == 777);
66 
67     typedef boost::variant<int, vbase, vderived1, vderived2, vderived3> vvar_t;
68 
69     vvar_t v = vderived3();
70     boost::polymorphic_get<vderived3>(v).trash = 777;
71     const vvar_t& cv = v;
72     BOOST_TEST(boost::polymorphic_get<vbase>(cv).trash == 777);
73     BOOST_TEST(boost::polymorphic_get<const vbase>(cv).trash == 777);
74 
75     BOOST_TEST(boost::polymorphic_get<vbase>(cv).foo() == 3);
76     BOOST_TEST(boost::polymorphic_get<vbase>(v).foo() == 3);
77     BOOST_TEST(boost::polymorphic_get<const vbase>(cv).foo() == 3);
78     BOOST_TEST(boost::polymorphic_get<const vbase>(v).foo() == 3);
79 
80     return boost::report_errors();
81 }
82