ExpectedTest.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <folly/Expected.h>
  17. #include <folly/Portability.h>
  18. #include <folly/portability/GTest.h>
  19. #include <algorithm>
  20. #include <iomanip>
  21. #include <memory>
  22. #include <string>
  23. #include <type_traits>
  24. #include <vector>
  25. #include <glog/logging.h>
  26. using std::shared_ptr;
  27. using std::unique_ptr;
  28. namespace folly {
  29. enum class E { E1, E2 };
  30. std::ostream& operator<<(std::ostream& os, E e) {
  31. switch (e) {
  32. case E::E1:
  33. return os << "E::E1";
  34. case E::E2:
  35. return os << "E::E2";
  36. default:;
  37. }
  38. return os;
  39. }
  40. template <class V, class E>
  41. std::ostream& operator<<(std::ostream& os, const Expected<V, E>& e) {
  42. if (e) {
  43. os << "Expected(" << e.value() << ')';
  44. } else {
  45. os << "Unexpected(" << e.error() << ')';
  46. }
  47. return os;
  48. }
  49. struct NoDefault {
  50. NoDefault(int, int) {}
  51. char a, b, c;
  52. };
  53. TEST(Expected, NoDefault) {
  54. static_assert(
  55. std::is_default_constructible<Expected<NoDefault, int>>::value, "");
  56. Expected<NoDefault, int> x{in_place, 42, 42};
  57. EXPECT_TRUE(bool(x));
  58. x.emplace(4, 5);
  59. EXPECT_TRUE(bool(x));
  60. x = makeUnexpected(42);
  61. EXPECT_FALSE(bool(x));
  62. EXPECT_EQ(42, x.error());
  63. }
  64. TEST(Expected, String) {
  65. Expected<std::string, int> maybeString;
  66. EXPECT_FALSE(bool(maybeString));
  67. EXPECT_EQ(0, maybeString.error());
  68. maybeString = "hello";
  69. EXPECT_TRUE(bool(maybeString));
  70. EXPECT_EQ("hello", *maybeString);
  71. }
  72. TEST(Expected, Ambiguous) {
  73. // Potentially ambiguous and confusing construction and assignment disallowed:
  74. EXPECT_FALSE((std::is_constructible<Expected<int, int>, int>::value));
  75. EXPECT_FALSE((std::is_assignable<Expected<int, int>&, int>::value));
  76. }
  77. TEST(Expected, Const) {
  78. { // default construct
  79. Expected<const int, int> ex;
  80. EXPECT_FALSE(bool(ex));
  81. EXPECT_EQ(0, ex.error());
  82. ex.emplace(4);
  83. EXPECT_EQ(4, *ex);
  84. ex.emplace(5);
  85. EXPECT_EQ(5, *ex);
  86. ex = makeUnexpected(42);
  87. EXPECT_FALSE(bool(ex));
  88. EXPECT_EQ(42, ex.error());
  89. }
  90. { // copy-constructed
  91. const int x = 6;
  92. Expected<const int, int> ex{in_place, x};
  93. Expected<const int, int> ex2 = ex;
  94. EXPECT_EQ(6, *ex2);
  95. }
  96. { // move-constructed
  97. const int x = 7;
  98. Expected<const int, int> ex{in_place, std::move(x)};
  99. Expected<const int, int> ex2 = std::move(ex);
  100. EXPECT_EQ(7, *ex2);
  101. }
  102. // no assignment allowed
  103. EXPECT_FALSE((std::is_copy_assignable<Expected<const int, int>>::value));
  104. }
  105. TEST(Expected, Simple) {
  106. Expected<int, int> ex;
  107. EXPECT_FALSE(bool(ex));
  108. EXPECT_EQ(42, ex.value_or(42));
  109. ex.emplace(4);
  110. EXPECT_TRUE(bool(ex));
  111. EXPECT_EQ(4, *ex);
  112. EXPECT_EQ(4, ex.value_or(42));
  113. ex = makeUnexpected(-1);
  114. EXPECT_FALSE(bool(ex));
  115. EXPECT_EQ(-1, ex.error());
  116. EXPECT_EQ(42, ex.value_or(42));
  117. }
  118. class MoveTester {
  119. public:
  120. /* implicit */ MoveTester(const char* s) : s_(s) {}
  121. MoveTester(const MoveTester&) = default;
  122. MoveTester(MoveTester&& other) noexcept {
  123. s_ = std::move(other.s_);
  124. other.s_ = "";
  125. }
  126. MoveTester& operator=(const MoveTester&) = default;
  127. MoveTester& operator=(MoveTester&& other) noexcept {
  128. s_ = std::move(other.s_);
  129. other.s_ = "";
  130. return *this;
  131. }
  132. private:
  133. friend bool operator==(const MoveTester& o1, const MoveTester& o2);
  134. std::string s_;
  135. };
  136. bool operator==(const MoveTester& o1, const MoveTester& o2) {
  137. return o1.s_ == o2.s_;
  138. }
  139. TEST(Expected, value_or_rvalue_arg) {
  140. Expected<MoveTester, int> ex = makeUnexpected(-1);
  141. MoveTester dflt = "hello";
  142. EXPECT_EQ("hello", ex.value_or(dflt));
  143. EXPECT_EQ("hello", dflt);
  144. EXPECT_EQ("hello", ex.value_or(std::move(dflt)));
  145. EXPECT_EQ("", dflt);
  146. EXPECT_EQ("world", ex.value_or("world"));
  147. dflt = "hello";
  148. // Make sure that the const overload works on const objects
  149. const auto& exc = ex;
  150. EXPECT_EQ("hello", exc.value_or(dflt));
  151. EXPECT_EQ("hello", dflt);
  152. EXPECT_EQ("hello", exc.value_or(std::move(dflt)));
  153. EXPECT_EQ("", dflt);
  154. EXPECT_EQ("world", exc.value_or("world"));
  155. dflt = "hello";
  156. ex = "meow";
  157. EXPECT_EQ("meow", ex.value_or(dflt));
  158. EXPECT_EQ("hello", dflt);
  159. EXPECT_EQ("meow", ex.value_or(std::move(dflt)));
  160. EXPECT_EQ("hello", dflt); // only moved if used
  161. }
  162. TEST(Expected, value_or_noncopyable) {
  163. Expected<std::unique_ptr<int>, int> ex{unexpected, 42};
  164. std::unique_ptr<int> dflt(new int(42));
  165. EXPECT_EQ(42, *std::move(ex).value_or(std::move(dflt)));
  166. }
  167. struct ExpectingDeleter {
  168. explicit ExpectingDeleter(int expected_) : expected(expected_) {}
  169. int expected;
  170. void operator()(const int* ptr) {
  171. EXPECT_EQ(*ptr, expected);
  172. delete ptr;
  173. }
  174. };
  175. TEST(Expected, value_move) {
  176. auto ptr = Expected<std::unique_ptr<int, ExpectingDeleter>, int>(
  177. in_place, new int(42), ExpectingDeleter{1337})
  178. .value();
  179. *ptr = 1337;
  180. }
  181. TEST(Expected, dereference_move) {
  182. auto ptr = *Expected<std::unique_ptr<int, ExpectingDeleter>, int>(
  183. in_place, new int(42), ExpectingDeleter{1337});
  184. *ptr = 1337;
  185. }
  186. TEST(Expected, EmptyConstruct) {
  187. Expected<int, int> ex{unexpected, 42};
  188. EXPECT_FALSE(bool(ex));
  189. Expected<int, int> test1(ex);
  190. EXPECT_FALSE(bool(test1));
  191. Expected<int, int> test2(std::move(ex));
  192. EXPECT_FALSE(bool(test2));
  193. EXPECT_EQ(42, test2.error());
  194. }
  195. TEST(Expected, Unique) {
  196. Expected<unique_ptr<int>, int> ex;
  197. ex = makeUnexpected(-1);
  198. EXPECT_FALSE(bool(ex));
  199. // empty->emplaced
  200. ex.emplace(new int(5));
  201. EXPECT_TRUE(bool(ex));
  202. EXPECT_EQ(5, **ex);
  203. ex = makeUnexpected(-1);
  204. // empty->moved
  205. ex = std::make_unique<int>(6);
  206. EXPECT_EQ(6, **ex);
  207. // full->moved
  208. ex = std::make_unique<int>(7);
  209. EXPECT_EQ(7, **ex);
  210. // move it out by move construct
  211. Expected<unique_ptr<int>, int> moved(std::move(ex));
  212. EXPECT_TRUE(bool(moved));
  213. EXPECT_TRUE(bool(ex));
  214. EXPECT_EQ(nullptr, ex->get());
  215. EXPECT_EQ(7, **moved);
  216. EXPECT_TRUE(bool(moved));
  217. ex = std::move(moved); // move it back by move assign
  218. EXPECT_TRUE(bool(moved));
  219. EXPECT_EQ(nullptr, moved->get());
  220. EXPECT_TRUE(bool(ex));
  221. EXPECT_EQ(7, **ex);
  222. }
  223. TEST(Expected, Shared) {
  224. shared_ptr<int> ptr;
  225. Expected<shared_ptr<int>, int> ex{unexpected, -1};
  226. EXPECT_FALSE(bool(ex));
  227. // empty->emplaced
  228. ex.emplace(new int(5));
  229. EXPECT_TRUE(bool(ex));
  230. ptr = ex.value();
  231. EXPECT_EQ(ptr.get(), ex->get());
  232. EXPECT_EQ(2, ptr.use_count());
  233. ex = makeUnexpected(-1);
  234. EXPECT_EQ(1, ptr.use_count());
  235. // full->copied
  236. ex = ptr;
  237. EXPECT_EQ(2, ptr.use_count());
  238. EXPECT_EQ(ptr.get(), ex->get());
  239. ex = makeUnexpected(-1);
  240. EXPECT_EQ(1, ptr.use_count());
  241. // full->moved
  242. ex = std::move(ptr);
  243. EXPECT_EQ(1, ex->use_count());
  244. EXPECT_EQ(nullptr, ptr.get());
  245. {
  246. EXPECT_EQ(1, ex->use_count());
  247. Expected<shared_ptr<int>, int> copied(ex);
  248. EXPECT_EQ(2, ex->use_count());
  249. Expected<shared_ptr<int>, int> moved(std::move(ex));
  250. EXPECT_EQ(2, moved->use_count());
  251. moved.emplace(new int(6));
  252. EXPECT_EQ(1, moved->use_count());
  253. copied = moved;
  254. EXPECT_EQ(2, moved->use_count());
  255. }
  256. }
  257. TEST(Expected, Order) {
  258. std::vector<Expected<int, E>> vect{
  259. {unexpected, E::E1},
  260. {3},
  261. {1},
  262. {unexpected, E::E1},
  263. {2},
  264. };
  265. std::vector<Expected<int, E>> expected{
  266. {unexpected, E::E1},
  267. {unexpected, E::E1},
  268. {1},
  269. {2},
  270. {3},
  271. };
  272. std::sort(vect.begin(), vect.end());
  273. EXPECT_EQ(vect, expected);
  274. }
  275. TEST(Expected, SwapMethod) {
  276. Expected<std::string, E> a;
  277. Expected<std::string, E> b;
  278. a.swap(b);
  279. EXPECT_FALSE(a.hasValue());
  280. EXPECT_FALSE(b.hasValue());
  281. a = "hello";
  282. EXPECT_TRUE(a.hasValue());
  283. EXPECT_FALSE(b.hasValue());
  284. EXPECT_EQ("hello", a.value());
  285. b.swap(a);
  286. EXPECT_FALSE(a.hasValue());
  287. EXPECT_TRUE(b.hasValue());
  288. EXPECT_EQ("hello", b.value());
  289. a = "bye";
  290. EXPECT_TRUE(a.hasValue());
  291. EXPECT_EQ("bye", a.value());
  292. a.swap(b);
  293. EXPECT_EQ("hello", a.value());
  294. EXPECT_EQ("bye", b.value());
  295. }
  296. TEST(Expected, StdSwapFunction) {
  297. Expected<std::string, E> a;
  298. Expected<std::string, E> b;
  299. std::swap(a, b);
  300. EXPECT_FALSE(a.hasValue());
  301. EXPECT_FALSE(b.hasValue());
  302. a = "greeting";
  303. EXPECT_TRUE(a.hasValue());
  304. EXPECT_FALSE(b.hasValue());
  305. EXPECT_EQ("greeting", a.value());
  306. std::swap(a, b);
  307. EXPECT_FALSE(a.hasValue());
  308. EXPECT_TRUE(b.hasValue());
  309. EXPECT_EQ("greeting", b.value());
  310. a = "goodbye";
  311. EXPECT_TRUE(a.hasValue());
  312. EXPECT_EQ("goodbye", a.value());
  313. std::swap(a, b);
  314. EXPECT_EQ("greeting", a.value());
  315. EXPECT_EQ("goodbye", b.value());
  316. }
  317. TEST(Expected, FollySwapFunction) {
  318. Expected<std::string, E> a;
  319. Expected<std::string, E> b;
  320. folly::swap(a, b);
  321. EXPECT_FALSE(a.hasValue());
  322. EXPECT_FALSE(b.hasValue());
  323. a = "salute";
  324. EXPECT_TRUE(a.hasValue());
  325. EXPECT_FALSE(b.hasValue());
  326. EXPECT_EQ("salute", a.value());
  327. folly::swap(a, b);
  328. EXPECT_FALSE(a.hasValue());
  329. EXPECT_TRUE(b.hasValue());
  330. EXPECT_EQ("salute", b.value());
  331. a = "adieu";
  332. EXPECT_TRUE(a.hasValue());
  333. EXPECT_EQ("adieu", a.value());
  334. folly::swap(a, b);
  335. EXPECT_EQ("salute", a.value());
  336. EXPECT_EQ("adieu", b.value());
  337. }
  338. TEST(Expected, Comparisons) {
  339. Expected<int, E> o_;
  340. Expected<int, E> o1(1);
  341. Expected<int, E> o2(2);
  342. EXPECT_TRUE(o_ <= (o_));
  343. EXPECT_TRUE(o_ == (o_));
  344. EXPECT_TRUE(o_ >= (o_));
  345. EXPECT_TRUE(o1 < o2);
  346. EXPECT_TRUE(o1 <= o2);
  347. EXPECT_TRUE(o1 <= (o1));
  348. EXPECT_TRUE(o1 == (o1));
  349. EXPECT_TRUE(o1 != o2);
  350. EXPECT_TRUE(o1 >= (o1));
  351. EXPECT_TRUE(o2 >= o1);
  352. EXPECT_TRUE(o2 > o1);
  353. EXPECT_FALSE(o2 < o1);
  354. EXPECT_FALSE(o2 <= o1);
  355. EXPECT_FALSE(o2 <= o1);
  356. EXPECT_FALSE(o2 == o1);
  357. EXPECT_FALSE(o1 != (o1));
  358. EXPECT_FALSE(o1 >= o2);
  359. EXPECT_FALSE(o1 >= o2);
  360. EXPECT_FALSE(o1 > o2);
  361. /* folly::Expected explicitly doesn't support comparisons with contained value
  362. EXPECT_TRUE(1 < o2);
  363. EXPECT_TRUE(1 <= o2);
  364. EXPECT_TRUE(1 <= o1);
  365. EXPECT_TRUE(1 == o1);
  366. EXPECT_TRUE(2 != o1);
  367. EXPECT_TRUE(1 >= o1);
  368. EXPECT_TRUE(2 >= o1);
  369. EXPECT_TRUE(2 > o1);
  370. EXPECT_FALSE(o2 < 1);
  371. EXPECT_FALSE(o2 <= 1);
  372. EXPECT_FALSE(o2 <= 1);
  373. EXPECT_FALSE(o2 == 1);
  374. EXPECT_FALSE(o2 != 2);
  375. EXPECT_FALSE(o1 >= 2);
  376. EXPECT_FALSE(o1 >= 2);
  377. EXPECT_FALSE(o1 > 2);
  378. */
  379. }
  380. TEST(Expected, Conversions) {
  381. Expected<bool, E> mbool;
  382. Expected<short, E> mshort;
  383. Expected<char*, E> mstr;
  384. Expected<int, E> mint;
  385. EXPECT_FALSE((std::is_convertible<Expected<bool, E>&, bool>::value));
  386. EXPECT_FALSE((std::is_convertible<Expected<short, E>&, short>::value));
  387. EXPECT_FALSE((std::is_convertible<Expected<char*, E>&, char*>::value));
  388. EXPECT_FALSE((std::is_convertible<Expected<int, E>&, int>::value));
  389. // intended explicit operator bool, for if (ex).
  390. bool b(mbool);
  391. EXPECT_FALSE(b);
  392. // Truthy tests work and are not ambiguous
  393. if (mbool && mshort && mstr && mint) { // only checks not-empty
  394. if (*mbool && *mshort && *mstr && *mint) { // only checks value
  395. ;
  396. }
  397. }
  398. mbool = false;
  399. EXPECT_TRUE(bool(mbool));
  400. EXPECT_FALSE(*mbool);
  401. mbool = true;
  402. EXPECT_TRUE(bool(mbool));
  403. EXPECT_TRUE(*mbool);
  404. mbool = {unexpected, E::E1};
  405. EXPECT_FALSE(bool(mbool));
  406. // No conversion allowed; does not compile
  407. // mbool == false;
  408. }
  409. TEST(Expected, Pointee) {
  410. Expected<int, E> x;
  411. EXPECT_FALSE(get_pointer(x));
  412. x = 1;
  413. EXPECT_TRUE(get_pointer(x));
  414. *get_pointer(x) = 2;
  415. EXPECT_TRUE(*x == 2);
  416. x = {unexpected, E::E1};
  417. EXPECT_FALSE(get_pointer(x));
  418. }
  419. TEST(Expected, MakeOptional) {
  420. // const L-value version
  421. const std::string s("abc");
  422. auto exStr = makeExpected<E>(s);
  423. ASSERT_TRUE(exStr.hasValue());
  424. EXPECT_EQ(*exStr, "abc");
  425. *exStr = "cde";
  426. EXPECT_EQ(s, "abc");
  427. EXPECT_EQ(*exStr, "cde");
  428. // L-value version
  429. std::string s2("abc");
  430. auto exStr2 = makeExpected<E>(s2);
  431. ASSERT_TRUE(exStr2.hasValue());
  432. EXPECT_EQ(*exStr2, "abc");
  433. *exStr2 = "cde";
  434. // it's vital to check that s2 wasn't clobbered
  435. EXPECT_EQ(s2, "abc");
  436. // L-value reference version
  437. std::string& s3(s2);
  438. auto exStr3 = makeExpected<E>(s3);
  439. ASSERT_TRUE(exStr3.hasValue());
  440. EXPECT_EQ(*exStr3, "abc");
  441. *exStr3 = "cde";
  442. EXPECT_EQ(s3, "abc");
  443. // R-value ref version
  444. unique_ptr<int> pInt(new int(3));
  445. auto exIntPtr = makeExpected<E>(std::move(pInt));
  446. EXPECT_TRUE(pInt.get() == nullptr);
  447. ASSERT_TRUE(exIntPtr.hasValue());
  448. EXPECT_EQ(**exIntPtr, 3);
  449. }
  450. TEST(Expected, SelfAssignment) {
  451. Expected<std::string, E> a = "42";
  452. a = static_cast<decltype(a)&>(a); // suppress self-assign warning
  453. ASSERT_TRUE(a.hasValue() && a.value() == "42");
  454. Expected<std::string, E> b = "23333333";
  455. b = static_cast<decltype(b)&&>(b); // suppress self-move warning
  456. ASSERT_TRUE(b.hasValue() && b.value() == "23333333");
  457. }
  458. class ContainsExpected {
  459. public:
  460. ContainsExpected() {}
  461. explicit ContainsExpected(int x) : ex_(x) {}
  462. bool hasValue() const {
  463. return ex_.hasValue();
  464. }
  465. int value() const {
  466. return ex_.value();
  467. }
  468. ContainsExpected(const ContainsExpected& other) = default;
  469. ContainsExpected& operator=(const ContainsExpected& other) = default;
  470. ContainsExpected(ContainsExpected&& other) = default;
  471. ContainsExpected& operator=(ContainsExpected&& other) = default;
  472. private:
  473. Expected<int, E> ex_;
  474. };
  475. /**
  476. * Test that a class containing an Expected can be copy and move assigned.
  477. * This was broken under gcc 4.7 until assignment operators were explicitly
  478. * defined.
  479. */
  480. TEST(Expected, AssignmentContained) {
  481. {
  482. ContainsExpected source(5), target;
  483. target = source;
  484. EXPECT_TRUE(target.hasValue());
  485. EXPECT_EQ(5, target.value());
  486. }
  487. {
  488. ContainsExpected source(5), target;
  489. target = std::move(source);
  490. EXPECT_TRUE(target.hasValue());
  491. EXPECT_EQ(5, target.value());
  492. EXPECT_TRUE(source.hasValue());
  493. }
  494. {
  495. ContainsExpected ex_uninit, target(10);
  496. target = ex_uninit;
  497. EXPECT_FALSE(target.hasValue());
  498. }
  499. }
  500. TEST(Expected, Exceptions) {
  501. Expected<int, E> empty;
  502. EXPECT_THROW(empty.value(), Unexpected<E>::BadExpectedAccess);
  503. }
  504. struct ThrowingBadness {
  505. ThrowingBadness() noexcept(false);
  506. ThrowingBadness(const ThrowingBadness&) noexcept(false);
  507. ThrowingBadness(ThrowingBadness&&) noexcept(false);
  508. ThrowingBadness& operator=(const ThrowingBadness&) noexcept(false);
  509. ThrowingBadness& operator=(ThrowingBadness&&) noexcept(false);
  510. };
  511. TEST(Expected, NoThrowDefaultConstructible) {
  512. EXPECT_TRUE(
  513. (std::is_nothrow_default_constructible<Expected<bool, E>>::value));
  514. EXPECT_TRUE(
  515. (std::is_nothrow_default_constructible<Expected<std::string, E>>::value));
  516. EXPECT_TRUE((std::is_nothrow_default_constructible<
  517. Expected<ThrowingBadness, E>>::value));
  518. EXPECT_FALSE((std::is_nothrow_default_constructible<
  519. Expected<int, ThrowingBadness>>::value));
  520. }
  521. TEST(Expected, NoThrowMoveConstructible) {
  522. EXPECT_TRUE((std::is_nothrow_move_constructible<Expected<bool, E>>::value));
  523. EXPECT_TRUE((std::is_nothrow_move_constructible<
  524. Expected<std::unique_ptr<int>, E>>::value));
  525. EXPECT_FALSE((
  526. std::is_nothrow_move_constructible<Expected<ThrowingBadness, E>>::value));
  527. }
  528. TEST(Expected, NoThrowMoveAssignable) {
  529. EXPECT_TRUE((std::is_nothrow_move_assignable<Expected<bool, E>>::value));
  530. EXPECT_TRUE((std::is_nothrow_move_assignable<
  531. Expected<std::unique_ptr<int>, E>>::value));
  532. EXPECT_FALSE(
  533. (std::is_nothrow_move_assignable<Expected<ThrowingBadness, E>>::value));
  534. }
  535. struct NoSelfAssign {
  536. NoSelfAssign() = default;
  537. NoSelfAssign(NoSelfAssign&&) = default;
  538. NoSelfAssign(const NoSelfAssign&) = default;
  539. NoSelfAssign& operator=(NoSelfAssign&& that) {
  540. EXPECT_NE(this, &that);
  541. return *this;
  542. }
  543. NoSelfAssign& operator=(const NoSelfAssign& that) {
  544. EXPECT_NE(this, &that);
  545. return *this;
  546. }
  547. };
  548. #ifdef __GNUC__
  549. #pragma GCC diagnostic push
  550. #pragma GCC diagnostic ignored "-Wpragmas"
  551. #endif
  552. TEST(Expected, NoSelfAssign) {
  553. folly::Expected<NoSelfAssign, int> e{NoSelfAssign{}};
  554. e = static_cast<decltype(e)&>(e); // suppress self-assign warning
  555. e = static_cast<decltype(e)&&>(e); // @nolint suppress self-move warning
  556. }
  557. #ifdef __GNUC__
  558. #pragma GCC diagnostic pop
  559. #endif
  560. struct NoDestructor {};
  561. struct WithDestructor {
  562. ~WithDestructor();
  563. };
  564. TEST(Expected, TriviallyDestructible) {
  565. // These could all be static_asserts but EXPECT_* give much nicer output on
  566. // failure.
  567. EXPECT_TRUE(
  568. (std::is_trivially_destructible<Expected<NoDestructor, E>>::value));
  569. EXPECT_TRUE((std::is_trivially_destructible<Expected<int, E>>::value));
  570. EXPECT_FALSE(
  571. (std::is_trivially_destructible<Expected<WithDestructor, E>>::value));
  572. }
  573. struct NoConstructor {};
  574. struct WithConstructor {
  575. WithConstructor();
  576. };
  577. // libstdc++ with GCC 4.x doesn't have std::is_trivially_copyable
  578. #if (defined(__clang__) && !defined(_LIBCPP_VERSION)) || \
  579. !(defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5)
  580. TEST(Expected, TriviallyCopyable) {
  581. // These could all be static_asserts but EXPECT_* give much nicer output on
  582. // failure.
  583. EXPECT_TRUE((is_trivially_copyable<Expected<int, E>>::value));
  584. EXPECT_TRUE((is_trivially_copyable<Expected<char*, E>>::value));
  585. EXPECT_TRUE((is_trivially_copyable<Expected<NoDestructor, E>>::value));
  586. EXPECT_FALSE((is_trivially_copyable<Expected<WithDestructor, E>>::value));
  587. EXPECT_TRUE((is_trivially_copyable<Expected<NoConstructor, E>>::value));
  588. EXPECT_FALSE((is_trivially_copyable<Expected<std::string, E>>::value));
  589. EXPECT_FALSE((is_trivially_copyable<Expected<int, std::string>>::value));
  590. EXPECT_TRUE((is_trivially_copyable<Expected<WithConstructor, E>>::value));
  591. EXPECT_TRUE((is_trivially_copyable<Expected<Expected<int, E>, E>>::value));
  592. }
  593. #endif
  594. TEST(Expected, Then) {
  595. // Lifting
  596. {
  597. Expected<int, E> ex =
  598. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
  599. [](std::unique_ptr<int> p) { return *p; });
  600. EXPECT_TRUE(bool(ex));
  601. EXPECT_EQ(42, *ex);
  602. }
  603. // Flattening
  604. {
  605. Expected<int, E> ex =
  606. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
  607. [](std::unique_ptr<int> p) { return makeExpected<E>(*p); });
  608. EXPECT_TRUE(bool(ex));
  609. EXPECT_EQ(42, *ex);
  610. }
  611. // Void
  612. {
  613. Expected<Unit, E> ex =
  614. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
  615. [](std::unique_ptr<int>) {});
  616. EXPECT_TRUE(bool(ex));
  617. }
  618. // Non-flattening (different error codes)
  619. {
  620. Expected<Expected<int, int>, E> ex =
  621. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
  622. [](std::unique_ptr<int> p) { return makeExpected<int>(*p); });
  623. EXPECT_TRUE(bool(ex));
  624. EXPECT_TRUE(bool(*ex));
  625. EXPECT_EQ(42, **ex);
  626. }
  627. {
  628. // Error case:
  629. Expected<int, E> ex =
  630. Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.then(
  631. [](std::unique_ptr<int> p) -> int {
  632. ADD_FAILURE();
  633. return *p;
  634. });
  635. EXPECT_FALSE(bool(ex));
  636. EXPECT_EQ(E::E1, ex.error());
  637. }
  638. // Chaining
  639. {
  640. Expected<std::string, E> ex =
  641. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
  642. [](std::unique_ptr<int> p) { return makeExpected<E>(*p); },
  643. [](int i) { return i == 42 ? "yes" : "no"; });
  644. EXPECT_TRUE(bool(ex));
  645. EXPECT_EQ("yes", *ex);
  646. }
  647. // Chaining with errors
  648. {
  649. Expected<std::string, E> ex =
  650. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
  651. [](std::unique_ptr<int>) {
  652. return Expected<int, E>(unexpected, E::E1);
  653. },
  654. [](int i) { return i == 42 ? "yes" : "no"; });
  655. EXPECT_FALSE(bool(ex));
  656. EXPECT_EQ(E::E1, ex.error());
  657. }
  658. }
  659. TEST(Expected, ThenOrThrow) {
  660. {
  661. int e =
  662. Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.thenOrThrow(
  663. [](std::unique_ptr<int> p) { return *p; });
  664. EXPECT_EQ(42, e);
  665. }
  666. {
  667. EXPECT_THROW(
  668. (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
  669. [](std::unique_ptr<int> p) { return *p; })),
  670. Unexpected<E>::BadExpectedAccess);
  671. }
  672. {
  673. EXPECT_THROW(
  674. (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
  675. [](std::unique_ptr<int> p) { return *p; },
  676. [](E) { return std::runtime_error(""); })),
  677. std::runtime_error);
  678. }
  679. {
  680. EXPECT_THROW(
  681. (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
  682. [](std::unique_ptr<int> p) { return *p; },
  683. [](E) { throw std::runtime_error(""); })),
  684. std::runtime_error);
  685. }
  686. {
  687. EXPECT_THROW(
  688. (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
  689. [](std::unique_ptr<int> p) { return *p; }, [](E) {})),
  690. Unexpected<E>::BadExpectedAccess);
  691. }
  692. }
  693. } // namespace folly