expected.hpp 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
  1. // This version targets C++11 and later.
  2. //
  3. // Copyright (C) 2016-2020 Martin Moene.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // expected lite is based on:
  9. // A proposal to add a utility class to represent expected monad
  10. // by Vicente J. Botet Escriba and Pierre Talbot. http:://wg21.link/p0323
  11. #ifndef NONSTD_EXPECTED_LITE_HPP
  12. #define NONSTD_EXPECTED_LITE_HPP
  13. #define expected_lite_MAJOR 0
  14. #define expected_lite_MINOR 6
  15. #define expected_lite_PATCH 2
  16. #define expected_lite_VERSION expected_STRINGIFY(expected_lite_MAJOR) "." expected_STRINGIFY(expected_lite_MINOR) "." expected_STRINGIFY(expected_lite_PATCH)
  17. #define expected_STRINGIFY( x ) expected_STRINGIFY_( x )
  18. #define expected_STRINGIFY_( x ) #x
  19. // expected-lite configuration:
  20. #define nsel_EXPECTED_DEFAULT 0
  21. #define nsel_EXPECTED_NONSTD 1
  22. #define nsel_EXPECTED_STD 2
  23. // tweak header support:
  24. #ifdef __has_include
  25. # if __has_include(<nonstd/expected.tweak.hpp>)
  26. # include <nonstd/expected.tweak.hpp>
  27. # endif
  28. #define expected_HAVE_TWEAK_HEADER 1
  29. #else
  30. #define expected_HAVE_TWEAK_HEADER 0
  31. //# pragma message("expected.hpp: Note: Tweak header not supported.")
  32. #endif
  33. // expected selection and configuration:
  34. #if !defined( nsel_CONFIG_SELECT_EXPECTED )
  35. # define nsel_CONFIG_SELECT_EXPECTED ( nsel_HAVE_STD_EXPECTED ? nsel_EXPECTED_STD : nsel_EXPECTED_NONSTD )
  36. #endif
  37. // Proposal revisions:
  38. //
  39. // DXXXXR0: --
  40. // N4015 : -2 (2014-05-26)
  41. // N4109 : -1 (2014-06-29)
  42. // P0323R0: 0 (2016-05-28)
  43. // P0323R1: 1 (2016-10-12)
  44. // -------:
  45. // P0323R2: 2 (2017-06-15)
  46. // P0323R3: 3 (2017-10-15)
  47. // P0323R4: 4 (2017-11-26)
  48. // P0323R5: 5 (2018-02-08)
  49. // P0323R6: 6 (2018-04-02)
  50. // P0323R7: 7 (2018-06-22) *
  51. //
  52. // expected-lite uses 2 and higher
  53. #ifndef nsel_P0323R
  54. # define nsel_P0323R 7
  55. #endif
  56. // Control presence of C++ exception handling (try and auto discover):
  57. #ifndef nsel_CONFIG_NO_EXCEPTIONS
  58. # if defined(_MSC_VER)
  59. # include <cstddef> // for _HAS_EXCEPTIONS
  60. # endif
  61. # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
  62. # define nsel_CONFIG_NO_EXCEPTIONS 0
  63. # else
  64. # define nsel_CONFIG_NO_EXCEPTIONS 1
  65. # endif
  66. #endif
  67. // at default use SEH with MSVC for no C++ exceptions
  68. #ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH
  69. # define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER )
  70. #endif
  71. // C++ language version detection (C++23 is speculative):
  72. // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
  73. #ifndef nsel_CPLUSPLUS
  74. # if defined(_MSVC_LANG ) && !defined(__clang__)
  75. # define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
  76. # else
  77. # define nsel_CPLUSPLUS __cplusplus
  78. # endif
  79. #endif
  80. #define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L )
  81. #define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L )
  82. #define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L )
  83. #define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L )
  84. #define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202002L )
  85. #define nsel_CPP23_OR_GREATER ( nsel_CPLUSPLUS >= 202300L )
  86. // Use C++23 std::expected if available and requested:
  87. #if nsel_CPP23_OR_GREATER && defined(__has_include )
  88. # if __has_include( <expected> )
  89. # define nsel_HAVE_STD_EXPECTED 1
  90. # else
  91. # define nsel_HAVE_STD_EXPECTED 0
  92. # endif
  93. #else
  94. # define nsel_HAVE_STD_EXPECTED 0
  95. #endif
  96. #define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) )
  97. //
  98. // in_place: code duplicated in any-lite, expected-lite, expected-lite, value-ptr-lite, variant-lite:
  99. //
  100. #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
  101. #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
  102. // C++17 std::in_place in <utility>:
  103. #if nsel_CPP17_OR_GREATER
  104. #include <utility>
  105. namespace nonstd {
  106. using std::in_place;
  107. using std::in_place_type;
  108. using std::in_place_index;
  109. using std::in_place_t;
  110. using std::in_place_type_t;
  111. using std::in_place_index_t;
  112. #define nonstd_lite_in_place_t( T) std::in_place_t
  113. #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
  114. #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
  115. #define nonstd_lite_in_place( T) std::in_place_t{}
  116. #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
  117. #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
  118. } // namespace nonstd
  119. #else // nsel_CPP17_OR_GREATER
  120. #include <cstddef>
  121. namespace nonstd {
  122. namespace detail {
  123. template< class T >
  124. struct in_place_type_tag {};
  125. template< std::size_t K >
  126. struct in_place_index_tag {};
  127. } // namespace detail
  128. struct in_place_t {};
  129. template< class T >
  130. inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
  131. {
  132. return in_place_t();
  133. }
  134. template< std::size_t K >
  135. inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
  136. {
  137. return in_place_t();
  138. }
  139. template< class T >
  140. inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
  141. {
  142. return in_place_t();
  143. }
  144. template< std::size_t K >
  145. inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
  146. {
  147. return in_place_t();
  148. }
  149. // mimic templated typedef:
  150. #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
  151. #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
  152. #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
  153. #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
  154. #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
  155. #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
  156. } // namespace nonstd
  157. #endif // nsel_CPP17_OR_GREATER
  158. #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
  159. //
  160. // Using std::expected:
  161. //
  162. #if nsel_USES_STD_EXPECTED
  163. #include <expected>
  164. namespace nonstd {
  165. using std::expected;
  166. // ...
  167. }
  168. #else // nsel_USES_STD_EXPECTED
  169. #include <cassert>
  170. #include <exception>
  171. #include <functional>
  172. #include <initializer_list>
  173. #include <memory>
  174. #include <new>
  175. #include <system_error>
  176. #include <type_traits>
  177. #include <utility>
  178. // additional includes:
  179. #if nsel_CONFIG_NO_EXCEPTIONS
  180. # if nsel_CONFIG_NO_EXCEPTIONS_SEH
  181. # include <windows.h> // for ExceptionCodes
  182. # else
  183. // already included: <cassert>
  184. # endif
  185. #else
  186. # include <stdexcept>
  187. #endif
  188. // C++ feature usage:
  189. #if nsel_CPP11_OR_GREATER
  190. # define nsel_constexpr constexpr
  191. #else
  192. # define nsel_constexpr /*constexpr*/
  193. #endif
  194. #if nsel_CPP14_OR_GREATER
  195. # define nsel_constexpr14 constexpr
  196. #else
  197. # define nsel_constexpr14 /*constexpr*/
  198. #endif
  199. #if nsel_CPP17_OR_GREATER
  200. # define nsel_inline17 inline
  201. #else
  202. # define nsel_inline17 /*inline*/
  203. #endif
  204. // Compiler versions:
  205. //
  206. // MSVC++ 6.0 _MSC_VER == 1200 nsel_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
  207. // MSVC++ 7.0 _MSC_VER == 1300 nsel_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
  208. // MSVC++ 7.1 _MSC_VER == 1310 nsel_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
  209. // MSVC++ 8.0 _MSC_VER == 1400 nsel_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
  210. // MSVC++ 9.0 _MSC_VER == 1500 nsel_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
  211. // MSVC++ 10.0 _MSC_VER == 1600 nsel_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
  212. // MSVC++ 11.0 _MSC_VER == 1700 nsel_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
  213. // MSVC++ 12.0 _MSC_VER == 1800 nsel_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
  214. // MSVC++ 14.0 _MSC_VER == 1900 nsel_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
  215. // MSVC++ 14.1 _MSC_VER >= 1910 nsel_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
  216. // MSVC++ 14.2 _MSC_VER >= 1920 nsel_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
  217. #if defined(_MSC_VER) && !defined(__clang__)
  218. # define nsel_COMPILER_MSVC_VER (_MSC_VER )
  219. # define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
  220. #else
  221. # define nsel_COMPILER_MSVC_VER 0
  222. # define nsel_COMPILER_MSVC_VERSION 0
  223. #endif
  224. #define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
  225. #if defined(__clang__)
  226. # define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
  227. #else
  228. # define nsel_COMPILER_CLANG_VERSION 0
  229. #endif
  230. #if defined(__GNUC__) && !defined(__clang__)
  231. # define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
  232. #else
  233. # define nsel_COMPILER_GNUC_VERSION 0
  234. #endif
  235. // half-open range [lo..hi):
  236. //#define nsel_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
  237. // Method enabling
  238. #define nsel_REQUIRES_0(...) \
  239. template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
  240. #define nsel_REQUIRES_T(...) \
  241. , typename std::enable_if< (__VA_ARGS__), int >::type = 0
  242. #define nsel_REQUIRES_R(R, ...) \
  243. typename std::enable_if< (__VA_ARGS__), R>::type
  244. #define nsel_REQUIRES_A(...) \
  245. , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
  246. // Presence of language and library features:
  247. #ifdef _HAS_CPP0X
  248. # define nsel_HAS_CPP0X _HAS_CPP0X
  249. #else
  250. # define nsel_HAS_CPP0X 0
  251. #endif
  252. //#define nsel_CPP11_140 (nsel_CPP11_OR_GREATER || nsel_COMPILER_MSVC_VER >= 1900)
  253. // Clang, GNUC, MSVC warning suppression macros:
  254. #ifdef __clang__
  255. # pragma clang diagnostic push
  256. #elif defined __GNUC__
  257. # pragma GCC diagnostic push
  258. #endif // __clang__
  259. #if nsel_COMPILER_MSVC_VERSION >= 140
  260. # pragma warning( push )
  261. # define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(disable: codes) )
  262. #else
  263. # define nsel_DISABLE_MSVC_WARNINGS(codes)
  264. #endif
  265. #ifdef __clang__
  266. # define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
  267. #elif defined __GNUC__
  268. # define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
  269. #elif nsel_COMPILER_MSVC_VERSION >= 140
  270. # define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) )
  271. #else
  272. # define nsel_RESTORE_WARNINGS()
  273. #endif
  274. // Suppress the following MSVC (GSL) warnings:
  275. // - C26409: Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11)
  276. nsel_DISABLE_MSVC_WARNINGS( 26409 )
  277. //
  278. // expected:
  279. //
  280. namespace nonstd { namespace expected_lite {
  281. // type traits C++17:
  282. namespace std17 {
  283. #if nsel_CPP17_OR_GREATER
  284. using std::conjunction;
  285. using std::is_swappable;
  286. using std::is_nothrow_swappable;
  287. #else // nsel_CPP17_OR_GREATER
  288. namespace detail {
  289. using std::swap;
  290. struct is_swappable
  291. {
  292. template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
  293. static std::true_type test( int /* unused */);
  294. template< typename >
  295. static std::false_type test(...);
  296. };
  297. struct is_nothrow_swappable
  298. {
  299. // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
  300. template< typename T >
  301. static constexpr bool satisfies()
  302. {
  303. return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
  304. }
  305. template< typename T >
  306. static auto test( int ) -> std::integral_constant<bool, satisfies<T>()>{}
  307. template< typename >
  308. static auto test(...) -> std::false_type;
  309. };
  310. } // namespace detail
  311. // is [nothow] swappable:
  312. template< typename T >
  313. struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
  314. template< typename T >
  315. struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
  316. // conjunction:
  317. template< typename... > struct conjunction : std::true_type{};
  318. template< typename B1 > struct conjunction<B1> : B1{};
  319. template< typename B1, typename... Bn >
  320. struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type{};
  321. #endif // nsel_CPP17_OR_GREATER
  322. } // namespace std17
  323. // type traits C++20:
  324. namespace std20 {
  325. #if defined(__cpp_lib_remove_cvref)
  326. using std::remove_cvref;
  327. #else
  328. template< typename T >
  329. struct remove_cvref
  330. {
  331. typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
  332. };
  333. #endif
  334. } // namespace std20
  335. // forward declaration:
  336. template< typename T, typename E >
  337. class expected;
  338. namespace detail {
  339. /// discriminated union to hold value or 'error'.
  340. template< typename T, typename E >
  341. class storage_t_impl
  342. {
  343. template< typename, typename > friend class nonstd::expected_lite::expected;
  344. public:
  345. using value_type = T;
  346. using error_type = E;
  347. // no-op construction
  348. storage_t_impl() {}
  349. ~storage_t_impl() {}
  350. explicit storage_t_impl( bool has_value )
  351. : m_has_value( has_value )
  352. {}
  353. void construct_value( value_type const & e )
  354. {
  355. new( &m_value ) value_type( e );
  356. }
  357. void construct_value( value_type && e )
  358. {
  359. new( &m_value ) value_type( std::move( e ) );
  360. }
  361. template< class... Args >
  362. void emplace_value( Args&&... args )
  363. {
  364. new( &m_value ) value_type( std::forward<Args>(args)...);
  365. }
  366. template< class U, class... Args >
  367. void emplace_value( std::initializer_list<U> il, Args&&... args )
  368. {
  369. new( &m_value ) value_type( il, std::forward<Args>(args)... );
  370. }
  371. void destruct_value()
  372. {
  373. m_value.~value_type();
  374. }
  375. void construct_error( error_type const & e )
  376. {
  377. new( &m_error ) error_type( e );
  378. }
  379. void construct_error( error_type && e )
  380. {
  381. new( &m_error ) error_type( std::move( e ) );
  382. }
  383. template< class... Args >
  384. void emplace_error( Args&&... args )
  385. {
  386. new( &m_error ) error_type( std::forward<Args>(args)...);
  387. }
  388. template< class U, class... Args >
  389. void emplace_error( std::initializer_list<U> il, Args&&... args )
  390. {
  391. new( &m_error ) error_type( il, std::forward<Args>(args)... );
  392. }
  393. void destruct_error()
  394. {
  395. m_error.~error_type();
  396. }
  397. constexpr value_type const & value() const &
  398. {
  399. return m_value;
  400. }
  401. value_type & value() &
  402. {
  403. return m_value;
  404. }
  405. constexpr value_type const && value() const &&
  406. {
  407. return std::move( m_value );
  408. }
  409. nsel_constexpr14 value_type && value() &&
  410. {
  411. return std::move( m_value );
  412. }
  413. value_type const * value_ptr() const
  414. {
  415. return &m_value;
  416. }
  417. value_type * value_ptr()
  418. {
  419. return &m_value;
  420. }
  421. error_type const & error() const &
  422. {
  423. return m_error;
  424. }
  425. error_type & error() &
  426. {
  427. return m_error;
  428. }
  429. constexpr error_type const && error() const &&
  430. {
  431. return std::move( m_error );
  432. }
  433. nsel_constexpr14 error_type && error() &&
  434. {
  435. return std::move( m_error );
  436. }
  437. bool has_value() const
  438. {
  439. return m_has_value;
  440. }
  441. void set_has_value( bool v )
  442. {
  443. m_has_value = v;
  444. }
  445. private:
  446. union
  447. {
  448. value_type m_value;
  449. error_type m_error;
  450. };
  451. bool m_has_value = false;
  452. };
  453. /// discriminated union to hold only 'error'.
  454. template< typename E >
  455. struct storage_t_impl<void, E>
  456. {
  457. template< typename, typename > friend class nonstd::expected_lite::expected;
  458. public:
  459. using value_type = void;
  460. using error_type = E;
  461. // no-op construction
  462. storage_t_impl() {}
  463. ~storage_t_impl() {}
  464. explicit storage_t_impl( bool has_value )
  465. : m_has_value( has_value )
  466. {}
  467. void construct_error( error_type const & e )
  468. {
  469. new( &m_error ) error_type( e );
  470. }
  471. void construct_error( error_type && e )
  472. {
  473. new( &m_error ) error_type( std::move( e ) );
  474. }
  475. template< class... Args >
  476. void emplace_error( Args&&... args )
  477. {
  478. new( &m_error ) error_type( std::forward<Args>(args)...);
  479. }
  480. template< class U, class... Args >
  481. void emplace_error( std::initializer_list<U> il, Args&&... args )
  482. {
  483. new( &m_error ) error_type( il, std::forward<Args>(args)... );
  484. }
  485. void destruct_error()
  486. {
  487. m_error.~error_type();
  488. }
  489. error_type const & error() const &
  490. {
  491. return m_error;
  492. }
  493. error_type & error() &
  494. {
  495. return m_error;
  496. }
  497. constexpr error_type const && error() const &&
  498. {
  499. return std::move( m_error );
  500. }
  501. nsel_constexpr14 error_type && error() &&
  502. {
  503. return std::move( m_error );
  504. }
  505. bool has_value() const
  506. {
  507. return m_has_value;
  508. }
  509. void set_has_value( bool v )
  510. {
  511. m_has_value = v;
  512. }
  513. private:
  514. union
  515. {
  516. char m_dummy;
  517. error_type m_error;
  518. };
  519. bool m_has_value = false;
  520. };
  521. template< typename T, typename E, bool isConstructable, bool isMoveable >
  522. class storage_t
  523. {
  524. public:
  525. storage_t() = default;
  526. ~storage_t() = default;
  527. explicit storage_t( bool has_value )
  528. : storage_t_impl<T, E>( has_value )
  529. {}
  530. storage_t( storage_t const & other ) = delete;
  531. storage_t( storage_t && other ) = delete;
  532. };
  533. template< typename T, typename E >
  534. class storage_t<T, E, true, true> : public storage_t_impl<T, E>
  535. {
  536. public:
  537. storage_t() = default;
  538. ~storage_t() = default;
  539. explicit storage_t( bool has_value )
  540. : storage_t_impl<T, E>( has_value )
  541. {}
  542. storage_t( storage_t const & other )
  543. : storage_t_impl<T, E>( other.has_value() )
  544. {
  545. if ( this->has_value() ) this->construct_value( other.value() );
  546. else this->construct_error( other.error() );
  547. }
  548. storage_t(storage_t && other )
  549. : storage_t_impl<T, E>( other.has_value() )
  550. {
  551. if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
  552. else this->construct_error( std::move( other.error() ) );
  553. }
  554. };
  555. template< typename E >
  556. class storage_t<void, E, true, true> : public storage_t_impl<void, E>
  557. {
  558. public:
  559. storage_t() = default;
  560. ~storage_t() = default;
  561. explicit storage_t( bool has_value )
  562. : storage_t_impl<void, E>( has_value )
  563. {}
  564. storage_t( storage_t const & other )
  565. : storage_t_impl<void, E>( other.has_value() )
  566. {
  567. if ( this->has_value() ) ;
  568. else this->construct_error( other.error() );
  569. }
  570. storage_t(storage_t && other )
  571. : storage_t_impl<void, E>( other.has_value() )
  572. {
  573. if ( this->has_value() ) ;
  574. else this->construct_error( std::move( other.error() ) );
  575. }
  576. };
  577. template< typename T, typename E >
  578. class storage_t<T, E, true, false> : public storage_t_impl<T, E>
  579. {
  580. public:
  581. storage_t() = default;
  582. ~storage_t() = default;
  583. explicit storage_t( bool has_value )
  584. : storage_t_impl<T, E>( has_value )
  585. {}
  586. storage_t( storage_t const & other )
  587. : storage_t_impl<T, E>(other.has_value())
  588. {
  589. if ( this->has_value() ) this->construct_value( other.value() );
  590. else this->construct_error( other.error() );
  591. }
  592. storage_t( storage_t && other ) = delete;
  593. };
  594. template< typename E >
  595. class storage_t<void, E, true, false> : public storage_t_impl<void, E>
  596. {
  597. public:
  598. storage_t() = default;
  599. ~storage_t() = default;
  600. explicit storage_t( bool has_value )
  601. : storage_t_impl<void, E>( has_value )
  602. {}
  603. storage_t( storage_t const & other )
  604. : storage_t_impl<void, E>(other.has_value())
  605. {
  606. if ( this->has_value() ) ;
  607. else this->construct_error( other.error() );
  608. }
  609. storage_t( storage_t && other ) = delete;
  610. };
  611. template< typename T, typename E >
  612. class storage_t<T, E, false, true> : public storage_t_impl<T, E>
  613. {
  614. public:
  615. storage_t() = default;
  616. ~storage_t() = default;
  617. explicit storage_t( bool has_value )
  618. : storage_t_impl<T, E>( has_value )
  619. {}
  620. storage_t( storage_t const & other ) = delete;
  621. storage_t( storage_t && other )
  622. : storage_t_impl<T, E>( other.has_value() )
  623. {
  624. if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
  625. else this->construct_error( std::move( other.error() ) );
  626. }
  627. };
  628. template< typename E >
  629. class storage_t<void, E, false, true> : public storage_t_impl<void, E>
  630. {
  631. public:
  632. storage_t() = default;
  633. ~storage_t() = default;
  634. explicit storage_t( bool has_value )
  635. : storage_t_impl<void, E>( has_value )
  636. {}
  637. storage_t( storage_t const & other ) = delete;
  638. storage_t( storage_t && other )
  639. : storage_t_impl<void, E>( other.has_value() )
  640. {
  641. if ( this->has_value() ) ;
  642. else this->construct_error( std::move( other.error() ) );
  643. }
  644. };
  645. } // namespace detail
  646. /// x.x.5 Unexpected object type; unexpected_type; C++17 and later can also use aliased type unexpected.
  647. #if nsel_P0323R <= 2
  648. template< typename E = std::exception_ptr >
  649. class unexpected_type
  650. #else
  651. template< typename E >
  652. class unexpected_type
  653. #endif // nsel_P0323R
  654. {
  655. public:
  656. using error_type = E;
  657. // x.x.5.2.1 Constructors
  658. // unexpected_type() = delete;
  659. constexpr unexpected_type( unexpected_type const & ) = default;
  660. constexpr unexpected_type( unexpected_type && ) = default;
  661. template< typename... Args
  662. nsel_REQUIRES_T(
  663. std::is_constructible<E, Args&&...>::value
  664. )
  665. >
  666. constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), Args &&... args )
  667. : m_error( std::forward<Args>( args )...)
  668. {}
  669. template< typename U, typename... Args
  670. nsel_REQUIRES_T(
  671. std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
  672. )
  673. >
  674. constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), std::initializer_list<U> il, Args &&... args )
  675. : m_error( il, std::forward<Args>( args )...)
  676. {}
  677. template< typename E2
  678. nsel_REQUIRES_T(
  679. std::is_constructible<E,E2>::value
  680. && !std::is_same< typename std20::remove_cvref<E2>::type, nonstd_lite_in_place_t(E2) >::value
  681. && !std::is_same< typename std20::remove_cvref<E2>::type, unexpected_type >::value
  682. )
  683. >
  684. constexpr explicit unexpected_type( E2 && error )
  685. : m_error( std::forward<E2>( error ) )
  686. {}
  687. template< typename E2
  688. nsel_REQUIRES_T(
  689. std::is_constructible< E, E2>::value
  690. && !std::is_constructible<E, unexpected_type<E2> & >::value
  691. && !std::is_constructible<E, unexpected_type<E2> >::value
  692. && !std::is_constructible<E, unexpected_type<E2> const & >::value
  693. && !std::is_constructible<E, unexpected_type<E2> const >::value
  694. && !std::is_convertible< unexpected_type<E2> &, E>::value
  695. && !std::is_convertible< unexpected_type<E2> , E>::value
  696. && !std::is_convertible< unexpected_type<E2> const &, E>::value
  697. && !std::is_convertible< unexpected_type<E2> const , E>::value
  698. && !std::is_convertible< E2 const &, E>::value /*=> explicit */
  699. )
  700. >
  701. constexpr explicit unexpected_type( unexpected_type<E2> const & error )
  702. : m_error( E{ error.value() } )
  703. {}
  704. template< typename E2
  705. nsel_REQUIRES_T(
  706. std::is_constructible< E, E2>::value
  707. && !std::is_constructible<E, unexpected_type<E2> & >::value
  708. && !std::is_constructible<E, unexpected_type<E2> >::value
  709. && !std::is_constructible<E, unexpected_type<E2> const & >::value
  710. && !std::is_constructible<E, unexpected_type<E2> const >::value
  711. && !std::is_convertible< unexpected_type<E2> &, E>::value
  712. && !std::is_convertible< unexpected_type<E2> , E>::value
  713. && !std::is_convertible< unexpected_type<E2> const &, E>::value
  714. && !std::is_convertible< unexpected_type<E2> const , E>::value
  715. && std::is_convertible< E2 const &, E>::value /*=> explicit */
  716. )
  717. >
  718. constexpr /*non-explicit*/ unexpected_type( unexpected_type<E2> const & error )
  719. : m_error( error.value() )
  720. {}
  721. template< typename E2
  722. nsel_REQUIRES_T(
  723. std::is_constructible< E, E2>::value
  724. && !std::is_constructible<E, unexpected_type<E2> & >::value
  725. && !std::is_constructible<E, unexpected_type<E2> >::value
  726. && !std::is_constructible<E, unexpected_type<E2> const & >::value
  727. && !std::is_constructible<E, unexpected_type<E2> const >::value
  728. && !std::is_convertible< unexpected_type<E2> &, E>::value
  729. && !std::is_convertible< unexpected_type<E2> , E>::value
  730. && !std::is_convertible< unexpected_type<E2> const &, E>::value
  731. && !std::is_convertible< unexpected_type<E2> const , E>::value
  732. && !std::is_convertible< E2 const &, E>::value /*=> explicit */
  733. )
  734. >
  735. constexpr explicit unexpected_type( unexpected_type<E2> && error )
  736. : m_error( E{ std::move( error.value() ) } )
  737. {}
  738. template< typename E2
  739. nsel_REQUIRES_T(
  740. std::is_constructible< E, E2>::value
  741. && !std::is_constructible<E, unexpected_type<E2> & >::value
  742. && !std::is_constructible<E, unexpected_type<E2> >::value
  743. && !std::is_constructible<E, unexpected_type<E2> const & >::value
  744. && !std::is_constructible<E, unexpected_type<E2> const >::value
  745. && !std::is_convertible< unexpected_type<E2> &, E>::value
  746. && !std::is_convertible< unexpected_type<E2> , E>::value
  747. && !std::is_convertible< unexpected_type<E2> const &, E>::value
  748. && !std::is_convertible< unexpected_type<E2> const , E>::value
  749. && std::is_convertible< E2 const &, E>::value /*=> non-explicit */
  750. )
  751. >
  752. constexpr /*non-explicit*/ unexpected_type( unexpected_type<E2> && error )
  753. : m_error( std::move( error.value() ) )
  754. {}
  755. // x.x.5.2.2 Assignment
  756. nsel_constexpr14 unexpected_type& operator=( unexpected_type const & ) = default;
  757. nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) = default;
  758. template< typename E2 = E >
  759. nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> const & other )
  760. {
  761. unexpected_type{ other.value() }.swap( *this );
  762. return *this;
  763. }
  764. template< typename E2 = E >
  765. nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> && other )
  766. {
  767. unexpected_type{ std::move( other.value() ) }.swap( *this );
  768. return *this;
  769. }
  770. // x.x.5.2.3 Observers
  771. nsel_constexpr14 E & value() & noexcept
  772. {
  773. return m_error;
  774. }
  775. constexpr E const & value() const & noexcept
  776. {
  777. return m_error;
  778. }
  779. #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
  780. nsel_constexpr14 E && value() && noexcept
  781. {
  782. return std::move( m_error );
  783. }
  784. constexpr E const && value() const && noexcept
  785. {
  786. return std::move( m_error );
  787. }
  788. #endif
  789. // x.x.5.2.4 Swap
  790. nsel_REQUIRES_R( void,
  791. std17::is_swappable<E>::value
  792. )
  793. swap( unexpected_type & other ) noexcept (
  794. std17::is_nothrow_swappable<E>::value
  795. )
  796. {
  797. using std::swap;
  798. swap( m_error, other.m_error );
  799. }
  800. // TODO: ??? unexpected_type: in-class friend operator==, !=
  801. private:
  802. error_type m_error;
  803. };
  804. #if nsel_CPP17_OR_GREATER
  805. /// template deduction guide:
  806. template< typename E >
  807. unexpected_type( E ) -> unexpected_type< E >;
  808. #endif
  809. /// class unexpected_type, std::exception_ptr specialization (P0323R2)
  810. #if !nsel_CONFIG_NO_EXCEPTIONS
  811. #if nsel_P0323R <= 2
  812. // TODO: Should expected be specialized for particular E types such as exception_ptr and how?
  813. // See p0323r7 2.1. Ergonomics, http://wg21.link/p0323
  814. template<>
  815. class unexpected_type< std::exception_ptr >
  816. {
  817. public:
  818. using error_type = std::exception_ptr;
  819. unexpected_type() = delete;
  820. ~unexpected_type(){}
  821. explicit unexpected_type( std::exception_ptr const & error )
  822. : m_error( error )
  823. {}
  824. explicit unexpected_type(std::exception_ptr && error )
  825. : m_error( std::move( error ) )
  826. {}
  827. template< typename E >
  828. explicit unexpected_type( E error )
  829. : m_error( std::make_exception_ptr( error ) )
  830. {}
  831. std::exception_ptr const & value() const
  832. {
  833. return m_error;
  834. }
  835. std::exception_ptr & value()
  836. {
  837. return m_error;
  838. }
  839. private:
  840. std::exception_ptr m_error;
  841. };
  842. #endif // nsel_P0323R
  843. #endif // !nsel_CONFIG_NO_EXCEPTIONS
  844. /// x.x.4, Unexpected equality operators
  845. template< typename E1, typename E2 >
  846. constexpr bool operator==( unexpected_type<E1> const & x, unexpected_type<E2> const & y )
  847. {
  848. return x.value() == y.value();
  849. }
  850. template< typename E1, typename E2 >
  851. constexpr bool operator!=( unexpected_type<E1> const & x, unexpected_type<E2> const & y )
  852. {
  853. return ! ( x == y );
  854. }
  855. #if nsel_P0323R <= 2
  856. template< typename E >
  857. constexpr bool operator<( unexpected_type<E> const & x, unexpected_type<E> const & y )
  858. {
  859. return x.value() < y.value();
  860. }
  861. template< typename E >
  862. constexpr bool operator>( unexpected_type<E> const & x, unexpected_type<E> const & y )
  863. {
  864. return ( y < x );
  865. }
  866. template< typename E >
  867. constexpr bool operator<=( unexpected_type<E> const & x, unexpected_type<E> const & y )
  868. {
  869. return ! ( y < x );
  870. }
  871. template< typename E >
  872. constexpr bool operator>=( unexpected_type<E> const & x, unexpected_type<E> const & y )
  873. {
  874. return ! ( x < y );
  875. }
  876. #endif // nsel_P0323R
  877. /// x.x.5 Specialized algorithms
  878. template< typename E
  879. nsel_REQUIRES_T(
  880. std17::is_swappable<E>::value
  881. )
  882. >
  883. void swap( unexpected_type<E> & x, unexpected_type<E> & y) noexcept ( noexcept ( x.swap(y) ) )
  884. {
  885. x.swap( y );
  886. }
  887. #if nsel_P0323R <= 2
  888. // unexpected: relational operators for std::exception_ptr:
  889. inline constexpr bool operator<( unexpected_type<std::exception_ptr> const & /*x*/, unexpected_type<std::exception_ptr> const & /*y*/ )
  890. {
  891. return false;
  892. }
  893. inline constexpr bool operator>( unexpected_type<std::exception_ptr> const & /*x*/, unexpected_type<std::exception_ptr> const & /*y*/ )
  894. {
  895. return false;
  896. }
  897. inline constexpr bool operator<=( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
  898. {
  899. return ( x == y );
  900. }
  901. inline constexpr bool operator>=( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
  902. {
  903. return ( x == y );
  904. }
  905. #endif // nsel_P0323R
  906. // unexpected: traits
  907. #if nsel_P0323R <= 3
  908. template< typename E>
  909. struct is_unexpected : std::false_type {};
  910. template< typename E>
  911. struct is_unexpected< unexpected_type<E> > : std::true_type {};
  912. #endif // nsel_P0323R
  913. // unexpected: factory
  914. // keep make_unexpected() removed in p0323r2 for pre-C++17:
  915. template< typename E>
  916. nsel_constexpr14 auto
  917. make_unexpected( E && value ) -> unexpected_type< typename std::decay<E>::type >
  918. {
  919. return unexpected_type< typename std::decay<E>::type >( std::forward<E>(value) );
  920. }
  921. #if nsel_P0323R <= 3
  922. /*nsel_constexpr14*/ auto inline
  923. make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
  924. {
  925. return unexpected_type< std::exception_ptr >( std::current_exception() );
  926. }
  927. #endif // nsel_P0323R
  928. /// x.x.6, x.x.7 expected access error
  929. template< typename E >
  930. class bad_expected_access;
  931. /// x.x.7 bad_expected_access<void>: expected access error
  932. template <>
  933. class bad_expected_access< void > : public std::exception
  934. {
  935. public:
  936. explicit bad_expected_access()
  937. : std::exception()
  938. {}
  939. };
  940. /// x.x.6 bad_expected_access: expected access error
  941. #if !nsel_CONFIG_NO_EXCEPTIONS
  942. template< typename E >
  943. class bad_expected_access : public bad_expected_access< void >
  944. {
  945. public:
  946. using error_type = E;
  947. explicit bad_expected_access( error_type error )
  948. : m_error( error )
  949. {}
  950. virtual char const * what() const noexcept override
  951. {
  952. return "bad_expected_access";
  953. }
  954. nsel_constexpr14 error_type & error() &
  955. {
  956. return m_error;
  957. }
  958. constexpr error_type const & error() const &
  959. {
  960. return m_error;
  961. }
  962. #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
  963. nsel_constexpr14 error_type && error() &&
  964. {
  965. return std::move( m_error );
  966. }
  967. constexpr error_type const && error() const &&
  968. {
  969. return std::move( m_error );
  970. }
  971. #endif
  972. private:
  973. error_type m_error;
  974. };
  975. #endif // nsel_CONFIG_NO_EXCEPTIONS
  976. /// x.x.8 unexpect tag, in_place_unexpected tag: construct an error
  977. struct unexpect_t{};
  978. using in_place_unexpected_t = unexpect_t;
  979. nsel_inline17 constexpr unexpect_t unexpect{};
  980. nsel_inline17 constexpr unexpect_t in_place_unexpected{};
  981. /// class error_traits
  982. #if nsel_CONFIG_NO_EXCEPTIONS
  983. namespace detail {
  984. inline bool text( char const * /*text*/ ) { return true; }
  985. }
  986. template< typename Error >
  987. struct error_traits
  988. {
  989. static void rethrow( Error const & /*e*/ )
  990. {
  991. #if nsel_CONFIG_NO_EXCEPTIONS_SEH
  992. RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
  993. #else
  994. assert( false && detail::text("throw bad_expected_access<Error>{ e };") );
  995. #endif
  996. }
  997. };
  998. template<>
  999. struct error_traits< std::exception_ptr >
  1000. {
  1001. static void rethrow( std::exception_ptr const & /*e*/ )
  1002. {
  1003. #if nsel_CONFIG_NO_EXCEPTIONS_SEH
  1004. RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
  1005. #else
  1006. assert( false && detail::text("throw bad_expected_access<std::exception_ptr>{ e };") );
  1007. #endif
  1008. }
  1009. };
  1010. template<>
  1011. struct error_traits< std::error_code >
  1012. {
  1013. static void rethrow( std::error_code const & /*e*/ )
  1014. {
  1015. #if nsel_CONFIG_NO_EXCEPTIONS_SEH
  1016. RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
  1017. #else
  1018. assert( false && detail::text("throw std::system_error( e );") );
  1019. #endif
  1020. }
  1021. };
  1022. #else // nsel_CONFIG_NO_EXCEPTIONS
  1023. template< typename Error >
  1024. struct error_traits
  1025. {
  1026. static void rethrow( Error const & e )
  1027. {
  1028. throw bad_expected_access<Error>{ e };
  1029. }
  1030. };
  1031. template<>
  1032. struct error_traits< std::exception_ptr >
  1033. {
  1034. static void rethrow( std::exception_ptr const & e )
  1035. {
  1036. std::rethrow_exception( e );
  1037. }
  1038. };
  1039. template<>
  1040. struct error_traits< std::error_code >
  1041. {
  1042. static void rethrow( std::error_code const & e )
  1043. {
  1044. throw std::system_error( e );
  1045. }
  1046. };
  1047. #endif // nsel_CONFIG_NO_EXCEPTIONS
  1048. } // namespace expected_lite
  1049. // provide nonstd::unexpected_type:
  1050. using expected_lite::unexpected_type;
  1051. namespace expected_lite {
  1052. /// class expected
  1053. #if nsel_P0323R <= 2
  1054. template< typename T, typename E = std::exception_ptr >
  1055. class expected
  1056. #else
  1057. template< typename T, typename E >
  1058. class expected
  1059. #endif // nsel_P0323R
  1060. {
  1061. private:
  1062. template< typename, typename > friend class expected;
  1063. public:
  1064. using value_type = T;
  1065. using error_type = E;
  1066. using unexpected_type = nonstd::unexpected_type<E>;
  1067. template< typename U >
  1068. struct rebind
  1069. {
  1070. using type = expected<U, error_type>;
  1071. };
  1072. // x.x.4.1 constructors
  1073. nsel_REQUIRES_0(
  1074. std::is_default_constructible<T>::value
  1075. )
  1076. nsel_constexpr14 expected()
  1077. : contained( true )
  1078. {
  1079. contained.construct_value( value_type() );
  1080. }
  1081. nsel_constexpr14 expected( expected const & ) = default;
  1082. nsel_constexpr14 expected( expected && ) = default;
  1083. template< typename U, typename G
  1084. nsel_REQUIRES_T(
  1085. std::is_constructible< T, U const &>::value
  1086. && std::is_constructible<E, G const &>::value
  1087. && !std::is_constructible<T, expected<U, G> & >::value
  1088. && !std::is_constructible<T, expected<U, G> && >::value
  1089. && !std::is_constructible<T, expected<U, G> const & >::value
  1090. && !std::is_constructible<T, expected<U, G> const && >::value
  1091. && !std::is_convertible< expected<U, G> & , T>::value
  1092. && !std::is_convertible< expected<U, G> &&, T>::value
  1093. && !std::is_convertible< expected<U, G> const & , T>::value
  1094. && !std::is_convertible< expected<U, G> const &&, T>::value
  1095. && (!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value ) /*=> explicit */
  1096. )
  1097. >
  1098. nsel_constexpr14 explicit expected( expected<U, G> const & other )
  1099. : contained( other.has_value() )
  1100. {
  1101. if ( has_value() ) contained.construct_value( T{ other.contained.value() } );
  1102. else contained.construct_error( E{ other.contained.error() } );
  1103. }
  1104. template< typename U, typename G
  1105. nsel_REQUIRES_T(
  1106. std::is_constructible< T, U const &>::value
  1107. && std::is_constructible<E, G const &>::value
  1108. && !std::is_constructible<T, expected<U, G> & >::value
  1109. && !std::is_constructible<T, expected<U, G> && >::value
  1110. && !std::is_constructible<T, expected<U, G> const & >::value
  1111. && !std::is_constructible<T, expected<U, G> const && >::value
  1112. && !std::is_convertible< expected<U, G> & , T>::value
  1113. && !std::is_convertible< expected<U, G> &&, T>::value
  1114. && !std::is_convertible< expected<U, G> const &, T>::value
  1115. && !std::is_convertible< expected<U, G> const &&, T>::value
  1116. && !(!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value ) /*=> non-explicit */
  1117. )
  1118. >
  1119. nsel_constexpr14 /*non-explicit*/ expected( expected<U, G> const & other )
  1120. : contained( other.has_value() )
  1121. {
  1122. if ( has_value() ) contained.construct_value( other.contained.value() );
  1123. else contained.construct_error( other.contained.error() );
  1124. }
  1125. template< typename U, typename G
  1126. nsel_REQUIRES_T(
  1127. std::is_constructible< T, U>::value
  1128. && std::is_constructible<E, G>::value
  1129. && !std::is_constructible<T, expected<U, G> & >::value
  1130. && !std::is_constructible<T, expected<U, G> && >::value
  1131. && !std::is_constructible<T, expected<U, G> const & >::value
  1132. && !std::is_constructible<T, expected<U, G> const && >::value
  1133. && !std::is_convertible< expected<U, G> & , T>::value
  1134. && !std::is_convertible< expected<U, G> &&, T>::value
  1135. && !std::is_convertible< expected<U, G> const & , T>::value
  1136. && !std::is_convertible< expected<U, G> const &&, T>::value
  1137. && (!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value ) /*=> explicit */
  1138. )
  1139. >
  1140. nsel_constexpr14 explicit expected( expected<U, G> && other )
  1141. : contained( other.has_value() )
  1142. {
  1143. if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } );
  1144. else contained.construct_error( E{ std::move( other.contained.error() ) } );
  1145. }
  1146. template< typename U, typename G
  1147. nsel_REQUIRES_T(
  1148. std::is_constructible< T, U>::value
  1149. && std::is_constructible<E, G>::value
  1150. && !std::is_constructible<T, expected<U, G> & >::value
  1151. && !std::is_constructible<T, expected<U, G> && >::value
  1152. && !std::is_constructible<T, expected<U, G> const & >::value
  1153. && !std::is_constructible<T, expected<U, G> const && >::value
  1154. && !std::is_convertible< expected<U, G> & , T>::value
  1155. && !std::is_convertible< expected<U, G> &&, T>::value
  1156. && !std::is_convertible< expected<U, G> const & , T>::value
  1157. && !std::is_convertible< expected<U, G> const &&, T>::value
  1158. && !(!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value ) /*=> non-explicit */
  1159. )
  1160. >
  1161. nsel_constexpr14 /*non-explicit*/ expected( expected<U, G> && other )
  1162. : contained( other.has_value() )
  1163. {
  1164. if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
  1165. else contained.construct_error( std::move( other.contained.error() ) );
  1166. }
  1167. template< typename U = T
  1168. nsel_REQUIRES_T(
  1169. std::is_copy_constructible<U>::value
  1170. )
  1171. >
  1172. nsel_constexpr14 expected( value_type const & value )
  1173. : contained( true )
  1174. {
  1175. contained.construct_value( value );
  1176. }
  1177. template< typename U = T
  1178. nsel_REQUIRES_T(
  1179. std::is_constructible<T,U&&>::value
  1180. && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  1181. && !std::is_same< expected<T,E> , typename std20::remove_cvref<U>::type>::value
  1182. && !std::is_same<nonstd::unexpected_type<E>, typename std20::remove_cvref<U>::type>::value
  1183. && !std::is_convertible<U&&,T>::value /*=> explicit */
  1184. )
  1185. >
  1186. nsel_constexpr14 explicit expected( U && value ) noexcept
  1187. (
  1188. std::is_nothrow_move_constructible<U>::value &&
  1189. std::is_nothrow_move_constructible<E>::value
  1190. )
  1191. : contained( true )
  1192. {
  1193. contained.construct_value( T{ std::forward<U>( value ) } );
  1194. }
  1195. template< typename U = T
  1196. nsel_REQUIRES_T(
  1197. std::is_constructible<T,U&&>::value
  1198. && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  1199. && !std::is_same< expected<T,E> , typename std20::remove_cvref<U>::type>::value
  1200. && !std::is_same<nonstd::unexpected_type<E>, typename std20::remove_cvref<U>::type>::value
  1201. && std::is_convertible<U&&,T>::value /*=> non-explicit */
  1202. )
  1203. >
  1204. nsel_constexpr14 /*non-explicit*/ expected( U && value ) noexcept
  1205. (
  1206. std::is_nothrow_move_constructible<U>::value &&
  1207. std::is_nothrow_move_constructible<E>::value
  1208. )
  1209. : contained( true )
  1210. {
  1211. contained.construct_value( std::forward<U>( value ) );
  1212. }
  1213. // construct error:
  1214. template< typename G = E
  1215. nsel_REQUIRES_T(
  1216. std::is_constructible<E, G const & >::value
  1217. && !std::is_convertible< G const &, E>::value /*=> explicit */
  1218. )
  1219. >
  1220. nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> const & error )
  1221. : contained( false )
  1222. {
  1223. contained.construct_error( E{ error.value() } );
  1224. }
  1225. template< typename G = E
  1226. nsel_REQUIRES_T(
  1227. std::is_constructible<E, G const & >::value
  1228. && std::is_convertible< G const &, E>::value /*=> non-explicit */
  1229. )
  1230. >
  1231. nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> const & error )
  1232. : contained( false )
  1233. {
  1234. contained.construct_error( error.value() );
  1235. }
  1236. template< typename G = E
  1237. nsel_REQUIRES_T(
  1238. std::is_constructible<E, G&& >::value
  1239. && !std::is_convertible< G&&, E>::value /*=> explicit */
  1240. )
  1241. >
  1242. nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> && error )
  1243. : contained( false )
  1244. {
  1245. contained.construct_error( E{ std::move( error.value() ) } );
  1246. }
  1247. template< typename G = E
  1248. nsel_REQUIRES_T(
  1249. std::is_constructible<E, G&& >::value
  1250. && std::is_convertible< G&&, E>::value /*=> non-explicit */
  1251. )
  1252. >
  1253. nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> && error )
  1254. : contained( false )
  1255. {
  1256. contained.construct_error( std::move( error.value() ) );
  1257. }
  1258. // in-place construction, value
  1259. template< typename... Args
  1260. nsel_REQUIRES_T(
  1261. std::is_constructible<T, Args&&...>::value
  1262. )
  1263. >
  1264. nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), Args&&... args )
  1265. : contained( true )
  1266. {
  1267. contained.emplace_value( std::forward<Args>( args )... );
  1268. }
  1269. template< typename U, typename... Args
  1270. nsel_REQUIRES_T(
  1271. std::is_constructible<T, std::initializer_list<U>, Args&&...>::value
  1272. )
  1273. >
  1274. nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
  1275. : contained( true )
  1276. {
  1277. contained.emplace_value( il, std::forward<Args>( args )... );
  1278. }
  1279. // in-place construction, error
  1280. template< typename... Args
  1281. nsel_REQUIRES_T(
  1282. std::is_constructible<E, Args&&...>::value
  1283. )
  1284. >
  1285. nsel_constexpr14 explicit expected( unexpect_t, Args&&... args )
  1286. : contained( false )
  1287. {
  1288. contained.emplace_error( std::forward<Args>( args )... );
  1289. }
  1290. template< typename U, typename... Args
  1291. nsel_REQUIRES_T(
  1292. std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
  1293. )
  1294. >
  1295. nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
  1296. : contained( false )
  1297. {
  1298. contained.emplace_error( il, std::forward<Args>( args )... );
  1299. }
  1300. // x.x.4.2 destructor
  1301. // TODO: ~expected: triviality
  1302. // Effects: If T is not cv void and is_trivially_destructible_v<T> is false and bool(*this), calls val.~T(). If is_trivially_destructible_v<E> is false and !bool(*this), calls unexpect.~unexpected<E>().
  1303. // Remarks: If either T is cv void or is_trivially_destructible_v<T> is true, and is_trivially_destructible_v<E> is true, then this destructor shall be a trivial destructor.
  1304. ~expected()
  1305. {
  1306. if ( has_value() ) contained.destruct_value();
  1307. else contained.destruct_error();
  1308. }
  1309. // x.x.4.3 assignment
  1310. expected & operator=( expected const & other )
  1311. {
  1312. expected( other ).swap( *this );
  1313. return *this;
  1314. }
  1315. expected & operator=( expected && other ) noexcept
  1316. (
  1317. std::is_nothrow_move_constructible< T>::value
  1318. && std::is_nothrow_move_assignable< T>::value
  1319. && std::is_nothrow_move_constructible<E>::value // added for missing
  1320. && std::is_nothrow_move_assignable< E>::value ) // nothrow above
  1321. {
  1322. expected( std::move( other ) ).swap( *this );
  1323. return *this;
  1324. }
  1325. template< typename U
  1326. nsel_REQUIRES_T(
  1327. !std::is_same<expected<T,E>, typename std20::remove_cvref<U>::type>::value
  1328. && std17::conjunction<std::is_scalar<T>, std::is_same<T, std::decay<U>> >::value
  1329. && std::is_constructible<T ,U>::value
  1330. && std::is_assignable< T&,U>::value
  1331. && std::is_nothrow_move_constructible<E>::value )
  1332. >
  1333. expected & operator=( U && value )
  1334. {
  1335. expected( std::forward<U>( value ) ).swap( *this );
  1336. return *this;
  1337. }
  1338. template< typename G = E
  1339. nsel_REQUIRES_T(
  1340. std::is_constructible<E, G const&>::value &&
  1341. std::is_copy_constructible<G>::value // TODO: std::is_nothrow_copy_constructible<G>
  1342. && std::is_copy_assignable<G>::value
  1343. )
  1344. >
  1345. expected & operator=( nonstd::unexpected_type<G> const & error )
  1346. {
  1347. expected( unexpect, error.value() ).swap( *this );
  1348. return *this;
  1349. }
  1350. template< typename G = E
  1351. nsel_REQUIRES_T(
  1352. std::is_constructible<E, G&&>::value &&
  1353. std::is_move_constructible<G>::value // TODO: std::is_nothrow_move_constructible<G>
  1354. && std::is_move_assignable<G>::value
  1355. )
  1356. >
  1357. expected & operator=( nonstd::unexpected_type<G> && error )
  1358. {
  1359. expected( unexpect, std::move( error.value() ) ).swap( *this );
  1360. return *this;
  1361. }
  1362. template< typename... Args
  1363. nsel_REQUIRES_T(
  1364. std::is_nothrow_constructible<T, Args&&...>::value
  1365. )
  1366. >
  1367. value_type & emplace( Args &&... args )
  1368. {
  1369. expected( nonstd_lite_in_place(T), std::forward<Args>(args)... ).swap( *this );
  1370. return value();
  1371. }
  1372. template< typename U, typename... Args
  1373. nsel_REQUIRES_T(
  1374. std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::value
  1375. )
  1376. >
  1377. value_type & emplace( std::initializer_list<U> il, Args &&... args )
  1378. {
  1379. expected( nonstd_lite_in_place(T), il, std::forward<Args>(args)... ).swap( *this );
  1380. return value();
  1381. }
  1382. // x.x.4.4 swap
  1383. template< typename U=T, typename G=E >
  1384. nsel_REQUIRES_R( void,
  1385. std17::is_swappable< U>::value
  1386. && std17::is_swappable<G>::value
  1387. && ( std::is_move_constructible<U>::value || std::is_move_constructible<G>::value )
  1388. )
  1389. swap( expected & other ) noexcept
  1390. (
  1391. std::is_nothrow_move_constructible<T>::value && std17::is_nothrow_swappable<T&>::value &&
  1392. std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
  1393. )
  1394. {
  1395. using std::swap;
  1396. if ( bool(*this) && bool(other) ) { swap( contained.value(), other.contained.value() ); }
  1397. else if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); }
  1398. else if ( bool(*this) && ! bool(other) ) { error_type t( std::move( other.error() ) );
  1399. other.contained.destruct_error();
  1400. other.contained.construct_value( std::move( contained.value() ) );
  1401. contained.destruct_value();
  1402. contained.construct_error( std::move( t ) );
  1403. bool has_value = contained.has_value();
  1404. bool other_has_value = other.has_value();
  1405. other.contained.set_has_value(has_value);
  1406. contained.set_has_value(other_has_value);
  1407. }
  1408. else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); }
  1409. }
  1410. // x.x.4.5 observers
  1411. constexpr value_type const * operator ->() const
  1412. {
  1413. return assert( has_value() ), contained.value_ptr();
  1414. }
  1415. value_type * operator ->()
  1416. {
  1417. return assert( has_value() ), contained.value_ptr();
  1418. }
  1419. constexpr value_type const & operator *() const &
  1420. {
  1421. return assert( has_value() ), contained.value();
  1422. }
  1423. value_type & operator *() &
  1424. {
  1425. return assert( has_value() ), contained.value();
  1426. }
  1427. #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
  1428. constexpr value_type const && operator *() const &&
  1429. {
  1430. return std::move( ( assert( has_value() ), contained.value() ) );
  1431. }
  1432. nsel_constexpr14 value_type && operator *() &&
  1433. {
  1434. return std::move( ( assert( has_value() ), contained.value() ) );
  1435. }
  1436. #endif
  1437. constexpr explicit operator bool() const noexcept
  1438. {
  1439. return has_value();
  1440. }
  1441. constexpr bool has_value() const noexcept
  1442. {
  1443. return contained.has_value();
  1444. }
  1445. constexpr value_type const & value() const &
  1446. {
  1447. return has_value()
  1448. ? ( contained.value() )
  1449. : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
  1450. }
  1451. value_type & value() &
  1452. {
  1453. return has_value()
  1454. ? ( contained.value() )
  1455. : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
  1456. }
  1457. #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
  1458. constexpr value_type const && value() const &&
  1459. {
  1460. return std::move( has_value()
  1461. ? ( contained.value() )
  1462. : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
  1463. }
  1464. nsel_constexpr14 value_type && value() &&
  1465. {
  1466. return std::move( has_value()
  1467. ? ( contained.value() )
  1468. : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
  1469. }
  1470. #endif
  1471. constexpr error_type const & error() const &
  1472. {
  1473. return assert( ! has_value() ), contained.error();
  1474. }
  1475. error_type & error() &
  1476. {
  1477. return assert( ! has_value() ), contained.error();
  1478. }
  1479. #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
  1480. constexpr error_type const && error() const &&
  1481. {
  1482. return std::move( ( assert( ! has_value() ), contained.error() ) );
  1483. }
  1484. error_type && error() &&
  1485. {
  1486. return std::move( ( assert( ! has_value() ), contained.error() ) );
  1487. }
  1488. #endif
  1489. constexpr unexpected_type get_unexpected() const
  1490. {
  1491. return make_unexpected( contained.error() );
  1492. }
  1493. template< typename Ex >
  1494. bool has_exception() const
  1495. {
  1496. using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
  1497. return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
  1498. }
  1499. template< typename U
  1500. nsel_REQUIRES_T(
  1501. std::is_copy_constructible< T>::value
  1502. && std::is_convertible<U&&, T>::value
  1503. )
  1504. >
  1505. value_type value_or( U && v ) const &
  1506. {
  1507. return has_value()
  1508. ? contained.value()
  1509. : static_cast<T>( std::forward<U>( v ) );
  1510. }
  1511. template< typename U
  1512. nsel_REQUIRES_T(
  1513. std::is_move_constructible< T>::value
  1514. && std::is_convertible<U&&, T>::value
  1515. )
  1516. >
  1517. value_type value_or( U && v ) &&
  1518. {
  1519. return has_value()
  1520. ? std::move( contained.value() )
  1521. : static_cast<T>( std::forward<U>( v ) );
  1522. }
  1523. // unwrap()
  1524. // template <class U, class E>
  1525. // constexpr expected<U,E> expected<expected<U,E>,E>::unwrap() const&;
  1526. // template <class T, class E>
  1527. // constexpr expected<T,E> expected<T,E>::unwrap() const&;
  1528. // template <class U, class E>
  1529. // expected<U,E> expected<expected<U,E>, E>::unwrap() &&;
  1530. // template <class T, class E>
  1531. // template expected<T,E> expected<T,E>::unwrap() &&;
  1532. // factories
  1533. // template< typename Ex, typename F>
  1534. // expected<T,E> catch_exception(F&& f);
  1535. // template< typename F>
  1536. // expected<decltype(func(declval<T>())),E> map(F&& func) ;
  1537. // template< typename F>
  1538. // 'see below' bind(F&& func);
  1539. // template< typename F>
  1540. // expected<T,E> catch_error(F&& f);
  1541. // template< typename F>
  1542. // 'see below' then(F&& func);
  1543. private:
  1544. detail::storage_t
  1545. <
  1546. T
  1547. ,E
  1548. , std::is_copy_constructible<T>::value && std::is_copy_constructible<E>::value
  1549. , std::is_move_constructible<T>::value && std::is_move_constructible<E>::value
  1550. >
  1551. contained;
  1552. };
  1553. /// class expected, void specialization
  1554. template< typename E >
  1555. class expected<void, E>
  1556. {
  1557. private:
  1558. template< typename, typename > friend class expected;
  1559. public:
  1560. using value_type = void;
  1561. using error_type = E;
  1562. using unexpected_type = nonstd::unexpected_type<E>;
  1563. // x.x.4.1 constructors
  1564. constexpr expected() noexcept
  1565. : contained( true )
  1566. {}
  1567. nsel_constexpr14 expected( expected const & other ) = default;
  1568. nsel_constexpr14 expected( expected && other ) = default;
  1569. constexpr explicit expected( nonstd_lite_in_place_t(void) )
  1570. : contained( true )
  1571. {}
  1572. template< typename G = E
  1573. nsel_REQUIRES_T(
  1574. !std::is_convertible<G const &, E>::value /*=> explicit */
  1575. )
  1576. >
  1577. nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> const & error )
  1578. : contained( false )
  1579. {
  1580. contained.construct_error( E{ error.value() } );
  1581. }
  1582. template< typename G = E
  1583. nsel_REQUIRES_T(
  1584. std::is_convertible<G const &, E>::value /*=> non-explicit */
  1585. )
  1586. >
  1587. nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> const & error )
  1588. : contained( false )
  1589. {
  1590. contained.construct_error( error.value() );
  1591. }
  1592. template< typename G = E
  1593. nsel_REQUIRES_T(
  1594. !std::is_convertible<G&&, E>::value /*=> explicit */
  1595. )
  1596. >
  1597. nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> && error )
  1598. : contained( false )
  1599. {
  1600. contained.construct_error( E{ std::move( error.value() ) } );
  1601. }
  1602. template< typename G = E
  1603. nsel_REQUIRES_T(
  1604. std::is_convertible<G&&, E>::value /*=> non-explicit */
  1605. )
  1606. >
  1607. nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> && error )
  1608. : contained( false )
  1609. {
  1610. contained.construct_error( std::move( error.value() ) );
  1611. }
  1612. template< typename... Args
  1613. nsel_REQUIRES_T(
  1614. std::is_constructible<E, Args&&...>::value
  1615. )
  1616. >
  1617. nsel_constexpr14 explicit expected( unexpect_t, Args&&... args )
  1618. : contained( false )
  1619. {
  1620. contained.emplace_error( std::forward<Args>( args )... );
  1621. }
  1622. template< typename U, typename... Args
  1623. nsel_REQUIRES_T(
  1624. std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
  1625. )
  1626. >
  1627. nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
  1628. : contained( false )
  1629. {
  1630. contained.emplace_error( il, std::forward<Args>( args )... );
  1631. }
  1632. // destructor
  1633. ~expected()
  1634. {
  1635. if ( ! has_value() )
  1636. {
  1637. contained.destruct_error();
  1638. }
  1639. }
  1640. // x.x.4.3 assignment
  1641. expected & operator=( expected const & other )
  1642. {
  1643. expected( other ).swap( *this );
  1644. return *this;
  1645. }
  1646. expected & operator=( expected && other ) noexcept
  1647. (
  1648. std::is_nothrow_move_assignable<E>::value &&
  1649. std::is_nothrow_move_constructible<E>::value )
  1650. {
  1651. expected( std::move( other ) ).swap( *this );
  1652. return *this;
  1653. }
  1654. void emplace()
  1655. {
  1656. expected().swap( *this );
  1657. }
  1658. // x.x.4.4 swap
  1659. template< typename G = E >
  1660. nsel_REQUIRES_R( void,
  1661. std17::is_swappable<G>::value
  1662. && std::is_move_constructible<G>::value
  1663. )
  1664. swap( expected & other ) noexcept
  1665. (
  1666. std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
  1667. )
  1668. {
  1669. using std::swap;
  1670. if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); }
  1671. else if ( bool(*this) && ! bool(other) ) { contained.construct_error( std::move( other.error() ) );
  1672. bool has_value = contained.has_value();
  1673. bool other_has_value = other.has_value();
  1674. other.contained.set_has_value(has_value);
  1675. contained.set_has_value(other_has_value);
  1676. }
  1677. else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); }
  1678. }
  1679. // x.x.4.5 observers
  1680. constexpr explicit operator bool() const noexcept
  1681. {
  1682. return has_value();
  1683. }
  1684. constexpr bool has_value() const noexcept
  1685. {
  1686. return contained.has_value();
  1687. }
  1688. void value() const
  1689. {
  1690. if ( ! has_value() )
  1691. {
  1692. error_traits<error_type>::rethrow( contained.error() );
  1693. }
  1694. }
  1695. constexpr error_type const & error() const &
  1696. {
  1697. return assert( ! has_value() ), contained.error();
  1698. }
  1699. error_type & error() &
  1700. {
  1701. return assert( ! has_value() ), contained.error();
  1702. }
  1703. #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
  1704. constexpr error_type const && error() const &&
  1705. {
  1706. return std::move( ( assert( ! has_value() ), contained.error() ) );
  1707. }
  1708. error_type && error() &&
  1709. {
  1710. return std::move( ( assert( ! has_value() ), contained.error() ) );
  1711. }
  1712. #endif
  1713. constexpr unexpected_type get_unexpected() const
  1714. {
  1715. return make_unexpected( contained.error() );
  1716. }
  1717. template< typename Ex >
  1718. bool has_exception() const
  1719. {
  1720. using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
  1721. return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
  1722. }
  1723. // template constexpr 'see below' unwrap() const&;
  1724. //
  1725. // template 'see below' unwrap() &&;
  1726. // factories
  1727. // template< typename Ex, typename F>
  1728. // expected<void,E> catch_exception(F&& f);
  1729. //
  1730. // template< typename F>
  1731. // expected<decltype(func()), E> map(F&& func) ;
  1732. //
  1733. // template< typename F>
  1734. // 'see below' bind(F&& func) ;
  1735. //
  1736. // template< typename F>
  1737. // expected<void,E> catch_error(F&& f);
  1738. //
  1739. // template< typename F>
  1740. // 'see below' then(F&& func);
  1741. private:
  1742. detail::storage_t
  1743. <
  1744. void
  1745. , E
  1746. , std::is_copy_constructible<E>::value
  1747. , std::is_move_constructible<E>::value
  1748. >
  1749. contained;
  1750. };
  1751. // x.x.4.6 expected<>: comparison operators
  1752. template< typename T1, typename E1, typename T2, typename E2 >
  1753. constexpr bool operator==( expected<T1,E1> const & x, expected<T2,E2> const & y )
  1754. {
  1755. return bool(x) != bool(y) ? false : bool(x) == false ? x.error() == y.error() : *x == *y;
  1756. }
  1757. template< typename T1, typename E1, typename T2, typename E2 >
  1758. constexpr bool operator!=( expected<T1,E1> const & x, expected<T2,E2> const & y )
  1759. {
  1760. return !(x == y);
  1761. }
  1762. template< typename E1, typename E2 >
  1763. constexpr bool operator==( expected<void,E1> const & x, expected<void,E1> const & y )
  1764. {
  1765. return bool(x) != bool(y) ? false : bool(x) == false ? x.error() == y.error() : true;
  1766. }
  1767. #if nsel_P0323R <= 2
  1768. template< typename T, typename E >
  1769. constexpr bool operator<( expected<T,E> const & x, expected<T,E> const & y )
  1770. {
  1771. return (!y) ? false : (!x) ? true : *x < *y;
  1772. }
  1773. template< typename T, typename E >
  1774. constexpr bool operator>( expected<T,E> const & x, expected<T,E> const & y )
  1775. {
  1776. return (y < x);
  1777. }
  1778. template< typename T, typename E >
  1779. constexpr bool operator<=( expected<T,E> const & x, expected<T,E> const & y )
  1780. {
  1781. return !(y < x);
  1782. }
  1783. template< typename T, typename E >
  1784. constexpr bool operator>=( expected<T,E> const & x, expected<T,E> const & y )
  1785. {
  1786. return !(x < y);
  1787. }
  1788. #endif
  1789. // x.x.4.7 expected: comparison with T
  1790. template< typename T1, typename E1, typename T2 >
  1791. constexpr bool operator==( expected<T1,E1> const & x, T2 const & v )
  1792. {
  1793. return bool(x) ? *x == v : false;
  1794. }
  1795. template< typename T1, typename E1, typename T2 >
  1796. constexpr bool operator==(T2 const & v, expected<T1,E1> const & x )
  1797. {
  1798. return bool(x) ? v == *x : false;
  1799. }
  1800. template< typename T1, typename E1, typename T2 >
  1801. constexpr bool operator!=( expected<T1,E1> const & x, T2 const & v )
  1802. {
  1803. return bool(x) ? *x != v : true;
  1804. }
  1805. template< typename T1, typename E1, typename T2 >
  1806. constexpr bool operator!=( T2 const & v, expected<T1,E1> const & x )
  1807. {
  1808. return bool(x) ? v != *x : true;
  1809. }
  1810. #if nsel_P0323R <= 2
  1811. template< typename T, typename E >
  1812. constexpr bool operator<( expected<T,E> const & x, T const & v )
  1813. {
  1814. return bool(x) ? *x < v : true;
  1815. }
  1816. template< typename T, typename E >
  1817. constexpr bool operator<( T const & v, expected<T,E> const & x )
  1818. {
  1819. return bool(x) ? v < *x : false;
  1820. }
  1821. template< typename T, typename E >
  1822. constexpr bool operator>( T const & v, expected<T,E> const & x )
  1823. {
  1824. return bool(x) ? *x < v : false;
  1825. }
  1826. template< typename T, typename E >
  1827. constexpr bool operator>( expected<T,E> const & x, T const & v )
  1828. {
  1829. return bool(x) ? v < *x : false;
  1830. }
  1831. template< typename T, typename E >
  1832. constexpr bool operator<=( T const & v, expected<T,E> const & x )
  1833. {
  1834. return bool(x) ? ! ( *x < v ) : false;
  1835. }
  1836. template< typename T, typename E >
  1837. constexpr bool operator<=( expected<T,E> const & x, T const & v )
  1838. {
  1839. return bool(x) ? ! ( v < *x ) : true;
  1840. }
  1841. template< typename T, typename E >
  1842. constexpr bool operator>=( expected<T,E> const & x, T const & v )
  1843. {
  1844. return bool(x) ? ! ( *x < v ) : false;
  1845. }
  1846. template< typename T, typename E >
  1847. constexpr bool operator>=( T const & v, expected<T,E> const & x )
  1848. {
  1849. return bool(x) ? ! ( v < *x ) : true;
  1850. }
  1851. #endif // nsel_P0323R
  1852. // x.x.4.8 expected: comparison with unexpected_type
  1853. template< typename T1, typename E1 , typename E2 >
  1854. constexpr bool operator==( expected<T1,E1> const & x, unexpected_type<E2> const & u )
  1855. {
  1856. return (!x) ? x.get_unexpected() == u : false;
  1857. }
  1858. template< typename T1, typename E1 , typename E2 >
  1859. constexpr bool operator==( unexpected_type<E2> const & u, expected<T1,E1> const & x )
  1860. {
  1861. return ( x == u );
  1862. }
  1863. template< typename T1, typename E1 , typename E2 >
  1864. constexpr bool operator!=( expected<T1,E1> const & x, unexpected_type<E2> const & u )
  1865. {
  1866. return ! ( x == u );
  1867. }
  1868. template< typename T1, typename E1 , typename E2 >
  1869. constexpr bool operator!=( unexpected_type<E2> const & u, expected<T1,E1> const & x )
  1870. {
  1871. return ! ( x == u );
  1872. }
  1873. #if nsel_P0323R <= 2
  1874. template< typename T, typename E >
  1875. constexpr bool operator<( expected<T,E> const & x, unexpected_type<E> const & u )
  1876. {
  1877. return (!x) ? ( x.get_unexpected() < u ) : false;
  1878. }
  1879. template< typename T, typename E >
  1880. constexpr bool operator<( unexpected_type<E> const & u, expected<T,E> const & x )
  1881. {
  1882. return (!x) ? ( u < x.get_unexpected() ) : true ;
  1883. }
  1884. template< typename T, typename E >
  1885. constexpr bool operator>( expected<T,E> const & x, unexpected_type<E> const & u )
  1886. {
  1887. return ( u < x );
  1888. }
  1889. template< typename T, typename E >
  1890. constexpr bool operator>( unexpected_type<E> const & u, expected<T,E> const & x )
  1891. {
  1892. return ( x < u );
  1893. }
  1894. template< typename T, typename E >
  1895. constexpr bool operator<=( expected<T,E> const & x, unexpected_type<E> const & u )
  1896. {
  1897. return ! ( u < x );
  1898. }
  1899. template< typename T, typename E >
  1900. constexpr bool operator<=( unexpected_type<E> const & u, expected<T,E> const & x)
  1901. {
  1902. return ! ( x < u );
  1903. }
  1904. template< typename T, typename E >
  1905. constexpr bool operator>=( expected<T,E> const & x, unexpected_type<E> const & u )
  1906. {
  1907. return ! ( u > x );
  1908. }
  1909. template< typename T, typename E >
  1910. constexpr bool operator>=( unexpected_type<E> const & u, expected<T,E> const & x )
  1911. {
  1912. return ! ( x > u );
  1913. }
  1914. #endif // nsel_P0323R
  1915. /// x.x.x Specialized algorithms
  1916. template< typename T, typename E
  1917. nsel_REQUIRES_T(
  1918. ( std::is_void<T>::value || std::is_move_constructible<T>::value )
  1919. && std::is_move_constructible<E>::value
  1920. && std17::is_swappable<T>::value
  1921. && std17::is_swappable<E>::value )
  1922. >
  1923. void swap( expected<T,E> & x, expected<T,E> & y ) noexcept ( noexcept ( x.swap(y) ) )
  1924. {
  1925. x.swap( y );
  1926. }
  1927. #if nsel_P0323R <= 3
  1928. template< typename T >
  1929. constexpr auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
  1930. {
  1931. return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
  1932. }
  1933. // expected<void> specialization:
  1934. auto inline make_expected() -> expected<void>
  1935. {
  1936. return expected<void>( in_place );
  1937. }
  1938. template< typename T >
  1939. constexpr auto make_expected_from_current_exception() -> expected<T>
  1940. {
  1941. return expected<T>( make_unexpected_from_current_exception() );
  1942. }
  1943. template< typename T >
  1944. auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
  1945. {
  1946. return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
  1947. }
  1948. template< typename T, typename E >
  1949. constexpr auto make_expected_from_error( E e ) -> expected<T, typename std::decay<E>::type>
  1950. {
  1951. return expected<T, typename std::decay<E>::type>( make_unexpected( e ) );
  1952. }
  1953. template< typename F
  1954. nsel_REQUIRES_T( ! std::is_same<typename std::result_of<F()>::type, void>::value )
  1955. >
  1956. /*nsel_constexpr14*/
  1957. auto make_expected_from_call( F f ) -> expected< typename std::result_of<F()>::type >
  1958. {
  1959. try
  1960. {
  1961. return make_expected( f() );
  1962. }
  1963. catch (...)
  1964. {
  1965. return make_unexpected_from_current_exception();
  1966. }
  1967. }
  1968. template< typename F
  1969. nsel_REQUIRES_T( std::is_same<typename std::result_of<F()>::type, void>::value )
  1970. >
  1971. /*nsel_constexpr14*/
  1972. auto make_expected_from_call( F f ) -> expected<void>
  1973. {
  1974. try
  1975. {
  1976. f();
  1977. return make_expected();
  1978. }
  1979. catch (...)
  1980. {
  1981. return make_unexpected_from_current_exception();
  1982. }
  1983. }
  1984. #endif // nsel_P0323R
  1985. } // namespace expected_lite
  1986. using namespace expected_lite;
  1987. // using expected_lite::expected;
  1988. // using ...
  1989. } // namespace nonstd
  1990. namespace std {
  1991. // expected: hash support
  1992. template< typename T, typename E >
  1993. struct hash< nonstd::expected<T,E> >
  1994. {
  1995. using result_type = std::size_t;
  1996. using argument_type = nonstd::expected<T,E>;
  1997. constexpr result_type operator()(argument_type const & arg) const
  1998. {
  1999. return arg ? std::hash<T>{}(*arg) : result_type{};
  2000. }
  2001. };
  2002. // TBD - ?? remove? see spec.
  2003. template< typename T, typename E >
  2004. struct hash< nonstd::expected<T&,E> >
  2005. {
  2006. using result_type = std::size_t;
  2007. using argument_type = nonstd::expected<T&,E>;
  2008. constexpr result_type operator()(argument_type const & arg) const
  2009. {
  2010. return arg ? std::hash<T>{}(*arg) : result_type{};
  2011. }
  2012. };
  2013. // TBD - implement
  2014. // bool(e), hash<expected<void,E>>()(e) shall evaluate to the hashing true;
  2015. // otherwise it evaluates to an unspecified value if E is exception_ptr or
  2016. // a combination of hashing false and hash<E>()(e.error()).
  2017. template< typename E >
  2018. struct hash< nonstd::expected<void,E> >
  2019. {
  2020. };
  2021. } // namespace std
  2022. namespace nonstd {
  2023. // void unexpected() is deprecated && removed in C++17
  2024. #if nsel_CPP17_OR_GREATER || nsel_COMPILER_MSVC_VERSION > 141
  2025. template< typename E >
  2026. using unexpected = unexpected_type<E>;
  2027. #endif
  2028. } // namespace nonstd
  2029. #undef nsel_REQUIRES
  2030. #undef nsel_REQUIRES_0
  2031. #undef nsel_REQUIRES_T
  2032. nsel_RESTORE_WARNINGS()
  2033. #endif // nsel_USES_STD_EXPECTED
  2034. #endif // NONSTD_EXPECTED_LITE_HPP