Ticket #7620: rvalue_test.cpp

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

Boost.Test for rvalue support of variant

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 BOOST_HAS_RVALUE_REFS
19
20#ifndef BOOST_HAS_RVALUE_REFS
21
22void run()
23{
24 BOOST_CHECK(true);
25}
26
27#else
28
29class move_copy_conting_class {
30public:
31 static unsigned int moves_count;
32 static unsigned int copy_count;
33
34 move_copy_conting_class(){}
35 move_copy_conting_class(move_copy_conting_class&&) {
36 ++ moves_count;
37 }
38
39 move_copy_conting_class& operator=(move_copy_conting_class&&) {
40 ++ moves_count;
41 return *this;
42 }
43
44 move_copy_conting_class(const move_copy_conting_class&) {
45 ++ copy_count;
46 }
47 move_copy_conting_class& operator=(const move_copy_conting_class&) {
48 ++ copy_count;
49 return *this;
50 }
51};
52
53unsigned int move_copy_conting_class::moves_count = 0;
54unsigned int move_copy_conting_class::copy_count = 0;
55
56void run()
57{
58 typedef boost::variant<int, move_copy_conting_class> variant_I_type;
59 variant_I_type v1, v2;
60
61 // Assuring that `move_copy_conting_class` was not created
62 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
63 BOOST_CHECK(move_copy_conting_class::moves_count == 0);
64
65 v1 = move_copy_conting_class();
66 // Assuring that `move_copy_conting_class` was moved at least once
67 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
68
69 unsigned int total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
70 move_copy_conting_class var;
71 v1 = 0;
72 move_copy_conting_class::moves_count = 0;
73 move_copy_conting_class::copy_count = 0;
74 v1 = var;
75 // Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
76 BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
77
78 move_copy_conting_class::moves_count = 0;
79 move_copy_conting_class::copy_count = 0;
80 v2 = static_cast<variant_I_type&&>(v1);
81 // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
82 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
83 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
84
85 v1 = move_copy_conting_class();
86 move_copy_conting_class::moves_count = 0;
87 move_copy_conting_class::copy_count = 0;
88 v2 = static_cast<variant_I_type&&>(v1);
89 // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
90 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
91 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
92 total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
93 move_copy_conting_class::moves_count = 0;
94 move_copy_conting_class::copy_count = 0;
95 v1 = v2;
96 // Assuring that move assignment operator moves/copyes value not more times than copy assignment operator
97 BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
98
99
100 typedef boost::variant<move_copy_conting_class, int> variant_II_type;
101 variant_II_type v3;
102 move_copy_conting_class::moves_count = 0;
103 move_copy_conting_class::copy_count = 0;
104 v1 = static_cast<variant_II_type&&>(v3);
105 // Assuring that `move_copy_conting_class` in v3 was moved at least once (v1 and v3 have different types)
106 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
107
108 move_copy_conting_class::moves_count = 0;
109 move_copy_conting_class::copy_count = 0;
110 v2 = static_cast<variant_I_type&&>(v1);
111 // Assuring that `move_copy_conting_class` in v1 was moved at least once (v1 and v3 have different types)
112 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
113
114 move_copy_conting_class::moves_count = 0;
115 move_copy_conting_class::copy_count = 0;
116 variant_I_type v5(static_cast<variant_I_type&&>(v1));
117 // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
118 BOOST_CHECK(move_copy_conting_class::moves_count != 0);
119 BOOST_CHECK(move_copy_conting_class::copy_count == 0);
120
121 total_count = move_copy_conting_class::moves_count + move_copy_conting_class::copy_count;
122 move_copy_conting_class::moves_count = 0;
123 move_copy_conting_class::copy_count = 0;
124 variant_I_type v6(v1);
125 // Assuring that move constructor moves/copyes value not more times than copy constructor
126 BOOST_CHECK(total_count <= move_copy_conting_class::moves_count + move_copy_conting_class::copy_count);
127}
128
129
130#endif
131
132
133int test_main(int , char* [])
134{
135 run();
136 return 0;
137}