1// Boost.TypeErasure library
2//
3// Copyright 2011 Steven Watanabe
4//
5// Distributed under the Boost Software License Version 1.0. (See
6// accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// $Id$
10
11#include <boost/config.hpp>
12
13#ifdef BOOST_MSVC
14#pragma warning(disable:4244) // conversion from double to int
15#endif
16
17#include <boost/type_erasure/any.hpp>
18#include <boost/type_erasure/tuple.hpp>
19#include <boost/type_erasure/builtin.hpp>
20#include <boost/type_erasure/operators.hpp>
21#include <boost/type_erasure/any_cast.hpp>
22#include <boost/type_erasure/relaxed.hpp>
23#include <boost/mpl/vector.hpp>
24
25#define BOOST_TEST_MAIN
26#include <boost/test/unit_test.hpp>
27
28using namespace boost::type_erasure;
29using boost::core::demangle;
30
31template<class T = _self>
32struct common : ::boost::mpl::vector<
33 copy_constructible<T>,
34 typeid_<T>
35> {};
36
37#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
38
39template<class T = _self>
40struct movable_common : ::boost::mpl::vector<
41 destructible<T>,
42 constructible<T(T&&)>,
43 typeid_<T>
44> {};
45
46template<class T = _self, class U = T>
47struct move_assignable : ::boost::mpl::vector<
48 assignable<T, U&&>
49> {};
50
51#endif
52
53template<class T, bool CCtor, bool MoveCtor, bool CAssign, bool MoveAssign>
54struct test_class
55{
56 explicit test_class(T n) : value(n) {}
57 test_class(const test_class& src) : value(src.value)
58 {
59 BOOST_STATIC_ASSERT_MSG(CCtor, "Copy constructor not allowed.");
60 }
61 test_class& operator=(const test_class& src)
62 {
63 BOOST_STATIC_ASSERT_MSG(CAssign, "Copy assignment not allowed.");
64 value = src.value;
65 return *this;
66 }
67#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
68 test_class(test_class&& src) : value(src.value)
69 {
70 BOOST_STATIC_ASSERT_MSG(MoveCtor, "Move constructor not allowed.");
71 src.value = 0;
72 }
73 test_class& operator=(test_class&& src)
74 {
75 BOOST_STATIC_ASSERT_MSG(MoveAssign, "Move assignment not allowed.");
76 value = src.value;
77 src.value = 0;
78 return *this;
79 }
80#endif
81 bool operator==(T n) const { return value == n; }
82 T value;
83};
84
85template<class T, bool CCtor, bool MoveCtor, bool CAssign, bool MoveAssign>
86std::ostream& operator<<(std::ostream& os, const test_class<T, CCtor, MoveCtor, CAssign, MoveAssign>& t)
87{
88 return os << t.value;
89}
90
91enum copy_info {
92 id_lvalue = 1,
93 id_const_lvalue = 2,
94#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
95 id_rvalue = 3,
96 id_maybe_const_lvalue = id_lvalue, // used for the id of construction from a raw value
97#else
98 id_rvalue = id_const_lvalue,
99 id_maybe_const_lvalue = id_const_lvalue,
100#endif
101 id_construct = 4,
102 id_assign = 8,
103 id_copy = 16,
104 id_int = 32
105};
106
107#ifdef BOOST_MSVC
108#pragma warning(disable:4521) // multiple copy constructors specified
109#pragma warning(disable:4522) // multiple assignment operators specified
110#endif
111
112template<class T>
113struct copy_tracker
114{
115 copy_tracker(const copy_tracker& src) : value(src.value), info(id_const_lvalue | id_construct | id_copy), moved_from(false) {}
116 copy_tracker(copy_tracker& src) : value(src.value), info(id_lvalue | id_construct | id_copy), moved_from(false) {}
117 copy_tracker& operator=(const copy_tracker& src) { value = (src.value); info = (id_const_lvalue | id_assign | id_copy); moved_from = false; return *this; }
118 copy_tracker& operator=(copy_tracker& src) { value = (src.value); info = (id_lvalue | id_assign | id_copy); moved_from = false; return *this; }
119 copy_tracker(const T& src) : value(src), info(id_const_lvalue | id_construct | id_int), moved_from(false) {}
120 copy_tracker(T& src) : value(src), info(id_lvalue | id_construct | id_int), moved_from(false) {}
121 copy_tracker& operator=(const T& src) { value = (src); info = (id_const_lvalue | id_assign | id_int); moved_from = false; return *this; }
122 copy_tracker& operator=(T& src) { value = (src); info = (id_lvalue | id_assign | id_int); moved_from = false; return *this; }
123#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
124 copy_tracker(copy_tracker&& src) : value(std::move(src.value)), info(id_rvalue | id_construct | id_copy), moved_from(false) { src.moved_from = true; }
125 copy_tracker& operator=(copy_tracker&& src) { value = std::move(src.value); info = (id_rvalue | id_assign | id_copy); moved_from = false; src.moved_from = true; return *this; }
126 copy_tracker(T&& src) : value(std::move(src)), info(id_rvalue | id_construct | id_int), moved_from(false) {}
127 copy_tracker& operator=(T&& src) { value = std::move(src); info = (id_rvalue | id_assign | id_int); moved_from = false; return *this; }
128#endif
129 template<class U>
130 explicit copy_tracker(const U& src) : value(src), info(id_const_lvalue | id_construct | id_int), moved_from(false) {}
131 T value;
132 int info;
133 bool moved_from;
134};
135
136template<class T>
137struct value_holder
138{
139 typedef copy_tracker<T> type;
140 typedef copy_tracker<T> unwrapped_type;
141 template<class U>
142 value_holder(const U& u) : value(u) {}
143 type value;
144 type get() { return value; }
145 const unwrapped_type& unwrap() { return value; }
146 template<class U>
147 const U& unwrap() { return value; }
148};
149
150template<class C, class P>
151struct value_holder<any<C, P> >
152{
153 typedef any<C, P> type;
154 typedef any<C, P> unwrapped_type;
155#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
156 template<class U>
157 value_holder(U&& u) : value(std::forward<U>(u)) {}
158#else
159 template<class U>
160 value_holder(U& u) : value(u) {}
161 template<class U>
162 value_holder(const U& u) : value(u) {}
163#endif
164 type value;
165 type get() { return value; }
166 const unwrapped_type& unwrap() { return value; }
167 template<class U>
168 const U& unwrap() { return any_cast<const U&>(value); }
169};
170
171template<class T>
172struct value_holder<T&>
173{
174 typedef typename value_holder<T>::type& type;
175 typedef typename value_holder<T>::unwrapped_type unwrapped_type;
176#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
177 template<class U>
178 value_holder(U&& u) : impl(std::forward<U>(u)) {}
179#else
180 template<class U>
181 value_holder(U& u) : impl(u) {}
182 template<class U>
183 value_holder(const U& u) : impl(u) {}
184#endif
185 value_holder<T> impl;
186 type get() { return impl.value; }
187 const unwrapped_type& unwrap() { return unwrap<unwrapped_type>(); }
188 template<class U>
189 const U& unwrap() { return impl.template unwrap<unwrapped_type>(); }
190};
191
192template<class T>
193struct value_holder<const T&>
194{
195 typedef const typename value_holder<T>::type& type;
196 typedef typename value_holder<T>::unwrapped_type unwrapped_type;
197#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
198 template<class U>
199 value_holder(U&& u) : impl(std::forward<U>(u)) {}
200#else
201 template<class U>
202 value_holder(U& u) : impl(u) {}
203 template<class U>
204 value_holder(const U& u) : impl(u) {}
205#endif
206 value_holder<T> impl;
207 type get() { return impl.value; }
208 const unwrapped_type& unwrap() { return unwrap<unwrapped_type>(); }
209 template<class U>
210 const U& unwrap() { return impl.template unwrap<unwrapped_type>(); }
211};
212
213#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
214
215template<class T>
216struct value_holder<T&&>
217{
218 typedef typename value_holder<T>::type&& type;
219 typedef typename value_holder<T>::unwrapped_type unwrapped_type;
220 template<class U>
221 value_holder(U&& u) : impl(std::forward<U>(u)) {}
222 value_holder<T> impl;
223 type get() { return std::move(impl.value); }
224 const unwrapped_type& unwrap() { return unwrap<unwrapped_type>(); }
225 template<class U>
226 const U& unwrap() { return impl.template unwrap<unwrapped_type>(); }
227};
228
229#endif
230
231template<class T, class A>
232struct value_holder<T(A)>
233{
234#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
235 template<class U>
236 value_holder(U&& u) : init(std::forward<U>(u)), impl(init.get()) {}
237#else
238 template<class U>
239 value_holder(U& u) : init(u), impl(init.get()) {}
240 template<class U>
241 value_holder(const U& u) : init(u), impl(init.get()) {}
242#endif
243 value_holder<A> init;
244 value_holder<T> impl;
245 typedef typename value_holder<T>::type type;
246 typedef typename value_holder<A>::unwrapped_type unwrapped_type;
247 type get() { return impl.get(); }
248 const unwrapped_type& unwrap() { return unwrap<unwrapped_type>(); }
249 template<class U>
250 const U& unwrap() { return impl.template unwrap<unwrapped_type>(); }
251};
252
253#define TEST_ASSIGNMENT_I(LHS, RHS, result, ptr_op, R) \
254 try \
255 { \
256 value_holder<LHS> lhs(17); \
257 value_holder<RHS> rhs(23); \
258 const void * original = any_cast<const void*>(&lhs.get()); \
259 lhs.get() = rhs.get(); \
260 typedef value_holder<R>::unwrapped_type expected_type; \
261 if(const expected_type* ptr = \
262 any_cast<const expected_type*>(&lhs.get())) \
263 { \
264 BOOST_TEST(ptr->value == 23); \
265 BOOST_TEST(ptr->info == (result)); \
266 BOOST_TEST(ptr ptr_op original); \
267 } \
268 else \
269 { \
270 BOOST_ERROR("Wrong type: Expected " \
271 << boost::core::demangle(typeid(expected_type).name()) \
272 << " but got " \
273 << boost::core::demangle(typeid_of(lhs.get()).name())); \
274 } \
275 } \
276 catch(bad_function_call&) \
277 { \
278 BOOST_ERROR("bad_function_call in " \
279 << demangle(typeid(value_holder<LHS>::type).name()) \
280 << " = " \
281 << demangle(typeid(value_holder<RHS>::type).name())); \
282 }
283
284#define TEST_ASSIGNMENT_id_dispatch(LHS, RHS, result) \
285 TEST_ASSIGNMENT_I(LHS, RHS, result, ==, LHS)
286
287#define TEST_ASSIGNMENT_id_fallback(LHS, RHS, result) \
288 TEST_ASSIGNMENT_I(LHS, RHS, result, !=, RHS)
289
290#define TEST_ASSIGNMENT_id_throw(LHS, RHS, result) \
291 { \
292 value_holder<LHS> lhs(17); \
293 value_holder<RHS> rhs(23); \
294 BOOST_CHECK_THROW(lhs.get() = rhs.get(), bad_function_call); \
295 }
296
297#define TEST_ASSIGNMENT(LHS, RHS, tag, result) \
298 BOOST_PP_CAT(TEST_ASSIGNMENT_, tag)(LHS, RHS, result)
299
300BOOST_AUTO_TEST_CASE(test_nothing)
301{
302 // Nothing to test. Assignment is entirely illegal
303}
304
305BOOST_AUTO_TEST_CASE(test_nothing_relaxed)
306{
307 typedef ::boost::mpl::vector<
308 destructible<>,
309 typeid_<>,
310 constructible<_self(int)>,
311 relaxed
312 > test_concept;
313 typedef test_class<int, false, false, false, false> test_type;
314
315 typedef any<test_concept> any_val;
316 typedef any<test_concept, _self&> any_ref;
317
318 // Compile-time check.
319 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
320 any_val v1(test_binding, 1);
321
322 // assignment of same type
323
324 // different stored type
325
326 // raw value
327
328 // assignment to a reference
329 TEST_ASSIGNMENT(any_ref&(int&), any_val&(int), id_fallback, id_rvalue | id_construct | id_copy);
330 TEST_ASSIGNMENT(any_ref&(int&), any_ref(int&), id_fallback, id_const_lvalue | id_construct | id_int);
331 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(int&), id_fallback, id_const_lvalue | id_construct | id_int);
332 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(int&), id_fallback, id_const_lvalue | id_construct | id_int);
333
334 // reference with a different type
335 TEST_ASSIGNMENT(any_ref&(int&), any_val&(long), id_fallback, id_rvalue | id_construct | id_copy);
336 TEST_ASSIGNMENT(any_ref&(int&), any_ref(long&), id_fallback, id_const_lvalue | id_construct | id_int);
337 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
338 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
339
340 // reference with raw value
341 TEST_ASSIGNMENT(any_ref&(int&), int&, id_fallback, id_const_lvalue | id_construct | id_int);
342 TEST_ASSIGNMENT(any_ref&(int&), long&, id_fallback, id_const_lvalue | id_construct | id_int);
343
344#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
345
346 typedef any<test_concept, _self&&> any_rref;
347
348 // rvalue reference as the rhs
349
350 // assignment to an rvalue reference
351 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_fallback, id_rvalue | id_construct | id_copy);
352 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_fallback, id_const_lvalue | id_construct | id_int);
353 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_fallback, id_const_lvalue | id_construct | id_int);
354 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_fallback, id_const_lvalue | id_construct | id_int);
355
356 // rvalue reference with a different type
357 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(long), id_fallback, id_rvalue | id_construct | id_copy);
358 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
359 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
360 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
361
362 // rvalue reference with raw value
363 TEST_ASSIGNMENT(any_rref&(int&&), int&&, id_fallback, id_const_lvalue | id_construct | id_int);
364 TEST_ASSIGNMENT(any_rref&(int&&), long&&, id_fallback, id_const_lvalue | id_construct | id_int);
365#endif
366}
367
368BOOST_AUTO_TEST_CASE(test_copy_assignable)
369{
370 typedef ::boost::mpl::vector<
371 destructible<>,
372 typeid_<>,
373 assignable<>,
374 constructible<_self(int)>
375 > test_concept;
376 typedef test_class<int, false, false, true, false> test_type;
377
378 typedef any<test_concept> any_val;
379 typedef any<test_concept, _self&> any_ref;
380 typedef any<test_concept, const _self&> any_cref;
381
382 // Compile-time check.
383 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
384 any_val v1(test_binding, 1);
385
386 // assignment of same type
387#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
388 TEST_ASSIGNMENT(any_val&(int), any_val&&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
389#endif
390 TEST_ASSIGNMENT(any_val&(int), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
391 TEST_ASSIGNMENT(any_val&(int), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
392 TEST_ASSIGNMENT(any_val&(int), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
393 TEST_ASSIGNMENT(any_val&(int), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
394 TEST_ASSIGNMENT(any_val&(int), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
395 TEST_ASSIGNMENT(any_val&(int), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
396 TEST_ASSIGNMENT(any_val&(int), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
397 TEST_ASSIGNMENT(any_val&(int), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
398
399 // different stored type (undefined behavior)
400
401 // raw value (compile error)
402
403 // assignment to a reference
404#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
405 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
406#endif
407 TEST_ASSIGNMENT(any_ref&(int&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
408 TEST_ASSIGNMENT(any_ref&(int&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
409 TEST_ASSIGNMENT(any_ref&(int&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
410 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
411 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
412 TEST_ASSIGNMENT(any_ref&(int&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
413 TEST_ASSIGNMENT(any_ref&(int&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
414 TEST_ASSIGNMENT(any_ref&(int&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
415
416 // reference with a different type (undefined behavior)
417
418 // reference with raw value (compile error)
419
420#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
421
422 typedef any<test_concept, _self&&> any_rref;
423
424 // rvalue reference as the rhs
425 TEST_ASSIGNMENT(any_val&(int), any_rref(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
426 TEST_ASSIGNMENT(any_val&(int), any_rref&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
427 TEST_ASSIGNMENT(any_val&(int), any_rref const&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
428 TEST_ASSIGNMENT(any_ref&(int&), any_rref(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
429 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
430 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
431
432 // assignment to an rvalue reference (same dispatching behavior as lvalue reference)
433 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
434 TEST_ASSIGNMENT(any_rref&(int&&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
435 TEST_ASSIGNMENT(any_rref&(int&&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
436 TEST_ASSIGNMENT(any_rref&(int&&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
437 TEST_ASSIGNMENT(any_rref&(int&&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
438 TEST_ASSIGNMENT(any_rref&(int&&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
439 TEST_ASSIGNMENT(any_rref&(int&&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
440 TEST_ASSIGNMENT(any_rref&(int&&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
441 TEST_ASSIGNMENT(any_rref&(int&&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
442 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
443 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
444 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
445
446 // rvalue reference with a different type (undefined behavior)
447
448 // rvalue reference with raw value (compile error)
449#endif
450}
451
452BOOST_AUTO_TEST_CASE(test_copy_assignable_relaxed)
453{
454 typedef ::boost::mpl::vector<
455 destructible<>,
456 typeid_<>,
457 assignable<>,
458 constructible<_self(int)>,
459 relaxed
460 > test_concept;
461 typedef test_class<int, false, false, true, false> test_type;
462
463 typedef any<test_concept> any_val;
464 typedef any<test_concept, _self&> any_ref;
465 typedef any<test_concept, const _self&> any_cref;
466
467 // Compile-time check.
468 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
469 any_val v1(test_binding, 1);
470
471 // assignment of same type
472#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
473 TEST_ASSIGNMENT(any_val&(int), any_val&&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
474#endif
475 TEST_ASSIGNMENT(any_val&(int), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
476 TEST_ASSIGNMENT(any_val&(int), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
477 TEST_ASSIGNMENT(any_val&(int), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
478 TEST_ASSIGNMENT(any_val&(int), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
479 TEST_ASSIGNMENT(any_val&(int), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
480 TEST_ASSIGNMENT(any_val&(int), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
481 TEST_ASSIGNMENT(any_val&(int), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
482 TEST_ASSIGNMENT(any_val&(int), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
483
484 // different stored type
485#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
486 TEST_ASSIGNMENT(any_val&(int), any_val&&(long), id_throw, 0);
487#endif
488 TEST_ASSIGNMENT(any_val&(int), any_val&(long), id_throw, 0);
489 TEST_ASSIGNMENT(any_val&(int), any_val const&(long), id_throw, 0);
490 TEST_ASSIGNMENT(any_val&(int), any_ref(long&), id_throw, 0);
491 TEST_ASSIGNMENT(any_val&(int), any_ref&(long&), id_throw, 0);
492 TEST_ASSIGNMENT(any_val&(int), any_ref const&(long&), id_throw, 0);
493 TEST_ASSIGNMENT(any_val&(int), any_cref(long&), id_throw, 0);
494 TEST_ASSIGNMENT(any_val&(int), any_cref&(long&), id_throw, 0);
495 TEST_ASSIGNMENT(any_val&(int), any_cref const&(long&), id_throw, 0);
496
497 // raw value
498 TEST_ASSIGNMENT(any_val&(int), int, id_fallback, id_rvalue | id_construct | id_copy);
499 TEST_ASSIGNMENT(any_val&(int), int&, id_fallback, id_maybe_const_lvalue | id_construct | id_copy);
500 TEST_ASSIGNMENT(any_val&(int), int const&, id_fallback, id_const_lvalue | id_construct | id_copy);
501 TEST_ASSIGNMENT(any_val&(int), long, id_fallback, id_rvalue | id_construct | id_copy);
502 TEST_ASSIGNMENT(any_val&(int), long&, id_fallback, id_maybe_const_lvalue | id_construct | id_copy);
503 TEST_ASSIGNMENT(any_val&(int), long const&, id_fallback, id_const_lvalue | id_construct | id_copy);
504
505 // assignment to a reference
506#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
507 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
508#endif
509 TEST_ASSIGNMENT(any_ref&(int&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
510 TEST_ASSIGNMENT(any_ref&(int&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
511 TEST_ASSIGNMENT(any_ref&(int&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
512 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
513 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
514 TEST_ASSIGNMENT(any_ref&(int&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
515 TEST_ASSIGNMENT(any_ref&(int&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
516 TEST_ASSIGNMENT(any_ref&(int&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
517
518 // reference with a different type
519#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
520 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(long), id_throw, 0);
521#endif
522 TEST_ASSIGNMENT(any_ref&(int&), any_val&(long), id_fallback, id_rvalue | id_construct | id_copy);
523 TEST_ASSIGNMENT(any_ref&(int&), any_val const&(long), id_throw, 0);
524 TEST_ASSIGNMENT(any_ref&(int&), any_ref(long&), id_fallback, id_const_lvalue | id_construct | id_int);
525 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
526 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
527 TEST_ASSIGNMENT(any_ref&(int&), any_cref(long&), id_throw, 0);
528 TEST_ASSIGNMENT(any_ref&(int&), any_cref&(long&), id_throw, 0);
529 TEST_ASSIGNMENT(any_ref&(int&), any_cref const&(long&), id_throw, 0);
530
531 // reference with raw value
532 TEST_ASSIGNMENT(any_ref&(int&), int&, id_fallback, id_const_lvalue | id_construct | id_int);
533 TEST_ASSIGNMENT(any_ref&(int&), long&, id_fallback, id_const_lvalue | id_construct | id_int);
534
535#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
536
537 typedef any<test_concept, _self&&> any_rref;
538
539 // rvalue reference as the rhs
540 TEST_ASSIGNMENT(any_val&(int), any_rref(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
541 TEST_ASSIGNMENT(any_val&(int), any_rref&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
542 TEST_ASSIGNMENT(any_val&(int), any_rref const&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
543 TEST_ASSIGNMENT(any_val&(int), any_rref(long&&), id_throw, 0);
544 TEST_ASSIGNMENT(any_val&(int), any_rref&(long&&), id_throw, 0);
545 TEST_ASSIGNMENT(any_val&(int), any_rref const&(long&&), id_throw, );
546 TEST_ASSIGNMENT(any_ref&(int&), any_rref(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
547 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
548 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
549 TEST_ASSIGNMENT(any_ref&(int&), any_rref(long&&), id_throw, 0);
550 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(long&&), id_throw, 0);
551 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(long&&), id_throw, 0);
552
553 // assignment to an rvalue reference (same dispatching behavior as lvalue reference)
554 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
555 TEST_ASSIGNMENT(any_rref&(int&&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
556 TEST_ASSIGNMENT(any_rref&(int&&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
557 TEST_ASSIGNMENT(any_rref&(int&&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
558 TEST_ASSIGNMENT(any_rref&(int&&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
559 TEST_ASSIGNMENT(any_rref&(int&&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
560 TEST_ASSIGNMENT(any_rref&(int&&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
561 TEST_ASSIGNMENT(any_rref&(int&&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
562 TEST_ASSIGNMENT(any_rref&(int&&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
563 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
564 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
565 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_dispatch, id_const_lvalue | id_assign | id_copy);
566
567 // rvalue reference with a different type
568 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(long), id_fallback, id_rvalue | id_construct | id_copy);
569 TEST_ASSIGNMENT(any_rref&(int&&), any_val&(long), id_throw, 0);
570 TEST_ASSIGNMENT(any_rref&(int&&), any_val const&(long), id_throw, 0);
571 TEST_ASSIGNMENT(any_rref&(int&&), any_ref(long&), id_throw, 0);
572 TEST_ASSIGNMENT(any_rref&(int&&), any_ref&(long&), id_throw, 0);
573 TEST_ASSIGNMENT(any_rref&(int&&), any_ref const&(long&), id_throw, 0);
574 TEST_ASSIGNMENT(any_rref&(int&&), any_cref(long&), id_throw, 0);
575 TEST_ASSIGNMENT(any_rref&(int&&), any_cref&(long&), id_throw, 0);
576 TEST_ASSIGNMENT(any_rref&(int&&), any_cref const&(long&), id_throw, 0);
577 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
578 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
579 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
580
581 // rvalue reference with raw value
582 TEST_ASSIGNMENT(any_rref&(int&&), int&&, id_fallback, id_const_lvalue | id_construct | id_int);
583 TEST_ASSIGNMENT(any_rref&(int&&), long&&, id_fallback, id_const_lvalue | id_construct | id_int);
584#endif
585}
586
587#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
588
589BOOST_AUTO_TEST_CASE(test_move_assignable)
590{
591 typedef ::boost::mpl::vector<
592 destructible<>,
593 typeid_<>,
594 move_assignable<>,
595 constructible<_self(int)>
596 > test_concept;
597 typedef test_class<int, false, false, false, true> test_type;
598
599 typedef any<test_concept> any_val;
600 typedef any<test_concept, _self&> any_ref;
601
602 // Compile-time check.
603 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
604 any_val v1(test_binding, 1);
605
606 // assignment of same type
607 TEST_ASSIGNMENT(any_val&(int), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
608
609 // different stored type
610
611 // raw value
612
613 // assignment to a reference
614 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
615
616 // reference with a different type
617
618 // reference with raw value
619
620 typedef any<test_concept, _self&&> any_rref;
621
622 // rvalue reference as the rhs
623 TEST_ASSIGNMENT(any_val&(int), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
624 TEST_ASSIGNMENT(any_val&(int), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
625 TEST_ASSIGNMENT(any_val&(int), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
626 TEST_ASSIGNMENT(any_ref&(int&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
627 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
628 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);;
629
630 // assignment to an rvalue reference (same dispatching behavior as lvalue reference)
631 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
632 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
633 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
634 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
635
636 // rvalue reference with a different type
637
638 // rvalue reference with raw value
639}
640
641BOOST_AUTO_TEST_CASE(test_move_assignable_relaxed)
642{
643 typedef ::boost::mpl::vector<
644 destructible<>,
645 typeid_<>,
646 move_assignable<>,
647 constructible<_self(int)>,
648 relaxed
649 > test_concept;
650 typedef test_class<int, false, false, false, true> test_type;
651
652 typedef any<test_concept> any_val;
653 typedef any<test_concept, _self&> any_ref;
654
655 // Compile-time check.
656 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
657 any_val v1(test_binding, 1);
658
659 // assignment of same type
660 TEST_ASSIGNMENT(any_val&(int), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
661
662 // different stored type
663 TEST_ASSIGNMENT(any_val&(int), any_val&&(long), id_throw, 0);
664
665 // raw value
666
667 // assignment to a reference
668 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
669 TEST_ASSIGNMENT(any_ref&(int&), any_val&(int), id_fallback, id_rvalue | id_construct | id_copy);
670 TEST_ASSIGNMENT(any_ref&(int&), any_ref(int&), id_fallback, id_const_lvalue | id_construct | id_int);
671 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(int&), id_fallback, id_const_lvalue | id_construct | id_int);
672 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(int&), id_fallback, id_const_lvalue | id_construct | id_int);
673
674 // reference with a different type
675 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(long), id_throw, 0);
676 TEST_ASSIGNMENT(any_ref&(int&), any_val&(long), id_fallback, id_rvalue | id_construct | id_copy);
677 TEST_ASSIGNMENT(any_ref&(int&), any_ref(long&), id_fallback, id_const_lvalue | id_construct | id_int);
678 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
679 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
680
681 // reference with raw value
682 TEST_ASSIGNMENT(any_ref&(int&), int&, id_fallback, id_const_lvalue | id_construct | id_int);
683 TEST_ASSIGNMENT(any_ref&(int&), long&, id_fallback, id_const_lvalue | id_construct | id_int);
684
685 typedef any<test_concept, _self&&> any_rref;
686
687 // rvalue reference as the rhs
688 TEST_ASSIGNMENT(any_val&(int), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
689 TEST_ASSIGNMENT(any_val&(int), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
690 TEST_ASSIGNMENT(any_val&(int), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
691 TEST_ASSIGNMENT(any_val&(int), any_rref(long&&), id_throw, 0);
692 TEST_ASSIGNMENT(any_val&(int), any_rref&(long&&), id_throw, 0);
693 TEST_ASSIGNMENT(any_val&(int), any_rref const&(long&&), id_throw, 0);
694 TEST_ASSIGNMENT(any_ref&(int&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
695 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
696 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
697 TEST_ASSIGNMENT(any_ref&(int&), any_rref(long&&), id_throw, 0);
698 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(long&&), id_throw, 0);
699 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(long&&), id_throw, 0);
700
701 // assignment to an rvalue reference (same dispatching behavior as lvalue reference)
702 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
703 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
704 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
705 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
706
707 // rvalue reference with a different type
708 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(long), id_fallback, id_rvalue | id_construct | id_copy);
709 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
710 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
711 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(long&&), id_fallback, id_const_lvalue | id_construct | id_int);
712
713 // rvalue reference with raw value
714 TEST_ASSIGNMENT(any_rref&(int&&), int&&, id_fallback, id_const_lvalue | id_construct | id_int);
715 TEST_ASSIGNMENT(any_rref&(int&&), long&&, id_fallback, id_const_lvalue | id_construct | id_int);
716}
717
718#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
719
720BOOST_AUTO_TEST_CASE(test_move_and_copy_assignable)
721{
722 typedef ::boost::mpl::vector<
723 destructible<>,
724 typeid_<>,
725 assignable<>,
726 move_assignable<>,
727 constructible<_self(int)>
728 > test_concept;
729 typedef test_class<int, false, false, true, true> test_type;
730
731 typedef any<test_concept> any_val;
732 typedef any<test_concept, _self&> any_ref;
733 typedef any<test_concept, const _self&> any_cref;
734
735 // Compile-time check.
736 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
737 any_val v1(test_binding, 1);
738
739 // assignment of same type
740 TEST_ASSIGNMENT(any_val&(int), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
741 TEST_ASSIGNMENT(any_val&(int), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
742 TEST_ASSIGNMENT(any_val&(int), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
743 TEST_ASSIGNMENT(any_val&(int), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
744 TEST_ASSIGNMENT(any_val&(int), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
745 TEST_ASSIGNMENT(any_val&(int), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
746 TEST_ASSIGNMENT(any_val&(int), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
747 TEST_ASSIGNMENT(any_val&(int), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
748 TEST_ASSIGNMENT(any_val&(int), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
749
750 // different stored type (undefined behavior)
751
752 // raw value (compile error)
753
754 // assignment to a reference
755 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
756 TEST_ASSIGNMENT(any_ref&(int&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
757 TEST_ASSIGNMENT(any_ref&(int&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
758 TEST_ASSIGNMENT(any_ref&(int&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
759 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
760 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
761 TEST_ASSIGNMENT(any_ref&(int&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
762 TEST_ASSIGNMENT(any_ref&(int&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
763 TEST_ASSIGNMENT(any_ref&(int&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
764
765 // reference with a different type (undefined behavior)
766
767 // reference with raw value (compile error)
768
769 typedef any<test_concept, _self&&> any_rref;
770
771 // rvalue reference as the rhs
772 TEST_ASSIGNMENT(any_val&(int), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
773 TEST_ASSIGNMENT(any_val&(int), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
774 TEST_ASSIGNMENT(any_val&(int), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
775 TEST_ASSIGNMENT(any_ref&(int&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
776 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
777 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
778
779 // assignment to an rvalue reference (same dispatching behavior as lvalue reference)
780 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
781 TEST_ASSIGNMENT(any_rref&(int&&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
782 TEST_ASSIGNMENT(any_rref&(int&&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
783 TEST_ASSIGNMENT(any_rref&(int&&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
784 TEST_ASSIGNMENT(any_rref&(int&&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
785 TEST_ASSIGNMENT(any_rref&(int&&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
786 TEST_ASSIGNMENT(any_rref&(int&&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
787 TEST_ASSIGNMENT(any_rref&(int&&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
788 TEST_ASSIGNMENT(any_rref&(int&&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
789 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
790 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
791 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
792
793 // rvalue reference with a different type (undefined behavior)
794
795 // rvalue reference with raw value (compile error)
796}
797
798BOOST_AUTO_TEST_CASE(test_move_and_copy_assignable_relaxed)
799{
800 typedef ::boost::mpl::vector<
801 destructible<>,
802 typeid_<>,
803 assignable<>,
804 move_assignable<>,
805 constructible<_self(int)>,
806 relaxed
807 > test_concept;
808 typedef test_class<int, false, false, true, true> test_type;
809
810 typedef any<test_concept> any_val;
811 typedef any<test_concept, _self&> any_ref;
812 typedef any<test_concept, const _self&> any_cref;
813
814 // Compile-time check.
815 binding<test_concept> test_binding = make_binding< ::boost::mpl::map< ::boost::mpl::pair<_self, test_type> > >();
816 any_val v1(test_binding, 1);
817
818 // assignment of same type
819 TEST_ASSIGNMENT(any_val&(int), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
820 TEST_ASSIGNMENT(any_val&(int), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
821 TEST_ASSIGNMENT(any_val&(int), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
822 TEST_ASSIGNMENT(any_val&(int), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
823 TEST_ASSIGNMENT(any_val&(int), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
824 TEST_ASSIGNMENT(any_val&(int), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
825 TEST_ASSIGNMENT(any_val&(int), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
826 TEST_ASSIGNMENT(any_val&(int), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
827 TEST_ASSIGNMENT(any_val&(int), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
828
829 // different stored type
830 TEST_ASSIGNMENT(any_val&(int), any_val&&(long), id_throw, 0);
831 TEST_ASSIGNMENT(any_val&(int), any_val&(long), id_throw, 0);
832 TEST_ASSIGNMENT(any_val&(int), any_val const&(long), id_throw, 0);
833 TEST_ASSIGNMENT(any_val&(int), any_ref(long&), id_throw, 0);
834 TEST_ASSIGNMENT(any_val&(int), any_ref&(long&), id_throw, 0);
835 TEST_ASSIGNMENT(any_val&(int), any_ref const&(long&), id_throw, 0);
836 TEST_ASSIGNMENT(any_val&(int), any_cref(long&), id_throw, 0);
837 TEST_ASSIGNMENT(any_val&(int), any_cref&(long&), id_throw, 0);
838 TEST_ASSIGNMENT(any_val&(int), any_cref const&(long&), id_throw, 0);
839
840 // raw value
841 TEST_ASSIGNMENT(any_val&(int), int, id_fallback, id_rvalue | id_construct | id_copy);
842 TEST_ASSIGNMENT(any_val&(int), int&, id_fallback, id_lvalue | id_construct | id_copy);
843 TEST_ASSIGNMENT(any_val&(int), int const&, id_fallback, id_const_lvalue | id_construct | id_copy);
844 TEST_ASSIGNMENT(any_val&(int), long, id_fallback, id_rvalue | id_construct | id_copy);
845 TEST_ASSIGNMENT(any_val&(int), long&, id_fallback, id_lvalue | id_construct | id_copy);
846 TEST_ASSIGNMENT(any_val&(int), long const&, id_fallback, id_const_lvalue | id_construct | id_copy);
847
848 // assignment to a reference
849 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
850 TEST_ASSIGNMENT(any_ref&(int&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
851 TEST_ASSIGNMENT(any_ref&(int&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
852 TEST_ASSIGNMENT(any_ref&(int&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
853 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
854 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
855 TEST_ASSIGNMENT(any_ref&(int&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
856 TEST_ASSIGNMENT(any_ref&(int&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
857 TEST_ASSIGNMENT(any_ref&(int&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
858
859 // reference with a different type
860 TEST_ASSIGNMENT(any_ref&(int&), any_val&&(long), id_throw, 0);
861 TEST_ASSIGNMENT(any_ref&(int&), any_val&(long), id_fallback, id_rvalue | id_construct | id_copy);
862 TEST_ASSIGNMENT(any_ref&(int&), any_val const&(long), id_throw, 0);
863 TEST_ASSIGNMENT(any_ref&(int&), any_ref(long&), id_fallback, id_const_lvalue | id_construct | id_int);
864 TEST_ASSIGNMENT(any_ref&(int&), any_ref&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
865 TEST_ASSIGNMENT(any_ref&(int&), any_ref const&(long&), id_fallback, id_const_lvalue | id_construct | id_int);
866 TEST_ASSIGNMENT(any_ref&(int&), any_cref(long&), id_throw, 0);
867 TEST_ASSIGNMENT(any_ref&(int&), any_cref&(long&), id_throw, 0);
868 TEST_ASSIGNMENT(any_ref&(int&), any_cref const&(long&), id_throw, 0);
869
870 // reference with raw value
871 TEST_ASSIGNMENT(any_ref&(int&), int&, id_fallback, id_const_lvalue | id_construct | id_int);
872 TEST_ASSIGNMENT(any_ref&(int&), long&, id_fallback, id_const_lvalue | id_construct | id_int);
873
874 typedef any<test_concept, _self&&> any_rref;
875
876 // rvalue reference as the rhs
877 TEST_ASSIGNMENT(any_val&(int), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
878 TEST_ASSIGNMENT(any_val&(int), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
879 TEST_ASSIGNMENT(any_val&(int), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
880 TEST_ASSIGNMENT(any_val&(int), any_rref(long&&), id_throw, 0);
881 TEST_ASSIGNMENT(any_val&(int), any_rref&(long&&), id_throw, 0);
882 TEST_ASSIGNMENT(any_val&(int), any_rref const&(long&&), id_throw, 0);
883 TEST_ASSIGNMENT(any_ref&(int&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
884 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
885 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
886 TEST_ASSIGNMENT(any_ref&(int&), any_rref(long&&), id_throw, 0);
887 TEST_ASSIGNMENT(any_ref&(int&), any_rref&(long&&), id_throw, 0);
888 TEST_ASSIGNMENT(any_ref&(int&), any_rref const&(long&&), id_throw, 0);
889
890 // assignment to an rvalue reference (same dispatching behavior as lvalue reference)
891 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(int), id_dispatch, id_rvalue | id_assign | id_copy);
892 TEST_ASSIGNMENT(any_rref&(int&&), any_val&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
893 TEST_ASSIGNMENT(any_rref&(int&&), any_val const&(int), id_dispatch, id_const_lvalue | id_assign | id_copy);
894 TEST_ASSIGNMENT(any_rref&(int&&), any_ref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
895 TEST_ASSIGNMENT(any_rref&(int&&), any_ref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
896 TEST_ASSIGNMENT(any_rref&(int&&), any_ref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
897 TEST_ASSIGNMENT(any_rref&(int&&), any_cref(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
898 TEST_ASSIGNMENT(any_rref&(int&&), any_cref&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
899 TEST_ASSIGNMENT(any_rref&(int&&), any_cref const&(int&), id_dispatch, id_const_lvalue | id_assign | id_copy);
900 TEST_ASSIGNMENT(any_rref&(int&&), any_rref(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
901 TEST_ASSIGNMENT(any_rref&(int&&), any_rref&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
902 TEST_ASSIGNMENT(any_rref&(int&&), any_rref const&(int&&), id_dispatch, id_rvalue | id_assign | id_copy);
903
904 // rvalue reference with a different type
905 TEST_ASSIGNMENT(any_rref&(int&&), any_val&&(long), id_fallback, id_rvalue | id_construct | id_copy);
906 TEST_ASSIGNMENT(any_rref&(int&&), any_val&(long), id_throw, 0);
907 TEST_ASSIGNMENT(any_rref&(int&&), any_val const&(long), id_throw, 0);
908 TEST_ASSIGNMENT(any_rref&(int&&), any_ref(long&), id_throw, 0);
909 TEST_ASSIGNMENT(any_rref&(int&&), any_ref&(long&), id_throw, 0);
910 TEST_ASSIGNMENT(any_rref&(int&&), any_ref const&(long&), id_throw, 0);
911 TEST_ASSIGNMENT(any_rref&(int&&), any_cref(long&), id_throw, 0);
912 TEST_ASSIGNMENT(any_rref&(int&&), any_cref&(long&), id_throw, 0);
913 TEST_ASSIGNMENT(any_rref&(int&&), any_cref const&(long&), id_throw, 0);
914