1 // (C) Copyright 2013 Ruslan Baratov
2 // Copyright (C) 2014 Vicente J. Botet Escriba
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 // See www.boost.org/libs/thread for documentation.
8
9 #define BOOST_THREAD_VERSION 4
10
11 #include <boost/detail/lightweight_test.hpp> // BOOST_TEST
12
13 #include <boost/thread/mutex.hpp>
14 #include <boost/thread/with_lock_guard.hpp>
15
16 class Foo {
17 public:
Foo(int a)18 explicit Foo(int a) : a_(a) {
19 }
20
Foo(BOOST_RV_REF (Foo)foo)21 Foo(BOOST_RV_REF(Foo) foo) : a_(foo.a_) {
22 BOOST_ASSERT(&foo != this);
23 foo.a_ = 0;
24 }
25
operator =(BOOST_RV_REF (Foo)foo)26 Foo& operator=(BOOST_RV_REF(Foo) foo) {
27 BOOST_ASSERT(&foo != this);
28 a_ = foo.a_;
29 foo.a_ = 0;
30 return *this;
31 }
32
get() const33 int get() const {
34 return a_;
35 }
36
37 private:
38 BOOST_MOVABLE_BUT_NOT_COPYABLE(Foo)
39
40 int a_;
41 };
42
43 template <class T1, class T2>
func_with_2_arg(BOOST_FWD_REF (T1)arg_1,BOOST_FWD_REF (T2)arg_2)44 bool func_with_2_arg(BOOST_FWD_REF(T1) arg_1, BOOST_FWD_REF(T2) arg_2) {
45 BOOST_TEST(arg_1.get() == 3);
46 BOOST_TEST(arg_2.get() == 767);
47 return false;
48 }
49
test_movable()50 void test_movable() {
51 boost::mutex m;
52
53 Foo foo_1(3);
54 Foo foo_2(767);
55
56 bool res = boost::with_lock_guard(
57 m, &func_with_2_arg<Foo, Foo>, boost::move(foo_1), boost::move(foo_2)
58 );
59 BOOST_TEST(!res);
60 }
61
62 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
test_real_movable()63 void test_real_movable() {
64 std::cout << "c++11 move emulated" << std::endl;
65 }
66 #else
67 // test real one
68 class Boo {
69 public:
Boo(int a)70 Boo(int a) : a_(a) {
71 }
72
Boo(Boo && boo)73 Boo(Boo&& boo) : a_(boo.a_) {
74 BOOST_ASSERT(&boo != this);
75 boo.a_ = 0;
76 }
77
get() const78 int get() const {
79 return a_;
80 }
81
82 BOOST_DELETED_FUNCTION(Boo(Boo&))
83 BOOST_DELETED_FUNCTION(Boo& operator=(Boo&))
84 BOOST_DELETED_FUNCTION(Boo& operator=(Boo&&))
85 private:
86 int a_;
87 };
88
func_with_3_arg(Boo && boo_1,Boo && boo_2,Boo && boo_3)89 void func_with_3_arg(Boo&& boo_1, Boo&& boo_2, Boo&& boo_3) {
90 BOOST_TEST(boo_1.get() == 11);
91 BOOST_TEST(boo_2.get() == 12);
92 BOOST_TEST(boo_3.get() == 13);
93 }
94
test_real_movable()95 void test_real_movable() {
96 boost::mutex m;
97
98 Boo boo_3(13);
99
100 boost::with_lock_guard(
101 m, func_with_3_arg, Boo(11), Boo(12), boost::move(boo_3)
102 );
103 }
104 #endif
105
main()106 int main() {
107 test_movable();
108 test_real_movable();
109 return boost::report_errors();
110 }
111