1// Copyright 2021 Peter Dimov
2// Distributed under the Boost Software License, Version 1.0.
3// https://www.boost.org/LICENSE_1_0.txt
4
5#include <boost/shared_ptr.hpp>
6#include <boost/core/lightweight_test.hpp>
7#include <boost/config.hpp>
8#include <boost/config/pragma_message.hpp>
9#include <memory>
10#include <utility>
11
12#if defined( BOOST_NO_CXX11_SMART_PTR )
13
14BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_SMART_PTR is defined")
15int main() {}
16
17#elif defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
18
19BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_RVALUE_REFERENCES is defined")
20int main() {}
21
22#elif defined(BOOST_MSVC) && BOOST_MSVC < 1700
23
24BOOST_PRAGMA_MESSAGE("Skipping test because msvc-10.0 unique_ptr doesn't support move-only deleters")
25int main() {}
26
27#else
28
29struct Y
30{
31 static int instances;
32
33 bool deleted_;
34
35 Y(): deleted_( false )
36 {
37 ++instances;
38 }
39
40 ~Y()
41 {
42 BOOST_TEST( deleted_ );
43 --instances;
44 }
45
46private:
47
48 Y( Y const & );
49 Y & operator=( Y const & );
50};
51
52int Y::instances = 0;
53
54struct YD
55{
56 bool moved_;
57
58 YD(): moved_( false )
59 {
60 }
61
62 YD( YD&& r ): moved_( false )
63 {
64 r.moved_ = true;
65 }
66
67 void operator()( Y* p ) const
68 {
69 BOOST_TEST( !moved_ );
70
71 if( p )
72 {
73 p->deleted_ = true;
74 delete p;
75 }
76 else
77 {
78 BOOST_ERROR( "YD::operator()(0) called" );
79 }
80 }
81
82private:
83
84 YD( YD const & );
85 YD & operator=( YD const & );
86};
87
88int main()
89{
90 BOOST_TEST( Y::instances == 0 );
91
92 {
93 std::unique_ptr<Y, YD> p( new Y );
94 BOOST_TEST( Y::instances == 1 );
95
96 boost::shared_ptr<Y> p2( std::move( p ) );
97
98 BOOST_TEST( Y::instances == 1 );
99 BOOST_TEST( p.get() == 0 );
100 BOOST_TEST( p.get_deleter().moved_ );
101
102 p2.reset();
103 BOOST_TEST( Y::instances == 0 );
104 }
105
106 {
107 std::unique_ptr<Y, YD> p( new Y );
108 BOOST_TEST( Y::instances == 1 );
109
110 boost::shared_ptr<void> p2( std::move( p ) );
111
112 BOOST_TEST( Y::instances == 1 );
113 BOOST_TEST( p.get() == 0 );
114 BOOST_TEST( p.get_deleter().moved_ );
115
116 p2.reset();
117 BOOST_TEST( Y::instances == 0 );
118 }
119
120 {
121 std::unique_ptr<Y, YD> p( new Y );
122 BOOST_TEST( Y::instances == 1 );
123
124 boost::shared_ptr<Y> p2;
125 p2 = std::move( p );
126
127 BOOST_TEST( Y::instances == 1 );
128 BOOST_TEST( p.get() == 0 );
129 BOOST_TEST( p.get_deleter().moved_ );
130
131 p2.reset();
132 BOOST_TEST( Y::instances == 0 );
133 }
134
135 {
136 std::unique_ptr<Y, YD> p( new Y );
137 BOOST_TEST( Y::instances == 1 );
138
139 boost::shared_ptr<void> p2( new int(0) );
140 p2 = std::move( p );
141
142 BOOST_TEST( Y::instances == 1 );
143 BOOST_TEST( p.get() == 0 );
144 BOOST_TEST( p.get_deleter().moved_ );
145
146 p2.reset();
147 BOOST_TEST( Y::instances == 0 );
148 }
149
150 return boost::report_errors();
151}
152
153#endif
154

source code of boost/libs/smart_ptr/test/sp_unique_ptr_test2.cpp