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_RVALUE_REFERENCES )
13
14BOOST_PRAGMA_MESSAGE("Skipping test because BOOST_NO_CXX11_RVALUE_REFERENCES is defined")
15int main() {}
16
17#else
18
19struct Y
20{
21 static int instances;
22
23 bool deleted_;
24
25 Y(): deleted_( false )
26 {
27 ++instances;
28 }
29
30 ~Y()
31 {
32 BOOST_TEST( deleted_ );
33 --instances;
34 }
35
36private:
37
38 Y( Y const & );
39 Y & operator=( Y const & );
40};
41
42int Y::instances = 0;
43
44struct YD
45{
46 bool moved_;
47
48 YD(): moved_( false )
49 {
50 }
51
52 YD( YD&& r ): moved_( false )
53 {
54 r.moved_ = true;
55 }
56
57 void operator()( Y* p ) const
58 {
59 BOOST_TEST( !moved_ );
60
61 if( p )
62 {
63 p->deleted_ = true;
64 delete p;
65 }
66 }
67
68private:
69
70 YD( YD const & );
71 YD & operator=( YD const & );
72};
73
74int main()
75{
76 BOOST_TEST( Y::instances == 0 );
77
78 {
79 YD del;
80 boost::shared_ptr<Y> p( new Y, std::move( del ) );
81
82 BOOST_TEST( Y::instances == 1 );
83 BOOST_TEST( del.moved_ );
84
85 p.reset( p: new Y, d: YD() );
86
87 BOOST_TEST( Y::instances == 1 );
88
89 p = boost::shared_ptr<Y>( new Y, YD() );
90
91 BOOST_TEST( Y::instances == 1 );
92
93 YD del2;
94 p.reset( p: new Y, d: std::move( del2 ) );
95
96 BOOST_TEST( Y::instances == 1 );
97 BOOST_TEST( del2.moved_ );
98
99 p.reset();
100 BOOST_TEST( Y::instances == 0 );
101 }
102
103 {
104 YD del;
105 boost::shared_ptr<Y> p( new Y, std::move( del ), std::allocator<Y>() );
106
107 BOOST_TEST( Y::instances == 1 );
108 BOOST_TEST( del.moved_ );
109
110 p.reset( p: new Y, d: YD(), a: std::allocator<Y>() );
111
112 BOOST_TEST( Y::instances == 1 );
113
114 p = boost::shared_ptr<Y>( new Y, YD(), std::allocator<Y>() );
115
116 BOOST_TEST( Y::instances == 1 );
117
118 YD del2;
119 p.reset( p: new Y, d: std::move( del2 ), a: std::allocator<Y>() );
120
121 BOOST_TEST( Y::instances == 1 );
122 BOOST_TEST( del2.moved_ );
123
124 p.reset();
125 BOOST_TEST( Y::instances == 0 );
126 }
127
128#if !defined( BOOST_NO_CXX11_NULLPTR )
129
130 {
131 boost::shared_ptr<Y> p( nullptr, YD() );
132
133 YD del;
134 p = boost::shared_ptr<Y>( nullptr, std::move( del ) );
135
136 BOOST_TEST( del.moved_ );
137 }
138
139 {
140 boost::shared_ptr<Y> p( nullptr, YD(), std::allocator<Y>() );
141
142 YD del;
143 p = boost::shared_ptr<Y>( nullptr, std::move( del ), std::allocator<Y>() );
144
145 BOOST_TEST( del.moved_ );
146 }
147
148#endif
149
150 return boost::report_errors();
151}
152
153#endif
154

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