1 // Tests for boost::signals2::deconstruct_ptr and friends
2
3 // Copyright Frank Mori Hess 2007-2008.
4 // Distributed under the Boost Software License, Version
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 // See http://www.boost.org/libs/signals2 for library home page.
9
10 #include <boost/enable_shared_from_this.hpp>
11 #include <boost/shared_ptr.hpp>
12 #include <boost/signals2/deconstruct.hpp>
13 #include <boost/signals2/deconstruct_ptr.hpp>
14 #define BOOST_TEST_MODULE deconstruct_test
15 #include <boost/test/included/unit_test.hpp>
16
17 class X: public boost::signals2::postconstructible {
18 public:
X()19 X(): _postconstructed(false)
20 {}
~X()21 ~X()
22 {
23 BOOST_CHECK(_postconstructed);
24 }
25 protected:
postconstruct()26 virtual void postconstruct()
27 {
28 BOOST_CHECK(!_postconstructed);
29 _postconstructed = true;
30 }
31 bool _postconstructed;
32 };
33
34 class Y: public boost::signals2::predestructible {
35 public:
Y()36 Y(): _predestructed(false)
37 {}
~Y()38 ~Y()
39 {
40 BOOST_CHECK(_predestructed);
41 }
42 protected:
predestruct()43 virtual void predestruct()
44 {
45 _predestructed = true;
46 }
47 bool _predestructed;
48 };
49
50 class Z: public X, public Y
51 {};
52
53 class by_deconstruct_only: public boost::signals2::postconstructible {
54 public:
~by_deconstruct_only()55 ~by_deconstruct_only()
56 {
57 BOOST_CHECK(_postconstructed);
58 }
59 int value;
60 protected:
postconstruct()61 virtual void postconstruct()
62 {
63 BOOST_CHECK(!_postconstructed);
64 _postconstructed = true;
65 }
66 bool _postconstructed;
67 private:
68 friend class boost::signals2::deconstruct_access;
by_deconstruct_only(int value_in)69 by_deconstruct_only(int value_in):
70 value(value_in), _postconstructed(false)
71 {}
72 };
73
74 namespace mytest
75 {
76 class A
77 {
78 public:
79 template<typename T> friend
adl_postconstruct(const boost::shared_ptr<T> & sp,A * p)80 void adl_postconstruct(const boost::shared_ptr<T> &sp, A *p)
81 {
82 BOOST_CHECK(!p->_postconstructed);
83 p->_postconstructed = true;
84 }
85 template<typename T> friend
adl_postconstruct(const boost::shared_ptr<T> & sp,A * p,int val)86 void adl_postconstruct(const boost::shared_ptr<T> &sp, A *p, int val)
87 {
88 p->value = val;
89 BOOST_CHECK(!p->_postconstructed);
90 p->_postconstructed = true;
91 }
adl_predestruct(A * p)92 friend void adl_predestruct(A *p)
93 {
94 p->_predestructed = true;
95 }
~A()96 ~A()
97 {
98 BOOST_CHECK(_postconstructed);
99 BOOST_CHECK(_predestructed);
100 }
101 int value;
102 private:
103 friend class boost::signals2::deconstruct_access;
A(int value_in=0)104 A(int value_in = 0):
105 value(value_in),
106 _postconstructed(false),
107 _predestructed(false)
108 {}
109 bool _postconstructed;
110 bool _predestructed;
111 };
112 }
113
deconstruct_ptr_test()114 void deconstruct_ptr_test()
115 {
116 {
117 boost::shared_ptr<X> x = boost::signals2::deconstruct_ptr(new X);
118 }
119 {
120 boost::shared_ptr<Y> x = boost::signals2::deconstruct_ptr(new Y);
121 }
122 {
123 boost::shared_ptr<Z> z = boost::signals2::deconstruct_ptr(new Z);
124 }
125 }
126
127 class deconstructed_esft : public boost::enable_shared_from_this<deconstructed_esft>
128 {
129 public:
deconstructed_esft()130 deconstructed_esft() : x(0) {}
131
132 private:
adl_postconstruct(boost::shared_ptr<void>,deconstructed_esft *)133 friend void adl_postconstruct(boost::shared_ptr<void>, deconstructed_esft *) {}
134 int x;
135 };
136
deconstruct_test()137 void deconstruct_test()
138 {
139 {
140 boost::shared_ptr<X> x = boost::signals2::deconstruct<X>();
141 }
142 {
143 boost::shared_ptr<Y> x = boost::signals2::deconstruct<Y>();
144 }
145 {
146 boost::shared_ptr<Z> z = boost::signals2::deconstruct<Z>();
147 }
148 {
149 boost::shared_ptr<by_deconstruct_only> a = boost::signals2::deconstruct<by_deconstruct_only>(1);
150 BOOST_CHECK(a->value == 1);
151 }
152 {
153 boost::shared_ptr<mytest::A> a = boost::signals2::deconstruct<mytest::A>(1);
154 BOOST_CHECK(a->value == 1);
155 }
156 {// deconstruct const type
157 boost::shared_ptr<const mytest::A> a = boost::signals2::deconstruct<const mytest::A>(3);
158 BOOST_CHECK(a->value == 3);
159 }
160 {// passing arguments to postconstructor
161 boost::shared_ptr<mytest::A> a = boost::signals2::deconstruct<mytest::A>().postconstruct(2);
162 BOOST_CHECK(a->value == 2);
163 }
164 {// enable_shared_from_this with deconstruct
165 boost::shared_ptr<deconstructed_esft> a = boost::signals2::deconstruct<deconstructed_esft>();
166 BOOST_CHECK(!(a->shared_from_this() < a || a < a->shared_from_this()));
167 }
168 }
169
BOOST_AUTO_TEST_CASE(test_main)170 BOOST_AUTO_TEST_CASE(test_main)
171 {
172 deconstruct_ptr_test();
173 deconstruct_test();
174 }
175