]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
92f5a8d4 TL |
12 | #if defined(__GNUC__) && __GNUC__ > 4 |
13 | # pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" | |
14 | #endif | |
15 | ||
7c673cae FG |
16 | #include <boost/smart_ptr/enable_shared_from_raw.hpp> |
17 | #include <boost/shared_ptr.hpp> | |
18 | ||
19 | #include <boost/detail/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>(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( 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.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( &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.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 | } |