Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / smart_ptr / test / shared_from_raw_test.cpp
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/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 }