expected-pass.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015
  1. //! \file test_expected.cpp
  2. // Copyright Pierre Talbot 2013.
  3. // Copyright Vicente J. Botet Escriba 2013,2014.
  4. // Use, modification and distribution are subject to the
  5. // Boost Software License, Version 1.0.
  6. //(See accompanying file LICENSE_1_0.txt
  7. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. // Notes by ned:
  9. // Original is at https://github.com/viboes/std-make/blob/master/test/expected/expected_pass.cpp
  10. // This edition modified to use result with throw_bad_result_access policy
  11. // Quite a lot of the test suite I had to disable, not because our Expected implementation is
  12. // incorrect, but because the reference test suite is testing an Expected quite far away from
  13. // the latest WG21 proposal paper, and we're implementing that latest edition.
  14. #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 7
  15. #include <utility>
  16. #include <boost/outcome/iostream_support.hpp>
  17. #include <boost/outcome/std_result.hpp>
  18. #define QUICKCPPLIB_BOOST_UNIT_TEST_CUSTOM_MAIN_DEFINED
  19. #include <boost/test/unit_test.hpp>
  20. #include <boost/test/unit_test_monitor.hpp>
  21. #define JASEL_NORETURN
  22. #ifndef BOOST_TEST
  23. #define BOOST_TEST(expr) BOOST_CHECK(expr)
  24. #endif
  25. #ifndef BOOST_TEST_EQ
  26. #define BOOST_TEST_EQ(a, b) BOOST_CHECK_EQUAL((a), (b))
  27. #endif
  28. #ifndef BOOST_TEST_THROWS
  29. #define BOOST_TEST_THROWS(expr, ex) BOOST_CHECK_THROW((expr), ex)
  30. #endif
  31. #ifndef BOOST_CONSTEXPR
  32. #define BOOST_CONSTEXPR constexpr
  33. #endif
  34. #ifdef _MSC_VER
  35. #pragma warning(disable : 4127) // conditional expression is constant
  36. #pragma warning(disable : 4244) // conversion from int to short
  37. #endif
  38. namespace stde
  39. {
  40. #if __cplusplus >= 201700 || _HAS_CXX17
  41. using in_place_t = std::in_place_t;
  42. using std::in_place;
  43. #else
  44. struct in_place_t
  45. {
  46. explicit in_place_t() = default;
  47. };
  48. constexpr in_place_t in_place{};
  49. #endif
  50. //! [expected_implementation]
  51. /* Here is a fairly conforming implementation of P0323R3 `expected<T, E>` using `checked<T, E>`.
  52. It passes the reference test suite for P0323R3 at
  53. https://github.com/viboes/std-make/blob/master/test/expected/expected_pass.cpp with modifications
  54. only to move the test much closer to the P0323R3 Expected, as the reference test suite is for a
  55. much older proposed Expected.
  56. Known differences from P0323R3 in this implementation:
  57. - `T` and `E` cannot be the same type.
  58. - No variant storage is implemented.
  59. */
  60. namespace detail
  61. {
  62. template <class T, class E> using expected_result = BOOST_OUTCOME_V2_NAMESPACE::checked<T, E>;
  63. template <class T, class E> struct enable_default_constructor : public expected_result<T, E>
  64. {
  65. using base = expected_result<T, E>;
  66. using base::base;
  67. constexpr enable_default_constructor()
  68. : base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>}
  69. {
  70. }
  71. };
  72. template <class T, class E> using select_expected_base = std::conditional_t<std::is_default_constructible<T>::value, enable_default_constructor<T, E>, expected_result<T, E>>;
  73. } // namespace detail
  74. template <class T, class E> class expected : public detail::select_expected_base<T, E>
  75. {
  76. static_assert(!std::is_same<T, E>::value, "T and E cannot be the same in this expected implementation");
  77. using base = detail::select_expected_base<T, E>;
  78. public:
  79. // Inherit base's constructors
  80. using base::base;
  81. expected() = default;
  82. // Expected takes in_place not in_place_type
  83. template <class... Args>
  84. constexpr explicit expected(in_place_t /*unused*/, Args &&... args)
  85. : base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>, std::forward<Args>(args)...}
  86. {
  87. }
  88. // Expected always accepts a T even if ambiguous
  89. BOOST_OUTCOME_TEMPLATE(class U)
  90. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(std::is_constructible<T, U>::value))
  91. constexpr expected(U &&v) // NOLINT
  92. : base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>, std::forward<U>(v)}
  93. {
  94. }
  95. // Expected has an emplace() modifier
  96. template <class... Args> void emplace(Args &&... args) { *static_cast<base *>(this) = base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>, std::forward<Args>(args)...}; }
  97. // Expected has a narrow operator* and operator->
  98. constexpr const T &operator*() const & { return base::assume_value(); }
  99. constexpr T &operator*() & { return base::assume_value(); }
  100. constexpr const T &&operator*() const && { return base::assume_value(); }
  101. constexpr T &&operator*() && { return base::assume_value(); }
  102. constexpr const T *operator->() const { return &base::assume_value(); }
  103. constexpr T *operator->() { return &base::assume_value(); }
  104. // Expected has a narrow error() observer
  105. constexpr const E &error() const & { return base::assume_error(); }
  106. constexpr E &error() & { return base::assume_error(); }
  107. constexpr const E &&error() const && { return base::assume_error(); }
  108. constexpr E &error() && { return base::assume_error(); }
  109. };
  110. template <class E> class expected<void, E> : public BOOST_OUTCOME_V2_NAMESPACE::result<void, E, BOOST_OUTCOME_V2_NAMESPACE::policy::throw_bad_result_access<E, void>>
  111. {
  112. using base = BOOST_OUTCOME_V2_NAMESPACE::result<void, E, BOOST_OUTCOME_V2_NAMESPACE::policy::throw_bad_result_access<E, void>>;
  113. public:
  114. // Inherit base constructors
  115. using base::base;
  116. // Expected has a narrow operator* and operator->
  117. constexpr void operator*() const { base::assume_value(); }
  118. constexpr void operator->() const { base::assume_value(); }
  119. };
  120. template <class E> using unexpected = BOOST_OUTCOME_V2_NAMESPACE::failure_type<E>;
  121. template <class E> unexpected<E> make_unexpected(E &&arg) { return BOOST_OUTCOME_V2_NAMESPACE::failure<E>(std::forward<E>(arg)); }
  122. template <class E, class... Args> unexpected<E> make_unexpected(Args &&... args) { return BOOST_OUTCOME_V2_NAMESPACE::failure<E>(std::forward<Args>(args)...); }
  123. template <class E> using bad_expected_access = BOOST_OUTCOME_V2_NAMESPACE::bad_result_access_with<E>;
  124. //! [expected_implementation]
  125. // Not actually part of the Expected proposal, but needed to pass the test
  126. template <typename T> using exception_or = expected<T, std::exception_ptr>;
  127. } // namespace stde
  128. template <class T> using expected_sc = stde::expected<T, std::error_code>;
  129. struct NoDefaultConstructible
  130. {
  131. NoDefaultConstructible() = delete;
  132. NoDefaultConstructible(int /*unused*/) {} // NOLINT
  133. };
  134. struct NoCopyConstructible
  135. {
  136. NoCopyConstructible() = default;
  137. NoCopyConstructible(NoCopyConstructible const &) = delete;
  138. NoCopyConstructible(NoCopyConstructible &&) noexcept = default;
  139. };
  140. struct NoMoveConstructible
  141. {
  142. NoMoveConstructible() = default;
  143. NoMoveConstructible(NoMoveConstructible const &) noexcept = default;
  144. NoMoveConstructible(NoMoveConstructible &&) = delete;
  145. NoMoveConstructible &operator=(NoMoveConstructible const &) noexcept = default;
  146. NoMoveConstructible &operator=(NoMoveConstructible &&) = delete;
  147. };
  148. enum State
  149. {
  150. sDefaultConstructed,
  151. sValueCopyConstructed,
  152. sValueMoveConstructed,
  153. sCopyConstructed,
  154. sMoveConstructed,
  155. sMoveAssigned,
  156. sCopyAssigned,
  157. sValueCopyAssigned,
  158. sValueMoveAssigned,
  159. sMovedFrom,
  160. sValueConstructed
  161. };
  162. struct OracleVal
  163. {
  164. State s{sValueConstructed};
  165. int i;
  166. constexpr OracleVal(int i_ = 0) // NOLINT
  167. : i(i_)
  168. {
  169. }
  170. };
  171. struct Oracle
  172. {
  173. State s{sDefaultConstructed};
  174. OracleVal val;
  175. Oracle() = default;
  176. Oracle(const OracleVal &v) // NOLINT
  177. : s(sValueCopyConstructed),
  178. val(v)
  179. {
  180. }
  181. Oracle(OracleVal &&v) noexcept : s(sValueMoveConstructed), val(v) { v.s = sMovedFrom; } // NOLINT
  182. Oracle(const Oracle &o)
  183. : s(sCopyConstructed)
  184. , val(o.val)
  185. {
  186. }
  187. Oracle(Oracle &&o) noexcept : s(sMoveConstructed), val(std::move(o.val)) { o.s = sMovedFrom; } // NOLINT
  188. Oracle &operator=(const OracleVal &v)
  189. {
  190. s = sValueCopyConstructed;
  191. val = v;
  192. return *this;
  193. }
  194. Oracle &operator=(OracleVal &&v) noexcept
  195. {
  196. s = sValueMoveConstructed;
  197. val = std::move(v); // NOLINT
  198. v.s = sMovedFrom;
  199. return *this;
  200. }
  201. Oracle &operator=(const Oracle &o)
  202. {
  203. s = sCopyConstructed;
  204. val = o.val;
  205. return *this;
  206. }
  207. Oracle &operator=(Oracle &&o) noexcept
  208. {
  209. s = sMoveConstructed;
  210. val = std::move(o.val); // NOLINT
  211. o.s = sMovedFrom;
  212. return *this;
  213. }
  214. };
  215. struct Guard
  216. {
  217. std::string val;
  218. Guard() = default;
  219. explicit Guard(std::string s, int /*unused*/ = 0)
  220. : val(std::move(s))
  221. {
  222. }
  223. Guard(const Guard &) = delete;
  224. Guard(Guard &&) = delete;
  225. void operator=(const Guard &) = delete;
  226. void operator=(Guard &&) = delete;
  227. };
  228. struct ExplicitStr
  229. {
  230. std::string s;
  231. explicit ExplicitStr(const char *chp)
  232. : s(chp)
  233. {
  234. }
  235. };
  236. struct Date
  237. {
  238. int i;
  239. Date() = delete;
  240. Date(int i_) noexcept : i{i_} {} // NOLINT
  241. Date(Date &&d) noexcept : i(d.i) { d.i = 0; }
  242. Date(const Date &) = delete;
  243. Date &operator=(const Date &) = delete;
  244. Date &operator=(Date &&d) noexcept
  245. {
  246. i = d.i;
  247. d.i = 0;
  248. return *this;
  249. }
  250. };
  251. struct TExcept
  252. {
  253. int i;
  254. TExcept() = delete;
  255. TExcept(int i_) // NOLINT
  256. : i{i_}
  257. {
  258. }
  259. TExcept(TExcept &&d)
  260. : i(d.i)
  261. {
  262. d.i = 0;
  263. }
  264. TExcept(const TExcept &) = delete;
  265. TExcept &operator=(const TExcept &) = delete;
  266. TExcept &operator=(TExcept &&d)
  267. {
  268. i = d.i;
  269. d.i = 0;
  270. return *this;
  271. }
  272. };
  273. template <class T> struct MoveAware
  274. {
  275. T val;
  276. bool moved;
  277. MoveAware(T val_) // NOLINT
  278. : val(val_),
  279. moved(false)
  280. {
  281. }
  282. MoveAware(MoveAware const &) = delete;
  283. MoveAware(MoveAware &&rhs)
  284. : val(rhs.val)
  285. , moved(rhs.moved)
  286. {
  287. rhs.moved = true;
  288. }
  289. MoveAware &operator=(MoveAware const &) = delete;
  290. MoveAware &operator=(MoveAware &&rhs)
  291. {
  292. val = (rhs.val);
  293. moved = (rhs.moved);
  294. rhs.moved = true;
  295. return *this;
  296. }
  297. };
  298. struct OverloadedAddressOf
  299. {
  300. OverloadedAddressOf() = default;
  301. OverloadedAddressOf *operator&() const { return nullptr; }
  302. };
  303. // using namespace boost;
  304. // using namespace boost::functional;
  305. class test_exception : public std::exception
  306. {
  307. };
  308. int throwing_fun()
  309. {
  310. throw test_exception();
  311. }
  312. int nothrowing_fun()
  313. {
  314. return 4;
  315. }
  316. JASEL_NORETURN void void_throwing_fun()
  317. {
  318. throw test_exception();
  319. }
  320. void do_nothing_fun()
  321. {
  322. }
  323. void except_default_constructor()
  324. {
  325. // From value constructor.
  326. expected_sc<int> e{};
  327. try
  328. {
  329. int i = e.value();
  330. (void) i;
  331. BOOST_TEST(true);
  332. }
  333. catch(...)
  334. {
  335. BOOST_TEST(false);
  336. };
  337. BOOST_TEST(e.has_value());
  338. BOOST_TEST(e);
  339. BOOST_TEST(static_cast<bool>(e));
  340. }
  341. void except_default_constructor_error_code()
  342. {
  343. // From value constructor.
  344. stde::expected<int, std::error_code> e;
  345. BOOST_TEST(e.has_value());
  346. BOOST_TEST(e);
  347. BOOST_TEST(static_cast<bool>(e));
  348. }
  349. void except_default_constructor_constexpr()
  350. {
  351. // From value constructor.
  352. BOOST_CONSTEXPR stde::expected<int, long> e;
  353. BOOST_TEST(e.has_value());
  354. }
  355. void expected_from_value()
  356. {
  357. // using T = int;
  358. using E = std::error_code;
  359. // static_assert(noexcept(stde::adl::swap_impl(std::declval<T &>(), std::declval<T &>())), "");
  360. static_assert(std::is_nothrow_copy_constructible<E>::value, "");
  361. // static_assert(noexcept(stde::adl::swap_impl(std::declval<E &>(), std::declval<E &>())), "");
  362. static_assert(std::is_nothrow_copy_constructible<expected_sc<int>>::value, "");
  363. static_assert(std::is_nothrow_copy_assignable<expected_sc<int>>::value, "");
  364. static_assert(std::is_nothrow_move_constructible<expected_sc<int>>::value, "");
  365. static_assert(std::is_nothrow_move_assignable<expected_sc<int>>::value, "");
  366. // From value constructor.
  367. expected_sc<int> e(5);
  368. // BOOST_REQUIRE_NO_THROW(e.value());
  369. BOOST_TEST_EQ(e.value(), 5);
  370. BOOST_TEST_EQ(*e, 5);
  371. BOOST_TEST(e.has_value());
  372. BOOST_TEST(static_cast<bool>(e));
  373. }
  374. void expected_from_value2()
  375. {
  376. // From value constructor.
  377. expected_sc<int> e(5);
  378. e = {};
  379. BOOST_TEST(e.has_value());
  380. BOOST_TEST_EQ(e.value(), 0);
  381. }
  382. void expected_from_cnv_value()
  383. {
  384. OracleVal v;
  385. expected_sc<Oracle> e(v);
  386. // BOOST_REQUIRE_NO_THROW(e.value());
  387. BOOST_TEST(!!e);
  388. BOOST_TEST(e.has_value());
  389. BOOST_TEST(bool(e));
  390. BOOST_TEST_EQ(e.value().s, sValueCopyConstructed);
  391. BOOST_TEST_EQ(v.s, sValueConstructed);
  392. expected_sc<Oracle> e2(std::move(v)); // NOLINT
  393. // BOOST_REQUIRE_NO_THROW(e2.value());
  394. BOOST_TEST(!!e2);
  395. BOOST_TEST(e2.has_value());
  396. BOOST_TEST(bool(e2));
  397. BOOST_TEST_EQ(e2.value().s, sValueMoveConstructed);
  398. BOOST_TEST_EQ(v.s, sMovedFrom);
  399. }
  400. struct NDCE // no default constructor
  401. { // (no default date exists)
  402. explicit NDCE(int /*unused*/) {}
  403. };
  404. void except_constructor_NDCE()
  405. {
  406. expected_sc<NDCE> e{NDCE{1}};
  407. BOOST_TEST(e.has_value());
  408. }
  409. struct NDC // no default constructor
  410. { // (no default date exists)
  411. NDC(int /*unused*/) {} // NOLINT
  412. };
  413. void except_constructor_NDC()
  414. {
  415. static_assert(std::is_nothrow_copy_constructible<expected_sc<NDC>>::value, "");
  416. static_assert(std::is_nothrow_copy_assignable<expected_sc<NDC>>::value, "");
  417. static_assert(std::is_nothrow_move_constructible<expected_sc<NDC>>::value, "");
  418. static_assert(std::is_nothrow_move_assignable<expected_sc<NDC>>::value, "");
  419. expected_sc<NDC> e{1};
  420. BOOST_TEST(e.has_value());
  421. }
  422. void except_constructor_Date()
  423. {
  424. static_assert(std::is_nothrow_move_constructible<expected_sc<Date>>::value, "");
  425. static_assert(std::is_nothrow_move_assignable<expected_sc<Date>>::value, "");
  426. expected_sc<Date> e{Date{1}};
  427. BOOST_TEST(e.has_value());
  428. }
  429. void except_constructor_TExcept()
  430. {
  431. static_assert(!std::is_nothrow_move_constructible<expected_sc<TExcept>>::value, "");
  432. static_assert(!std::is_nothrow_move_assignable<expected_sc<TExcept>>::value, "");
  433. expected_sc<TExcept> e{TExcept{1}};
  434. BOOST_TEST(e.has_value());
  435. }
  436. void expected_from_in_place_value()
  437. {
  438. OracleVal v;
  439. expected_sc<Oracle> e{stde::in_place, v};
  440. // BOOST_REQUIRE_NO_THROW(e.value());
  441. BOOST_TEST(!!e);
  442. BOOST_TEST(e.has_value());
  443. BOOST_TEST(bool(e));
  444. BOOST_TEST_EQ(e.value().s, sValueCopyConstructed);
  445. BOOST_TEST_EQ(v.s, sValueConstructed);
  446. expected_sc<Oracle> e2{stde::in_place, std::move(v)}; // NOLINT
  447. // BOOST_REQUIRE_NO_THROW(e2.value());
  448. BOOST_TEST(!!e2);
  449. BOOST_TEST(e2.has_value());
  450. BOOST_TEST(bool(e2));
  451. BOOST_TEST_EQ(e2.value().s, sValueMoveConstructed);
  452. BOOST_TEST_EQ(v.s, sMovedFrom);
  453. }
  454. #if 0
  455. void expected_from_exception()
  456. {
  457. // From stde::unexpected constructor.
  458. stde::exception_or<int> e(stde::make_unexpected(test_exception()));
  459. BOOST_TEST_THROWS(e.value(), test_exception);
  460. BOOST_TEST_EQ(e.has_value(), false);
  461. BOOST_TEST_EQ(static_cast<bool>(e), false);
  462. }
  463. #endif
  464. void expected_from_copy_value()
  465. {
  466. // From copy constructor.
  467. expected_sc<int> ef(5);
  468. expected_sc<int> e(ef);
  469. // BOOST_REQUIRE_NO_THROW(e.value());
  470. BOOST_TEST_EQ(e.value(), 5);
  471. BOOST_TEST_EQ(*e, 5);
  472. BOOST_TEST(e.has_value());
  473. BOOST_TEST(static_cast<bool>(e));
  474. }
  475. #if 0
  476. void expected_from_copy_exception()
  477. {
  478. // From stde::unexpected constructor.
  479. stde::exception_or<int> ef(stde::make_unexpected(test_exception()));
  480. stde::exception_or<int> e(ef);
  481. BOOST_TEST_THROWS(e.value(), test_exception);
  482. BOOST_TEST_EQ(e.has_value(), false);
  483. BOOST_TEST_EQ(static_cast<bool>(e), false);
  484. }
  485. #endif
  486. void expected_from_in_place()
  487. {
  488. // From stde::in_place constructor.
  489. expected_sc<std::string> e(stde::in_place, "stde::in_place");
  490. // BOOST_REQUIRE_NO_THROW(e.value());
  491. BOOST_TEST_EQ(e.value(), "stde::in_place");
  492. BOOST_TEST_EQ(*e, "stde::in_place");
  493. BOOST_TEST(e.has_value());
  494. BOOST_TEST(static_cast<bool>(e));
  495. }
  496. #if 0
  497. void expected_from_exception_ptr()
  498. {
  499. // From exception_ptr constructor.
  500. stde::exception_or<int> e(stde::make_unexpected(std::make_exception_ptr(test_exception())));
  501. BOOST_TEST_THROWS(e.value(), test_exception);
  502. BOOST_TEST_EQ(e.has_value(), false);
  503. BOOST_TEST_EQ(static_cast<bool>(e), false);
  504. }
  505. #endif
  506. void expected_from_moved_value()
  507. {
  508. // From move value constructor.
  509. std::string value = "my value";
  510. expected_sc<std::string> e = std::move(value);
  511. // BOOST_REQUIRE_NO_THROW(e.value());
  512. BOOST_TEST_EQ(e.value(), "my value");
  513. BOOST_TEST_EQ(*e, "my value");
  514. BOOST_TEST(e.has_value());
  515. BOOST_TEST(static_cast<bool>(e));
  516. }
  517. void expected_from_catch_block()
  518. {
  519. // From catch block
  520. try
  521. {
  522. throw test_exception();
  523. }
  524. catch(...)
  525. {
  526. stde::exception_or<int> e(stde::make_unexpected(std::current_exception()));
  527. BOOST_TEST_THROWS(e.value(), std::exception);
  528. BOOST_TEST_EQ(e.has_value(), false);
  529. BOOST_TEST_EQ(static_cast<bool>(e), false);
  530. }
  531. }
  532. void make_expected_E_from_value()
  533. {
  534. // auto e = stde::make_expected<std::string>( 5 );
  535. // BOOST_TEST_EQ(e.has_value(), false);
  536. }
  537. void make_expected_const_from_value()
  538. {
  539. #if defined __clang__ && __clang_major__ >= 4 && __cplusplus > 201402L
  540. const int i = 0;
  541. auto e = expected_sc<const int>(i);
  542. (void) e;
  543. // static_assert(std::is_same<decltype(e), stde::success<const int>>::value, "");
  544. #endif
  545. }
  546. void make_expected_from_U_value()
  547. {
  548. expected_sc<int> e = expected_sc<int>(short(5));
  549. static_assert(std::is_same<decltype(e), expected_sc<int>>{}, "");
  550. BOOST_TEST_EQ(e.has_value(), true);
  551. }
  552. void make_expected_from_U_value2()
  553. {
  554. expected_sc<std::string> e = expected_sc<std::string>("aa");
  555. static_assert(std::is_same<decltype(e), expected_sc<std::string>>{}, "");
  556. BOOST_TEST_EQ(e.has_value(), true);
  557. }
  558. void expected_from_value_error_condition()
  559. {
  560. // From value constructor.
  561. stde::expected<int, std::error_condition> e(5);
  562. // BOOST_REQUIRE_NO_THROW(e.value());
  563. BOOST_TEST_EQ(e.value(), 5);
  564. BOOST_TEST_EQ(*e, 5);
  565. BOOST_TEST(e.has_value());
  566. BOOST_TEST(static_cast<bool>(e));
  567. }
  568. void expected_from_error_error_condition()
  569. {
  570. // From stde::unexpected constructor.
  571. stde::expected<int, std::error_condition> e(stde::make_unexpected<std::error_condition>(std::make_error_condition(std::errc::invalid_argument)));
  572. auto error_from_except_check = [](const stde::bad_expected_access<std::error_condition> &except) { return std::errc(except.error().value()) == std::errc::invalid_argument; };
  573. try
  574. {
  575. (void) e.value();
  576. }
  577. catch(stde::bad_expected_access<std::error_condition> &ex)
  578. {
  579. BOOST_TEST(error_from_except_check(ex));
  580. }
  581. BOOST_TEST_EQ(e.has_value(), false);
  582. BOOST_TEST_EQ(static_cast<bool>(e), false);
  583. }
  584. void expected_from_error_convertible()
  585. {
  586. {
  587. stde::expected<int, short> e1 = stde::make_unexpected<short>(1);
  588. stde::expected<int, long> e2(e1);
  589. BOOST_TEST_EQ(e2.has_value(), false);
  590. BOOST_TEST_EQ(static_cast<bool>(e2), false);
  591. BOOST_TEST_EQ(e2.error(), 1);
  592. }
  593. {
  594. stde::expected<void, short> e1 = stde::make_unexpected<short>(1);
  595. stde::expected<void, int> e2(e1);
  596. BOOST_TEST_EQ(e2.has_value(), false);
  597. BOOST_TEST_EQ(static_cast<bool>(e2), false);
  598. BOOST_TEST_EQ(e2.error(), 1);
  599. }
  600. }
  601. void except_valid_constexpr_int()
  602. {
  603. // From value constructor.
  604. BOOST_CONSTEXPR stde::expected<int, long> e;
  605. BOOST_CONSTEXPR bool b = e.has_value();
  606. BOOST_TEST(b);
  607. }
  608. void except_value_constexpr_int()
  609. {
  610. // From value constructor.
  611. BOOST_CONSTEXPR stde::expected<int, long> e(1);
  612. BOOST_CONSTEXPR int x = e.value();
  613. BOOST_TEST_EQ(x, 1);
  614. }
  615. void expected_from_value3()
  616. {
  617. expected_sc<int> e(5);
  618. BOOST_TEST_EQ(e.value(), 5);
  619. // From value assignment.
  620. e = 8;
  621. // BOOST_REQUIRE_NO_THROW(e.value());
  622. BOOST_TEST_EQ(e.value(), 8);
  623. BOOST_TEST_EQ(*e, 8);
  624. BOOST_TEST(e.has_value());
  625. BOOST_TEST(static_cast<bool>(e));
  626. }
  627. void expected_from_copy_expected()
  628. {
  629. expected_sc<int> e(5);
  630. expected_sc<int> e2(8);
  631. // From value assignment.
  632. e = e2;
  633. // BOOST_REQUIRE_NO_THROW(e.value());
  634. BOOST_TEST_EQ(e.value(), 8);
  635. BOOST_TEST_EQ(*e, 8);
  636. BOOST_TEST(e.has_value());
  637. BOOST_TEST(static_cast<bool>(e));
  638. }
  639. void expected_from_moved_expected()
  640. {
  641. expected_sc<std::string> e("e");
  642. expected_sc<std::string> e2("e2");
  643. // From value assignment.
  644. e = std::move(e2);
  645. // BOOST_REQUIRE_NO_THROW(e.value());
  646. BOOST_TEST_EQ(e.value(), "e2");
  647. BOOST_TEST_EQ(*e, "e2");
  648. BOOST_TEST(e.has_value());
  649. BOOST_TEST(static_cast<bool>(e));
  650. // BOOST_REQUIRE_NO_THROW(e2.value());
  651. #ifndef __GLIBBOOST_OUTCOME_C__
  652. BOOST_TEST_EQ(e2.value(), "");
  653. BOOST_TEST_EQ(*e2, "");
  654. #endif
  655. BOOST_TEST(e2.has_value());
  656. BOOST_TEST(static_cast<bool>(e2));
  657. }
  658. void expected_from_in_place2()
  659. {
  660. // From stde::in_place constructor.
  661. expected_sc<std::string> e(stde::in_place, "stde::in_place");
  662. BOOST_TEST_EQ(e.value(), "stde::in_place");
  663. // From emplace method.
  664. e.emplace("emplace method");
  665. // BOOST_REQUIRE_NO_THROW(e.value());
  666. BOOST_TEST_EQ(e.value(), "emplace method");
  667. BOOST_TEST_EQ(*e, "emplace method");
  668. BOOST_TEST(e.has_value());
  669. BOOST_TEST(static_cast<bool>(e));
  670. }
  671. void expected_from_move_value()
  672. {
  673. expected_sc<std::string> e("v");
  674. std::string value = "my value";
  675. // From assignment operator.
  676. e = std::move(value);
  677. // BOOST_REQUIRE_NO_THROW(e.value());
  678. BOOST_TEST_EQ(e.value(), "my value");
  679. BOOST_TEST_EQ(*e, "my value");
  680. BOOST_TEST(e.has_value());
  681. BOOST_TEST(static_cast<bool>(e));
  682. }
  683. void expected_from_in_place3()
  684. {
  685. // From stde::in_place factory.
  686. // auto e = stde::make_expected<std::string>("stde::in_place");
  687. auto e = expected_sc<std::string>("stde::in_place");
  688. // BOOST_REQUIRE_NO_THROW(e.value());
  689. BOOST_TEST_EQ(e.value(), "stde::in_place");
  690. BOOST_TEST_EQ(*e, "stde::in_place");
  691. BOOST_TEST(e.has_value());
  692. BOOST_TEST(static_cast<bool>(e));
  693. }
  694. void expected_from_in_place_error()
  695. {
  696. // From stde::in_place factory.
  697. auto e = stde::expected<std::string, std::error_condition>("stde::in_place");
  698. // BOOST_REQUIRE_NO_THROW(e.value());
  699. BOOST_TEST_EQ(e.value(), "stde::in_place");
  700. BOOST_TEST_EQ(*e, "stde::in_place");
  701. BOOST_TEST(e.has_value());
  702. BOOST_TEST(static_cast<bool>(e));
  703. }
  704. void expected_from_exception_catch()
  705. {
  706. // From catch block
  707. try
  708. {
  709. throw test_exception();
  710. }
  711. catch(...)
  712. {
  713. stde::exception_or<int> e = stde::make_unexpected(std::current_exception());
  714. BOOST_TEST_THROWS(e.value(), std::exception);
  715. BOOST_TEST_EQ(e.has_value(), false);
  716. BOOST_TEST_EQ(static_cast<bool>(e), false);
  717. }
  718. }
  719. #if 0
  720. void expected_from_error()
  721. {
  722. // From stde::unexpected constructor.
  723. auto e = stde::make_expected_from_error<int>(std::make_error_condition(std::errc::invalid_argument));
  724. auto error_from_except_check = [](const stde::bad_expected_access<std::error_condition> &except) { return std::errc(except.error().value()) == std::errc::invalid_argument; };
  725. try
  726. {
  727. (void) e.value();
  728. }
  729. catch(stde::bad_expected_access<std::error_condition> &ex)
  730. {
  731. BOOST_TEST(error_from_except_check(ex));
  732. }
  733. BOOST_TEST_EQ(e.has_value(), false);
  734. BOOST_TEST_EQ(static_cast<bool>(e), false);
  735. }
  736. void expected_from_error_U()
  737. {
  738. // From stde::unexpected constructor.
  739. auto e = stde::make_expected_from_error<int, short>(42);
  740. static_assert(std::is_same<decltype(e), stde::expected<int, short>>{}, "");
  741. BOOST_TEST_EQ(e.has_value(), false);
  742. BOOST_TEST_EQ(static_cast<bool>(e), false);
  743. }
  744. void expected_from_exception2()
  745. {
  746. // From stde::unexpected constructor.
  747. auto e = stde::make_expected_from_exception<int>(test_exception());
  748. // auto e = expected_sc<int>(stde::unexpected<>(test_exception()));
  749. BOOST_TEST_THROWS(e.value(), test_exception );
  750. BOOST_TEST_EQ(e.has_value(), false);
  751. BOOST_TEST_EQ(static_cast<bool>(e), false);
  752. }
  753. void expected_from_exception_ptr2()
  754. {
  755. // From exception_ptr constructor.
  756. auto e = stde::exception_or<int>(stde::make_unexpected(test_exception()));
  757. BOOST_TEST_THROWS(e.value(), test_exception );
  758. BOOST_TEST_EQ(e.has_value(), false);
  759. BOOST_TEST_EQ(static_cast<bool>(e), false);
  760. }
  761. void make_expected_from_call_fun()
  762. {
  763. try
  764. {
  765. stde::make_expected_from_call(throwing_fun);
  766. BOOST_TEST(true);
  767. }
  768. catch(...)
  769. {
  770. BOOST_TEST(false);
  771. }
  772. stde::exception_or<int> e = stde::make_expected_from_call(throwing_fun);
  773. BOOST_TEST_THROWS(e.value(), std::exception );
  774. BOOST_TEST_EQ(e.has_value(), false);
  775. BOOST_TEST_EQ(static_cast<bool>(e), false);
  776. e = stde::make_expected_from_call(nothrowing_fun);
  777. try
  778. {
  779. (void) e.value();
  780. BOOST_TEST(true);
  781. }
  782. catch(...)
  783. {
  784. BOOST_TEST(false);
  785. }
  786. BOOST_TEST_EQ(e.value(), 4);
  787. BOOST_TEST_EQ(*e, 4);
  788. BOOST_TEST_EQ(e.has_value(), true);
  789. BOOST_TEST_EQ(static_cast<bool>(e), true);
  790. #if 0
  791. BOOST_TEST_THROWS(stde::make_expected_from_call<std::error_condition>(throwing_fun), test_exception);
  792. BOOST_TEST_NO_THROW(stde::make_expected_from_call<std::error_condition>(nothrowing_fun));
  793. stde::expected<int, std::error_condition> e2 = stde::make_expected_from_call<std::error_condition>(nothrowing_fun);
  794. BOOST_TEST_NO_THROW(e2.value());
  795. BOOST_TEST_EQ(e2.value(), 4);
  796. BOOST_TEST_EQ(*e2, 4);
  797. BOOST_TEST_EQ(e2.has_value(), true);
  798. BOOST_TEST_EQ(static_cast<bool>(e2), true);
  799. #endif
  800. }
  801. void make_expected_from_call_void_fun()
  802. {
  803. #if 0
  804. BOOST_TEST_NO_THROW(stde::make_expected_from_call(void_throwing_fun));
  805. expected_sc<void> e = stde::make_expected_from_call(void_throwing_fun);
  806. BOOST_TEST_THROWS(e.value(), std::exception);
  807. BOOST_TEST_EQ(e.has_value(), false);
  808. BOOST_TEST_EQ(static_cast<bool>(e), false);
  809. e = stde::make_expected_from_call(do_nothing_fun);
  810. BOOST_TEST_NO_THROW(e.value());
  811. BOOST_TEST_EQ(e.has_value(), true);
  812. BOOST_TEST_EQ(static_cast<bool>(e), true);
  813. BOOST_TEST_THROWS(stde::make_expected_from_call<std::error_condition>(void_throwing_fun), test_exception);
  814. try {
  815. stde::make_expected_from_call<std::error_condition>(do_nothing_fun);
  816. BOOST_TEST(true);
  817. }
  818. catch (...)
  819. {
  820. BOOST_TEST(false);
  821. }
  822. stde::expected<void, std::error_condition> e2 = stde::make_expected_from_call<std::error_condition>(do_nothing_fun);
  823. try {
  824. (void)e2.value();
  825. BOOST_TEST(true);
  826. }
  827. catch (...)
  828. {
  829. BOOST_TEST(false);
  830. }
  831. //BOOST_TEST_NO_THROW(e2.value());
  832. BOOST_TEST_EQ(e2.has_value(), true);
  833. BOOST_TEST_EQ(static_cast<bool>(e2), true);
  834. #endif
  835. }
  836. #endif
  837. void expected_swap_value()
  838. {
  839. // From value constructor.
  840. expected_sc<int> e(5);
  841. expected_sc<int> e2(8);
  842. e.swap(e2);
  843. BOOST_TEST_EQ(e.value(), 8);
  844. BOOST_TEST_EQ(e2.value(), 5);
  845. e2.swap(e);
  846. BOOST_TEST_EQ(e.value(), 5);
  847. BOOST_TEST_EQ(e2.value(), 8);
  848. }
  849. #if 0
  850. void expected_swap_exception()
  851. {
  852. // From value constructor.
  853. stde::exception_or<int> e = stde::make_unexpected(std::invalid_argument("e"));
  854. stde::exception_or<int> e2 = stde::make_unexpected(std::invalid_argument("e2"));
  855. e.swap(e2);
  856. auto equal_to_e = [](const std::invalid_argument &except) { return std::string(except.what()) == "e"; };
  857. auto equal_to_e2 = [](const std::invalid_argument &except) { return std::string(except.what()) == "e2"; };
  858. try
  859. {
  860. (void) e.value();
  861. BOOST_TEST(true);
  862. }
  863. catch(std::invalid_argument &ex)
  864. {
  865. BOOST_TEST(equal_to_e2(ex));
  866. }
  867. try
  868. {
  869. (void) e2.value();
  870. BOOST_TEST(true);
  871. }
  872. catch(std::invalid_argument &ex)
  873. {
  874. BOOST_TEST(equal_to_e(ex));
  875. }
  876. e2.swap(e);
  877. try
  878. {
  879. (void) e.value();
  880. BOOST_TEST(true);
  881. }
  882. catch(std::invalid_argument &ex)
  883. {
  884. BOOST_TEST(equal_to_e(ex));
  885. }
  886. try
  887. {
  888. (void) e2.value();
  889. BOOST_TEST(true);
  890. }
  891. catch(std::invalid_argument &ex)
  892. {
  893. BOOST_TEST(equal_to_e2(ex));
  894. }
  895. }
  896. #endif
  897. void expected_swap_function_value()
  898. {
  899. // From value constructor.
  900. expected_sc<int> e(5);
  901. expected_sc<int> e2(8);
  902. swap(e, e2);
  903. BOOST_TEST_EQ(e.value(), 8);
  904. BOOST_TEST_EQ(e2.value(), 5);
  905. swap(e, e2);
  906. BOOST_TEST_EQ(e.value(), 5);
  907. BOOST_TEST_EQ(e2.value(), 8);
  908. }
  909. #ifdef QUICKCPPLIB_BOOST_UNIT_TEST_HPP
  910. int main()
  911. #else
  912. BOOST_AUTO_TEST_CASE(expected_pass)
  913. #endif
  914. {
  915. static_assert(!std::is_default_constructible<NoDefaultConstructible>::value, "");
  916. static_assert(!std::is_default_constructible<expected_sc<NoDefaultConstructible>>::value, "");
  917. static_assert(!std::is_copy_constructible<NoCopyConstructible>::value, "");
  918. static_assert(!std::is_constructible<expected_sc<NoCopyConstructible>, NoCopyConstructible const &>::value, "");
  919. static_assert(!std::is_constructible<stde::exception_or<NoCopyConstructible>, stde::exception_or<NoCopyConstructible> const &>::value, "");
  920. static_assert(!std::is_copy_constructible<stde::exception_or<NoCopyConstructible>>::value, "");
  921. #if 0
  922. // fixme
  923. {
  924. NoMoveConstructible nmc;
  925. // NoMoveConstructible nmc2 = std::move(nmc); // FAILS as expected
  926. expected_sc<NoMoveConstructible> x{std::move(nmc)}; // DOESN'T FAIL as copy is selected instead
  927. (void) x;
  928. }
  929. // fixme
  930. #if defined __clang__ && __clang_major__ >= 4 && __cplusplus > 201402L
  931. {
  932. NoMoveConstructible nmc;
  933. // NoMoveConstructible nmc2 = std::move(nmc); // FAILS as expected
  934. expected_sc<NoMoveConstructible> x = std::move(nmc); // DOESN'T FAIL as copy is selected instead
  935. (void) x;
  936. }
  937. #endif
  938. #endif
  939. static_assert(!std::is_move_constructible<NoMoveConstructible>::value, "");
  940. static_assert(!std::is_constructible<expected_sc<NoMoveConstructible>, NoMoveConstructible &&>::value, "");
  941. static_assert(std::is_move_constructible<expected_sc<NoMoveConstructible>>::value, "");
  942. except_default_constructor();
  943. except_default_constructor_error_code();
  944. except_default_constructor_constexpr();
  945. expected_from_value();
  946. expected_from_value2();
  947. expected_from_cnv_value();
  948. except_constructor_NDCE();
  949. except_constructor_NDC();
  950. except_constructor_Date();
  951. expected_from_in_place_value();
  952. // expected_from_exception();
  953. expected_from_copy_value();
  954. // expected_from_copy_exception();
  955. expected_from_in_place();
  956. // expected_from_exception_ptr();
  957. expected_from_moved_value();
  958. expected_from_catch_block();
  959. make_expected_E_from_value();
  960. make_expected_const_from_value();
  961. make_expected_from_U_value2();
  962. expected_from_value_error_condition();
  963. expected_from_error_error_condition();
  964. expected_from_error_convertible();
  965. except_valid_constexpr_int();
  966. except_value_constexpr_int();
  967. expected_from_value3();
  968. expected_from_copy_expected();
  969. expected_from_moved_expected();
  970. expected_from_in_place2();
  971. expected_from_move_value();
  972. expected_from_in_place3();
  973. expected_from_in_place_error();
  974. expected_from_exception_catch();
  975. // expected_from_error();
  976. // expected_from_error_U();
  977. // expected_from_exception2();
  978. // expected_from_exception_ptr2();
  979. // make_expected_from_call_fun();
  980. // make_expected_from_call_void_fun();
  981. expected_swap_value();
  982. // expected_swap_exception();
  983. expected_swap_function_value();
  984. #ifdef QUICKCPPLIB_BOOST_UNIT_TEST_HPP
  985. return QUICKCPPLIB_NAMESPACE::unit_test::current_test_case()->fails != 0;
  986. #endif
  987. }
  988. #if 0
  989. ///////////////////////////////////////////////////////////////////////////////////////////////
  990. ///////////////////////////////////////////////////////////////////////////////////////////////
  991. ///////////////////////////////////////////////////////////////////////////////////////////////
  992. ///////////////////////////////////////////////////////////////////////////////////////////////
  993. //void expected_from_error_catch_exception)
  994. //{
  995. // // From catch block
  996. // try
  997. // {
  998. // throw test_exception();
  999. // }
  1000. // catch(...)
  1001. // {
  1002. // auto throw_lambda = [](){ return stde::make_expected_from_error<int,std::error_condition>();};
  1003. //
  1004. // //BOOST_TEST_THROWS(throw_lambda(), test_exception);
  1005. // }
  1006. //}
  1007. ////////////////////////////////////
  1008. BOOST_AUTO_TEST_SUITE(expected_map)
  1009. void expected_map()
  1010. {
  1011. auto fun = [](bool b) -> expected_sc<int>
  1012. {
  1013. if (b)
  1014. return stde::make_expected(5);
  1015. else
  1016. return stde::make_unexpected(test_exception());
  1017. };
  1018. auto add_five = [](int sum) -> int
  1019. {
  1020. return sum + 5;
  1021. };
  1022. auto launch_except = [](int sum) -> int
  1023. {
  1024. throw test_exception();
  1025. };
  1026. expected_sc<int> e = fun(true).map(add_five);
  1027. BOOST_TEST_NO_THROW(e.value());
  1028. BOOST_TEST_EQ(*e, 10);
  1029. e = fun(true).map(add_five).map(add_five);
  1030. BOOST_TEST_NO_THROW(e.value());
  1031. BOOST_TEST_EQ(*e, 15);
  1032. e = fun(false).map(add_five).map(add_five);
  1033. BOOST_TEST_THROWS(e.value(), test_exception);
  1034. BOOST_TEST_THROWS(fun(true).map(launch_except), test_exception);
  1035. }
  1036. void expected_void_map()
  1037. {
  1038. auto fun = [](bool b)
  1039. {
  1040. if (b)
  1041. return stde::make_expected();
  1042. else
  1043. return expected_sc<void>(stde::make_unexpected(test_exception()));
  1044. };
  1045. auto launch_except = []() -> void
  1046. {
  1047. throw test_exception();
  1048. };
  1049. auto do_nothing = []() {};
  1050. expected_sc<void> e = fun(true).map(do_nothing);
  1051. BOOST_TEST_NO_THROW(e.value());
  1052. e = fun(false).map(do_nothing);
  1053. BOOST_TEST_THROWS(e.value(), test_exception);
  1054. BOOST_TEST_THROWS(fun(true).map(launch_except), test_exception);
  1055. }
  1056. BOOST_AUTO_TEST_SUITE_END()
  1057. ////////////////////////////////////
  1058. BOOST_AUTO_TEST_SUITE(expected_bind)
  1059. void expected_bind()
  1060. {
  1061. auto fun = [](bool b) -> expected_sc<int>
  1062. {
  1063. if (b)
  1064. return stde::make_expected(5);
  1065. else
  1066. return stde::make_unexpected(test_exception());
  1067. };
  1068. auto add_five = [](int sum) -> expected_sc<int>
  1069. {
  1070. return stde::make_expected(sum + 5);
  1071. };
  1072. auto launch_except = [](int sum) -> expected_sc<int>
  1073. {
  1074. throw test_exception();
  1075. };
  1076. expected_sc<int> e = fun(true).bind(add_five);
  1077. BOOST_TEST_NO_THROW(e.value());
  1078. BOOST_TEST_EQ(*e, 10);
  1079. e = fun(true).bind(add_five).bind(add_five);
  1080. BOOST_TEST_NO_THROW(e.value());
  1081. BOOST_TEST_EQ(*e, 15);
  1082. e = fun(false).bind(add_five).bind(add_five);
  1083. BOOST_TEST_THROWS(e.value(), test_exception);
  1084. BOOST_TEST_THROWS(fun(true).bind(launch_except), test_exception);
  1085. }
  1086. void expected_void_bind()
  1087. {
  1088. auto fun = [](bool b)
  1089. {
  1090. if (b)
  1091. return stde::make_expected();
  1092. else
  1093. return expected_sc<void>(stde::make_unexpected(test_exception()));
  1094. };
  1095. auto launch_except = []() -> expected_sc<void>
  1096. {
  1097. throw test_exception();
  1098. };
  1099. auto do_nothing = []() {
  1100. return stde::make_expected();
  1101. };
  1102. expected_sc<void> e = fun(true).bind(do_nothing);
  1103. BOOST_TEST_NO_THROW(e.value());
  1104. e = fun(false).bind(do_nothing);
  1105. BOOST_TEST_THROWS(e.value(), test_exception);
  1106. BOOST_TEST_THROWS(fun(true).bind(launch_except), test_exception);
  1107. }
  1108. BOOST_AUTO_TEST_SUITE_END()
  1109. ////////////////////////////////////
  1110. BOOST_AUTO_TEST_SUITE(expected_then)
  1111. void expected_non_void_then()
  1112. {
  1113. auto fun = [](bool b) -> expected_sc<int>
  1114. {
  1115. if (b)
  1116. return stde::make_expected(5);
  1117. else
  1118. return stde::make_unexpected(test_exception());
  1119. };
  1120. auto add_five = [](int sum) -> int
  1121. {
  1122. return sum + 5;
  1123. };
  1124. auto six = []() -> int
  1125. {
  1126. return 6;
  1127. };
  1128. auto pair = [](int a) -> bool
  1129. {
  1130. return (a % 2) == 0;
  1131. };
  1132. auto launch_except = [](int sum) -> int
  1133. {
  1134. throw test_exception();
  1135. };
  1136. auto then_launch_except = [](expected<int>) -> int
  1137. {
  1138. throw test_exception();
  1139. };
  1140. expected_sc<int> e = fun(true).then(if_valued(add_five));
  1141. BOOST_TEST_NO_THROW(e.value());
  1142. BOOST_TEST_EQ(*e, 10);
  1143. e = fun(true).then(if_valued(ident(six)));
  1144. BOOST_TEST_NO_THROW(e.value());
  1145. BOOST_TEST_EQ(*e, 6);
  1146. e = fun(false).then(if_unexpected(ident(six)));
  1147. BOOST_TEST_NO_THROW(e.value());
  1148. BOOST_TEST_EQ(*e, 6);
  1149. expected_sc<bool> e1 = fun(true).then(if_valued(pair));
  1150. BOOST_TEST_NO_THROW(e1.value());
  1151. BOOST_TEST_EQ(*e1, false);
  1152. e = fun(true).then(if_valued(add_five)).then(if_valued(add_five));
  1153. BOOST_TEST_NO_THROW(e.value());
  1154. BOOST_TEST_EQ(*e, 15);
  1155. e = fun(false).then(if_valued(add_five)).then(if_valued(add_five));
  1156. BOOST_TEST_THROWS(e.value(), test_exception);
  1157. BOOST_TEST_THROWS(fun(true).then(if_valued(launch_except)), test_exception);
  1158. e = fun(false).then(catch_all(then_launch_except));
  1159. BOOST_TEST_THROWS(e.value(), test_exception);
  1160. }
  1161. void expected_void_then()
  1162. {
  1163. auto fun = [](bool b) -> expected_sc<void>
  1164. {
  1165. if (b)
  1166. return stde::make_expected();
  1167. else
  1168. return stde::make_unexpected(test_exception());
  1169. };
  1170. auto launch_except = []()
  1171. {
  1172. throw test_exception();
  1173. };
  1174. auto do_nothing = []() {};
  1175. BOOST_TEST(true);
  1176. expected_sc<void> e = fun(true).then(if_valued(do_nothing));
  1177. BOOST_TEST_NO_THROW(e.value());
  1178. e = fun(false).then(if_valued(do_nothing));
  1179. BOOST_TEST_THROWS(e.value(), test_exception);
  1180. BOOST_TEST_THROWS(fun(true).then(if_valued(launch_except)), test_exception);
  1181. }
  1182. BOOST_AUTO_TEST_SUITE_END()
  1183. BOOST_AUTO_TEST_SUITE(expected_recover)
  1184. void expected_recover()
  1185. {
  1186. auto fun = [](bool b)
  1187. {
  1188. if (b)
  1189. return expected_sc<int>(5);
  1190. else
  1191. return expected_sc<int>(stde::make_unexpected(test_exception()));
  1192. };
  1193. auto add_five = [](int sum) -> expected_sc<int>
  1194. {
  1195. return stde::make_expected(sum + 5);
  1196. };
  1197. auto recover_error = [](std::exception_ptr p)
  1198. {
  1199. return stde::make_expected(0);
  1200. };
  1201. auto recover_error_silent_failure = [](std::exception_ptr p)
  1202. {
  1203. return expected_sc<int>(stde::make_unexpected(p));
  1204. };
  1205. auto recover_error_failure = [](std::exception_ptr p) -> expected_sc<int>
  1206. {
  1207. return expected_sc<int>(stde::make_unexpected(test_exception()));
  1208. };
  1209. auto recover_error_throws = [](std::exception_ptr p) -> expected_sc<int>
  1210. {
  1211. throw test_exception();
  1212. };
  1213. BOOST_TEST_EQ(fun(false).catch_error(recover_error).has_value(), true);
  1214. BOOST_TEST_EQ(fun(false).catch_error(recover_error).value(), 0);
  1215. BOOST_TEST_EQ(fun(true).catch_error(recover_error).value(), 5);
  1216. BOOST_TEST_EQ(fun(false).catch_error(recover_error_silent_failure).has_value(), false);
  1217. BOOST_TEST_EQ(fun(false).catch_error(recover_error_failure).has_value(), false);
  1218. BOOST_TEST_EQ(fun(true).bind(add_five).value(), 10);
  1219. BOOST_TEST_EQ(fun(true).bind(add_five).catch_error(recover_error).value(), 10);
  1220. BOOST_TEST_EQ(fun(true).bind(add_five).catch_error(recover_error_silent_failure).value(), 10);
  1221. BOOST_TEST_EQ(fun(true).bind(add_five).catch_error(recover_error_failure).value(), 10);
  1222. BOOST_TEST_EQ(fun(false).catch_error(recover_error).bind(add_five).value(), 5);
  1223. BOOST_TEST_EQ(fun(false).catch_error(recover_error).bind(add_five).bind(add_five).value(), 10);
  1224. BOOST_TEST_EQ(fun(false).catch_error(recover_error_failure).bind(add_five).has_value(), false);
  1225. BOOST_TEST_EQ(fun(false).bind(add_five).catch_error(recover_error_failure).bind(add_five).has_value(), false);
  1226. BOOST_TEST_EQ(fun(false).bind(add_five).catch_error(recover_error_silent_failure).bind(add_five).has_value(), false);
  1227. BOOST_TEST_THROWS(fun(false).catch_error(recover_error_throws), test_exception);
  1228. }
  1229. void expected_void_recover()
  1230. {
  1231. auto fun = [](bool b)
  1232. {
  1233. if (b)
  1234. return stde::make_expected();
  1235. else
  1236. return expected_sc<void>(boost::stde::make_unexpected(test_exception()));
  1237. };
  1238. auto do_nothing = []() {
  1239. return stde::make_expected();
  1240. };
  1241. auto recover_error = [](std::exception_ptr p)
  1242. {
  1243. return stde::make_expected();
  1244. };
  1245. auto recover_error_silent_failure = [](std::exception_ptr p)
  1246. {
  1247. return expected_sc<void>(boost::stde::make_unexpected(p));
  1248. };
  1249. auto recover_error_failure = [](std::exception_ptr p) -> expected_sc<void>
  1250. {
  1251. throw test_exception();
  1252. };
  1253. // The catch_error doesn't alter the stde::expected if it's valid.
  1254. BOOST_TEST_EQ(fun(true).catch_error(recover_error_failure).has_value(), true);
  1255. // Simple catch_error tests.
  1256. BOOST_TEST_EQ(fun(false).catch_error(recover_error).has_value(), true);
  1257. BOOST_TEST_THROWS(fun(false).catch_error(recover_error_failure), test_exception);
  1258. BOOST_TEST_EQ(fun(false).catch_error(recover_error_silent_failure).has_value(), false);
  1259. // With a bind between.
  1260. BOOST_TEST_THROWS(fun(false).bind(do_nothing).catch_error(recover_error_failure), test_exception);
  1261. }
  1262. BOOST_AUTO_TEST_SUITE_END()
  1263. BOOST_AUTO_TEST_SUITE(proposal)
  1264. void proposal_concept()
  1265. {
  1266. using namespace std;
  1267. {
  1268. stde::expected<int, string> ei = 0;
  1269. stde::expected<int, string> ej = 1;
  1270. stde::expected<int, string> ek = stde::make_unexpected(string());
  1271. ei = 1;
  1272. ej = stde::make_unexpected(string());;
  1273. ek = 0;
  1274. ei = stde::make_unexpected(string());;
  1275. ej = 0;
  1276. ek = 1;
  1277. }
  1278. }
  1279. void proposal_init()
  1280. {
  1281. using namespace std;
  1282. {
  1283. string s{ "STR" };
  1284. stde::expected<string, int> ep{ stde::make_unexpected(-1) }; // unexpected value, requires Movable<E>
  1285. stde::expected<string, int> eq = { stde::make_unexpected(-1) }; // unexpected value, requires Movable<E>
  1286. expected_sc<string> es{ s }; // requires Copyable<T>
  1287. expected_sc<string> et = s; // requires Copyable<T>
  1288. expected_sc<string> ev = string{ "STR" }; // requires Movable<T>
  1289. expected_sc<string> ew; // unexpected value
  1290. expected_sc<string> ex{}; // unexpected value
  1291. expected_sc<string> ey = {}; // unexpected value
  1292. expected_sc<string> ez = expected_sc<string>{}; // unexpected value
  1293. }
  1294. {
  1295. stde::expected<Guard, int> eg; // unexpected value
  1296. stde::expected<Guard, int> eh{}; // unexpected value
  1297. stde::expected<Guard, int> ei{ stde::in_place }; // calls Guard{} in place
  1298. stde::expected<Guard, int> ej{ stde::in_place, "arg" }; // calls Guard{"arg"} in place
  1299. }
  1300. {
  1301. stde::expected<int, string> ei{ unexpect }; // unexpected value, calls string{} in place
  1302. stde::expected<int, string> ej{ unexpect, "arg" }; // unexpected value, calls string{"arg"} in place
  1303. }
  1304. }
  1305. void proposal_make_unexpected_fact()
  1306. {
  1307. using namespace std;
  1308. {
  1309. stde::expected<string, int> opt1 = stde::make_unexpected(1);
  1310. stde::expected<string, int> opt2 = { unexpect, 1 };
  1311. opt1 = stde::make_unexpected(1);
  1312. opt2 = { unexpect, 1 };
  1313. }
  1314. }
  1315. void proposal_error_exception_ts()
  1316. {
  1317. using namespace std;
  1318. {
  1319. stde::expected<int, error_exception<std::error_code, std::system_error> > e =
  1320. stde::make_unexpected(make_error_code(errc::invalid_argument));
  1321. #if !defined BOOST_MSVC || BOOST_MSVC >= 1900
  1322. BOOST_TEST(e.error() == make_error_code(errc::invalid_argument));
  1323. #else
  1324. // VS2013 doesn't match operator==(boost::error_exception<std::error_code,std::system_error>, std::error_code)
  1325. BOOST_TEST(e.error() == (error_exception<std::error_code, std::system_error>(make_error_code(errc::invalid_argument))));
  1326. #endif
  1327. try {
  1328. e.value();
  1329. BOOST_TEST(false);
  1330. }
  1331. catch (std::system_error const& ex) {
  1332. }
  1333. catch (...) {
  1334. BOOST_TEST(false);
  1335. }
  1336. stde::expected<int, error_exception<std::error_code, std::system_error> > e2 = stde::make_unexpected(e.error());
  1337. #if !defined BOOST_MSVC || BOOST_MSVC >= 1900
  1338. BOOST_TEST(e2.error() == make_error_code(errc::invalid_argument));
  1339. #else
  1340. // VS2013 doesn't match operator==(boost::error_exception<std::error_code,std::system_error>, std::error_code)
  1341. BOOST_TEST(e2.error() == (error_exception<std::error_code, std::system_error>(make_error_code(errc::invalid_argument))));
  1342. #endif
  1343. try {
  1344. e2.value();
  1345. BOOST_TEST(false);
  1346. }
  1347. catch (std::system_error const& ex) {
  1348. }
  1349. catch (...) {
  1350. BOOST_TEST(false);
  1351. }
  1352. }
  1353. }
  1354. void proposal_ensured_read_ts()
  1355. {
  1356. using namespace std;
  1357. {
  1358. ensured_read<int> e = make_ensured_read(1);
  1359. BOOST_TEST(e == 1);
  1360. }
  1361. {
  1362. ensured_read<int> e = make_ensured_read(1);
  1363. stde::unexpected<ensured_read<int>> ue1 = stde::make_unexpected(std::move(e));
  1364. BOOST_TEST(ue1.value() == 1);
  1365. }
  1366. // {
  1367. // stde::make_unexpected(make_ensured_read(1));
  1368. // // calls to terminate.
  1369. // }
  1370. // {
  1371. // stde::expected<int, ensured_read<int> > e = stde::make_unexpected(make_ensured_read(1));
  1372. // // calls to terminate.
  1373. // }
  1374. {
  1375. stde::expected<int, ensured_read<int> > e{ 1 };
  1376. BOOST_TEST(e.value() == 1);
  1377. }
  1378. {
  1379. stde::expected<int, ensured_read<int> > e = stde::make_unexpected(make_ensured_read(1));
  1380. BOOST_TEST(e.error() == 1);
  1381. }
  1382. {
  1383. stde::expected<int, ensured_read<int> > e{ unexpect, 1 };
  1384. BOOST_TEST(e.error() == 1);
  1385. }
  1386. {
  1387. ensured_read<std::exception_ptr> e = make_ensured_read(std::make_exception_ptr(1));
  1388. BOOST_TEST_THROWS(std::rethrow_exception(e.value()), int);
  1389. }
  1390. {
  1391. stde::expected<int, ensured_read<std::exception_ptr> > e = stde::make_unexpected(make_ensured_read(std::make_exception_ptr(1)));
  1392. BOOST_TEST_THROWS(std::rethrow_exception(e.error().value()), int);
  1393. }
  1394. }
  1395. void proposal_relational_operators()
  1396. {
  1397. using namespace std;
  1398. {
  1399. stde::expected<unsigned, int> e0{ 0 };
  1400. stde::expected<unsigned, int> e1{ 1 };
  1401. stde::expected<unsigned, int> eN{ unexpect, -1 };
  1402. BOOST_TEST(eN < e0);
  1403. BOOST_TEST(e0 < e1);
  1404. BOOST_TEST(!(e0 < eN));
  1405. BOOST_TEST(eN <= e0);
  1406. BOOST_TEST(e0 <= e1);
  1407. BOOST_TEST(e0 > eN);
  1408. BOOST_TEST(e1 > e0);
  1409. BOOST_TEST(e0 >= eN);
  1410. BOOST_TEST(e1 >= e0);
  1411. BOOST_TEST(!(eN < eN));
  1412. BOOST_TEST(!(e1 < e1));
  1413. BOOST_TEST(eN <= eN);
  1414. BOOST_TEST(e1 <= e1);
  1415. BOOST_TEST(eN != e0);
  1416. BOOST_TEST(e0 != e1);
  1417. BOOST_TEST(eN == eN);
  1418. BOOST_TEST(e0 == e0);
  1419. //////
  1420. BOOST_TEST(eN == stde::make_unexpected(-1));
  1421. BOOST_TEST(e0 != stde::make_unexpected(1));
  1422. BOOST_TEST(eN != 1u);
  1423. BOOST_TEST(e1 == 1u);
  1424. BOOST_TEST(eN < 1u);
  1425. BOOST_TEST(eN <= 1u);
  1426. BOOST_TEST(1u > eN);
  1427. BOOST_TEST(!(1u < eN));
  1428. BOOST_TEST(1u >= eN);
  1429. BOOST_TEST(stde::make_unexpected(1) < e0);
  1430. BOOST_TEST(stde::make_unexpected(1) <= e0);
  1431. BOOST_TEST(!(stde::make_unexpected(1) > e0));
  1432. BOOST_TEST(!(stde::make_unexpected(1) >= e0));
  1433. BOOST_TEST(!(e0 < stde::make_unexpected(1)));
  1434. BOOST_TEST(!(e0 <= stde::make_unexpected(1)));
  1435. BOOST_TEST(e0 > stde::make_unexpected(1));
  1436. BOOST_TEST(e0 >= stde::make_unexpected(1));
  1437. }
  1438. {
  1439. stde::expected<void, int> e0{ boost::expect };
  1440. stde::expected<void, int> eN{ unexpect, -1 };
  1441. BOOST_TEST(!(e0 < e0));
  1442. BOOST_TEST(eN < e0);
  1443. BOOST_TEST(!(e0 < eN));
  1444. BOOST_TEST(!(eN < eN));
  1445. BOOST_TEST(e0 <= e0);
  1446. BOOST_TEST(eN <= e0);
  1447. BOOST_TEST(!(e0 <= eN));
  1448. BOOST_TEST(eN <= eN);
  1449. BOOST_TEST(!(e0 > e0));
  1450. BOOST_TEST(e0 > eN);
  1451. BOOST_TEST(!(eN > e0));
  1452. BOOST_TEST(!(eN > eN));
  1453. BOOST_TEST(e0 >= e0);
  1454. BOOST_TEST(e0 >= eN);
  1455. BOOST_TEST(!(eN >= e0));
  1456. BOOST_TEST(eN >= eN);
  1457. BOOST_TEST(!(e0 != e0));
  1458. BOOST_TEST(eN != e0);
  1459. BOOST_TEST(e0 != eN);
  1460. BOOST_TEST(!(eN != eN));
  1461. BOOST_TEST(e0 == e0);
  1462. BOOST_TEST(!(eN == e0));
  1463. BOOST_TEST(!(e0 == eN));
  1464. BOOST_TEST(eN == eN);
  1465. //////
  1466. BOOST_TEST(eN == stde::make_unexpected(-1));
  1467. BOOST_TEST(e0 != stde::make_unexpected(1));
  1468. BOOST_TEST(stde::make_unexpected(1) < e0);
  1469. BOOST_TEST(stde::make_unexpected(1) <= e0);
  1470. BOOST_TEST(!(stde::make_unexpected(1) > e0));
  1471. BOOST_TEST(!(stde::make_unexpected(1) >= e0));
  1472. BOOST_TEST(!(stde::make_unexpected(1) < eN));
  1473. BOOST_TEST(!(stde::make_unexpected(1) <= eN));
  1474. BOOST_TEST(stde::make_unexpected(1) > eN);
  1475. BOOST_TEST(stde::make_unexpected(1) >= eN);
  1476. BOOST_TEST(!(eN < stde::make_unexpected(-1)));
  1477. BOOST_TEST(eN <= stde::make_unexpected(-1));
  1478. BOOST_TEST(!(eN > stde::make_unexpected(-1)));
  1479. BOOST_TEST(eN >= stde::make_unexpected(-1));
  1480. }
  1481. }
  1482. void proposal_dereference_operators()
  1483. {
  1484. using namespace std;
  1485. {
  1486. const string s{ "STR" };
  1487. expected_sc<string> e0{ s };
  1488. const expected_sc<string> e1{ s };
  1489. BOOST_TEST(*e0.operator->() == s);
  1490. BOOST_TEST(*e1.operator->() == s);
  1491. // Test with class which has operator&() overloaded
  1492. const OverloadedAddressOf o{};
  1493. BOOST_TEST(&o == nullptr);
  1494. expected_sc<OverloadedAddressOf> e2{ o };
  1495. const expected_sc<OverloadedAddressOf> e3{ o };
  1496. BOOST_TEST(e2.operator->() != nullptr);
  1497. BOOST_TEST(e3.operator->() != nullptr);
  1498. }
  1499. }
  1500. BOOST_AUTO_TEST_SUITE_END()
  1501. BOOST_AUTO_TEST_SUITE(movesem)
  1502. //////////////////////////////
  1503. void movesem_moved_from_state()
  1504. {
  1505. // first, test mock:
  1506. MoveAware<int> i{ 1 }, j{ 2 };
  1507. BOOST_TEST(i.val == 1);
  1508. BOOST_TEST(!i.moved);
  1509. BOOST_TEST(j.val == 2);
  1510. BOOST_TEST(!j.moved);
  1511. MoveAware<int> k = std::move(i);
  1512. BOOST_TEST(k.val == 1);
  1513. BOOST_TEST(!k.moved);
  1514. BOOST_TEST(i.val == 1);
  1515. BOOST_TEST(i.moved);
  1516. k = std::move(j);
  1517. BOOST_TEST(k.val == 2);
  1518. BOOST_TEST(!k.moved);
  1519. BOOST_TEST(j.val == 2);
  1520. BOOST_TEST(j.moved);
  1521. // now, test stde::expected
  1522. expected_sc<MoveAware<int>> oi{ 1 }, oj{ 2 };
  1523. BOOST_TEST(oi);
  1524. BOOST_TEST(!oi->moved);
  1525. BOOST_TEST(oj);
  1526. BOOST_TEST(!oj->moved);
  1527. expected_sc<MoveAware<int>> ok{ std::move(oi) };
  1528. BOOST_TEST(ok);
  1529. BOOST_TEST(!ok->moved);
  1530. BOOST_TEST(oi);
  1531. BOOST_TEST(oi->moved);
  1532. ok = std::move(oj);
  1533. BOOST_TEST(ok);
  1534. BOOST_TEST(!ok->moved);
  1535. BOOST_TEST(oj);
  1536. BOOST_TEST(oj->moved);
  1537. }
  1538. void movesem_move_only_value()
  1539. {
  1540. const auto make_int = []() {
  1541. std::unique_ptr<int> value{ new int };
  1542. *value = 100;
  1543. return value;
  1544. };
  1545. const auto return_void = [](std::unique_ptr<int> value) {
  1546. BOOST_TEST(value != nullptr);
  1547. BOOST_TEST(*value == 100);
  1548. };
  1549. const auto return_expected = [](std::unique_ptr<int> value) {
  1550. BOOST_TEST(value != nullptr);
  1551. BOOST_TEST(*value == 100);
  1552. return expected_sc<void>{boost::expect};
  1553. };
  1554. const auto return_int = [](std::unique_ptr<int> value) {
  1555. BOOST_TEST(value != nullptr);
  1556. BOOST_TEST(*value == 100);
  1557. return 200;
  1558. };
  1559. BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.map(return_void));
  1560. BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.map(return_expected));
  1561. BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.map(return_int));
  1562. }
  1563. void movesem_move_only_value2()
  1564. {
  1565. const auto make_int = []() {
  1566. std::unique_ptr<int> value{ new int };
  1567. *value = 100;
  1568. return value;
  1569. };
  1570. const auto return_expected_void = [](std::unique_ptr<int> value) {
  1571. BOOST_TEST(value != nullptr);
  1572. BOOST_TEST(*value == 100);
  1573. return stde::make_expected();
  1574. };
  1575. const auto return_expected = [](std::unique_ptr<int> value) {
  1576. BOOST_TEST(value != nullptr);
  1577. BOOST_TEST(*value == 100);
  1578. return expected_sc<void>{boost::expect};
  1579. };
  1580. BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.bind(return_expected_void));
  1581. BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.bind(return_expected));
  1582. }
  1583. void movesem_copy_move_ctor_optional_int()
  1584. {
  1585. expected_sc<int> oi;
  1586. expected_sc<int> oj = oi;
  1587. BOOST_TEST(oj);
  1588. BOOST_TEST(oj == oi);
  1589. BOOST_TEST(bool(oj));
  1590. oi = 1;
  1591. expected_sc<int> ok = oi;
  1592. BOOST_TEST(!!ok);
  1593. BOOST_TEST(bool(ok));
  1594. BOOST_TEST(ok == oi);
  1595. BOOST_TEST(ok != oj);
  1596. BOOST_TEST(*ok == 1);
  1597. expected_sc<int> ol = std::move(oi);
  1598. BOOST_TEST(!!ol);
  1599. BOOST_TEST(bool(ol));
  1600. BOOST_TEST(ol == oi);
  1601. BOOST_TEST(ol != oj);
  1602. BOOST_TEST(*ol == 1);
  1603. }
  1604. void movesem_expected_expected()
  1605. {
  1606. expected_sc<stde::expected<int, int>> oi1 = stde::make_unexpected(-1);
  1607. BOOST_TEST(!oi1);
  1608. {
  1609. expected_sc<expected_sc<int>> oi2{ stde::expect };
  1610. BOOST_TEST(bool(oi2));
  1611. BOOST_TEST((*oi2));
  1612. //std::cout << typeid(**oi2).name() << std::endl;
  1613. }
  1614. {
  1615. expected_sc<stde::expected<int, int>> oi2{ stde::expect, stde::make_unexpected(-1) };
  1616. BOOST_TEST(bool(oi2));
  1617. BOOST_TEST(!*oi2);
  1618. }
  1619. {
  1620. stde::expected<stde::expected<int>> oi2{ stde::expected<int>{} };
  1621. BOOST_TEST(bool(oi2));
  1622. BOOST_TEST(*oi2);
  1623. }
  1624. stde::expected<int> oi;
  1625. auto ooi = stde::make_expected(oi);
  1626. static_assert(std::is_same<expected<expected<int>>, decltype(ooi)>::value, "");
  1627. }
  1628. BOOST_AUTO_TEST_SUITE_END()
  1629. void process() {}
  1630. void process(int) {}
  1631. void processNil() {}
  1632. BOOST_AUTO_TEST_SUITE(Examples)
  1633. //////////////////////////////
  1634. void example1()
  1635. {
  1636. stde::expected<int> oi; // create disengaged object
  1637. stde::expected<int> oj = { unexpect }; // alternative syntax
  1638. oi = oj; // assign disengaged object
  1639. stde::expected<int> ok = oj; // ok is disengaged
  1640. if (oi) BOOST_TEST(false); // 'if oi is engaged...'
  1641. if (!oi) BOOST_TEST(true); // 'if oi is disengaged...'
  1642. BOOST_TEST(oi == ok); // two disengaged optionals compare equal
  1643. ///////////////////////////////////////////////////////////////////////////
  1644. stde::expected<int> ol{ 1 }; // ol is engaged; its contained value is 1
  1645. ok = 2; // ok becomes engaged; its contained value is 2
  1646. oj = ol; // oj becomes engaged; its contained value is 1
  1647. BOOST_TEST(oi != ol); // disengaged != engaged
  1648. BOOST_TEST(ok != ol); // different contained values
  1649. BOOST_TEST(oj == ol); // same contained value
  1650. //BOOST_TEST(oi < ol); // disengaged < engaged
  1651. //BOOST_TEST(ol < ok); // less by contained value
  1652. /////////////////////////////////////////////////////////////////////////////
  1653. stde::expected<int> om{ 1 }; // om is engaged; its contained value is 1
  1654. stde::expected<int> on = om; // on is engaged; its contained value is 1
  1655. om = 2; // om is engaged; its contained value is 2
  1656. BOOST_TEST(on != om); // on still contains 3. They are not pointers
  1657. /////////////////////////////////////////////////////////////////////////////
  1658. int i = *ol; // i obtains the value contained in ol
  1659. BOOST_TEST(i == 1);
  1660. *ol = 9; // the object contained in ol becomes 9
  1661. BOOST_TEST(*ol == 9);
  1662. BOOST_TEST(ol == stde::make_expected(9));
  1663. ///////////////////////////////////
  1664. int p = 1;
  1665. stde::expected<int> op = p;
  1666. BOOST_TEST(*op == 1);
  1667. p = 2;
  1668. BOOST_TEST(*op == 1); // value contained in op is separated from p
  1669. ////////////////////////////////
  1670. if (ol)
  1671. process(*ol); // use contained value if present
  1672. else
  1673. process(); // proceed without contained value
  1674. if (!om)
  1675. processNil();
  1676. else
  1677. process(*om);
  1678. /////////////////////////////////////////
  1679. process(ol.value_or(0)); // use 0 if ol is disengaged
  1680. ////////////////////////////////////////////
  1681. ok = { unexpect }; // if ok was engaged calls T's dtor
  1682. oj = {}; // assigns a temporary disengaged stde::expected
  1683. }
  1684. //////////////////////////////////////////////////
  1685. void ValueOr()
  1686. {
  1687. stde::expected<int> oi = 1;
  1688. int i = oi.value_or(0);
  1689. BOOST_TEST(i == 1);
  1690. oi = { unexpect };
  1691. BOOST_TEST(oi.value_or(3) == 3);
  1692. stde::expected<std::string> os{ "AAA" };
  1693. BOOST_TEST(os.value_or("BBB") == "AAA");
  1694. os = {};
  1695. BOOST_TEST(os);
  1696. BOOST_TEST(os.value() == "");
  1697. BOOST_TEST(os.value_or(std::string("BBB")) == "");
  1698. {
  1699. constexpr stde::expected<int> e = 1;
  1700. static_assert(e.has_value(), "");
  1701. static_assert(*e == 1, "");
  1702. static_assert(e.value() == 1, "");
  1703. }
  1704. {
  1705. constexpr std::error_code ec = std::make_error_code(std::errc(1));
  1706. constexpr stde::expected<int> e = stde::make_unexpected(ec);
  1707. static_assert(!e.has_value(), "");
  1708. static_assert(e.error() == ec, "");
  1709. }
  1710. {
  1711. constexpr stde::expected<OracleVal> e = 1;
  1712. static_assert(e.has_value(), "");
  1713. static_assert(*e == 1, "");
  1714. static_assert(e.value() == 1, "");
  1715. }
  1716. {
  1717. constexpr std::error_code ec = std::make_error_code(std::errc(1));
  1718. constexpr stde::expected<OracleVal> e = stde::make_unexpected(ec);
  1719. static_assert(!e.has_value(), "");
  1720. static_assert(e.error() == ec, "");
  1721. }
  1722. }
  1723. //////////////////////////////////////////////////
  1724. BOOST_AUTO_TEST_SUITE_END()
  1725. #endif
  1726. #else
  1727. int main(void)
  1728. {
  1729. return 0;
  1730. }
  1731. #endif