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