1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2014-2014
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // See http://www.boost.org/libs/intrusive for documentation.
10 //
11 /////////////////////////////////////////////////////////////////////////////
12 #include <boost/intrusive/parent_from_member.hpp>
13 #include <boost/core/lightweight_test.hpp>
14
15 struct POD
16 {
17 int int_;
18 float float_;
19 }pod;
20
21 struct Derived
22 : public POD
23 {
24 int derived_int_;
25 float derived_float_;
26 }derived;
27
28 struct Abstract
29 {
30 int abstract_int_;
31 float abstract_float_;
32 virtual void virtual_func1() = 0;
33 virtual void virtual_func2() = 0;
~AbstractAbstract34 virtual ~Abstract(){}
35 };
36
37 struct DerivedPoly
38 : public Abstract
39 {
40 int derivedpoly_int_;
41 float derivedpoly_float_;
virtual_func1DerivedPoly42 virtual void virtual_func1(){}
virtual_func2DerivedPoly43 virtual void virtual_func2(){}
abstractDerivedPoly44 Abstract *abstract() { return this; }
abstractDerivedPoly45 Abstract const *abstract() const { return this; }
46 } derivedpoly;
47
48 struct MultiInheritance
49 : public Derived, public DerivedPoly
50 {
51 int multiinheritance_int_;
52 float multiinheritance_float_;
53 } multiinheritance;
54
55 struct Abstract2
56 {
57 int abstract2_int_;
58 float abstract2_float_;
59 virtual void virtual_func1() = 0;
60 virtual void virtual_func2() = 0;
~Abstract2Abstract261 virtual ~Abstract2(){}
62 };
63
64 struct DerivedPoly2
65 : public Abstract2
66 {
67 int derivedpoly2_int_;
68 float derivedpoly2_float_;
virtual_func1DerivedPoly269 virtual void virtual_func1(){}
virtual_func2DerivedPoly270 virtual void virtual_func2(){}
abstract2DerivedPoly271 Abstract2 *abstract2() { return this; }
abstract2DerivedPoly272 Abstract2 const *abstract2() const { return this; }
~DerivedPoly2DerivedPoly273 virtual ~DerivedPoly2(){}
74 } derivedpoly2;
75
76 struct MultiInheritance2
77 : public DerivedPoly, public DerivedPoly2
78 {
79 int multiinheritance2_int_;
80 float multiinheritance2_float_;
81 } multiinheritance2;
82
83 struct VirtualDerivedPoly
84 : public virtual Derived
85 {
86 int virtualderivedpoly_int_;
87 float virtualderivedpoly_float_;
f1VirtualDerivedPoly88 virtual void f1(){}
f2VirtualDerivedPoly89 virtual void f2(){}
~VirtualDerivedPolyVirtualDerivedPoly90 virtual ~VirtualDerivedPoly(){}
91 } virtualderivedpoly;
92
93 struct VirtualMultipleDerivedPoly
94 : public virtual Derived, virtual public DerivedPoly
95 {
96 int virtualmultiplederivedpoly_int_;
97 float virtualmultiplederivedpoly_float_;
f1VirtualMultipleDerivedPoly98 virtual void f1(){}
f2VirtualMultipleDerivedPoly99 virtual void f2(){}
~VirtualMultipleDerivedPolyVirtualMultipleDerivedPoly100 virtual ~VirtualMultipleDerivedPoly(){}
101 } virtualmultiplederivedpoly;
102
103 struct VirtualDerived
104 : public virtual Derived
105 {
106 int virtualderived_int_;
107 float virtualderived_float_;
f1VirtualDerived108 virtual void f1(){}
f2VirtualDerived109 virtual void f2(){}
~VirtualDerivedVirtualDerived110 virtual ~VirtualDerived(){}
111 } virtualderived;
112
113 using namespace boost::intrusive;
114
115 //Add new test with https://svn.boost.org/trac/boost/attachment/ticket/8512/Source1.cpp
116
main()117 int main()
118 {
119 //POD
120 BOOST_TEST(&pod == get_parent_from_member(&pod.int_, &POD::int_));
121 BOOST_TEST(&pod == get_parent_from_member(&pod.float_, &POD::float_));
122
123 //Derived
124 BOOST_TEST(&derived == get_parent_from_member(&derived.int_, &Derived::int_));
125 BOOST_TEST(&derived == get_parent_from_member(&derived.float_, &Derived::float_));
126 BOOST_TEST(&derived == get_parent_from_member(&derived.derived_int_, &Derived::derived_int_));
127 BOOST_TEST(&derived == get_parent_from_member(&derived.derived_float_, &Derived::derived_float_));
128
129 //Abstract
130 BOOST_TEST(derivedpoly.abstract() == get_parent_from_member(&derivedpoly.abstract_int_, &Abstract::abstract_int_));
131 BOOST_TEST(derivedpoly.abstract() == get_parent_from_member(&derivedpoly.abstract_float_, &Abstract::abstract_float_));
132
133 //DerivedPoly
134 BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.abstract_int_, &DerivedPoly::abstract_int_));
135 BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.abstract_float_, &DerivedPoly::abstract_float_));
136 BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.derivedpoly_int_, &DerivedPoly::derivedpoly_int_));
137 BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.derivedpoly_float_, &DerivedPoly::derivedpoly_float_));
138
139 //MultiInheritance
140 BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_int_, &MultiInheritance::abstract_int_));
141 BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_float_, &MultiInheritance::abstract_float_));
142 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_int_, &MultiInheritance::derivedpoly_int_));
143 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_float_, &MultiInheritance::derivedpoly_float_));
144 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.int_, &MultiInheritance::int_));
145 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.float_, &MultiInheritance::float_));
146 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derived_int_, &MultiInheritance::derived_int_));
147 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derived_float_, &MultiInheritance::derived_float_));
148
149 BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_int_, &MultiInheritance::abstract_int_));
150 BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_float_, &MultiInheritance::abstract_float_));
151 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_int_, &MultiInheritance::derivedpoly_int_));
152 BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_float_, &MultiInheritance::derivedpoly_float_));
153 BOOST_TEST(multiinheritance2.abstract2() == get_parent_from_member(&multiinheritance2.abstract2_int_, &MultiInheritance2::abstract2_int_));
154 BOOST_TEST(multiinheritance2.abstract2() == get_parent_from_member(&multiinheritance2.abstract2_float_, &MultiInheritance2::abstract2_float_));
155 BOOST_TEST(&multiinheritance2 == get_parent_from_member(&multiinheritance2.derivedpoly2_int_, &MultiInheritance2::derivedpoly2_int_));
156 BOOST_TEST(&multiinheritance2 == get_parent_from_member(&multiinheritance2.derivedpoly2_float_, &MultiInheritance2::derivedpoly2_float_));
157
158 //MSVC pointer to member data uses RTTI info even when not crossing virtual base boundaries
159 #ifndef BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER
160 BOOST_TEST(&virtualderived == get_parent_from_member(&virtualderived.virtualderived_int_, &VirtualDerived::virtualderived_int_));
161 BOOST_TEST(&virtualderived == get_parent_from_member(&virtualderived.virtualderived_float_, &VirtualDerived::virtualderived_float_));
162
163 BOOST_TEST(&virtualderivedpoly == get_parent_from_member(&virtualderivedpoly.virtualderivedpoly_int_, &VirtualDerivedPoly::virtualderivedpoly_int_));
164 BOOST_TEST(&virtualderivedpoly == get_parent_from_member(&virtualderivedpoly.virtualderivedpoly_float_, &VirtualDerivedPoly::virtualderivedpoly_float_));
165 BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.virtualmultiplederivedpoly_float_, &VirtualMultipleDerivedPoly::virtualmultiplederivedpoly_float_));
166 BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.virtualmultiplederivedpoly_int_, &VirtualMultipleDerivedPoly::virtualmultiplederivedpoly_int_));
167 BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.derivedpoly_float_, &VirtualMultipleDerivedPoly::derivedpoly_float_));
168 BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.derivedpoly_int_, &VirtualMultipleDerivedPoly::derivedpoly_int_));
169 #endif
170
171 return boost::report_errors();
172 }
173