1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Antony Polukhin 2014.
4// (C) Copyright Ion Gaztanaga 2014.
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// See http://www.boost.org/libs/move for documentation.
10//
11//////////////////////////////////////////////////////////////////////////////
12
13#include <boost/move/utility.hpp>
14#include <boost/core/lightweight_test.hpp>
15#include "../example/movable.hpp"
16#include "../example/copymovable.hpp"
17
18//////////////////////////////////////////////////////////////////////////////
19//A copy_movable_noexcept class
20class copy_movable_noexcept
21{
22 BOOST_COPYABLE_AND_MOVABLE(copy_movable_noexcept)
23 int value_;
24
25 public:
26 copy_movable_noexcept() : value_(1){}
27
28 //Move constructor and assignment
29 copy_movable_noexcept(BOOST_RV_REF(copy_movable_noexcept) m)
30 { value_ = m.value_; m.value_ = 0; }
31
32 copy_movable_noexcept(const copy_movable_noexcept &m)
33 { value_ = m.value_; }
34
35 copy_movable_noexcept & operator=(BOOST_RV_REF(copy_movable_noexcept) m)
36 { value_ = m.value_; m.value_ = 0; return *this; }
37
38 copy_movable_noexcept & operator=(BOOST_COPY_ASSIGN_REF(copy_movable_noexcept) m)
39 { value_ = m.value_; return *this; }
40
41 bool moved() const //Observer
42 { return value_ == 0; }
43};
44
45namespace boost{
46
47template<>
48struct has_nothrow_move<copy_movable_noexcept>
49{
50 static const bool value = true;
51};
52
53} //namespace boost{
54
55//////////////////////////////////////////////////////////////////////////////
56//A movable_throwable class
57class movable_throwable
58{
59 BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_throwable)
60 int value_;
61
62 public:
63 movable_throwable() : value_(1){}
64
65 //Move constructor and assignment
66 movable_throwable(BOOST_RV_REF(movable_throwable) m)
67 { value_ = m.value_; m.value_ = 0; }
68
69 movable_throwable & operator=(BOOST_RV_REF(movable_throwable) m)
70 { value_ = m.value_; m.value_ = 0; return *this; }
71
72 bool moved() const //Observer
73 { return !value_; }
74
75 int value() const //Observer
76 { return value_; }
77};
78
79
80//////////////////////////////////////////////////////////////////////////////
81// Helper functions
82movable function(movable m)
83{
84 return movable(boost::move_if_noexcept(x&: m));
85}
86
87copy_movable function(copy_movable m)
88{
89 return copy_movable(boost::move_if_noexcept(x&: m));
90}
91
92copy_movable_noexcept function(copy_movable_noexcept m)
93{
94 return copy_movable_noexcept(boost::move_if_noexcept(x&: m));
95}
96
97movable_throwable function(movable_throwable m)
98{
99 return movable_throwable(boost::move_if_noexcept(x&: m));
100}
101
102movable functionr(BOOST_RV_REF(movable) m)
103{
104 return movable(boost::move_if_noexcept(x&: m));
105}
106
107movable function2(movable m)
108{
109 return boost::move_if_noexcept(x&: m);
110}
111
112BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
113{
114 return boost::move_if_noexcept(x&: m);
115}
116
117movable move_return_function2 ()
118{
119 return movable();
120}
121
122movable move_return_function ()
123{
124 movable m;
125 return (boost::move_if_noexcept(x&: m));
126}
127
128#define BOOST_CHECK(x) if (!(x)) { return __LINE__; }
129
130int main()
131{
132 {
133 movable m;
134 movable m2(boost::move_if_noexcept(x&: m));
135 BOOST_CHECK(m.moved());
136 movable m3(function(m: movable(boost::move_if_noexcept(x&: m2))));
137 BOOST_CHECK(m2.moved());
138 movable m4(function(m: boost::move_if_noexcept(x&: m3)));
139 BOOST_CHECK(m3.moved());
140 BOOST_CHECK(!m4.moved());
141 }
142 {
143 movable m;
144 movable m2(boost::move_if_noexcept(x&: m));
145 BOOST_CHECK(m.moved());
146 movable m3(functionr(m: movable(boost::move_if_noexcept(x&: m2))));
147 BOOST_CHECK(m2.moved());
148 movable m4(functionr(m: boost::move_if_noexcept(x&: m3)));
149 BOOST_CHECK(m3.moved());
150 BOOST_CHECK(!m4.moved());
151 }
152 {
153 movable m;
154 movable m2(boost::move_if_noexcept(x&: m));
155 BOOST_CHECK(m.moved());
156 movable m3(function2(m: movable(boost::move_if_noexcept(x&: m2))));
157 BOOST_CHECK(m2.moved());
158 movable m4(function2(m: boost::move_if_noexcept(x&: m3)));
159 BOOST_CHECK(m3.moved());
160 BOOST_CHECK(!m4.moved());
161 }
162 {
163 movable m;
164 movable m2(boost::move_if_noexcept(x&: m));
165 BOOST_CHECK(m.moved());
166 movable m3(function2r(m: movable(boost::move_if_noexcept(x&: m2))));
167 BOOST_CHECK(m2.moved());
168 movable m4(function2r(m: boost::move_if_noexcept(x&: m3)));
169 BOOST_CHECK(m3.moved());
170 BOOST_CHECK(!m4.moved());
171 }
172 {
173 movable m;
174 movable m2(boost::move_if_noexcept(x&: m));
175 BOOST_CHECK(m.moved());
176 BOOST_CHECK(!m2.moved());
177 movable m3(move_return_function());
178 BOOST_CHECK(!m3.moved());
179 }
180 {
181 movable m;
182 movable m2(boost::move_if_noexcept(x&: m));
183 BOOST_CHECK(m.moved());
184 BOOST_CHECK(!m2.moved());
185 movable m3(move_return_function2());
186 BOOST_CHECK(!m3.moved());
187 }
188
189 // copy_movable may throw during move, so it must be copied
190 {
191 copy_movable m;
192 copy_movable m2(boost::move_if_noexcept(x&: m));
193 BOOST_CHECK(!m.moved());
194 copy_movable m3(function(m: copy_movable(boost::move_if_noexcept(x&: m2))));
195 BOOST_CHECK(!m2.moved());
196 copy_movable m4(function(m: boost::move_if_noexcept(x&: m3)));
197 BOOST_CHECK(!m3.moved());
198 BOOST_CHECK(!m4.moved());
199 }
200
201
202 // copy_movable_noexcept can not throw during move
203 {
204 copy_movable_noexcept m;
205 copy_movable_noexcept m2(boost::move_if_noexcept(x&: m));
206 BOOST_CHECK(m.moved());
207 copy_movable_noexcept m3(function(m: copy_movable_noexcept(boost::move_if_noexcept(x&: m2))));
208 BOOST_CHECK(m2.moved());
209 copy_movable_noexcept m4(function(m: boost::move_if_noexcept(x&: m3)));
210 BOOST_CHECK(m3.moved());
211 BOOST_CHECK(!m4.moved());
212 }
213
214 // movable_throwable can not throw during move but it has no copy constructor
215 {
216 movable_throwable m;
217 movable_throwable m2(boost::move_if_noexcept(x&: m));
218 BOOST_CHECK(m.moved());
219 movable_throwable m3(function(m: movable_throwable(boost::move_if_noexcept(x&: m2))));
220 BOOST_CHECK(m2.moved());
221 movable_throwable m4(function(m: boost::move_if_noexcept(x&: m3)));
222 BOOST_CHECK(m3.moved());
223 BOOST_CHECK(!m4.moved());
224 }
225
226 return boost::report_errors();
227}
228

source code of boost/libs/move/test/move_if_noexcept.cpp