maybeCastObj_t.cc
Go to the documentation of this file.
1 #define BOOST_TEST_MODULE (Tests of maybeCastObj interface)
2 #include "boost/test/unit_test.hpp"
3 
4 #include <string>
5 
7 namespace {
8  // Helper function
9  template <typename T, typename U>
10  bool
11  runUpcastAllowed()
12  {
13  return art::detail::upcastAllowed(typeid(T), typeid(U));
14  }
15 
16  // Testing hierarchy
17  // Non virtual
18  class MCBase {};
19 
20  class MCConcrete : public MCBase {};
21 
22  // Virtual
23  class MCBaseVirtual {
24  public:
25  virtual ~MCBaseVirtual() {}
26  virtual int
27  foo()
28  {
29  return 0;
30  }
31  };
32 
33  class MCConcreteVirtual_A : public MCBaseVirtual {
34  public:
35  virtual ~MCConcreteVirtual_A() {}
36  virtual int
37  foo()
38  {
39  return 1;
40  }
41  };
42 
43  class MCConcreteVirtual_B : public MCBaseVirtual {
44  public:
45  virtual ~MCConcreteVirtual_B() {}
46  virtual int
47  foo()
48  {
49  return 2;
50  }
51  };
52 
53  class MCConcreteVirtual_C : public MCConcreteVirtual_B, public MCConcrete {
54  public:
55  virtual ~MCConcreteVirtual_C() {}
56  virtual int
57  foo()
58  {
59  return 3;
60  }
61  };
62 
63  // Other tree of inheritance
64  class MCOtherBase {};
65 
66  // Multiple
67  class MCConcreteMultiple : public MCBase, public MCOtherBase {};
68 
69  // Ambiguous?
70 }
71 
72 BOOST_AUTO_TEST_SUITE(maybeCastObj_t)
73 
74 BOOST_AUTO_TEST_CASE(identical_types)
75 {
76  // Primitive types
77  BOOST_TEST_REQUIRE((runUpcastAllowed<int, int>()));
78  BOOST_TEST_REQUIRE((runUpcastAllowed<double, double>()));
79 
80  // Std class type
81  BOOST_TEST_REQUIRE((runUpcastAllowed<std::string, std::string>()));
82 
83  // User class types
84  BOOST_TEST_REQUIRE((runUpcastAllowed<MCBase, MCBase>()));
85  BOOST_TEST_REQUIRE((runUpcastAllowed<MCConcrete, MCConcrete>()));
86 }
87 
88 BOOST_AUTO_TEST_CASE(mismatched_types)
89 {
90  // Different non-class types are never castable
91  BOOST_TEST_REQUIRE(!(runUpcastAllowed<int, double>()));
92 
93  // Can never cast primitive->class or class->primitive
94  BOOST_TEST_REQUIRE((!runUpcastAllowed<double, std::string>()));
95  BOOST_TEST_REQUIRE((!runUpcastAllowed<std::string, char>()));
96 
97  // Should not be able to cast from one user hierarchy to another
98  BOOST_TEST_REQUIRE((!runUpcastAllowed<MCConcrete, MCOtherBase>()));
99 }
100 
102 {
103  // NB: In all of the below, tests of valid upcasts fail on
104  // Root implementation. *Possibly* due to lack of dictionary?
105  // Cast from base <-> concrete (non-virtual)
106  BOOST_TEST_REQUIRE((!runUpcastAllowed<MCBase, MCConcrete>()));
107  BOOST_TEST_REQUIRE((runUpcastAllowed<MCConcrete, MCBase>()));
108 
109  // Cast from raw base <-> concrete (virtual)
110  BOOST_TEST_REQUIRE((!runUpcastAllowed<MCBaseVirtual, MCConcreteVirtual_A>()));
111  BOOST_TEST_REQUIRE((runUpcastAllowed<MCConcreteVirtual_A, MCBaseVirtual>()));
112 
113  // Across hierarchy
115  (!runUpcastAllowed<MCConcreteVirtual_B, MCConcreteVirtual_A>()));
116 
117  // Between levels
119  (runUpcastAllowed<MCConcreteVirtual_C, MCConcreteVirtual_B>()));
120  BOOST_TEST_REQUIRE((runUpcastAllowed<MCConcreteVirtual_C, MCConcrete>()));
121 
122  // Multiple
123  BOOST_TEST_REQUIRE((runUpcastAllowed<MCConcreteMultiple, MCBase>()));
124  BOOST_TEST_REQUIRE((runUpcastAllowed<MCConcreteMultiple, MCOtherBase>()));
125 }
126 
127 BOOST_AUTO_TEST_CASE(user_type_variables)
128 {
129  // Non Virtual
130  MCConcrete actualConcrete{};
131  MCBase& refToBase = actualConcrete;
133  (!art::detail::upcastAllowed(typeid(refToBase), typeid(MCConcrete))));
134 
135  // Virtual
136  MCConcreteVirtual_A actualConcreteVirtual{};
137  MCBaseVirtual& refToBaseVirtual = actualConcreteVirtual;
138  BOOST_TEST_REQUIRE((art::detail::upcastAllowed(typeid(refToBaseVirtual),
139  typeid(MCConcreteVirtual_A))));
141  typeid(refToBaseVirtual), typeid(MCConcreteVirtual_B))));
142 }
143 
144 BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST_REQUIRE(static_cast< bool >(inFile))
BOOST_AUTO_TEST_CASE(identical_types)
bool upcastAllowed(std::type_info const &tiFrom, std::type_info const &tiTo)