testOptional.cxx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <vector>
  4. #include <cm/optional>
  5. #include <cm/utility>
  6. class EventLogger;
  7. class Event
  8. {
  9. public:
  10. enum EventType
  11. {
  12. DEFAULT_CONSTRUCT,
  13. COPY_CONSTRUCT,
  14. MOVE_CONSTRUCT,
  15. VALUE_CONSTRUCT,
  16. DESTRUCT,
  17. COPY_ASSIGN,
  18. MOVE_ASSIGN,
  19. VALUE_ASSIGN,
  20. REFERENCE,
  21. CONST_REFERENCE,
  22. RVALUE_REFERENCE,
  23. CONST_RVALUE_REFERENCE,
  24. SWAP,
  25. };
  26. EventType Type;
  27. const EventLogger* Logger1;
  28. const EventLogger* Logger2;
  29. int Value;
  30. bool operator==(const Event& other) const;
  31. bool operator!=(const Event& other) const;
  32. };
  33. bool Event::operator==(const Event& other) const
  34. {
  35. return this->Type == other.Type && this->Logger1 == other.Logger1 &&
  36. this->Logger2 == other.Logger2 && this->Value == other.Value;
  37. }
  38. bool Event::operator!=(const Event& other) const
  39. {
  40. return !(*this == other);
  41. }
  42. static std::vector<Event> events;
  43. class EventLogger
  44. {
  45. public:
  46. EventLogger();
  47. EventLogger(const EventLogger& other);
  48. EventLogger(EventLogger&& other);
  49. EventLogger(int value);
  50. ~EventLogger();
  51. EventLogger& operator=(const EventLogger& other);
  52. EventLogger& operator=(EventLogger&& other);
  53. EventLogger& operator=(int value);
  54. void Reference() &;
  55. void Reference() const&;
  56. void Reference() &&;
  57. void Reference() const&&;
  58. int Value = 0;
  59. };
  60. // Certain builds of GCC generate false -Wmaybe-uninitialized warnings when
  61. // doing a release build with the system version of std::optional. These
  62. // warnings do not manifest when using our own cm::optional implementation.
  63. // Silence these false warnings.
  64. #if defined(__GNUC__) && !defined(__clang__)
  65. # define BEGIN_IGNORE_UNINITIALIZED \
  66. _Pragma("GCC diagnostic push") \
  67. _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
  68. # define END_IGNORE_UNINITIALIZED _Pragma("GCC diagnostic pop")
  69. #else
  70. # define BEGIN_IGNORE_UNINITIALIZED
  71. # define END_IGNORE_UNINITIALIZED
  72. #endif
  73. void swap(EventLogger& e1, EventLogger& e2)
  74. {
  75. BEGIN_IGNORE_UNINITIALIZED
  76. events.push_back({ Event::SWAP, &e1, &e2, e2.Value });
  77. END_IGNORE_UNINITIALIZED
  78. auto tmp = e1.Value;
  79. e1.Value = e2.Value;
  80. e2.Value = tmp;
  81. }
  82. EventLogger::EventLogger()
  83. : Value(0)
  84. {
  85. events.push_back({ Event::DEFAULT_CONSTRUCT, this, nullptr, 0 });
  86. }
  87. EventLogger::EventLogger(const EventLogger& other)
  88. : Value(other.Value)
  89. {
  90. events.push_back({ Event::COPY_CONSTRUCT, this, &other, other.Value });
  91. }
  92. BEGIN_IGNORE_UNINITIALIZED
  93. EventLogger::EventLogger(EventLogger&& other)
  94. : Value(other.Value)
  95. {
  96. events.push_back({ Event::MOVE_CONSTRUCT, this, &other, other.Value });
  97. }
  98. END_IGNORE_UNINITIALIZED
  99. EventLogger::EventLogger(int value)
  100. : Value(value)
  101. {
  102. events.push_back({ Event::VALUE_CONSTRUCT, this, nullptr, value });
  103. }
  104. EventLogger::~EventLogger()
  105. {
  106. BEGIN_IGNORE_UNINITIALIZED
  107. events.push_back({ Event::DESTRUCT, this, nullptr, this->Value });
  108. END_IGNORE_UNINITIALIZED
  109. }
  110. EventLogger& EventLogger::operator=(const EventLogger& other)
  111. {
  112. events.push_back({ Event::COPY_ASSIGN, this, &other, other.Value });
  113. this->Value = other.Value;
  114. return *this;
  115. }
  116. EventLogger& EventLogger::operator=(EventLogger&& other)
  117. {
  118. events.push_back({ Event::MOVE_ASSIGN, this, &other, other.Value });
  119. this->Value = other.Value;
  120. return *this;
  121. }
  122. EventLogger& EventLogger::operator=(int value)
  123. {
  124. events.push_back({ Event::VALUE_ASSIGN, this, nullptr, value });
  125. this->Value = value;
  126. return *this;
  127. }
  128. void EventLogger::Reference() &
  129. {
  130. events.push_back({ Event::REFERENCE, this, nullptr, this->Value });
  131. }
  132. void EventLogger::Reference() const&
  133. {
  134. events.push_back({ Event::CONST_REFERENCE, this, nullptr, this->Value });
  135. }
  136. void EventLogger::Reference() &&
  137. {
  138. events.push_back({ Event::RVALUE_REFERENCE, this, nullptr, this->Value });
  139. }
  140. void EventLogger::Reference() const&&
  141. {
  142. events.push_back(
  143. { Event::CONST_RVALUE_REFERENCE, this, nullptr, this->Value });
  144. }
  145. static bool testDefaultConstruct(std::vector<Event>& expected)
  146. {
  147. const cm::optional<EventLogger> o{};
  148. expected = {};
  149. return true;
  150. }
  151. static bool testNulloptConstruct(std::vector<Event>& expected)
  152. {
  153. const cm::optional<EventLogger> o{ cm::nullopt };
  154. expected = {};
  155. return true;
  156. }
  157. static bool testValueConstruct(std::vector<Event>& expected)
  158. {
  159. const cm::optional<EventLogger> o{ 4 };
  160. expected = {
  161. { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
  162. { Event::DESTRUCT, &*o, nullptr, 4 },
  163. };
  164. return true;
  165. }
  166. static bool testInPlaceConstruct(std::vector<Event>& expected)
  167. {
  168. const cm::optional<EventLogger> o1{ cm::in_place, 4 };
  169. const cm::optional<EventLogger> o2{ cm::in_place_t{}, 4 };
  170. expected = {
  171. { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
  172. { Event::VALUE_CONSTRUCT, &*o2, nullptr, 4 },
  173. { Event::DESTRUCT, &*o2, nullptr, 4 },
  174. { Event::DESTRUCT, &*o1, nullptr, 4 },
  175. };
  176. return true;
  177. }
  178. static bool testCopyConstruct(std::vector<Event>& expected)
  179. {
  180. const cm::optional<EventLogger> o1{ 4 };
  181. const cm::optional<EventLogger> o2{ o1 };
  182. const cm::optional<EventLogger> o3{};
  183. const cm::optional<EventLogger> o4{ o3 };
  184. expected = {
  185. { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
  186. { Event::COPY_CONSTRUCT, &*o2, &o1.value(), 4 },
  187. { Event::DESTRUCT, &*o2, nullptr, 4 },
  188. { Event::DESTRUCT, &*o1, nullptr, 4 },
  189. };
  190. return true;
  191. }
  192. static bool testMoveConstruct(std::vector<Event>& expected)
  193. {
  194. cm::optional<EventLogger> o1{ 4 };
  195. const cm::optional<EventLogger> o2{ std::move(o1) };
  196. cm::optional<EventLogger> o3{};
  197. const cm::optional<EventLogger> o4{ std::move(o3) };
  198. expected = {
  199. { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
  200. { Event::MOVE_CONSTRUCT, &*o2, &*o1, 4 },
  201. { Event::DESTRUCT, &*o2, nullptr, 4 },
  202. { Event::DESTRUCT, &*o1, nullptr, 4 },
  203. };
  204. return true;
  205. }
  206. static bool testNulloptAssign(std::vector<Event>& expected)
  207. {
  208. cm::optional<EventLogger> o1{ 4 };
  209. auto const* v1 = &*o1;
  210. o1 = cm::nullopt;
  211. cm::optional<EventLogger> o2{};
  212. o2 = cm::nullopt;
  213. expected = {
  214. { Event::VALUE_CONSTRUCT, v1, nullptr, 4 },
  215. { Event::DESTRUCT, v1, nullptr, 4 },
  216. };
  217. return true;
  218. }
  219. static bool testCopyAssign(std::vector<Event>& expected)
  220. {
  221. cm::optional<EventLogger> o1{};
  222. const cm::optional<EventLogger> o2{ 4 };
  223. auto const* v2 = &*o2;
  224. o1 = o2;
  225. auto const* v1 = &*o1;
  226. const cm::optional<EventLogger> o3{ 5 };
  227. auto const* v3 = &*o3;
  228. o1 = o3;
  229. const cm::optional<EventLogger> o4{};
  230. o1 = o4;
  231. o1 = o4; // Intentionally duplicated to test assigning an empty optional to
  232. // an empty optional
  233. expected = {
  234. { Event::VALUE_CONSTRUCT, v2, nullptr, 4 },
  235. { Event::COPY_CONSTRUCT, v1, v2, 4 },
  236. { Event::VALUE_CONSTRUCT, v3, nullptr, 5 },
  237. { Event::COPY_ASSIGN, v1, v3, 5 },
  238. { Event::DESTRUCT, v1, nullptr, 5 },
  239. { Event::DESTRUCT, v3, nullptr, 5 },
  240. { Event::DESTRUCT, v2, nullptr, 4 },
  241. };
  242. return true;
  243. }
  244. static bool testMoveAssign(std::vector<Event>& expected)
  245. {
  246. cm::optional<EventLogger> o1{};
  247. cm::optional<EventLogger> o2{ 4 };
  248. auto const* v2 = &*o2;
  249. o1 = std::move(o2);
  250. auto const* v1 = &*o1;
  251. cm::optional<EventLogger> o3{ 5 };
  252. auto const* v3 = &*o3;
  253. o1 = std::move(o3);
  254. cm::optional<EventLogger> o4{};
  255. o1 = std::move(o4);
  256. expected = {
  257. { Event::VALUE_CONSTRUCT, v2, nullptr, 4 },
  258. { Event::MOVE_CONSTRUCT, v1, v2, 4 },
  259. { Event::VALUE_CONSTRUCT, v3, nullptr, 5 },
  260. { Event::MOVE_ASSIGN, v1, v3, 5 },
  261. { Event::DESTRUCT, v1, nullptr, 5 },
  262. { Event::DESTRUCT, v3, nullptr, 5 },
  263. { Event::DESTRUCT, v2, nullptr, 4 },
  264. };
  265. return true;
  266. }
  267. static bool testPointer(std::vector<Event>& expected)
  268. {
  269. cm::optional<EventLogger> o1{ 4 };
  270. const cm::optional<EventLogger> o2{ 5 };
  271. o1->Reference();
  272. o2->Reference();
  273. expected = {
  274. { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
  275. { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
  276. { Event::REFERENCE, &*o1, nullptr, 4 },
  277. { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
  278. { Event::DESTRUCT, &*o2, nullptr, 5 },
  279. { Event::DESTRUCT, &*o1, nullptr, 4 },
  280. };
  281. return true;
  282. }
  283. #if !__GNUC__ || __GNUC__ > 4
  284. # define ALLOW_CONST_RVALUE
  285. #endif
  286. static bool testDereference(std::vector<Event>& expected)
  287. {
  288. cm::optional<EventLogger> o1{ 4 };
  289. auto const* v1 = &*o1;
  290. const cm::optional<EventLogger> o2{ 5 };
  291. auto const* v2 = &*o2;
  292. (*o1).Reference();
  293. (*o2).Reference();
  294. (*std::move(o1)).Reference();
  295. #ifdef ALLOW_CONST_RVALUE
  296. (*std::move(o2)).Reference(); // Broken in GCC 4.9.0. Sigh...
  297. #endif
  298. expected = {
  299. { Event::VALUE_CONSTRUCT, v1, nullptr, 4 },
  300. { Event::VALUE_CONSTRUCT, v2, nullptr, 5 },
  301. { Event::REFERENCE, v1, nullptr, 4 },
  302. { Event::CONST_REFERENCE, v2, nullptr, 5 },
  303. { Event::RVALUE_REFERENCE, v1, nullptr, 4 },
  304. #ifdef ALLOW_CONST_RVALUE
  305. { Event::CONST_RVALUE_REFERENCE, v2, nullptr, 5 },
  306. #endif
  307. { Event::DESTRUCT, v2, nullptr, 5 },
  308. { Event::DESTRUCT, v1, nullptr, 4 },
  309. };
  310. return true;
  311. }
  312. static bool testHasValue(std::vector<Event>& expected)
  313. {
  314. bool retval = true;
  315. const cm::optional<EventLogger> o1{ 4 };
  316. const cm::optional<EventLogger> o2{};
  317. if (!o1.has_value()) {
  318. std::cout << "o1 should have a value" << std::endl;
  319. retval = false;
  320. }
  321. if (!o1) {
  322. std::cout << "(bool)o1 should be true" << std::endl;
  323. retval = false;
  324. }
  325. if (o2.has_value()) {
  326. std::cout << "o2 should not have a value" << std::endl;
  327. retval = false;
  328. }
  329. if (o2) {
  330. std::cout << "(bool)o2 should be false" << std::endl;
  331. retval = false;
  332. }
  333. expected = {
  334. { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
  335. { Event::DESTRUCT, &*o1, nullptr, 4 },
  336. };
  337. return retval;
  338. }
  339. static bool testValue(std::vector<Event>& expected)
  340. {
  341. bool retval = true;
  342. cm::optional<EventLogger> o1{ 4 };
  343. const cm::optional<EventLogger> o2{ 5 };
  344. cm::optional<EventLogger> o3{};
  345. const cm::optional<EventLogger> o4{};
  346. o1.value().Reference();
  347. o2.value().Reference();
  348. bool thrown = false;
  349. try {
  350. (void)o3.value();
  351. } catch (cm::bad_optional_access&) {
  352. thrown = true;
  353. }
  354. if (!thrown) {
  355. std::cout << "o3.value() did not throw" << std::endl;
  356. retval = false;
  357. }
  358. thrown = false;
  359. try {
  360. (void)o4.value();
  361. } catch (cm::bad_optional_access&) {
  362. thrown = true;
  363. }
  364. if (!thrown) {
  365. std::cout << "o4.value() did not throw" << std::endl;
  366. retval = false;
  367. }
  368. expected = {
  369. { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
  370. { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
  371. { Event::REFERENCE, &*o1, nullptr, 4 },
  372. { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
  373. { Event::DESTRUCT, &*o2, nullptr, 5 },
  374. { Event::DESTRUCT, &*o1, nullptr, 4 },
  375. };
  376. return retval;
  377. }
  378. static bool testValueOr()
  379. {
  380. bool retval = true;
  381. const cm::optional<EventLogger> o1{ 4 };
  382. cm::optional<EventLogger> o2{ 5 };
  383. const cm::optional<EventLogger> o3{};
  384. cm::optional<EventLogger> o4{};
  385. EventLogger e1{ 6 };
  386. EventLogger e2{ 7 };
  387. EventLogger e3{ 8 };
  388. EventLogger e4{ 9 };
  389. EventLogger r1 = o1.value_or(e1);
  390. if (r1.Value != 4) {
  391. std::cout << "r1.Value should be 4" << std::endl;
  392. retval = false;
  393. }
  394. EventLogger r2 = std::move(o2).value_or(e2);
  395. if (r2.Value != 5) {
  396. std::cout << "r2.Value should be 5" << std::endl;
  397. retval = false;
  398. }
  399. EventLogger r3 = o3.value_or(e3);
  400. if (r3.Value != 8) {
  401. std::cout << "r3.Value should be 8" << std::endl;
  402. retval = false;
  403. }
  404. EventLogger r4 = std::move(o4).value_or(e4);
  405. if (r4.Value != 9) {
  406. std::cout << "r4.Value should be 9" << std::endl;
  407. retval = false;
  408. }
  409. return retval;
  410. }
  411. static bool testSwap(std::vector<Event>& expected)
  412. {
  413. bool retval = true;
  414. cm::optional<EventLogger> o1{ 4 };
  415. auto const* v1 = &*o1;
  416. cm::optional<EventLogger> o2{};
  417. o1.swap(o2);
  418. auto const* v2 = &*o2;
  419. if (o1.has_value()) {
  420. std::cout << "o1 should not have value" << std::endl;
  421. retval = false;
  422. }
  423. if (!o2.has_value()) {
  424. std::cout << "o2 should have value" << std::endl;
  425. retval = false;
  426. }
  427. if (o2.value().Value != 4) {
  428. std::cout << "value of o2 should be 4" << std::endl;
  429. retval = false;
  430. }
  431. o1.swap(o2);
  432. if (!o1.has_value()) {
  433. std::cout << "o1 should have value" << std::endl;
  434. retval = false;
  435. }
  436. if (o1.value().Value != 4) {
  437. std::cout << "value of o1 should be 4" << std::endl;
  438. retval = false;
  439. }
  440. if (o2.has_value()) {
  441. std::cout << "o2 should not have value" << std::endl;
  442. retval = false;
  443. }
  444. o2.emplace(5);
  445. o1.swap(o2);
  446. if (!o1.has_value()) {
  447. std::cout << "o1 should have value" << std::endl;
  448. retval = false;
  449. }
  450. if (o1.value().Value != 5) {
  451. std::cout << "value of o1 should be 5" << std::endl;
  452. retval = false;
  453. }
  454. if (!o2.has_value()) {
  455. std::cout << "o2 should not have value" << std::endl;
  456. retval = false;
  457. }
  458. if (o2.value().Value != 4) {
  459. std::cout << "value of o2 should be 4" << std::endl;
  460. retval = false;
  461. }
  462. o1.reset();
  463. o2.reset();
  464. o1.swap(o2);
  465. if (o1.has_value()) {
  466. std::cout << "o1 should not have value" << std::endl;
  467. retval = false;
  468. }
  469. if (o2.has_value()) {
  470. std::cout << "o2 should not have value" << std::endl;
  471. retval = false;
  472. }
  473. expected = {
  474. { Event::VALUE_CONSTRUCT, v1, nullptr, 4 },
  475. { Event::MOVE_CONSTRUCT, v2, v1, 4 },
  476. { Event::DESTRUCT, v1, nullptr, 4 },
  477. { Event::MOVE_CONSTRUCT, v1, v2, 4 },
  478. { Event::DESTRUCT, v2, nullptr, 4 },
  479. { Event::VALUE_CONSTRUCT, v2, nullptr, 5 },
  480. { Event::SWAP, v1, v2, 5 },
  481. { Event::DESTRUCT, v1, nullptr, 5 },
  482. { Event::DESTRUCT, v2, nullptr, 4 },
  483. };
  484. return retval;
  485. }
  486. static bool testReset(std::vector<Event>& expected)
  487. {
  488. bool retval = true;
  489. cm::optional<EventLogger> o{ 4 };
  490. auto const* v = &*o;
  491. o.reset();
  492. if (o.has_value()) {
  493. std::cout << "o should not have value" << std::endl;
  494. retval = false;
  495. }
  496. o.reset();
  497. expected = {
  498. { Event::VALUE_CONSTRUCT, v, nullptr, 4 },
  499. { Event::DESTRUCT, v, nullptr, 4 },
  500. };
  501. return retval;
  502. }
  503. static bool testEmplace(std::vector<Event>& expected)
  504. {
  505. cm::optional<EventLogger> o{ 4 };
  506. o.emplace(5);
  507. o.reset();
  508. o.emplace();
  509. expected = {
  510. { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
  511. { Event::DESTRUCT, &*o, nullptr, 4 },
  512. { Event::VALUE_CONSTRUCT, &*o, nullptr, 5 },
  513. { Event::DESTRUCT, &*o, nullptr, 5 },
  514. { Event::DEFAULT_CONSTRUCT, &*o, nullptr, 0 },
  515. { Event::DESTRUCT, &*o, nullptr, 0 },
  516. };
  517. return true;
  518. }
  519. static bool testMakeOptional(std::vector<Event>& expected)
  520. {
  521. EventLogger e{ 4 };
  522. cm::optional<EventLogger> o1 = cm::make_optional<EventLogger>(e);
  523. cm::optional<EventLogger> o2 = cm::make_optional<EventLogger>(5);
  524. expected = {
  525. { Event::VALUE_CONSTRUCT, &e, nullptr, 4 },
  526. { Event::COPY_CONSTRUCT, &*o1, &e, 4 },
  527. { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
  528. { Event::DESTRUCT, &*o2, nullptr, 5 },
  529. { Event::DESTRUCT, &*o1, nullptr, 4 },
  530. { Event::DESTRUCT, &e, nullptr, 4 },
  531. };
  532. return true;
  533. }
  534. static bool testMemoryRange(std::vector<Event>& expected)
  535. {
  536. bool retval = true;
  537. cm::optional<EventLogger> o{ 4 };
  538. auto* ostart = &o;
  539. auto* oend = ostart + 1;
  540. auto* estart = &o.value();
  541. auto* eend = estart + 1;
  542. if (static_cast<void*>(estart) < static_cast<void*>(ostart) ||
  543. static_cast<void*>(eend) > static_cast<void*>(oend)) {
  544. std::cout << "value is not within memory range of optional" << std::endl;
  545. retval = false;
  546. }
  547. expected = {
  548. { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
  549. { Event::DESTRUCT, &*o, nullptr, 4 },
  550. };
  551. return retval;
  552. }
  553. int testOptional(int /*unused*/, char* /*unused*/ [])
  554. {
  555. int retval = 0;
  556. #define DO_EVENT_TEST(name) \
  557. do { \
  558. events.clear(); \
  559. std::vector<Event> expected; \
  560. if (!name(expected)) { \
  561. std::cout << "in " #name << std::endl; \
  562. retval = 1; \
  563. } else if (expected != events) { \
  564. std::cout << #name " did not produce expected events" << std::endl; \
  565. retval = 1; \
  566. } \
  567. } while (0)
  568. #define DO_TEST(name) \
  569. do { \
  570. if (!name()) { \
  571. std::cout << "in " #name << std::endl; \
  572. retval = 1; \
  573. } \
  574. } while (0)
  575. DO_EVENT_TEST(testDefaultConstruct);
  576. DO_EVENT_TEST(testNulloptConstruct);
  577. DO_EVENT_TEST(testValueConstruct);
  578. DO_EVENT_TEST(testInPlaceConstruct);
  579. DO_EVENT_TEST(testCopyConstruct);
  580. DO_EVENT_TEST(testMoveConstruct);
  581. DO_EVENT_TEST(testNulloptAssign);
  582. DO_EVENT_TEST(testCopyAssign);
  583. DO_EVENT_TEST(testMoveAssign);
  584. DO_EVENT_TEST(testPointer);
  585. DO_EVENT_TEST(testDereference);
  586. DO_EVENT_TEST(testHasValue);
  587. DO_EVENT_TEST(testValue);
  588. DO_TEST(testValueOr);
  589. DO_EVENT_TEST(testSwap);
  590. DO_EVENT_TEST(testReset);
  591. DO_EVENT_TEST(testEmplace);
  592. DO_EVENT_TEST(testMakeOptional);
  593. DO_EVENT_TEST(testMemoryRange);
  594. return retval;
  595. }