1 | #include <boost/config.hpp> |
---|---|
2 | |
3 | #if defined(BOOST_MSVC) |
4 | #pragma warning(disable: 4786) // identifier truncated in debug info |
5 | #pragma warning(disable: 4710) // function not inlined |
6 | #pragma warning(disable: 4711) // function selected for automatic inline expansion |
7 | #pragma warning(disable: 4514) // unreferenced inline removed |
8 | #endif |
9 | |
10 | #if defined(__GNUC__) && __GNUC__ > 4 |
11 | # pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" |
12 | #endif |
13 | |
14 | // |
15 | // shared_from_this_test.cpp |
16 | // |
17 | // Copyright (c) 2002, 2003 Peter Dimov |
18 | // |
19 | // Distributed under the Boost Software License, Version 1.0. (See |
20 | // accompanying file LICENSE_1_0.txt or copy at |
21 | // http://www.boost.org/LICENSE_1_0.txt) |
22 | // |
23 | |
24 | |
25 | #include <boost/enable_shared_from_this.hpp> |
26 | #include <boost/shared_ptr.hpp> |
27 | |
28 | #include <boost/core/lightweight_test.hpp> |
29 | |
30 | // |
31 | |
32 | class X |
33 | { |
34 | public: |
35 | |
36 | virtual void f() = 0; |
37 | |
38 | protected: |
39 | |
40 | ~X() {} |
41 | }; |
42 | |
43 | class Y |
44 | { |
45 | public: |
46 | |
47 | virtual boost::shared_ptr<X> getX() = 0; |
48 | |
49 | protected: |
50 | |
51 | ~Y() {} |
52 | }; |
53 | |
54 | boost::shared_ptr<Y> createY(); |
55 | |
56 | void test() |
57 | { |
58 | boost::shared_ptr<Y> py = createY(); |
59 | BOOST_TEST(py.get() != 0); |
60 | BOOST_TEST(py.use_count() == 1); |
61 | |
62 | try |
63 | { |
64 | boost::shared_ptr<X> px = py->getX(); |
65 | BOOST_TEST(px.get() != 0); |
66 | BOOST_TEST(py.use_count() == 2); |
67 | |
68 | px->f(); |
69 | |
70 | #if !defined( BOOST_NO_RTTI ) |
71 | boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(r: px); |
72 | BOOST_TEST(py.get() == py2.get()); |
73 | BOOST_TEST(!(py < py2 || py2 < py)); |
74 | BOOST_TEST(py.use_count() == 3); |
75 | #endif |
76 | } |
77 | catch( boost::bad_weak_ptr const& ) |
78 | { |
79 | BOOST_ERROR( "py->getX() failed"); |
80 | } |
81 | } |
82 | |
83 | void test2(); |
84 | void test3(); |
85 | |
86 | int main() |
87 | { |
88 | test(); |
89 | test2(); |
90 | test3(); |
91 | return boost::report_errors(); |
92 | } |
93 | |
94 | // virtual inheritance to stress the implementation |
95 | // (prevents Y* -> impl*, enable_shared_from_this<impl>* -> impl* casts) |
96 | |
97 | class impl: public X, public virtual Y, public virtual boost::enable_shared_from_this<impl> |
98 | { |
99 | public: |
100 | |
101 | virtual void f() |
102 | { |
103 | } |
104 | |
105 | virtual boost::shared_ptr<X> getX() |
106 | { |
107 | boost::shared_ptr<impl> pi = shared_from_this(); |
108 | BOOST_TEST(pi.get() == this); |
109 | return pi; |
110 | } |
111 | }; |
112 | |
113 | // intermediate impl2 to stress the implementation |
114 | |
115 | class impl2: public impl |
116 | { |
117 | }; |
118 | |
119 | boost::shared_ptr<Y> createY() |
120 | { |
121 | boost::shared_ptr<Y> pi(new impl2); |
122 | return pi; |
123 | } |
124 | |
125 | void test2() |
126 | { |
127 | boost::shared_ptr<Y> pi(static_cast<impl2*>(0)); |
128 | } |
129 | |
130 | // |
131 | |
132 | struct V: public boost::enable_shared_from_this<V> |
133 | { |
134 | }; |
135 | |
136 | void test3() |
137 | { |
138 | boost::shared_ptr<V> p(new V); |
139 | |
140 | try |
141 | { |
142 | boost::shared_ptr<V> q = p->shared_from_this(); |
143 | BOOST_TEST(p == q); |
144 | BOOST_TEST(!(p < q) && !(q < p)); |
145 | } |
146 | catch( boost::bad_weak_ptr const & ) |
147 | { |
148 | BOOST_ERROR( "p->shared_from_this() failed"); |
149 | } |
150 | |
151 | V v2(*p); |
152 | |
153 | try |
154 | { |
155 | boost::shared_ptr<V> r = v2.shared_from_this(); |
156 | BOOST_ERROR("v2.shared_from_this() failed to throw"); |
157 | } |
158 | catch( boost::bad_weak_ptr const & ) |
159 | { |
160 | } |
161 | |
162 | try |
163 | { |
164 | *p = V(); |
165 | boost::shared_ptr<V> r = p->shared_from_this(); |
166 | BOOST_TEST(p == r); |
167 | BOOST_TEST(!(p < r) && !(r < p)); |
168 | } |
169 | catch( boost::bad_weak_ptr const & ) |
170 | { |
171 | BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = V()"); |
172 | } |
173 | } |
174 |