1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker *
4*8f0ba417SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker *
8*8f0ba417SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker *
10*8f0ba417SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker */
16*8f0ba417SAndroid Build Coastguard Worker
17*8f0ba417SAndroid Build Coastguard Worker #include "android-base/expected.h"
18*8f0ba417SAndroid Build Coastguard Worker
19*8f0ba417SAndroid Build Coastguard Worker #include <cstdio>
20*8f0ba417SAndroid Build Coastguard Worker #include <memory>
21*8f0ba417SAndroid Build Coastguard Worker #include <string>
22*8f0ba417SAndroid Build Coastguard Worker
23*8f0ba417SAndroid Build Coastguard Worker #include <gtest/gtest.h>
24*8f0ba417SAndroid Build Coastguard Worker
25*8f0ba417SAndroid Build Coastguard Worker using android::base::expected;
26*8f0ba417SAndroid Build Coastguard Worker using android::base::unexpected;
27*8f0ba417SAndroid Build Coastguard Worker
28*8f0ba417SAndroid Build Coastguard Worker typedef expected<int, int> exp_int;
29*8f0ba417SAndroid Build Coastguard Worker typedef expected<double, double> exp_double;
30*8f0ba417SAndroid Build Coastguard Worker typedef expected<std::string, std::string> exp_string;
31*8f0ba417SAndroid Build Coastguard Worker typedef expected<std::pair<std::string, int>, int> exp_pair;
32*8f0ba417SAndroid Build Coastguard Worker typedef expected<void, int> exp_void;
33*8f0ba417SAndroid Build Coastguard Worker
34*8f0ba417SAndroid Build Coastguard Worker struct T {
35*8f0ba417SAndroid Build Coastguard Worker int a;
36*8f0ba417SAndroid Build Coastguard Worker int b;
37*8f0ba417SAndroid Build Coastguard Worker T() = default;
TT38*8f0ba417SAndroid Build Coastguard Worker T(int a, int b) noexcept : a(a), b(b) {}
39*8f0ba417SAndroid Build Coastguard Worker };
operator ==(const T & x,const T & y)40*8f0ba417SAndroid Build Coastguard Worker bool operator==(const T& x, const T& y) {
41*8f0ba417SAndroid Build Coastguard Worker return x.a == y.a && x.b == y.b;
42*8f0ba417SAndroid Build Coastguard Worker }
operator !=(const T & x,const T & y)43*8f0ba417SAndroid Build Coastguard Worker bool operator!=(const T& x, const T& y) {
44*8f0ba417SAndroid Build Coastguard Worker return x.a != y.a || x.b != y.b;
45*8f0ba417SAndroid Build Coastguard Worker }
46*8f0ba417SAndroid Build Coastguard Worker
47*8f0ba417SAndroid Build Coastguard Worker struct E {
48*8f0ba417SAndroid Build Coastguard Worker std::string message;
49*8f0ba417SAndroid Build Coastguard Worker int cause;
EE50*8f0ba417SAndroid Build Coastguard Worker E(const std::string& message, int cause) : message(message), cause(cause) {}
51*8f0ba417SAndroid Build Coastguard Worker };
52*8f0ba417SAndroid Build Coastguard Worker
53*8f0ba417SAndroid Build Coastguard Worker typedef expected<T,E> exp_complex;
54*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testDefaultConstructible)55*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testDefaultConstructible) {
56*8f0ba417SAndroid Build Coastguard Worker exp_int e;
57*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
58*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0, e.value());
59*8f0ba417SAndroid Build Coastguard Worker
60*8f0ba417SAndroid Build Coastguard Worker exp_complex e2;
61*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
62*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(0,0), e2.value());
63*8f0ba417SAndroid Build Coastguard Worker
64*8f0ba417SAndroid Build Coastguard Worker exp_void e3;
65*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
66*8f0ba417SAndroid Build Coastguard Worker }
67*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testCopyConstructible)68*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCopyConstructible) {
69*8f0ba417SAndroid Build Coastguard Worker exp_int e;
70*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = e;
71*8f0ba417SAndroid Build Coastguard Worker
72*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
73*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
74*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0, e.value());
75*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0, e2.value());
76*8f0ba417SAndroid Build Coastguard Worker
77*8f0ba417SAndroid Build Coastguard Worker exp_void e3;
78*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = e3;
79*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
80*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
81*8f0ba417SAndroid Build Coastguard Worker }
82*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testMoveConstructible)83*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testMoveConstructible) {
84*8f0ba417SAndroid Build Coastguard Worker exp_int e;
85*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = std::move(e);
86*8f0ba417SAndroid Build Coastguard Worker
87*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
88*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
89*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0, e.value());
90*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0, e2.value());
91*8f0ba417SAndroid Build Coastguard Worker
92*8f0ba417SAndroid Build Coastguard Worker exp_string e3(std::string("hello"));
93*8f0ba417SAndroid Build Coastguard Worker exp_string e4 = std::move(e3);
94*8f0ba417SAndroid Build Coastguard Worker
95*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
96*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
97*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("", e3.value()); // e3 is moved
98*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("hello", e4.value());
99*8f0ba417SAndroid Build Coastguard Worker
100*8f0ba417SAndroid Build Coastguard Worker exp_void e5;
101*8f0ba417SAndroid Build Coastguard Worker exp_void e6 = std::move(e5);
102*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e5.has_value());
103*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e6.has_value());
104*8f0ba417SAndroid Build Coastguard Worker }
105*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testCopyConstructibleFromConvertibleType)106*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCopyConstructibleFromConvertibleType) {
107*8f0ba417SAndroid Build Coastguard Worker exp_double e = 3.3;
108*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = e;
109*8f0ba417SAndroid Build Coastguard Worker
110*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
111*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
112*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3.3, e.value());
113*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, e2.value());
114*8f0ba417SAndroid Build Coastguard Worker }
115*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testMoveConstructibleFromConvertibleType)116*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testMoveConstructibleFromConvertibleType) {
117*8f0ba417SAndroid Build Coastguard Worker exp_double e = 3.3;
118*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = std::move(e);
119*8f0ba417SAndroid Build Coastguard Worker
120*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
121*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
122*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3.3, e.value());
123*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, e2.value());
124*8f0ba417SAndroid Build Coastguard Worker }
125*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConstructibleFromValue)126*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConstructibleFromValue) {
127*8f0ba417SAndroid Build Coastguard Worker exp_int e = 3;
128*8f0ba417SAndroid Build Coastguard Worker exp_double e2 = 5.5;
129*8f0ba417SAndroid Build Coastguard Worker exp_string e3 = std::string("hello");
130*8f0ba417SAndroid Build Coastguard Worker exp_complex e4 = T(10, 20);
131*8f0ba417SAndroid Build Coastguard Worker exp_void e5 = {};
132*8f0ba417SAndroid Build Coastguard Worker
133*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
134*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
135*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
136*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
137*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e5.has_value());
138*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, e.value());
139*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(5.5, e2.value());
140*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("hello", e3.value());
141*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(10,20), e4.value());
142*8f0ba417SAndroid Build Coastguard Worker }
143*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConstructibleFromMovedValue)144*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConstructibleFromMovedValue) {
145*8f0ba417SAndroid Build Coastguard Worker std::string hello = "hello";
146*8f0ba417SAndroid Build Coastguard Worker exp_string e = std::move(hello);
147*8f0ba417SAndroid Build Coastguard Worker
148*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
149*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("hello", e.value());
150*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("", hello);
151*8f0ba417SAndroid Build Coastguard Worker }
152*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConstructibleFromConvertibleValue)153*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConstructibleFromConvertibleValue) {
154*8f0ba417SAndroid Build Coastguard Worker exp_int e = 3.3; // double to int
155*8f0ba417SAndroid Build Coastguard Worker exp_string e2 = "hello"; // char* to std::string
156*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
157*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, e.value());
158*8f0ba417SAndroid Build Coastguard Worker
159*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
160*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("hello", e2.value());
161*8f0ba417SAndroid Build Coastguard Worker }
162*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConstructibleFromUnexpected)163*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConstructibleFromUnexpected) {
164*8f0ba417SAndroid Build Coastguard Worker exp_int::unexpected_type unexp = unexpected(10);
165*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexp;
166*8f0ba417SAndroid Build Coastguard Worker
167*8f0ba417SAndroid Build Coastguard Worker exp_double::unexpected_type unexp2 = unexpected(10.5);
168*8f0ba417SAndroid Build Coastguard Worker exp_double e2 = unexp2;
169*8f0ba417SAndroid Build Coastguard Worker
170*8f0ba417SAndroid Build Coastguard Worker exp_string::unexpected_type unexp3 = unexpected(std::string("error"));
171*8f0ba417SAndroid Build Coastguard Worker exp_string e3 = unexp3;
172*8f0ba417SAndroid Build Coastguard Worker
173*8f0ba417SAndroid Build Coastguard Worker exp_void::unexpected_type unexp4 = unexpected(10);
174*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexp4;
175*8f0ba417SAndroid Build Coastguard Worker
176*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
177*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
178*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.has_value());
179*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4.has_value());
180*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e.error());
181*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, e2.error());
182*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("error", e3.error());
183*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e4.error());
184*8f0ba417SAndroid Build Coastguard Worker }
185*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testMoveConstructibleFromUnexpected)186*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testMoveConstructibleFromUnexpected) {
187*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexpected(10);
188*8f0ba417SAndroid Build Coastguard Worker exp_double e2 = unexpected(10.5);
189*8f0ba417SAndroid Build Coastguard Worker exp_string e3 = unexpected(std::string("error"));
190*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(10);
191*8f0ba417SAndroid Build Coastguard Worker
192*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
193*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
194*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.has_value());
195*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4.has_value());
196*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e.error());
197*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, e2.error());
198*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("error", e3.error());
199*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e4.error());
200*8f0ba417SAndroid Build Coastguard Worker }
201*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConstructibleByForwarding)202*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConstructibleByForwarding) {
203*8f0ba417SAndroid Build Coastguard Worker exp_string e(std::in_place, 5, 'a');
204*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
205*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("aaaaa", e.value());
206*8f0ba417SAndroid Build Coastguard Worker
207*8f0ba417SAndroid Build Coastguard Worker exp_string e2({'a', 'b', 'c'});
208*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
209*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", e2.value());
210*8f0ba417SAndroid Build Coastguard Worker
211*8f0ba417SAndroid Build Coastguard Worker exp_pair e3({"hello", 30});
212*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
213*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("hello",e3->first);
214*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(30,e3->second);
215*8f0ba417SAndroid Build Coastguard Worker
216*8f0ba417SAndroid Build Coastguard Worker exp_void e4({});
217*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
218*8f0ba417SAndroid Build Coastguard Worker }
219*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testDestructible)220*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testDestructible) {
221*8f0ba417SAndroid Build Coastguard Worker bool destroyed = false;
222*8f0ba417SAndroid Build Coastguard Worker struct T {
223*8f0ba417SAndroid Build Coastguard Worker bool* flag_;
224*8f0ba417SAndroid Build Coastguard Worker T(bool* flag) : flag_(flag) {}
225*8f0ba417SAndroid Build Coastguard Worker ~T() { *flag_ = true; }
226*8f0ba417SAndroid Build Coastguard Worker };
227*8f0ba417SAndroid Build Coastguard Worker {
228*8f0ba417SAndroid Build Coastguard Worker expected<T, int> exp = T(&destroyed);
229*8f0ba417SAndroid Build Coastguard Worker }
230*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(destroyed);
231*8f0ba417SAndroid Build Coastguard Worker }
232*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testAssignable)233*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testAssignable) {
234*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
235*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = 20;
236*8f0ba417SAndroid Build Coastguard Worker e = e2;
237*8f0ba417SAndroid Build Coastguard Worker
238*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e.value());
239*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e2.value());
240*8f0ba417SAndroid Build Coastguard Worker
241*8f0ba417SAndroid Build Coastguard Worker exp_int e3 = 10;
242*8f0ba417SAndroid Build Coastguard Worker exp_int e4 = 20;
243*8f0ba417SAndroid Build Coastguard Worker e3 = std::move(e4);
244*8f0ba417SAndroid Build Coastguard Worker
245*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e3.value());
246*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e4.value());
247*8f0ba417SAndroid Build Coastguard Worker
248*8f0ba417SAndroid Build Coastguard Worker exp_void e5 = unexpected(10);
249*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(e5.has_value());
250*8f0ba417SAndroid Build Coastguard Worker exp_void e6;
251*8f0ba417SAndroid Build Coastguard Worker e5 = e6;
252*8f0ba417SAndroid Build Coastguard Worker
253*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e5.has_value());
254*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e6.has_value());
255*8f0ba417SAndroid Build Coastguard Worker }
256*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testAssignableFromValue)257*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testAssignableFromValue) {
258*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
259*8f0ba417SAndroid Build Coastguard Worker e = 20;
260*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e.value());
261*8f0ba417SAndroid Build Coastguard Worker
262*8f0ba417SAndroid Build Coastguard Worker exp_double e2 = 3.5;
263*8f0ba417SAndroid Build Coastguard Worker e2 = 10.5;
264*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, e2.value());
265*8f0ba417SAndroid Build Coastguard Worker
266*8f0ba417SAndroid Build Coastguard Worker exp_string e3 = "hello";
267*8f0ba417SAndroid Build Coastguard Worker e3 = "world";
268*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("world", e3.value());
269*8f0ba417SAndroid Build Coastguard Worker
270*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(10);
271*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(e4.has_value());
272*8f0ba417SAndroid Build Coastguard Worker e4 = {};
273*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
274*8f0ba417SAndroid Build Coastguard Worker }
275*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testAssignableFromUnexpected)276*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testAssignableFromUnexpected) {
277*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
278*8f0ba417SAndroid Build Coastguard Worker e = unexpected(30);
279*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
280*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(30, e.error());
281*8f0ba417SAndroid Build Coastguard Worker
282*8f0ba417SAndroid Build Coastguard Worker exp_double e2 = 3.5;
283*8f0ba417SAndroid Build Coastguard Worker e2 = unexpected(10.5);
284*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
285*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, e2.error());
286*8f0ba417SAndroid Build Coastguard Worker
287*8f0ba417SAndroid Build Coastguard Worker exp_string e3 = "hello";
288*8f0ba417SAndroid Build Coastguard Worker e3 = unexpected("world");
289*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.has_value());
290*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("world", e3.error());
291*8f0ba417SAndroid Build Coastguard Worker
292*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = {};
293*8f0ba417SAndroid Build Coastguard Worker e4 = unexpected(10);
294*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4.has_value());
295*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e4.error());
296*8f0ba417SAndroid Build Coastguard Worker }
297*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testAssignableFromMovedValue)298*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testAssignableFromMovedValue) {
299*8f0ba417SAndroid Build Coastguard Worker std::string world = "world";
300*8f0ba417SAndroid Build Coastguard Worker exp_string e = "hello";
301*8f0ba417SAndroid Build Coastguard Worker e = std::move(world);
302*8f0ba417SAndroid Build Coastguard Worker
303*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
304*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("world", e.value());
305*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("", world);
306*8f0ba417SAndroid Build Coastguard Worker }
307*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testAssignableFromMovedUnexpected)308*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testAssignableFromMovedUnexpected) {
309*8f0ba417SAndroid Build Coastguard Worker std::string world = "world";
310*8f0ba417SAndroid Build Coastguard Worker exp_string e = "hello";
311*8f0ba417SAndroid Build Coastguard Worker e = unexpected(std::move(world));
312*8f0ba417SAndroid Build Coastguard Worker
313*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
314*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("world", e.error());
315*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("", world);
316*8f0ba417SAndroid Build Coastguard Worker }
317*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testEmplace)318*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testEmplace) {
319*8f0ba417SAndroid Build Coastguard Worker struct T {
320*8f0ba417SAndroid Build Coastguard Worker int a;
321*8f0ba417SAndroid Build Coastguard Worker double b;
322*8f0ba417SAndroid Build Coastguard Worker T() {}
323*8f0ba417SAndroid Build Coastguard Worker T(int a, double b) noexcept : a(a), b(b) {}
324*8f0ba417SAndroid Build Coastguard Worker };
325*8f0ba417SAndroid Build Coastguard Worker expected<T, int> exp;
326*8f0ba417SAndroid Build Coastguard Worker T& t = exp.emplace(3, 10.5);
327*8f0ba417SAndroid Build Coastguard Worker
328*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(exp.has_value());
329*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, t.a);
330*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, t.b);
331*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, exp.value().a);
332*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, exp.value().b);
333*8f0ba417SAndroid Build Coastguard Worker
334*8f0ba417SAndroid Build Coastguard Worker exp_void e = unexpected(10);
335*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(e.has_value());
336*8f0ba417SAndroid Build Coastguard Worker e.emplace();
337*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
338*8f0ba417SAndroid Build Coastguard Worker }
339*8f0ba417SAndroid Build Coastguard Worker
340*8f0ba417SAndroid Build Coastguard Worker // For the swap tests, call swap using an unqualified identifier, which should
341*8f0ba417SAndroid Build Coastguard Worker // find the namespace-scope android::base::swap() function using
342*8f0ba417SAndroid Build Coastguard Worker // argument-dependent lookup. The usual idiom for swapping an arbitrary C++ type
343*8f0ba417SAndroid Build Coastguard Worker // is `using std::swap; swap(...);`.
TEST(Expected,testSwapExpectedExpected)344*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testSwapExpectedExpected) {
345*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
346*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = 20;
347*8f0ba417SAndroid Build Coastguard Worker swap(e, e2);
348*8f0ba417SAndroid Build Coastguard Worker
349*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
350*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
351*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e.value());
352*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e2.value());
353*8f0ba417SAndroid Build Coastguard Worker
354*8f0ba417SAndroid Build Coastguard Worker exp_void e3;
355*8f0ba417SAndroid Build Coastguard Worker exp_void e4;
356*8f0ba417SAndroid Build Coastguard Worker swap(e3, e4);
357*8f0ba417SAndroid Build Coastguard Worker
358*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
359*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
360*8f0ba417SAndroid Build Coastguard Worker }
361*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testSwapUnexpectedUnexpected)362*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testSwapUnexpectedUnexpected) {
363*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexpected(10);
364*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(20);
365*8f0ba417SAndroid Build Coastguard Worker swap(e, e2);
366*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
367*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
368*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e.error());
369*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e2.error());
370*8f0ba417SAndroid Build Coastguard Worker
371*8f0ba417SAndroid Build Coastguard Worker exp_void e3 = unexpected(10);
372*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(20);
373*8f0ba417SAndroid Build Coastguard Worker swap(e3, e4);
374*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.has_value());
375*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4.has_value());
376*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e3.error());
377*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e4.error());
378*8f0ba417SAndroid Build Coastguard Worker }
379*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testSwapExpectedUnepected)380*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testSwapExpectedUnepected) {
381*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
382*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(30);
383*8f0ba417SAndroid Build Coastguard Worker swap(e, e2);
384*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
385*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
386*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(30, e.error());
387*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e2.value());
388*8f0ba417SAndroid Build Coastguard Worker
389*8f0ba417SAndroid Build Coastguard Worker exp_void e3;
390*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(10);
391*8f0ba417SAndroid Build Coastguard Worker swap(e3, e4);
392*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.has_value());
393*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4.has_value());
394*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e3.error());
395*8f0ba417SAndroid Build Coastguard Worker }
396*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testNonswappable)397*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testNonswappable) {
398*8f0ba417SAndroid Build Coastguard Worker struct NoSwap {
399*8f0ba417SAndroid Build Coastguard Worker NoSwap(int val) : val(val) {}
400*8f0ba417SAndroid Build Coastguard Worker NoSwap(const NoSwap& other) : val(other.val) {}
401*8f0ba417SAndroid Build Coastguard Worker NoSwap(NoSwap&& other) : val(other.val) {}
402*8f0ba417SAndroid Build Coastguard Worker int val;
403*8f0ba417SAndroid Build Coastguard Worker };
404*8f0ba417SAndroid Build Coastguard Worker
405*8f0ba417SAndroid Build Coastguard Worker // NoSwap has no namespace-scope swap function, and because it lacks a
406*8f0ba417SAndroid Build Coastguard Worker // move assignment operator, std::swap is also not defined for it.
407*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_move_assignable_v<NoSwap>);
408*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_swappable_v<NoSwap>);
409*8f0ba417SAndroid Build Coastguard Worker
410*8f0ba417SAndroid Build Coastguard Worker // A non-swappable type may still be used in the expected class.
411*8f0ba417SAndroid Build Coastguard Worker expected<NoSwap, int> e1(NoSwap(3));
412*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, e1.value().val);
413*8f0ba417SAndroid Build Coastguard Worker expected<int, NoSwap> e2(unexpected(NoSwap(5)));
414*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(5, e2.error().val);
415*8f0ba417SAndroid Build Coastguard Worker expected<void, NoSwap> e3(unexpected(NoSwap(7)));
416*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(7, e3.error().val);
417*8f0ba417SAndroid Build Coastguard Worker
418*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_move_assignable_v<decltype(e1)>);
419*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_move_assignable_v<decltype(e2)>);
420*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_move_assignable_v<decltype(e3)>);
421*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_swappable_v<decltype(e1)>);
422*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_swappable_v<decltype(e2)>);
423*8f0ba417SAndroid Build Coastguard Worker static_assert(!std::is_swappable_v<decltype(e3)>);
424*8f0ba417SAndroid Build Coastguard Worker }
425*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testDereference)426*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testDereference) {
427*8f0ba417SAndroid Build Coastguard Worker struct T {
428*8f0ba417SAndroid Build Coastguard Worker int a;
429*8f0ba417SAndroid Build Coastguard Worker double b;
430*8f0ba417SAndroid Build Coastguard Worker T() {}
431*8f0ba417SAndroid Build Coastguard Worker T(int a, double b) : a(a), b(b) {}
432*8f0ba417SAndroid Build Coastguard Worker };
433*8f0ba417SAndroid Build Coastguard Worker expected<T, int> exp = T(3, 10.5);
434*8f0ba417SAndroid Build Coastguard Worker
435*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, exp->a);
436*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, exp->b);
437*8f0ba417SAndroid Build Coastguard Worker
438*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, (*exp).a);
439*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10.5, (*exp).b);
440*8f0ba417SAndroid Build Coastguard Worker }
441*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testTest)442*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testTest) {
443*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
444*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.ok());
445*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
446*8f0ba417SAndroid Build Coastguard Worker
447*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(10);
448*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.ok());
449*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
450*8f0ba417SAndroid Build Coastguard Worker }
451*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testGetValue)452*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testGetValue) {
453*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
454*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e.value());
455*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e.value_or(20));
456*8f0ba417SAndroid Build Coastguard Worker
457*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(10);
458*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, e2.error());
459*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(20, e2.value_or(20));
460*8f0ba417SAndroid Build Coastguard Worker }
461*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testSameValues)462*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testSameValues) {
463*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
464*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = 10;
465*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e == e2);
466*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 == e);
467*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e != e2);
468*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 != e);
469*8f0ba417SAndroid Build Coastguard Worker
470*8f0ba417SAndroid Build Coastguard Worker exp_void e3;
471*8f0ba417SAndroid Build Coastguard Worker exp_void e4;
472*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3 == e4);
473*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4 == e3);
474*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3 != e4);
475*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4 != e3);
476*8f0ba417SAndroid Build Coastguard Worker }
477*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testDifferentValues)478*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testDifferentValues) {
479*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
480*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = 20;
481*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e == e2);
482*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 == e);
483*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e != e2);
484*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 != e);
485*8f0ba417SAndroid Build Coastguard Worker }
486*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testValueWithError)487*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testValueWithError) {
488*8f0ba417SAndroid Build Coastguard Worker exp_int e = 10;
489*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(10);
490*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e == e2);
491*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 == e);
492*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e != e2);
493*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 != e);
494*8f0ba417SAndroid Build Coastguard Worker
495*8f0ba417SAndroid Build Coastguard Worker exp_void e3;
496*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(10);
497*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3 == e4);
498*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4 == e3);
499*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3 != e4);
500*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4 != e3);
501*8f0ba417SAndroid Build Coastguard Worker }
502*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testSameErrors)503*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testSameErrors) {
504*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexpected(10);
505*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(10);
506*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e == e2);
507*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 == e);
508*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e != e2);
509*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 != e);
510*8f0ba417SAndroid Build Coastguard Worker
511*8f0ba417SAndroid Build Coastguard Worker exp_void e3 = unexpected(10);
512*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(10);
513*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3 == e4);
514*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4 == e3);
515*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3 != e4);
516*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4 != e3);
517*8f0ba417SAndroid Build Coastguard Worker }
518*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testDifferentErrors)519*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testDifferentErrors) {
520*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexpected(10);
521*8f0ba417SAndroid Build Coastguard Worker exp_int e2 = unexpected(20);
522*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e == e2);
523*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 == e);
524*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e != e2);
525*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 != e);
526*8f0ba417SAndroid Build Coastguard Worker
527*8f0ba417SAndroid Build Coastguard Worker exp_void e3 = unexpected(10);
528*8f0ba417SAndroid Build Coastguard Worker exp_void e4 = unexpected(20);
529*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3 == e4);
530*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4 == e3);
531*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3 != e4);
532*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e4 != e3);
533*8f0ba417SAndroid Build Coastguard Worker }
534*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testCompareWithSameError)535*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCompareWithSameError) {
536*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexpected(10);
537*8f0ba417SAndroid Build Coastguard Worker exp_int::unexpected_type error{10};
538*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e == error);
539*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(error == e);
540*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e != error);
541*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(error != e);
542*8f0ba417SAndroid Build Coastguard Worker
543*8f0ba417SAndroid Build Coastguard Worker exp_void e2 = unexpected(10);
544*8f0ba417SAndroid Build Coastguard Worker exp_void::unexpected_type error2{10};
545*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 == error2);
546*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(error2 == e2);
547*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 != error2);
548*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(error2 != e2);
549*8f0ba417SAndroid Build Coastguard Worker }
550*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testCompareWithDifferentError)551*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCompareWithDifferentError) {
552*8f0ba417SAndroid Build Coastguard Worker exp_int e = unexpected(10);
553*8f0ba417SAndroid Build Coastguard Worker exp_int::unexpected_type error{20};
554*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e == error);
555*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(error == e);
556*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e != error);
557*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(error != e);
558*8f0ba417SAndroid Build Coastguard Worker
559*8f0ba417SAndroid Build Coastguard Worker exp_void e2 = unexpected(10);
560*8f0ba417SAndroid Build Coastguard Worker exp_void::unexpected_type error2{20};
561*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2 == error2);
562*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(error2 == e2);
563*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2 != error2);
564*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(error2 != e2);
565*8f0ba417SAndroid Build Coastguard Worker }
566*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testCompareDifferentType)567*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCompareDifferentType) {
568*8f0ba417SAndroid Build Coastguard Worker expected<int,int> e = 10;
569*8f0ba417SAndroid Build Coastguard Worker expected<int32_t, int> e2 = 10;
570*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e == e2);
571*8f0ba417SAndroid Build Coastguard Worker e2 = 20;
572*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e == e2);
573*8f0ba417SAndroid Build Coastguard Worker
574*8f0ba417SAndroid Build Coastguard Worker expected<std::string_view,int> e3 = "hello";
575*8f0ba417SAndroid Build Coastguard Worker expected<std::string,int> e4 = "hello";
576*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3 == e4);
577*8f0ba417SAndroid Build Coastguard Worker e4 = "world";
578*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3 == e4);
579*8f0ba417SAndroid Build Coastguard Worker
580*8f0ba417SAndroid Build Coastguard Worker expected<void,int> e5;
581*8f0ba417SAndroid Build Coastguard Worker expected<int,int> e6 = 10;
582*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e5 == e6);
583*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e6 == e5);
584*8f0ba417SAndroid Build Coastguard Worker }
585*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testDivideExample)586*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testDivideExample) {
587*8f0ba417SAndroid Build Coastguard Worker struct QR {
588*8f0ba417SAndroid Build Coastguard Worker int quotient;
589*8f0ba417SAndroid Build Coastguard Worker int remainder;
590*8f0ba417SAndroid Build Coastguard Worker QR(int q, int r) noexcept : quotient(q), remainder(r) {}
591*8f0ba417SAndroid Build Coastguard Worker bool operator==(const QR& rhs) const {
592*8f0ba417SAndroid Build Coastguard Worker return quotient == rhs.quotient && remainder == rhs.remainder;
593*8f0ba417SAndroid Build Coastguard Worker }
594*8f0ba417SAndroid Build Coastguard Worker bool operator!=(const QR& rhs) const {
595*8f0ba417SAndroid Build Coastguard Worker return quotient != rhs.quotient || remainder == rhs.remainder;
596*8f0ba417SAndroid Build Coastguard Worker }
597*8f0ba417SAndroid Build Coastguard Worker };
598*8f0ba417SAndroid Build Coastguard Worker
599*8f0ba417SAndroid Build Coastguard Worker auto divide = [](int x, int y) -> expected<QR,E> {
600*8f0ba417SAndroid Build Coastguard Worker if (y == 0) {
601*8f0ba417SAndroid Build Coastguard Worker return unexpected(E("divide by zero", -1));
602*8f0ba417SAndroid Build Coastguard Worker } else {
603*8f0ba417SAndroid Build Coastguard Worker return QR(x / y, x % y);
604*8f0ba417SAndroid Build Coastguard Worker }
605*8f0ba417SAndroid Build Coastguard Worker };
606*8f0ba417SAndroid Build Coastguard Worker
607*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(divide(10, 0).ok());
608*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("divide by zero", divide(10, 0).error().message);
609*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(-1, divide(10, 0).error().cause);
610*8f0ba417SAndroid Build Coastguard Worker
611*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(divide(10, 3).ok());
612*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(QR(3, 1), *divide(10, 3));
613*8f0ba417SAndroid Build Coastguard Worker }
614*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testPair)615*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testPair) {
616*8f0ba417SAndroid Build Coastguard Worker auto test = [](bool yes) -> exp_pair {
617*8f0ba417SAndroid Build Coastguard Worker if (yes) {
618*8f0ba417SAndroid Build Coastguard Worker return exp_pair({"yes", 42});
619*8f0ba417SAndroid Build Coastguard Worker } else {
620*8f0ba417SAndroid Build Coastguard Worker return unexpected(42);
621*8f0ba417SAndroid Build Coastguard Worker }
622*8f0ba417SAndroid Build Coastguard Worker };
623*8f0ba417SAndroid Build Coastguard Worker
624*8f0ba417SAndroid Build Coastguard Worker auto r = test(true);
625*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(r.ok());
626*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("yes", r->first);
627*8f0ba417SAndroid Build Coastguard Worker }
628*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testVoid)629*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testVoid) {
630*8f0ba417SAndroid Build Coastguard Worker auto test = [](bool ok) -> exp_void {
631*8f0ba417SAndroid Build Coastguard Worker if (ok) {
632*8f0ba417SAndroid Build Coastguard Worker return {};
633*8f0ba417SAndroid Build Coastguard Worker } else {
634*8f0ba417SAndroid Build Coastguard Worker return unexpected(10);
635*8f0ba417SAndroid Build Coastguard Worker }
636*8f0ba417SAndroid Build Coastguard Worker };
637*8f0ba417SAndroid Build Coastguard Worker
638*8f0ba417SAndroid Build Coastguard Worker auto r = test(true);
639*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(r.ok());
640*8f0ba417SAndroid Build Coastguard Worker r = test(false);
641*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(r.ok());
642*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(10, r.error());
643*8f0ba417SAndroid Build Coastguard Worker }
644*8f0ba417SAndroid Build Coastguard Worker
645*8f0ba417SAndroid Build Coastguard Worker // copied from result_test.cpp
646*8f0ba417SAndroid Build Coastguard Worker struct ConstructorTracker {
647*8f0ba417SAndroid Build Coastguard Worker static size_t constructor_called;
648*8f0ba417SAndroid Build Coastguard Worker static size_t copy_constructor_called;
649*8f0ba417SAndroid Build Coastguard Worker static size_t move_constructor_called;
650*8f0ba417SAndroid Build Coastguard Worker static size_t copy_assignment_called;
651*8f0ba417SAndroid Build Coastguard Worker static size_t move_assignment_called;
652*8f0ba417SAndroid Build Coastguard Worker
653*8f0ba417SAndroid Build Coastguard Worker template <typename T,
654*8f0ba417SAndroid Build Coastguard Worker typename std::enable_if_t<std::is_convertible_v<T, std::string>>* = nullptr>
ConstructorTrackerConstructorTracker655*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker(T&& string) : string(string) {
656*8f0ba417SAndroid Build Coastguard Worker ++constructor_called;
657*8f0ba417SAndroid Build Coastguard Worker }
ConstructorTrackerConstructorTracker658*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker(const ConstructorTracker& ct) {
659*8f0ba417SAndroid Build Coastguard Worker ++copy_constructor_called;
660*8f0ba417SAndroid Build Coastguard Worker string = ct.string;
661*8f0ba417SAndroid Build Coastguard Worker }
ConstructorTrackerConstructorTracker662*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker(ConstructorTracker&& ct) noexcept {
663*8f0ba417SAndroid Build Coastguard Worker ++move_constructor_called;
664*8f0ba417SAndroid Build Coastguard Worker string = std::move(ct.string);
665*8f0ba417SAndroid Build Coastguard Worker }
operator =ConstructorTracker666*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker& operator=(const ConstructorTracker& ct) {
667*8f0ba417SAndroid Build Coastguard Worker ++copy_assignment_called;
668*8f0ba417SAndroid Build Coastguard Worker string = ct.string;
669*8f0ba417SAndroid Build Coastguard Worker return *this;
670*8f0ba417SAndroid Build Coastguard Worker }
operator =ConstructorTracker671*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker& operator=(ConstructorTracker&& ct) noexcept {
672*8f0ba417SAndroid Build Coastguard Worker ++move_assignment_called;
673*8f0ba417SAndroid Build Coastguard Worker string = std::move(ct.string);
674*8f0ba417SAndroid Build Coastguard Worker return *this;
675*8f0ba417SAndroid Build Coastguard Worker }
ResetConstructorTracker676*8f0ba417SAndroid Build Coastguard Worker static void Reset() {
677*8f0ba417SAndroid Build Coastguard Worker constructor_called = 0;
678*8f0ba417SAndroid Build Coastguard Worker copy_constructor_called = 0;
679*8f0ba417SAndroid Build Coastguard Worker move_constructor_called = 0;
680*8f0ba417SAndroid Build Coastguard Worker copy_assignment_called = 0;
681*8f0ba417SAndroid Build Coastguard Worker move_assignment_called = 0;
682*8f0ba417SAndroid Build Coastguard Worker }
683*8f0ba417SAndroid Build Coastguard Worker std::string string;
684*8f0ba417SAndroid Build Coastguard Worker };
685*8f0ba417SAndroid Build Coastguard Worker
686*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::constructor_called = 0;
687*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::copy_constructor_called = 0;
688*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::move_constructor_called = 0;
689*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::copy_assignment_called = 0;
690*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::move_assignment_called = 0;
691*8f0ba417SAndroid Build Coastguard Worker
692*8f0ba417SAndroid Build Coastguard Worker typedef expected<ConstructorTracker, int> exp_track;
693*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testNumberOfCopies)694*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testNumberOfCopies) {
695*8f0ba417SAndroid Build Coastguard Worker // ordinary constructor
696*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
697*8f0ba417SAndroid Build Coastguard Worker exp_track e("hello");
698*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
699*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
700*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
701*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
702*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
703*8f0ba417SAndroid Build Coastguard Worker
704*8f0ba417SAndroid Build Coastguard Worker // copy constructor
705*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
706*8f0ba417SAndroid Build Coastguard Worker exp_track e2 = e;
707*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::constructor_called);
708*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
709*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
710*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
711*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
712*8f0ba417SAndroid Build Coastguard Worker
713*8f0ba417SAndroid Build Coastguard Worker // move constructor
714*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
715*8f0ba417SAndroid Build Coastguard Worker exp_track e3 = std::move(e);
716*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::constructor_called);
717*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
718*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
719*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
720*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
721*8f0ba417SAndroid Build Coastguard Worker
722*8f0ba417SAndroid Build Coastguard Worker // construct from lvalue
723*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
724*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker ct = "hello";
725*8f0ba417SAndroid Build Coastguard Worker exp_track e4(ct);
726*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
727*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
728*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
729*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
730*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
731*8f0ba417SAndroid Build Coastguard Worker
732*8f0ba417SAndroid Build Coastguard Worker // construct from rvalue
733*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
734*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker ct2 = "hello";
735*8f0ba417SAndroid Build Coastguard Worker exp_track e5(std::move(ct2));
736*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
737*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
738*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
739*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
740*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
741*8f0ba417SAndroid Build Coastguard Worker
742*8f0ba417SAndroid Build Coastguard Worker // copy assignment
743*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
744*8f0ba417SAndroid Build Coastguard Worker exp_track e6 = "hello";
745*8f0ba417SAndroid Build Coastguard Worker exp_track e7 = "world";
746*8f0ba417SAndroid Build Coastguard Worker e7 = e6;
747*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(2U, ConstructorTracker::constructor_called);
748*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
749*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
750*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::copy_assignment_called);
751*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
752*8f0ba417SAndroid Build Coastguard Worker
753*8f0ba417SAndroid Build Coastguard Worker // move assignment
754*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
755*8f0ba417SAndroid Build Coastguard Worker exp_track e8 = "hello";
756*8f0ba417SAndroid Build Coastguard Worker exp_track e9 = "world";
757*8f0ba417SAndroid Build Coastguard Worker e9 = std::move(e8);
758*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(2U, ConstructorTracker::constructor_called);
759*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
760*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
761*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
762*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_assignment_called);
763*8f0ba417SAndroid Build Coastguard Worker
764*8f0ba417SAndroid Build Coastguard Worker // swap
765*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
766*8f0ba417SAndroid Build Coastguard Worker exp_track e10 = "hello";
767*8f0ba417SAndroid Build Coastguard Worker exp_track e11 = "world";
768*8f0ba417SAndroid Build Coastguard Worker swap(e10, e11);
769*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(2U, ConstructorTracker::constructor_called);
770*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
771*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
772*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
773*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(2U, ConstructorTracker::move_assignment_called);
774*8f0ba417SAndroid Build Coastguard Worker }
775*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testCopiesWithDifferentValueOrErrorTypes)776*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCopiesWithDifferentValueOrErrorTypes) {
777*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
778*8f0ba417SAndroid Build Coastguard Worker // copy success value
779*8f0ba417SAndroid Build Coastguard Worker expected<std::string, int> e1 = "hello";
780*8f0ba417SAndroid Build Coastguard Worker expected<ConstructorTracker, int> e2 = e1;
781*8f0ba417SAndroid Build Coastguard Worker // move success value
782*8f0ba417SAndroid Build Coastguard Worker expected<std::string, int> e3 = "hello";
783*8f0ba417SAndroid Build Coastguard Worker expected<ConstructorTracker, int> e4 = std::move(e3);
784*8f0ba417SAndroid Build Coastguard Worker // copy error value
785*8f0ba417SAndroid Build Coastguard Worker expected<int, std::string> e5 = unexpected("hello");
786*8f0ba417SAndroid Build Coastguard Worker expected<int, ConstructorTracker> e6 = e5;
787*8f0ba417SAndroid Build Coastguard Worker // move error value
788*8f0ba417SAndroid Build Coastguard Worker expected<int, std::string> e7 = unexpected("hello");
789*8f0ba417SAndroid Build Coastguard Worker expected<int, ConstructorTracker> e8 = std::move(e7);
790*8f0ba417SAndroid Build Coastguard Worker
791*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(4U, ConstructorTracker::constructor_called);
792*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
793*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
794*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
795*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
796*8f0ba417SAndroid Build Coastguard Worker }
797*8f0ba417SAndroid Build Coastguard Worker
798*8f0ba417SAndroid Build Coastguard Worker // Constructing an expected type from a different expected type where either the
799*8f0ba417SAndroid Build Coastguard Worker // value or the error type is ConstructorTracker in both expected types.
TEST(Expected,testCopyOrMoveTrackerAcrossExpectedConversion)800*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testCopyOrMoveTrackerAcrossExpectedConversion) {
801*8f0ba417SAndroid Build Coastguard Worker struct IntObj {
802*8f0ba417SAndroid Build Coastguard Worker IntObj(int) {}
803*8f0ba417SAndroid Build Coastguard Worker };
804*8f0ba417SAndroid Build Coastguard Worker
805*8f0ba417SAndroid Build Coastguard Worker // same value type, copy
806*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
807*8f0ba417SAndroid Build Coastguard Worker expected<ConstructorTracker, int> e1 = std::string("hello");
808*8f0ba417SAndroid Build Coastguard Worker expected<ConstructorTracker, IntObj> e2 = e1;
809*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
810*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
811*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
812*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
813*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
814*8f0ba417SAndroid Build Coastguard Worker
815*8f0ba417SAndroid Build Coastguard Worker // same value type, move
816*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
817*8f0ba417SAndroid Build Coastguard Worker expected<ConstructorTracker, int> e3 = std::string("hello");
818*8f0ba417SAndroid Build Coastguard Worker expected<ConstructorTracker, IntObj> e4 = std::move(e3);
819*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
820*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
821*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
822*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
823*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
824*8f0ba417SAndroid Build Coastguard Worker
825*8f0ba417SAndroid Build Coastguard Worker // same error type, copy
826*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
827*8f0ba417SAndroid Build Coastguard Worker expected<int, ConstructorTracker> e5 = unexpected(std::string("hello"));
828*8f0ba417SAndroid Build Coastguard Worker expected<IntObj, ConstructorTracker> e6 = e5;
829*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
830*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
831*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
832*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
833*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
834*8f0ba417SAndroid Build Coastguard Worker
835*8f0ba417SAndroid Build Coastguard Worker // same error type, move
836*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
837*8f0ba417SAndroid Build Coastguard Worker expected<int, ConstructorTracker> e7 = unexpected(std::string("hello"));
838*8f0ba417SAndroid Build Coastguard Worker expected<IntObj, ConstructorTracker> e8 = std::move(e7);
839*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
840*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
841*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
842*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
843*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
844*8f0ba417SAndroid Build Coastguard Worker }
845*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testNoCopyOnReturn)846*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testNoCopyOnReturn) {
847*8f0ba417SAndroid Build Coastguard Worker auto test = [](const std::string& in) -> exp_track {
848*8f0ba417SAndroid Build Coastguard Worker if (in.empty()) {
849*8f0ba417SAndroid Build Coastguard Worker return "literal string";
850*8f0ba417SAndroid Build Coastguard Worker }
851*8f0ba417SAndroid Build Coastguard Worker if (in == "test2") {
852*8f0ba417SAndroid Build Coastguard Worker return ConstructorTracker(in + in + "2");
853*8f0ba417SAndroid Build Coastguard Worker }
854*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker result(in + " " + in);
855*8f0ba417SAndroid Build Coastguard Worker return result;
856*8f0ba417SAndroid Build Coastguard Worker };
857*8f0ba417SAndroid Build Coastguard Worker
858*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
859*8f0ba417SAndroid Build Coastguard Worker auto result1 = test("");
860*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(result1.ok());
861*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("literal string", result1->string);
862*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
863*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
864*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
865*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
866*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
867*8f0ba417SAndroid Build Coastguard Worker
868*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
869*8f0ba417SAndroid Build Coastguard Worker auto result2 = test("test2");
870*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(result2.ok());
871*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("test2test22", result2->string);
872*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
873*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
874*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
875*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
876*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
877*8f0ba417SAndroid Build Coastguard Worker
878*8f0ba417SAndroid Build Coastguard Worker ConstructorTracker::Reset();
879*8f0ba417SAndroid Build Coastguard Worker auto result3 = test("test3");
880*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(result3.ok());
881*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("test3 test3", result3->string);
882*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::constructor_called);
883*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
884*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
885*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
886*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
887*8f0ba417SAndroid Build Coastguard Worker }
888*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testNested)889*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testNested) {
890*8f0ba417SAndroid Build Coastguard Worker expected<exp_string, std::string> e = "hello";
891*8f0ba417SAndroid Build Coastguard Worker
892*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.ok());
893*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
894*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.value().has_value());
895*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e->ok());
896*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("hello", e.value().value());
897*8f0ba417SAndroid Build Coastguard Worker
898*8f0ba417SAndroid Build Coastguard Worker expected<exp_string, std::string> e2 = unexpected("world");
899*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
900*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.ok());
901*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("world", e2.error());
902*8f0ba417SAndroid Build Coastguard Worker
903*8f0ba417SAndroid Build Coastguard Worker expected<exp_string, std::string> e3 = exp_string(unexpected("world"));
904*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.has_value());
905*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.value().has_value());
906*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e3.ok());
907*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3->ok());
908*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("world", e3.value().error());
909*8f0ba417SAndroid Build Coastguard Worker }
910*8f0ba417SAndroid Build Coastguard Worker
equals(const char * a,const char * b)911*8f0ba417SAndroid Build Coastguard Worker constexpr bool equals(const char* a, const char* b) {
912*8f0ba417SAndroid Build Coastguard Worker return (a == nullptr && b == nullptr) ||
913*8f0ba417SAndroid Build Coastguard Worker (a != nullptr && b != nullptr && *a == *b &&
914*8f0ba417SAndroid Build Coastguard Worker (*a == '\0' || equals(a + 1, b + 1)));
915*8f0ba417SAndroid Build Coastguard Worker }
916*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConstexpr)917*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConstexpr) {
918*8f0ba417SAndroid Build Coastguard Worker // Compilation error will occur if these expressions can't be
919*8f0ba417SAndroid Build Coastguard Worker // evaluated at compile time
920*8f0ba417SAndroid Build Coastguard Worker constexpr exp_int e(3);
921*8f0ba417SAndroid Build Coastguard Worker constexpr exp_int::unexpected_type err(3);
922*8f0ba417SAndroid Build Coastguard Worker constexpr int i = 4;
923*8f0ba417SAndroid Build Coastguard Worker
924*8f0ba417SAndroid Build Coastguard Worker // default constructor
925*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int().value() == 0);
926*8f0ba417SAndroid Build Coastguard Worker // copy constructor
927*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(e).value() == 3);
928*8f0ba417SAndroid Build Coastguard Worker // move constructor
929*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(exp_int(4)).value() == 4);
930*8f0ba417SAndroid Build Coastguard Worker // copy construct from value
931*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(i).value() == 4);
932*8f0ba417SAndroid Build Coastguard Worker // copy construct from unexpected
933*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(err).error() == 3);
934*8f0ba417SAndroid Build Coastguard Worker // move construct from unexpected
935*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(unexpected(3)).error() == 3);
936*8f0ba417SAndroid Build Coastguard Worker // observers
937*8f0ba417SAndroid Build Coastguard Worker static_assert(*exp_int(3) == 3);
938*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(3).has_value() == true);
939*8f0ba417SAndroid Build Coastguard Worker static_assert(static_cast<bool>(exp_int(3)));
940*8f0ba417SAndroid Build Coastguard Worker static_assert(!static_cast<bool>(exp_int(err)));
941*8f0ba417SAndroid Build Coastguard Worker static_assert(exp_int(3).value_or(4) == 3);
942*8f0ba417SAndroid Build Coastguard Worker
943*8f0ba417SAndroid Build Coastguard Worker typedef expected<const char*, int> exp_s;
944*8f0ba417SAndroid Build Coastguard Worker constexpr exp_s s("hello");
945*8f0ba417SAndroid Build Coastguard Worker constexpr const char* c = "hello";
946*8f0ba417SAndroid Build Coastguard Worker static_assert(equals(exp_s().value(), nullptr));
947*8f0ba417SAndroid Build Coastguard Worker static_assert(equals(exp_s(s).value(), "hello"));
948*8f0ba417SAndroid Build Coastguard Worker static_assert(equals(exp_s(exp_s("hello")).value(), "hello"));
949*8f0ba417SAndroid Build Coastguard Worker static_assert(equals(exp_s("hello").value(), "hello"));
950*8f0ba417SAndroid Build Coastguard Worker static_assert(equals(exp_s(c).value(), "hello"));
951*8f0ba417SAndroid Build Coastguard Worker }
952*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testWithNonConstructible)953*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testWithNonConstructible) {
954*8f0ba417SAndroid Build Coastguard Worker struct AssertNotConstructed {
955*8f0ba417SAndroid Build Coastguard Worker AssertNotConstructed() = delete;
956*8f0ba417SAndroid Build Coastguard Worker };
957*8f0ba417SAndroid Build Coastguard Worker
958*8f0ba417SAndroid Build Coastguard Worker expected<int, AssertNotConstructed> v(42);
959*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(v.has_value());
960*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(42, v.value());
961*8f0ba417SAndroid Build Coastguard Worker
962*8f0ba417SAndroid Build Coastguard Worker expected<AssertNotConstructed, int> e(unexpected(42));
963*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e.has_value());
964*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(42, e.error());
965*8f0ba417SAndroid Build Coastguard Worker }
966*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testWithMoveOnlyType)967*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testWithMoveOnlyType) {
968*8f0ba417SAndroid Build Coastguard Worker typedef expected<std::unique_ptr<int>,std::unique_ptr<int>> exp_ptr;
969*8f0ba417SAndroid Build Coastguard Worker exp_ptr e(std::make_unique<int>(3));
970*8f0ba417SAndroid Build Coastguard Worker exp_ptr e2(unexpected(std::make_unique<int>(4)));
971*8f0ba417SAndroid Build Coastguard Worker
972*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
973*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.has_value());
974*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, *(e.value()));
975*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(4, *(e2.error()));
976*8f0ba417SAndroid Build Coastguard Worker
977*8f0ba417SAndroid Build Coastguard Worker e2 = std::move(e);
978*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e.has_value());
979*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
980*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, *(e2.value()));
981*8f0ba417SAndroid Build Coastguard Worker }
982*8f0ba417SAndroid Build Coastguard Worker
983*8f0ba417SAndroid Build Coastguard Worker // Verify that operator bool doesn't cause surprising behavior when converting
984*8f0ba417SAndroid Build Coastguard Worker // between expected types. See wg21.link/LWG3836.
TEST(Expected,testExpectedConversionWithBoolType)985*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testExpectedConversionWithBoolType) {
986*8f0ba417SAndroid Build Coastguard Worker expected<bool, int> e1{false};
987*8f0ba417SAndroid Build Coastguard Worker expected<bool, long> e2{e1};
988*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e1.has_value());
989*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
990*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e1.value());
991*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e2.value());
992*8f0ba417SAndroid Build Coastguard Worker
993*8f0ba417SAndroid Build Coastguard Worker expected<bool, int> e3{unexpected{17}};
994*8f0ba417SAndroid Build Coastguard Worker expected<bool, long> e4{e3};
995*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e3.has_value());
996*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4.has_value());
997*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(17, e3.error());
998*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(17, e4.error());
999*8f0ba417SAndroid Build Coastguard Worker }
1000*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testConversionToClassWithExplicitCtor)1001*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testConversionToClassWithExplicitCtor) {
1002*8f0ba417SAndroid Build Coastguard Worker struct IntObj {
1003*8f0ba417SAndroid Build Coastguard Worker explicit IntObj(int val) : val(val) {}
1004*8f0ba417SAndroid Build Coastguard Worker int val;
1005*8f0ba417SAndroid Build Coastguard Worker };
1006*8f0ba417SAndroid Build Coastguard Worker
1007*8f0ba417SAndroid Build Coastguard Worker expected<int, int> e1(3);
1008*8f0ba417SAndroid Build Coastguard Worker expected<IntObj, int> e2(e1);
1009*8f0ba417SAndroid Build Coastguard Worker EXPECT_TRUE(e2.has_value());
1010*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(3, e2.value().val);
1011*8f0ba417SAndroid Build Coastguard Worker
1012*8f0ba417SAndroid Build Coastguard Worker expected<int, int> e3(unexpected(4));
1013*8f0ba417SAndroid Build Coastguard Worker expected<int, IntObj> e4(e3);
1014*8f0ba417SAndroid Build Coastguard Worker EXPECT_FALSE(e4.has_value());
1015*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(4, e4.error().val);
1016*8f0ba417SAndroid Build Coastguard Worker }
1017*8f0ba417SAndroid Build Coastguard Worker
TEST(Expected,testNoexcept)1018*8f0ba417SAndroid Build Coastguard Worker TEST(Expected, testNoexcept) {
1019*8f0ba417SAndroid Build Coastguard Worker struct Foo {
1020*8f0ba417SAndroid Build Coastguard Worker Foo(int) noexcept {}
1021*8f0ba417SAndroid Build Coastguard Worker };
1022*8f0ba417SAndroid Build Coastguard Worker struct Bar {
1023*8f0ba417SAndroid Build Coastguard Worker Bar(Foo) noexcept {}
1024*8f0ba417SAndroid Build Coastguard Worker };
1025*8f0ba417SAndroid Build Coastguard Worker expected<Foo, Foo> e1{3};
1026*8f0ba417SAndroid Build Coastguard Worker expected<Foo, Foo> e2{4};
1027*8f0ba417SAndroid Build Coastguard Worker expected<Bar, Bar> e3{e1};
1028*8f0ba417SAndroid Build Coastguard Worker Foo foo{5};
1029*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, Foo>(e1)));
1030*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, Foo>(std::move(e1))));
1031*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, Foo>(foo)));
1032*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, Foo>(std::move(foo))));
1033*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, Foo>(unexpected(Foo(5)))));
1034*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, Bar>(e1)));
1035*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, Bar>(std::move(e1))));
1036*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, Bar>(foo)));
1037*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, Bar>(std::move(foo))));
1038*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, Bar>(unexpected(Bar(foo)))));
1039*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e2 = e1));
1040*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e2 = std::move(e1)));
1041*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e3 = e1));
1042*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e3 = std::move(e1)));
1043*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e1 = Foo(5)));
1044*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e3 = Foo(5)));
1045*8f0ba417SAndroid Build Coastguard Worker
1046*8f0ba417SAndroid Build Coastguard Worker // std::string's move constructor is noexcept, but copying a string can throw
1047*8f0ba417SAndroid Build Coastguard Worker // bad_alloc.
1048*8f0ba417SAndroid Build Coastguard Worker expected<Foo, std::string> e11{11};
1049*8f0ba417SAndroid Build Coastguard Worker expected<Foo, std::string> e12{12};
1050*8f0ba417SAndroid Build Coastguard Worker expected<Bar, std::string> e13{e11};
1051*8f0ba417SAndroid Build Coastguard Worker std::string err = "hello";
1052*8f0ba417SAndroid Build Coastguard Worker static_assert(!noexcept(expected<Foo, std::string>(e11)));
1053*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, std::string>(std::move(e11))));
1054*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, std::string>(foo)));
1055*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, std::string>(std::move(foo))));
1056*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Foo, std::string>(unexpected(std::move(err)))));
1057*8f0ba417SAndroid Build Coastguard Worker static_assert(!noexcept(expected<Bar, std::string>(e11)));
1058*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, std::string>(std::move(e11))));
1059*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, std::string>(foo)));
1060*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(expected<Bar, std::string>(std::move(foo))));
1061*8f0ba417SAndroid Build Coastguard Worker static_assert(!noexcept(e12 = e11));
1062*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e12 = std::move(e11)));
1063*8f0ba417SAndroid Build Coastguard Worker static_assert(!noexcept(e13 = e11));
1064*8f0ba417SAndroid Build Coastguard Worker static_assert(noexcept(e13 = std::move(e11)));
1065*8f0ba417SAndroid Build Coastguard Worker }
1066