Ticket #7718: rvalue_test.cpp

File rvalue_test.cpp, 6.5 KB (added by Antony Polukhin, 10 years ago)

Updated tests (now tests variant usage with move-only containers)

Line 
1//-----------------------------------------------------------------------------
2// boost-libs variant/test/rvalue_test.cpp source file
3// See http://www.boost.org for updates, documentation, and revision history.
4//-----------------------------------------------------------------------------
5//
6// Copyright (c) 2012
7// Antony Polukhin
8//
9// Distributed under the Boost Software License, Version 1.0. (See
10// accompanying file LICENSE_1_0.txt or copy at
11// http://www.boost.org/LICENSE_1_0.txt)
12
13#include "boost/config.hpp"
14
15#include "boost/test/minimal.hpp"
16#include "boost/variant.hpp"
17
18// This test requires rvalue references support
19
20#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
21
22void run()
23{
24 BOOST_CHECK(true);
25}
26
27void run1()
28{
29 BOOST_CHECK(true);
30}
31
32void run_move_only()
33{
34 BOOST_CHECK(true);
35}
36
37#else
38
39class move_copy_conting_class {
40public:
41 static unsigned int moves_count;
42 static unsigned int copy_count;
43
44 move_copy_conting_class(){}
45 move_copy_conting_class(move_copy_conting_class&&) {
46 ++ moves_count;
47 }
48
49 move_copy_conting_class& operator=(move_copy_conting_class&&) {
50 ++ moves_count;
51 return *this;
52 }
53
54 move_copy_conting_class(const move_copy_conting_class&) {
55 ++ copy_count;
56 }
57 move_copy_conting_class& operator=(const move_copy_conting_class&) {
58 ++ copy_count;
59 return *this;
60 }
61};
62
63unsigned int move_copy_conting_class::moves_count = 0;
64unsigned int move_copy_conting_class::copy_count = 0;
65
66void run()
67{
68 typedef boost::variant<int, move_copy_conting_class> variant_I_type;
69 variant_I_type v1, v2;
70
71 // Assuring that `move_copy_conting_class` was not created
72 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
73 BOOST_CHECK(move_copy_conting_class::moves_count == 0);
74
75 v1 = move_copy_conting_class();
76 // Assuring that `move_copy_conting_class` was moved at least once
77 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
78
79 unsigned int total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
80 move_copy_conting_class var;
81 v1 = 0;
82 move_copy_conting_class::moves_count = 0;
83 move_copy_conting_class::copy_count = 0;
84 v1 = var;
85 // Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
86 BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
87
88 move_copy_conting_class::moves_count = 0;
89 move_copy_conting_class::copy_count = 0;
90 v2 = static_cast<variant_I_type&&>(v1);
91 // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
92 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
93 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
94
95 v1 = move_copy_conting_class();
96 move_copy_conting_class::moves_count = 0;
97 move_copy_conting_class::copy_count = 0;
98 v2 = static_cast<variant_I_type&&>(v1);
99 // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
100 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
101 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
102 total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
103 move_copy_conting_class::moves_count = 0;
104 move_copy_conting_class::copy_count = 0;
105 v1 = v2;
106 // Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
107 BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
108
109
110 typedef boost::variant<move_copy_conting_class, int> variant_II_type;
111 variant_II_type v3;
112 move_copy_conting_class::moves_count = 0;
113 move_copy_conting_class::copy_count = 0;
114 v1 = static_cast<variant_II_type&&>(v3);
115 // Assuring that `move_copy_conting_class` in v3 was moved at least once (v1 and v3 have different types)
116 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
117
118 move_copy_conting_class::moves_count = 0;
119 move_copy_conting_class::copy_count = 0;
120 v2 = static_cast<variant_I_type&&>(v1);
121 // Assuring that `move_copy_conting_class` in v1 was moved at least once (v1 and v3 have different types)
122 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
123
124 move_copy_conting_class::moves_count = 0;
125 move_copy_conting_class::copy_count = 0;
126 variant_I_type v5(static_cast<variant_I_type&&>(v1));
127 // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
128 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
129 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
130
131 total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
132 move_copy_conting_class::moves_count = 0;
133 move_copy_conting_class::copy_count = 0;
134 variant_I_type v6(v1);
135 // Assuring that move constructor moves/copyes value not more times than copy constructor
136 BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
137}
138
139void run1()
140{
141 move_copy_conting_class::moves_count = 0;
142 move_copy_conting_class::copy_count = 0;
143
144 move_copy_conting_class c1;
145 typedef boost::variant<int, move_copy_conting_class> variant_I_type;
146 variant_I_type v1(static_cast<move_copy_conting_class&&>(c1));
147
148 // Assuring that `move_copy_conting_class` was not copyied
149 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
150 BOOST_CHECK(move_copy_conting_class::moves_count > 0);
151}
152
153struct move_only_structure {
154 move_only_structure(){}
155 move_only_structure(move_only_structure&&){}
156 move_only_structure& operator=(move_only_structure&&) { return *this; }
157
158private:
159 move_only_structure(const move_only_structure&);
160 move_only_structure& operator=(const move_only_structure&);
161};
162
163void run_move_only()
164{
165 move_only_structure mo;
166 boost::variant<int, move_only_structure > vi, vi2(static_cast<move_only_structure&&>(mo));
167 BOOST_CHECK(vi.which() == 0);
168 BOOST_CHECK(vi2.which() == 1);
169
170 vi = 10;
171 vi2 = 10;
172 BOOST_CHECK(vi.which() == 0);
173 BOOST_CHECK(vi2.which() == 0);
174
175 vi = static_cast<move_only_structure&&>(mo);
176 vi2 = static_cast<move_only_structure&&>(mo);
177 BOOST_CHECK(vi.which() == 1);
178}
179
180#endif
181
182
183int test_main(int , char* [])
184{
185 run();
186 run1();
187 run_move_only();
188 return 0;
189}