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