1 //  Copyright 2013 (c) Agustin Berge
2 //
3 //  Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 
8 // For more information, see http://www.boost.org
9 
10 #include <hpx/hpx_main.hpp>
11 #include <hpx/include/util.hpp>
12 #include <hpx/util/lightweight_test.hpp>
13 
14 #include <iostream>
15 #include <utility>
16 
17 struct counter
18 {
19     static int default_constructions;
20     static int copy_constructions;
21     static int move_constructions;
22 
resetcounter23     static void reset()
24     {
25         default_constructions = 0;
26         copy_constructions = 0;
27         move_constructions = 0;
28     }
29 
printcounter30     static void print()
31     {
32         std::cout << "default-constructions: " << default_constructions << "\n";
33         std::cout << "copy-constructions: " << copy_constructions << "\n";
34         std::cout << "move-constructions: " << move_constructions << "\n" << std::endl;
35     }
36 
countercounter37     counter(){ ++default_constructions; }
countercounter38     counter(counter const&){ ++copy_constructions; }
countercounter39     counter(counter &&){ ++move_constructions; }
40 
41 private:
42     ;
43 
44     counter& operator=(counter const&);
45     counter& operator=(counter &&);
46 };
47 
48 int counter::default_constructions = 0;
49 int counter::copy_constructions = 0;
50 int counter::move_constructions = 0;
51 
52 ////////////////////////////////////////////////////////////////////////////////
f_value(counter)53 void f_value(counter){}
54 
test_by_value()55 void test_by_value()
56 {
57     hpx::util::function_nonser<void(counter)> f = f_value;
58 
59     counter::reset();
60 
61     counter c;
62     f(c);
63     f(std::move(c));
64 
65     HPX_TEST(counter::default_constructions == 1);
66     HPX_TEST(counter::copy_constructions <= 1);
67     HPX_TEST(counter::move_constructions <= 3);
68 
69     counter::print();
70 }
71 
f_lvalue_ref(counter &)72 void f_lvalue_ref(counter&){}
73 
test_by_lvalue_ref()74 void test_by_lvalue_ref()
75 {
76     hpx::util::function_nonser<void(counter&)> f = f_lvalue_ref;
77 
78     counter::reset();
79 
80     counter c;
81     f(c);
82     //f(std::move(c)); // cannot bind rvalue to lvalue-ref (except MSVC)
83 
84     HPX_TEST(counter::default_constructions == 1);
85     HPX_TEST(counter::copy_constructions == 0);
86     HPX_TEST(counter::move_constructions == 0);
87 
88     counter::print();
89 }
90 
f_const_lvalue_ref(counter const &)91 void f_const_lvalue_ref(counter const&){}
92 
test_by_const_lvalue_ref()93 void test_by_const_lvalue_ref()
94 {
95     hpx::util::function_nonser<void(counter const&)> f = f_const_lvalue_ref;
96 
97     counter::reset();
98 
99     counter c;
100     f(c);
101     f(std::move(c));
102 
103     HPX_TEST(counter::default_constructions == 1);
104     HPX_TEST(counter::copy_constructions == 0);
105     HPX_TEST(counter::move_constructions == 0);
106 
107     counter::print();
108 }
109 
f_rvalue_ref(counter &&)110 void f_rvalue_ref(counter &&){}
111 
test_by_rvalue_ref()112 void test_by_rvalue_ref()
113 {
114     hpx::util::function_nonser<void(counter &&)> f = f_rvalue_ref;
115 
116     counter::reset();
117 
118     counter c;
119     //f(c); // cannot bind lvalue to rvalue-ref
120     f(std::move(c));
121 
122     HPX_TEST(counter::default_constructions == 1);
123     HPX_TEST(counter::copy_constructions == 0);
124     HPX_TEST(counter::move_constructions == 0);
125 
126     counter::print();
127 }
128 
main(int,char * [])129 int main(int, char* [])
130 {
131     test_by_value();
132     test_by_lvalue_ref();
133     test_by_const_lvalue_ref();
134     test_by_rvalue_ref();
135 
136     return hpx::util::report_errors();
137 }
138