]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/unordered/test/unordered/noexcept_tests.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / unordered / test / unordered / noexcept_tests.cpp
1
2 // Copyright 2013 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 // clang-format off
7 #include "../helpers/prefix.hpp"
8 #include <boost/unordered_set.hpp>
9 #include <boost/unordered_map.hpp>
10 #include "../helpers/postfix.hpp"
11 // clang-format on
12
13 #include "../helpers/test.hpp"
14
15 namespace noexcept_tests {
16 // Test the noexcept is set correctly for the move constructor.
17
18 struct hash_possible_exception : boost::hash<int>
19 {
20 hash_possible_exception(hash_possible_exception const&) {}
21 };
22
23 struct equal_to_possible_exception : std::equal_to<int>
24 {
25 equal_to_possible_exception(equal_to_possible_exception const&) {}
26 };
27
28 // Test that the move constructor does actually move without throwing
29 // an exception when it claims to.
30
31 struct test_exception
32 {
33 };
34
35 bool throwing_test_exception = false;
36 void test_throw(char const* name)
37 {
38 if (throwing_test_exception) {
39 BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Throw exception in: " << name
40 << std::endl;
41 throw test_exception();
42 }
43 }
44
45 class hash_nothrow_move : boost::hash<int>
46 {
47 BOOST_COPYABLE_AND_MOVABLE(hash_nothrow_move)
48
49 typedef boost::hash<int> base;
50
51 public:
52 hash_nothrow_move(BOOST_RV_REF(hash_nothrow_move)) BOOST_NOEXCEPT {}
53
54 hash_nothrow_move() { test_throw("Constructor"); }
55 hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); }
56 hash_nothrow_move& operator=(BOOST_COPY_ASSIGN_REF(hash_nothrow_move))
57 {
58 test_throw("Assign");
59 return *this;
60 }
61 hash_nothrow_move& operator=(BOOST_RV_REF(hash_nothrow_move))
62 {
63 test_throw("Move Assign");
64 return *this;
65 }
66 std::size_t operator()(int x) const
67 {
68 test_throw("Operator");
69 return static_cast<base const&>(*this)(x);
70 }
71 };
72
73 class equal_to_nothrow_move : std::equal_to<int>
74 {
75 BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow_move)
76
77 typedef std::equal_to<int> base;
78
79 public:
80 equal_to_nothrow_move(BOOST_RV_REF(equal_to_nothrow_move)) BOOST_NOEXCEPT {}
81 equal_to_nothrow_move() { test_throw("Constructor"); }
82 equal_to_nothrow_move(equal_to_nothrow_move const&) { test_throw("Copy"); }
83 equal_to_nothrow_move& operator=(
84 BOOST_COPY_ASSIGN_REF(equal_to_nothrow_move))
85 {
86 test_throw("Assign");
87 return *this;
88 }
89 equal_to_nothrow_move& operator=(BOOST_RV_REF(equal_to_nothrow_move))
90 {
91 test_throw("Move Assign");
92 return *this;
93 }
94 std::size_t operator()(int x, int y) const
95 {
96 test_throw("Operator");
97 return static_cast<base const&>(*this)(x, y);
98 }
99 };
100
101 bool have_is_nothrow_move = false;
102
103 UNORDERED_AUTO_TEST (check_is_nothrow_move) {
104 BOOST_TEST(
105 !boost::is_nothrow_move_constructible<hash_possible_exception>::value);
106 have_is_nothrow_move =
107 boost::is_nothrow_move_constructible<hash_nothrow_move>::value;
108
109 // Copied from boost::is_nothrow_move_constructible implementation
110 // to make sure this does actually detect it when expected.
111 //
112 // The type trait is also available when BOOST_IS_NOTHROW_MOVE_CONSTRUCT
113 // is defined (for some versions of Visual C++?) but detects 'throw()',
114 // not noexcept.
115 #if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && \
116 !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)
117 BOOST_TEST(have_is_nothrow_move);
118 #endif
119 }
120
121 UNORDERED_AUTO_TEST (test_noexcept) {
122 if (have_is_nothrow_move) {
123 BOOST_TEST((boost::is_nothrow_move_constructible<
124 boost::unordered_set<int> >::value));
125 BOOST_TEST((boost::is_nothrow_move_constructible<
126 boost::unordered_multiset<int> >::value));
127 BOOST_TEST((boost::is_nothrow_move_constructible<
128 boost::unordered_map<int, int> >::value));
129 BOOST_TEST((boost::is_nothrow_move_constructible<
130 boost::unordered_multimap<int, int> >::value));
131 }
132
133 BOOST_TEST((!boost::is_nothrow_move_constructible<
134 boost::unordered_set<int, hash_possible_exception> >::value));
135 BOOST_TEST(
136 (!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
137 boost::hash<int>, equal_to_possible_exception> >::value));
138 }
139
140 UNORDERED_AUTO_TEST (test_no_throw_when_noexcept) {
141 typedef boost::unordered_set<int, hash_nothrow_move, equal_to_nothrow_move>
142 throwing_set;
143
144 if (have_is_nothrow_move) {
145 BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
146
147 throwing_test_exception = false;
148
149 throwing_set x1;
150 x1.insert(10);
151 x1.insert(50);
152
153 try {
154 throwing_test_exception = true;
155
156 throwing_set x2 = boost::move(x1);
157 BOOST_TEST(x2.size() == 2);
158 BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
159 } catch (test_exception) {
160 BOOST_TEST(false);
161 }
162
163 throwing_test_exception = false;
164 }
165 }
166 }
167
168 RUN_TESTS()