"Fossies" - the Fresh Open Source Software Archive 
Member "abseil-cpp-20230802.1/absl/types/any_exception_safety_test.cc" (18 Sep 2023, 6070 Bytes) of package /linux/misc/abseil-cpp-20230802.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "any_exception_safety_test.cc" see the
Fossies "Dox" file reference documentation.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/types/any.h"
16
17 #include "absl/base/config.h"
18
19 // This test is a no-op when absl::any is an alias for std::any and when
20 // exceptions are not enabled.
21 #if !defined(ABSL_USES_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS)
22
23 #include <typeinfo>
24 #include <vector>
25
26 #include "gtest/gtest.h"
27 #include "absl/base/internal/exception_safety_testing.h"
28
29 using Thrower = testing::ThrowingValue<>;
30 using NoThrowMoveThrower =
31 testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
32 using ThrowerList = std::initializer_list<Thrower>;
33 using ThrowerVec = std::vector<Thrower>;
34 using ThrowingAlloc = testing::ThrowingAllocator<Thrower>;
35 using ThrowingThrowerVec = std::vector<Thrower, ThrowingAlloc>;
36
37 namespace {
38
39 testing::AssertionResult AnyInvariants(absl::any* a) {
40 using testing::AssertionFailure;
41 using testing::AssertionSuccess;
42
43 if (a->has_value()) {
44 if (a->type() == typeid(void)) {
45 return AssertionFailure()
46 << "A non-empty any should not have type `void`";
47 }
48 } else {
49 if (a->type() != typeid(void)) {
50 return AssertionFailure()
51 << "An empty any should have type void, but has type "
52 << a->type().name();
53 }
54 }
55
56 // Make sure that reset() changes any to a valid state.
57 a->reset();
58 if (a->has_value()) {
59 return AssertionFailure() << "A reset `any` should be valueless";
60 }
61 if (a->type() != typeid(void)) {
62 return AssertionFailure() << "A reset `any` should have type() of `void`, "
63 "but instead has type "
64 << a->type().name();
65 }
66 try {
67 auto unused = absl::any_cast<Thrower>(*a);
68 static_cast<void>(unused);
69 return AssertionFailure()
70 << "A reset `any` should not be able to be any_cast";
71 } catch (const absl::bad_any_cast&) {
72 } catch (...) {
73 return AssertionFailure()
74 << "Unexpected exception thrown from absl::any_cast";
75 }
76 return AssertionSuccess();
77 }
78
79 testing::AssertionResult AnyIsEmpty(absl::any* a) {
80 if (!a->has_value()) {
81 return testing::AssertionSuccess();
82 }
83 return testing::AssertionFailure()
84 << "a should be empty, but instead has value "
85 << absl::any_cast<Thrower>(*a).Get();
86 }
87
88 TEST(AnyExceptionSafety, Ctors) {
89 Thrower val(1);
90 testing::TestThrowingCtor<absl::any>(val);
91
92 Thrower copy(val);
93 testing::TestThrowingCtor<absl::any>(copy);
94
95 testing::TestThrowingCtor<absl::any>(absl::in_place_type_t<Thrower>(), 1);
96
97 testing::TestThrowingCtor<absl::any>(absl::in_place_type_t<ThrowerVec>(),
98 ThrowerList{val});
99
100 testing::TestThrowingCtor<absl::any,
101 absl::in_place_type_t<ThrowingThrowerVec>,
102 ThrowerList, ThrowingAlloc>(
103 absl::in_place_type_t<ThrowingThrowerVec>(), {val}, ThrowingAlloc());
104 }
105
106 TEST(AnyExceptionSafety, Assignment) {
107 auto original =
108 absl::any(absl::in_place_type_t<Thrower>(), 1, testing::nothrow_ctor);
109 auto any_is_strong = [original](absl::any* ap) {
110 return testing::AssertionResult(ap->has_value() &&
111 absl::any_cast<Thrower>(original) ==
112 absl::any_cast<Thrower>(*ap));
113 };
114 auto any_strong_tester = testing::MakeExceptionSafetyTester()
115 .WithInitialValue(original)
116 .WithContracts(AnyInvariants, any_is_strong);
117
118 Thrower val(2);
119 absl::any any_val(val);
120 NoThrowMoveThrower mv_val(2);
121
122 auto assign_any = [&any_val](absl::any* ap) { *ap = any_val; };
123 auto assign_val = [&val](absl::any* ap) { *ap = val; };
124 auto move = [&val](absl::any* ap) { *ap = std::move(val); };
125 auto move_movable = [&mv_val](absl::any* ap) { *ap = std::move(mv_val); };
126
127 EXPECT_TRUE(any_strong_tester.Test(assign_any));
128 EXPECT_TRUE(any_strong_tester.Test(assign_val));
129 EXPECT_TRUE(any_strong_tester.Test(move));
130 EXPECT_TRUE(any_strong_tester.Test(move_movable));
131
132 auto empty_any_is_strong = [](absl::any* ap) {
133 return testing::AssertionResult{!ap->has_value()};
134 };
135 auto strong_empty_any_tester =
136 testing::MakeExceptionSafetyTester()
137 .WithInitialValue(absl::any{})
138 .WithContracts(AnyInvariants, empty_any_is_strong);
139
140 EXPECT_TRUE(strong_empty_any_tester.Test(assign_any));
141 EXPECT_TRUE(strong_empty_any_tester.Test(assign_val));
142 EXPECT_TRUE(strong_empty_any_tester.Test(move));
143 }
144
145 TEST(AnyExceptionSafety, Emplace) {
146 auto initial_val =
147 absl::any{absl::in_place_type_t<Thrower>(), 1, testing::nothrow_ctor};
148 auto one_tester = testing::MakeExceptionSafetyTester()
149 .WithInitialValue(initial_val)
150 .WithContracts(AnyInvariants, AnyIsEmpty);
151
152 auto emp_thrower = [](absl::any* ap) { ap->emplace<Thrower>(2); };
153 auto emp_throwervec = [](absl::any* ap) {
154 std::initializer_list<Thrower> il{Thrower(2, testing::nothrow_ctor)};
155 ap->emplace<ThrowerVec>(il);
156 };
157 auto emp_movethrower = [](absl::any* ap) {
158 ap->emplace<NoThrowMoveThrower>(2);
159 };
160
161 EXPECT_TRUE(one_tester.Test(emp_thrower));
162 EXPECT_TRUE(one_tester.Test(emp_throwervec));
163 EXPECT_TRUE(one_tester.Test(emp_movethrower));
164
165 auto empty_tester = one_tester.WithInitialValue(absl::any{});
166
167 EXPECT_TRUE(empty_tester.Test(emp_thrower));
168 EXPECT_TRUE(empty_tester.Test(emp_throwervec));
169 }
170
171 } // namespace
172
173 #endif // #if !defined(ABSL_USES_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS)