123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555 |
- // This version targets C++11 and later.
- //
- // Copyright (C) 2016-2020 Martin Moene.
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // expected lite is based on:
- // A proposal to add a utility class to represent expected monad
- // by Vicente J. Botet Escriba and Pierre Talbot. http:://wg21.link/p0323
- #ifndef NONSTD_EXPECTED_LITE_HPP
- #define NONSTD_EXPECTED_LITE_HPP
- #define expected_lite_MAJOR 0
- #define expected_lite_MINOR 8
- #define expected_lite_PATCH 0
- #define expected_lite_VERSION expected_STRINGIFY(expected_lite_MAJOR) "." expected_STRINGIFY(expected_lite_MINOR) "." expected_STRINGIFY(expected_lite_PATCH)
- #define expected_STRINGIFY( x ) expected_STRINGIFY_( x )
- #define expected_STRINGIFY_( x ) #x
- // expected-lite configuration:
- #define nsel_EXPECTED_DEFAULT 0
- #define nsel_EXPECTED_NONSTD 1
- #define nsel_EXPECTED_STD 2
- // tweak header support:
- #ifdef __has_include
- # if __has_include(<nonstd/expected.tweak.hpp>)
- # error #include <nonstd/expected.tweak.hpp>
- # endif
- #define expected_HAVE_TWEAK_HEADER 1
- #else
- #define expected_HAVE_TWEAK_HEADER 0
- //# pragma message("expected.hpp: Note: Tweak header not supported.")
- #endif
- // expected selection and configuration:
- #if !defined( nsel_CONFIG_SELECT_EXPECTED )
- # define nsel_CONFIG_SELECT_EXPECTED ( nsel_HAVE_STD_EXPECTED ? nsel_EXPECTED_STD : nsel_EXPECTED_NONSTD )
- #endif
- // Proposal revisions:
- //
- // DXXXXR0: --
- // N4015 : -2 (2014-05-26)
- // N4109 : -1 (2014-06-29)
- // P0323R0: 0 (2016-05-28)
- // P0323R1: 1 (2016-10-12)
- // -------:
- // P0323R2: 2 (2017-06-15)
- // P0323R3: 3 (2017-10-15)
- // P0323R4: 4 (2017-11-26)
- // P0323R5: 5 (2018-02-08)
- // P0323R6: 6 (2018-04-02)
- // P0323R7: 7 (2018-06-22) *
- //
- // expected-lite uses 2 and higher
- #ifndef nsel_P0323R
- # define nsel_P0323R 7
- #endif
- // Monadic operations proposal revisions:
- //
- // P2505R0: 0 (2021-12-12)
- // P2505R1: 1 (2022-02-10)
- // P2505R2: 2 (2022-04-15)
- // P2505R3: 3 (2022-06-05)
- // P2505R4: 4 (2022-06-15)
- // P2505R5: 5 (2022-09-20) *
- //
- // expected-lite uses 5
- #ifndef nsel_P2505R
- # define nsel_P2505R 5
- #endif
- // Control presence of C++ exception handling (try and auto discover):
- #ifndef nsel_CONFIG_NO_EXCEPTIONS
- # if defined(_MSC_VER)
- # include <cstddef> // for _HAS_EXCEPTIONS
- # endif
- # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
- # define nsel_CONFIG_NO_EXCEPTIONS 0
- # else
- # define nsel_CONFIG_NO_EXCEPTIONS 1
- # endif
- #endif
- // at default use SEH with MSVC for no C++ exceptions
- #ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH
- # define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER )
- #endif
- // C++ language version detection (C++23 is speculative):
- // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
- #ifndef nsel_CPLUSPLUS
- # if defined(_MSVC_LANG ) && !defined(__clang__)
- # define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
- # else
- # define nsel_CPLUSPLUS __cplusplus
- # endif
- #endif
- #define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L )
- #define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L )
- #define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L )
- #define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L )
- #define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202002L )
- #define nsel_CPP23_OR_GREATER ( nsel_CPLUSPLUS >= 202300L )
- // Use C++23 std::expected if available and requested:
- #if nsel_CPP23_OR_GREATER && defined(__has_include )
- # if __has_include( <expected> )
- # define nsel_HAVE_STD_EXPECTED 1
- # else
- # define nsel_HAVE_STD_EXPECTED 0
- # endif
- #else
- # define nsel_HAVE_STD_EXPECTED 0
- #endif
- #define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) )
- //
- // in_place: code duplicated in any-lite, expected-lite, expected-lite, value-ptr-lite, variant-lite:
- //
- #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
- #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
- // C++17 std::in_place in <utility>:
- #if nsel_CPP17_OR_GREATER
- #include <utility>
- namespace nonstd {
- using std::in_place;
- using std::in_place_type;
- using std::in_place_index;
- using std::in_place_t;
- using std::in_place_type_t;
- using std::in_place_index_t;
- #define nonstd_lite_in_place_t( T) std::in_place_t
- #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
- #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
- #define nonstd_lite_in_place( T) std::in_place_t{}
- #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
- #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
- } // namespace nonstd
- #else // nsel_CPP17_OR_GREATER
- #include <cstddef>
- namespace nonstd {
- namespace detail {
- template< class T >
- struct in_place_type_tag {};
- template< std::size_t K >
- struct in_place_index_tag {};
- } // namespace detail
- struct in_place_t {};
- template< class T >
- inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
- {
- return in_place_t();
- }
- template< std::size_t K >
- inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
- {
- return in_place_t();
- }
- template< class T >
- inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
- {
- return in_place_t();
- }
- template< std::size_t K >
- inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
- {
- return in_place_t();
- }
- // mimic templated typedef:
- #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
- #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
- #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
- #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
- #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
- #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
- } // namespace nonstd
- #endif // nsel_CPP17_OR_GREATER
- #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
- //
- // Using std::expected:
- //
- #if nsel_USES_STD_EXPECTED
- #error #include <expected>
- namespace nonstd {
- using std::expected;
- using std::unexpected;
- using std::bad_expected_access;
- using std::unexpect_t;
- using std::unexpect;
- //[[deprecated("replace unexpected_type with unexpected")]]
- template< typename E >
- using unexpected_type = unexpected<E>;
- // Unconditionally provide make_unexpected():
- template< typename E>
- constexpr auto make_unexpected( E && value ) -> unexpected< typename std::decay<E>::type >
- {
- return unexpected< typename std::decay<E>::type >( std::forward<E>(value) );
- }
- } // namespace nonstd
- #else // nsel_USES_STD_EXPECTED
- #include <cassert>
- #include <exception>
- #include <functional>
- #include <initializer_list>
- #include <memory>
- #include <new>
- #include <system_error>
- #include <type_traits>
- #include <utility>
- // additional includes:
- #if nsel_CONFIG_NO_EXCEPTIONS
- # if nsel_CONFIG_NO_EXCEPTIONS_SEH
- # include <windows.h> // for ExceptionCodes
- # else
- // already included: <cassert>
- # endif
- #else
- # include <stdexcept>
- #endif
- // C++ feature usage:
- #if nsel_CPP11_OR_GREATER
- # define nsel_constexpr constexpr
- #else
- # define nsel_constexpr /*constexpr*/
- #endif
- #if nsel_CPP14_OR_GREATER
- # define nsel_constexpr14 constexpr
- #else
- # define nsel_constexpr14 /*constexpr*/
- #endif
- #if nsel_CPP17_OR_GREATER
- # define nsel_inline17 inline
- #else
- # define nsel_inline17 /*inline*/
- #endif
- // Compiler versions:
- //
- // MSVC++ 6.0 _MSC_VER == 1200 nsel_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
- // MSVC++ 7.0 _MSC_VER == 1300 nsel_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
- // MSVC++ 7.1 _MSC_VER == 1310 nsel_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
- // MSVC++ 8.0 _MSC_VER == 1400 nsel_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
- // MSVC++ 9.0 _MSC_VER == 1500 nsel_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
- // MSVC++ 10.0 _MSC_VER == 1600 nsel_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
- // MSVC++ 11.0 _MSC_VER == 1700 nsel_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
- // MSVC++ 12.0 _MSC_VER == 1800 nsel_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
- // MSVC++ 14.0 _MSC_VER == 1900 nsel_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
- // MSVC++ 14.1 _MSC_VER >= 1910 nsel_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
- // MSVC++ 14.2 _MSC_VER >= 1920 nsel_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
- #if defined(_MSC_VER) && !defined(__clang__)
- # define nsel_COMPILER_MSVC_VER (_MSC_VER )
- # define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
- #else
- # define nsel_COMPILER_MSVC_VER 0
- # define nsel_COMPILER_MSVC_VERSION 0
- #endif
- #define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
- #if defined(__clang__)
- # define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
- #else
- # define nsel_COMPILER_CLANG_VERSION 0
- #endif
- #if defined(__GNUC__) && !defined(__clang__)
- # define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
- #else
- # define nsel_COMPILER_GNUC_VERSION 0
- #endif
- // half-open range [lo..hi):
- //#define nsel_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
- // Method enabling
- #define nsel_REQUIRES_0(...) \
- template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
- #define nsel_REQUIRES_T(...) \
- , typename std::enable_if< (__VA_ARGS__), int >::type = 0
- #define nsel_REQUIRES_R(R, ...) \
- typename std::enable_if< (__VA_ARGS__), R>::type
- #define nsel_REQUIRES_A(...) \
- , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
- // Clang, GNUC, MSVC warning suppression macros:
- #ifdef __clang__
- # pragma clang diagnostic push
- #elif defined __GNUC__
- # pragma GCC diagnostic push
- #endif // __clang__
- #if nsel_COMPILER_MSVC_VERSION >= 140
- # define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(push) ) __pragma( warning(disable: codes) )
- #else
- # define nsel_DISABLE_MSVC_WARNINGS(codes)
- #endif
- #ifdef __clang__
- # define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
- # define nsel_RESTORE_MSVC_WARNINGS()
- #elif defined __GNUC__
- # define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
- # define nsel_RESTORE_MSVC_WARNINGS()
- #elif nsel_COMPILER_MSVC_VERSION >= 140
- # define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) )
- # define nsel_RESTORE_MSVC_WARNINGS() nsel_RESTORE_WARNINGS()
- #else
- # define nsel_RESTORE_WARNINGS()
- # define nsel_RESTORE_MSVC_WARNINGS()
- #endif
- // Suppress the following MSVC (GSL) warnings:
- // - C26409: Avoid calling new and delete explicitly, use std::make_unique<T> instead (r.11)
- nsel_DISABLE_MSVC_WARNINGS( 26409 )
- // Presence of language and library features:
- #ifdef _HAS_CPP0X
- # define nsel_HAS_CPP0X _HAS_CPP0X
- #else
- # define nsel_HAS_CPP0X 0
- #endif
- // Presence of language and library features:
- #define nsel_CPP17_000 (nsel_CPP17_OR_GREATER)
- // Presence of C++17 language features:
- #define nsel_HAVE_DEPRECATED nsel_CPP17_000
- // C++ feature usage:
- #if nsel_HAVE_DEPRECATED
- # define nsel_deprecated(msg) [[deprecated(msg)]]
- #else
- # define nsel_deprecated(msg) /*[[deprecated]]*/
- #endif
- //
- // expected:
- //
- namespace nonstd { namespace expected_lite {
- // type traits C++17:
- namespace std17 {
- #if nsel_CPP17_OR_GREATER
- using std::conjunction;
- using std::is_swappable;
- using std::is_nothrow_swappable;
- #else // nsel_CPP17_OR_GREATER
- namespace detail {
- using std::swap;
- struct is_swappable
- {
- template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
- static std::true_type test( int /* unused */);
- template< typename >
- static std::false_type test(...);
- };
- struct is_nothrow_swappable
- {
- // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
- template< typename T >
- static constexpr bool satisfies()
- {
- return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
- }
- template< typename T >
- static auto test( int ) -> std::integral_constant<bool, satisfies<T>()>{}
- template< typename >
- static auto test(...) -> std::false_type;
- };
- } // namespace detail
- // is [nothrow] swappable:
- template< typename T >
- struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
- template< typename T >
- struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
- // conjunction:
- template< typename... > struct conjunction : std::true_type{};
- template< typename B1 > struct conjunction<B1> : B1{};
- template< typename B1, typename... Bn >
- struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type{};
- #endif // nsel_CPP17_OR_GREATER
- } // namespace std17
- // type traits C++20:
- namespace std20 {
- #if defined(__cpp_lib_remove_cvref)
- using std::remove_cvref;
- #else
- template< typename T >
- struct remove_cvref
- {
- typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
- };
- #endif
- } // namespace std20
- // forward declaration:
- template< typename T, typename E >
- class expected;
- namespace detail {
- #if nsel_P2505R >= 3
- template< typename T >
- struct is_expected : std::false_type {};
- template< typename T, typename E >
- struct is_expected< expected< T, E > > : std::true_type {};
- #endif // nsel_P2505R >= 3
- /// discriminated union to hold value or 'error'.
- template< typename T, typename E >
- class storage_t_noncopy_nonmove_impl
- {
- template< typename, typename > friend class nonstd::expected_lite::expected;
- public:
- using value_type = T;
- using error_type = E;
- // no-op construction
- storage_t_noncopy_nonmove_impl() {}
- ~storage_t_noncopy_nonmove_impl() {}
- explicit storage_t_noncopy_nonmove_impl( bool has_value )
- : m_has_value( has_value )
- {}
- void construct_value()
- {
- new( &m_value ) value_type();
- }
- // void construct_value( value_type const & e )
- // {
- // new( &m_value ) value_type( e );
- // }
- // void construct_value( value_type && e )
- // {
- // new( &m_value ) value_type( std::move( e ) );
- // }
- template< class... Args >
- void emplace_value( Args&&... args )
- {
- new( &m_value ) value_type( std::forward<Args>(args)...);
- }
- template< class U, class... Args >
- void emplace_value( std::initializer_list<U> il, Args&&... args )
- {
- new( &m_value ) value_type( il, std::forward<Args>(args)... );
- }
- void destruct_value()
- {
- m_value.~value_type();
- }
- // void construct_error( error_type const & e )
- // {
- // // new( &m_error ) error_type( e );
- // }
- // void construct_error( error_type && e )
- // {
- // // new( &m_error ) error_type( std::move( e ) );
- // }
- template< class... Args >
- void emplace_error( Args&&... args )
- {
- new( &m_error ) error_type( std::forward<Args>(args)...);
- }
- template< class U, class... Args >
- void emplace_error( std::initializer_list<U> il, Args&&... args )
- {
- new( &m_error ) error_type( il, std::forward<Args>(args)... );
- }
- void destruct_error()
- {
- m_error.~error_type();
- }
- constexpr value_type const & value() const &
- {
- return m_value;
- }
- value_type & value() &
- {
- return m_value;
- }
- constexpr value_type const && value() const &&
- {
- return std::move( m_value );
- }
- nsel_constexpr14 value_type && value() &&
- {
- return std::move( m_value );
- }
- value_type const * value_ptr() const
- {
- return &m_value;
- }
- value_type * value_ptr()
- {
- return &m_value;
- }
- error_type const & error() const &
- {
- return m_error;
- }
- error_type & error() &
- {
- return m_error;
- }
- constexpr error_type const && error() const &&
- {
- return std::move( m_error );
- }
- nsel_constexpr14 error_type && error() &&
- {
- return std::move( m_error );
- }
- bool has_value() const
- {
- return m_has_value;
- }
- void set_has_value( bool v )
- {
- m_has_value = v;
- }
- private:
- union
- {
- value_type m_value;
- error_type m_error;
- };
- bool m_has_value = false;
- };
- template< typename T, typename E >
- class storage_t_impl
- {
- template< typename, typename > friend class nonstd::expected_lite::expected;
- public:
- using value_type = T;
- using error_type = E;
- // no-op construction
- storage_t_impl() {}
- ~storage_t_impl() {}
- explicit storage_t_impl( bool has_value )
- : m_has_value( has_value )
- {}
- void construct_value()
- {
- new( &m_value ) value_type();
- }
- void construct_value( value_type const & e )
- {
- new( &m_value ) value_type( e );
- }
- void construct_value( value_type && e )
- {
- new( &m_value ) value_type( std::move( e ) );
- }
- template< class... Args >
- void emplace_value( Args&&... args )
- {
- new( &m_value ) value_type( std::forward<Args>(args)...);
- }
- template< class U, class... Args >
- void emplace_value( std::initializer_list<U> il, Args&&... args )
- {
- new( &m_value ) value_type( il, std::forward<Args>(args)... );
- }
- void destruct_value()
- {
- m_value.~value_type();
- }
- void construct_error( error_type const & e )
- {
- new( &m_error ) error_type( e );
- }
- void construct_error( error_type && e )
- {
- new( &m_error ) error_type( std::move( e ) );
- }
- template< class... Args >
- void emplace_error( Args&&... args )
- {
- new( &m_error ) error_type( std::forward<Args>(args)...);
- }
- template< class U, class... Args >
- void emplace_error( std::initializer_list<U> il, Args&&... args )
- {
- new( &m_error ) error_type( il, std::forward<Args>(args)... );
- }
- void destruct_error()
- {
- m_error.~error_type();
- }
- constexpr value_type const & value() const &
- {
- return m_value;
- }
- value_type & value() &
- {
- return m_value;
- }
- constexpr value_type const && value() const &&
- {
- return std::move( m_value );
- }
- nsel_constexpr14 value_type && value() &&
- {
- return std::move( m_value );
- }
- value_type const * value_ptr() const
- {
- return &m_value;
- }
- value_type * value_ptr()
- {
- return &m_value;
- }
- error_type const & error() const &
- {
- return m_error;
- }
- error_type & error() &
- {
- return m_error;
- }
- constexpr error_type const && error() const &&
- {
- return std::move( m_error );
- }
- nsel_constexpr14 error_type && error() &&
- {
- return std::move( m_error );
- }
- bool has_value() const
- {
- return m_has_value;
- }
- void set_has_value( bool v )
- {
- m_has_value = v;
- }
- private:
- union
- {
- value_type m_value;
- error_type m_error;
- };
- bool m_has_value = false;
- };
- /// discriminated union to hold only 'error'.
- template< typename E >
- struct storage_t_impl<void, E>
- {
- template< typename, typename > friend class nonstd::expected_lite::expected;
- public:
- using value_type = void;
- using error_type = E;
- // no-op construction
- storage_t_impl() {}
- ~storage_t_impl() {}
- explicit storage_t_impl( bool has_value )
- : m_has_value( has_value )
- {}
- void construct_error( error_type const & e )
- {
- new( &m_error ) error_type( e );
- }
- void construct_error( error_type && e )
- {
- new( &m_error ) error_type( std::move( e ) );
- }
- template< class... Args >
- void emplace_error( Args&&... args )
- {
- new( &m_error ) error_type( std::forward<Args>(args)...);
- }
- template< class U, class... Args >
- void emplace_error( std::initializer_list<U> il, Args&&... args )
- {
- new( &m_error ) error_type( il, std::forward<Args>(args)... );
- }
- void destruct_error()
- {
- m_error.~error_type();
- }
- error_type const & error() const &
- {
- return m_error;
- }
- error_type & error() &
- {
- return m_error;
- }
- constexpr error_type const && error() const &&
- {
- return std::move( m_error );
- }
- nsel_constexpr14 error_type && error() &&
- {
- return std::move( m_error );
- }
- bool has_value() const
- {
- return m_has_value;
- }
- void set_has_value( bool v )
- {
- m_has_value = v;
- }
- private:
- union
- {
- char m_dummy;
- error_type m_error;
- };
- bool m_has_value = false;
- };
- template< typename T, typename E, bool isConstructable, bool isMoveable >
- class storage_t
- {
- public:
- };
- template< typename T, typename E >
- class storage_t<T, E, false, false> : public storage_t_noncopy_nonmove_impl<T, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_noncopy_nonmove_impl<T, E>( has_value )
- {}
- storage_t( storage_t const & other ) = delete;
- storage_t( storage_t && other ) = delete;
- };
- template< typename T, typename E >
- class storage_t<T, E, true, true> : public storage_t_impl<T, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_impl<T, E>( has_value )
- {}
- storage_t( storage_t const & other )
- : storage_t_impl<T, E>( other.has_value() )
- {
- if ( this->has_value() ) this->construct_value( other.value() );
- else this->construct_error( other.error() );
- }
- storage_t(storage_t && other )
- : storage_t_impl<T, E>( other.has_value() )
- {
- if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
- else this->construct_error( std::move( other.error() ) );
- }
- };
- template< typename E >
- class storage_t<void, E, true, true> : public storage_t_impl<void, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_impl<void, E>( has_value )
- {}
- storage_t( storage_t const & other )
- : storage_t_impl<void, E>( other.has_value() )
- {
- if ( this->has_value() ) ;
- else this->construct_error( other.error() );
- }
- storage_t(storage_t && other )
- : storage_t_impl<void, E>( other.has_value() )
- {
- if ( this->has_value() ) ;
- else this->construct_error( std::move( other.error() ) );
- }
- };
- template< typename T, typename E >
- class storage_t<T, E, true, false> : public storage_t_impl<T, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_impl<T, E>( has_value )
- {}
- storage_t( storage_t const & other )
- : storage_t_impl<T, E>(other.has_value())
- {
- if ( this->has_value() ) this->construct_value( other.value() );
- else this->construct_error( other.error() );
- }
- storage_t( storage_t && other ) = delete;
- };
- template< typename E >
- class storage_t<void, E, true, false> : public storage_t_impl<void, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_impl<void, E>( has_value )
- {}
- storage_t( storage_t const & other )
- : storage_t_impl<void, E>(other.has_value())
- {
- if ( this->has_value() ) ;
- else this->construct_error( other.error() );
- }
- storage_t( storage_t && other ) = delete;
- };
- template< typename T, typename E >
- class storage_t<T, E, false, true> : public storage_t_impl<T, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_impl<T, E>( has_value )
- {}
- storage_t( storage_t const & other ) = delete;
- storage_t( storage_t && other )
- : storage_t_impl<T, E>( other.has_value() )
- {
- if ( this->has_value() ) this->construct_value( std::move( other.value() ) );
- else this->construct_error( std::move( other.error() ) );
- }
- };
- template< typename E >
- class storage_t<void, E, false, true> : public storage_t_impl<void, E>
- {
- public:
- storage_t() = default;
- ~storage_t() = default;
- explicit storage_t( bool has_value )
- : storage_t_impl<void, E>( has_value )
- {}
- storage_t( storage_t const & other ) = delete;
- storage_t( storage_t && other )
- : storage_t_impl<void, E>( other.has_value() )
- {
- if ( this->has_value() ) ;
- else this->construct_error( std::move( other.error() ) );
- }
- };
- #if nsel_P2505R >= 3
- // C++11 invoke implementation
- template< typename >
- struct is_reference_wrapper : std::false_type {};
- template< typename T >
- struct is_reference_wrapper< std::reference_wrapper< T > > : std::true_type {};
- template< typename FnT, typename ClassT, typename ObjectT, typename... Args
- nsel_REQUIRES_T(
- std::is_function<FnT>::value
- && ( std::is_same< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- || std::is_base_of< ClassT, typename std20::remove_cvref< ObjectT >::type >::value )
- )
- >
- nsel_constexpr auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
- noexcept( noexcept( (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )... ) ) )
- -> decltype( (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )...) )
- {
- return (std::forward< ObjectT >( obj ).*memfnptr)( std::forward< Args >( args )... );
- }
- template< typename FnT, typename ClassT, typename ObjectT, typename... Args
- nsel_REQUIRES_T(
- std::is_function<FnT>::value
- && is_reference_wrapper< typename std20::remove_cvref< ObjectT >::type >::value
- )
- >
- nsel_constexpr auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
- noexcept( noexcept( (obj.get().*memfnptr)( std::forward< Args >( args ) ... ) ) )
- -> decltype( (obj.get().*memfnptr)( std::forward< Args >( args ) ... ) )
- {
- return (obj.get().*memfnptr)( std::forward< Args >( args ) ... );
- }
- template< typename FnT, typename ClassT, typename ObjectT, typename... Args
- nsel_REQUIRES_T(
- std::is_function<FnT>::value
- && !std::is_same< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- && !std::is_base_of< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- && !is_reference_wrapper< typename std20::remove_cvref< ObjectT >::type >::value
- )
- >
- nsel_constexpr auto invoke_member_function_impl( FnT ClassT::* memfnptr, ObjectT && obj, Args && ... args )
- noexcept( noexcept( ((*std::forward< ObjectT >( obj )).*memfnptr)( std::forward< Args >( args ) ... ) ) )
- -> decltype( ((*std::forward< ObjectT >( obj )).*memfnptr)( std::forward< Args >( args ) ... ) )
- {
- return ((*std::forward<ObjectT>(obj)).*memfnptr)( std::forward< Args >( args ) ... );
- }
- template< typename MemberT, typename ClassT, typename ObjectT
- nsel_REQUIRES_T(
- std::is_same< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- || std::is_base_of< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- )
- >
- nsel_constexpr auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
- noexcept( noexcept( std::forward< ObjectT >( obj ).*memobjptr ) )
- -> decltype( std::forward< ObjectT >( obj ).*memobjptr )
- {
- return std::forward< ObjectT >( obj ).*memobjptr;
- }
- template< typename MemberT, typename ClassT, typename ObjectT
- nsel_REQUIRES_T(
- is_reference_wrapper< typename std20::remove_cvref< ObjectT >::type >::value
- )
- >
- nsel_constexpr auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
- noexcept( noexcept( obj.get().*memobjptr ) )
- -> decltype( obj.get().*memobjptr )
- {
- return obj.get().*memobjptr;
- }
- template< typename MemberT, typename ClassT, typename ObjectT
- nsel_REQUIRES_T(
- !std::is_same< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- && !std::is_base_of< ClassT, typename std20::remove_cvref< ObjectT >::type >::value
- && !is_reference_wrapper< typename std20::remove_cvref< ObjectT >::type >::value
- )
- >
- nsel_constexpr auto invoke_member_object_impl( MemberT ClassT::* memobjptr, ObjectT && obj )
- noexcept( noexcept( (*std::forward< ObjectT >( obj )).*memobjptr ) )
- -> decltype( (*std::forward< ObjectT >( obj )).*memobjptr )
- {
- return (*std::forward< ObjectT >( obj )).*memobjptr;
- }
- template< typename F, typename... Args
- nsel_REQUIRES_T(
- std::is_member_function_pointer< typename std20::remove_cvref< F >::type >::value
- )
- >
- nsel_constexpr auto invoke( F && f, Args && ... args )
- noexcept( noexcept( invoke_member_function_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) ) )
- -> decltype( invoke_member_function_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) )
- {
- return invoke_member_function_impl( std::forward< F >( f ), std::forward< Args >( args ) ... );
- }
- template< typename F, typename... Args
- nsel_REQUIRES_T(
- std::is_member_object_pointer< typename std20::remove_cvref< F >::type >::value
- )
- >
- nsel_constexpr auto invoke( F && f, Args && ... args )
- noexcept( noexcept( invoke_member_object_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) ) )
- -> decltype( invoke_member_object_impl( std::forward< F >( f ), std::forward< Args >( args ) ... ) )
- {
- return invoke_member_object_impl( std::forward< F >( f ), std::forward< Args >( args ) ... );
- }
- template< typename F, typename... Args
- nsel_REQUIRES_T(
- !std::is_member_function_pointer< typename std20::remove_cvref< F >::type >::value
- && !std::is_member_object_pointer< typename std20::remove_cvref< F >::type >::value
- )
- >
- nsel_constexpr auto invoke( F && f, Args && ... args )
- noexcept( noexcept( std::forward< F >( f )( std::forward< Args >( args ) ... ) ) )
- -> decltype( std::forward< F >( f )( std::forward< Args >( args ) ... ) )
- {
- return std::forward< F >( f )( std::forward< Args >( args ) ... );
- }
- template< typename F, typename ... Args >
- using invoke_result_nocvref_t = typename std20::remove_cvref< decltype( invoke( std::declval< F >(), std::declval< Args >()... ) ) >::type;
- #if nsel_P2505R >= 5
- template< typename F, typename ... Args >
- using transform_invoke_result_t = typename std::remove_cv< decltype( invoke( std::declval< F >(), std::declval< Args >()... ) ) >::type;
- #else
- template< typename F, typename ... Args >
- using transform_invoke_result_t = invoke_result_nocvref_t
- #endif // nsel_P2505R >= 5
- template< typename T >
- struct valid_expected_value_type : std::integral_constant< bool, std::is_destructible< T >::value && !std::is_reference< T >::value && !std::is_array< T >::value > {};
- #endif // nsel_P2505R >= 3
- } // namespace detail
- /// x.x.5 Unexpected object type; unexpected_type; C++17 and later can also use aliased type unexpected.
- #if nsel_P0323R <= 2
- template< typename E = std::exception_ptr >
- class unexpected_type
- #else
- template< typename E >
- class unexpected_type
- #endif // nsel_P0323R
- {
- public:
- using error_type = E;
- // x.x.5.2.1 Constructors
- // unexpected_type() = delete;
- constexpr unexpected_type( unexpected_type const & ) = default;
- constexpr unexpected_type( unexpected_type && ) = default;
- template< typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<E, Args&&...>::value
- )
- >
- constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), Args &&... args )
- : m_error( std::forward<Args>( args )...)
- {}
- template< typename U, typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
- )
- >
- constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), std::initializer_list<U> il, Args &&... args )
- : m_error( il, std::forward<Args>( args )...)
- {}
- template< typename E2
- nsel_REQUIRES_T(
- std::is_constructible<E,E2>::value
- && !std::is_same< typename std20::remove_cvref<E2>::type, nonstd_lite_in_place_t(E2) >::value
- && !std::is_same< typename std20::remove_cvref<E2>::type, unexpected_type >::value
- )
- >
- constexpr explicit unexpected_type( E2 && error )
- : m_error( std::forward<E2>( error ) )
- {}
- template< typename E2
- nsel_REQUIRES_T(
- std::is_constructible< E, E2>::value
- && !std::is_constructible<E, unexpected_type<E2> & >::value
- && !std::is_constructible<E, unexpected_type<E2> >::value
- && !std::is_constructible<E, unexpected_type<E2> const & >::value
- && !std::is_constructible<E, unexpected_type<E2> const >::value
- && !std::is_convertible< unexpected_type<E2> &, E>::value
- && !std::is_convertible< unexpected_type<E2> , E>::value
- && !std::is_convertible< unexpected_type<E2> const &, E>::value
- && !std::is_convertible< unexpected_type<E2> const , E>::value
- && !std::is_convertible< E2 const &, E>::value /*=> explicit */
- )
- >
- constexpr explicit unexpected_type( unexpected_type<E2> const & error )
- : m_error( E{ error.error() } )
- {}
- template< typename E2
- nsel_REQUIRES_T(
- std::is_constructible< E, E2>::value
- && !std::is_constructible<E, unexpected_type<E2> & >::value
- && !std::is_constructible<E, unexpected_type<E2> >::value
- && !std::is_constructible<E, unexpected_type<E2> const & >::value
- && !std::is_constructible<E, unexpected_type<E2> const >::value
- && !std::is_convertible< unexpected_type<E2> &, E>::value
- && !std::is_convertible< unexpected_type<E2> , E>::value
- && !std::is_convertible< unexpected_type<E2> const &, E>::value
- && !std::is_convertible< unexpected_type<E2> const , E>::value
- && std::is_convertible< E2 const &, E>::value /*=> explicit */
- )
- >
- constexpr /*non-explicit*/ unexpected_type( unexpected_type<E2> const & error )
- : m_error( error.error() )
- {}
- template< typename E2
- nsel_REQUIRES_T(
- std::is_constructible< E, E2>::value
- && !std::is_constructible<E, unexpected_type<E2> & >::value
- && !std::is_constructible<E, unexpected_type<E2> >::value
- && !std::is_constructible<E, unexpected_type<E2> const & >::value
- && !std::is_constructible<E, unexpected_type<E2> const >::value
- && !std::is_convertible< unexpected_type<E2> &, E>::value
- && !std::is_convertible< unexpected_type<E2> , E>::value
- && !std::is_convertible< unexpected_type<E2> const &, E>::value
- && !std::is_convertible< unexpected_type<E2> const , E>::value
- && !std::is_convertible< E2 const &, E>::value /*=> explicit */
- )
- >
- constexpr explicit unexpected_type( unexpected_type<E2> && error )
- : m_error( E{ std::move( error.error() ) } )
- {}
- template< typename E2
- nsel_REQUIRES_T(
- std::is_constructible< E, E2>::value
- && !std::is_constructible<E, unexpected_type<E2> & >::value
- && !std::is_constructible<E, unexpected_type<E2> >::value
- && !std::is_constructible<E, unexpected_type<E2> const & >::value
- && !std::is_constructible<E, unexpected_type<E2> const >::value
- && !std::is_convertible< unexpected_type<E2> &, E>::value
- && !std::is_convertible< unexpected_type<E2> , E>::value
- && !std::is_convertible< unexpected_type<E2> const &, E>::value
- && !std::is_convertible< unexpected_type<E2> const , E>::value
- && std::is_convertible< E2 const &, E>::value /*=> non-explicit */
- )
- >
- constexpr /*non-explicit*/ unexpected_type( unexpected_type<E2> && error )
- : m_error( std::move( error.error() ) )
- {}
- // x.x.5.2.2 Assignment
- nsel_constexpr14 unexpected_type& operator=( unexpected_type const & ) = default;
- nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) = default;
- template< typename E2 = E >
- nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> const & other )
- {
- unexpected_type{ other.error() }.swap( *this );
- return *this;
- }
- template< typename E2 = E >
- nsel_constexpr14 unexpected_type & operator=( unexpected_type<E2> && other )
- {
- unexpected_type{ std::move( other.error() ) }.swap( *this );
- return *this;
- }
- // x.x.5.2.3 Observers
- nsel_constexpr14 E & error() & noexcept
- {
- return m_error;
- }
- constexpr E const & error() const & noexcept
- {
- return m_error;
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- nsel_constexpr14 E && error() && noexcept
- {
- return std::move( m_error );
- }
- constexpr E const && error() const && noexcept
- {
- return std::move( m_error );
- }
- #endif
- // x.x.5.2.3 Observers - deprecated
- nsel_deprecated("replace value() with error()")
- nsel_constexpr14 E & value() & noexcept
- {
- return m_error;
- }
- nsel_deprecated("replace value() with error()")
- constexpr E const & value() const & noexcept
- {
- return m_error;
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- nsel_deprecated("replace value() with error()")
- nsel_constexpr14 E && value() && noexcept
- {
- return std::move( m_error );
- }
- nsel_deprecated("replace value() with error()")
- constexpr E const && value() const && noexcept
- {
- return std::move( m_error );
- }
- #endif
- // x.x.5.2.4 Swap
- template< typename U=E >
- nsel_REQUIRES_R( void,
- std17::is_swappable<U>::value
- )
- swap( unexpected_type & other ) noexcept (
- std17::is_nothrow_swappable<U>::value
- )
- {
- using std::swap;
- swap( m_error, other.m_error );
- }
- // TODO: ??? unexpected_type: in-class friend operator==, !=
- private:
- error_type m_error;
- };
- #if nsel_CPP17_OR_GREATER
- /// template deduction guide:
- template< typename E >
- unexpected_type( E ) -> unexpected_type< E >;
- #endif
- /// class unexpected_type, std::exception_ptr specialization (P0323R2)
- #if !nsel_CONFIG_NO_EXCEPTIONS
- #if nsel_P0323R <= 2
- // TODO: Should expected be specialized for particular E types such as exception_ptr and how?
- // See p0323r7 2.1. Ergonomics, http://wg21.link/p0323
- template<>
- class unexpected_type< std::exception_ptr >
- {
- public:
- using error_type = std::exception_ptr;
- unexpected_type() = delete;
- ~unexpected_type(){}
- explicit unexpected_type( std::exception_ptr const & error )
- : m_error( error )
- {}
- explicit unexpected_type(std::exception_ptr && error )
- : m_error( std::move( error ) )
- {}
- template< typename E >
- explicit unexpected_type( E error )
- : m_error( std::make_exception_ptr( error ) )
- {}
- std::exception_ptr const & value() const
- {
- return m_error;
- }
- std::exception_ptr & value()
- {
- return m_error;
- }
- private:
- std::exception_ptr m_error;
- };
- #endif // nsel_P0323R
- #endif // !nsel_CONFIG_NO_EXCEPTIONS
- /// x.x.4, Unexpected equality operators
- template< typename E1, typename E2 >
- constexpr bool operator==( unexpected_type<E1> const & x, unexpected_type<E2> const & y )
- {
- return x.error() == y.error();
- }
- template< typename E1, typename E2 >
- constexpr bool operator!=( unexpected_type<E1> const & x, unexpected_type<E2> const & y )
- {
- return ! ( x == y );
- }
- #if nsel_P0323R <= 2
- template< typename E >
- constexpr bool operator<( unexpected_type<E> const & x, unexpected_type<E> const & y )
- {
- return x.error() < y.error();
- }
- template< typename E >
- constexpr bool operator>( unexpected_type<E> const & x, unexpected_type<E> const & y )
- {
- return ( y < x );
- }
- template< typename E >
- constexpr bool operator<=( unexpected_type<E> const & x, unexpected_type<E> const & y )
- {
- return ! ( y < x );
- }
- template< typename E >
- constexpr bool operator>=( unexpected_type<E> const & x, unexpected_type<E> const & y )
- {
- return ! ( x < y );
- }
- #endif // nsel_P0323R
- /// x.x.5 Specialized algorithms
- template< typename E
- nsel_REQUIRES_T(
- std17::is_swappable<E>::value
- )
- >
- void swap( unexpected_type<E> & x, unexpected_type<E> & y) noexcept ( noexcept ( x.swap(y) ) )
- {
- x.swap( y );
- }
- #if nsel_P0323R <= 2
- // unexpected: relational operators for std::exception_ptr:
- inline constexpr bool operator<( unexpected_type<std::exception_ptr> const & /*x*/, unexpected_type<std::exception_ptr> const & /*y*/ )
- {
- return false;
- }
- inline constexpr bool operator>( unexpected_type<std::exception_ptr> const & /*x*/, unexpected_type<std::exception_ptr> const & /*y*/ )
- {
- return false;
- }
- inline constexpr bool operator<=( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
- {
- return ( x == y );
- }
- inline constexpr bool operator>=( unexpected_type<std::exception_ptr> const & x, unexpected_type<std::exception_ptr> const & y )
- {
- return ( x == y );
- }
- #endif // nsel_P0323R
- // unexpected: traits
- #if nsel_P0323R <= 3
- template< typename E>
- struct is_unexpected : std::false_type {};
- template< typename E>
- struct is_unexpected< unexpected_type<E> > : std::true_type {};
- #endif // nsel_P0323R
- // unexpected: factory
- // keep make_unexpected() removed in p0323r2 for pre-C++17:
- template< typename E>
- nsel_constexpr14 auto
- make_unexpected( E && value ) -> unexpected_type< typename std::decay<E>::type >
- {
- return unexpected_type< typename std::decay<E>::type >( std::forward<E>(value) );
- }
- #if nsel_P0323R <= 3
- /*nsel_constexpr14*/ auto inline
- make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
- {
- return unexpected_type< std::exception_ptr >( std::current_exception() );
- }
- #endif // nsel_P0323R
- /// x.x.6, x.x.7 expected access error
- template< typename E >
- class bad_expected_access;
- /// x.x.7 bad_expected_access<void>: expected access error
- template <>
- class bad_expected_access< void > : public std::exception
- {
- public:
- explicit bad_expected_access()
- : std::exception()
- {}
- };
- /// x.x.6 bad_expected_access: expected access error
- #if !nsel_CONFIG_NO_EXCEPTIONS
- template< typename E >
- class bad_expected_access : public bad_expected_access< void >
- {
- public:
- using error_type = E;
- explicit bad_expected_access( error_type error )
- : m_error( error )
- {}
- virtual char const * what() const noexcept override
- {
- return "bad_expected_access";
- }
- nsel_constexpr14 error_type & error() &
- {
- return m_error;
- }
- constexpr error_type const & error() const &
- {
- return m_error;
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- nsel_constexpr14 error_type && error() &&
- {
- return std::move( m_error );
- }
- constexpr error_type const && error() const &&
- {
- return std::move( m_error );
- }
- #endif
- private:
- error_type m_error;
- };
- #endif // nsel_CONFIG_NO_EXCEPTIONS
- /// x.x.8 unexpect tag, in_place_unexpected tag: construct an error
- struct unexpect_t{};
- using in_place_unexpected_t = unexpect_t;
- nsel_inline17 constexpr unexpect_t unexpect{};
- nsel_inline17 constexpr unexpect_t in_place_unexpected{};
- /// class error_traits
- #if nsel_CONFIG_NO_EXCEPTIONS
- namespace detail {
- inline bool text( char const * /*text*/ ) { return true; }
- }
- template< typename Error >
- struct error_traits
- {
- static void rethrow( Error const & /*e*/ )
- {
- #if nsel_CONFIG_NO_EXCEPTIONS_SEH
- RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
- #else
- assert( false && detail::text("throw bad_expected_access<Error>{ e };") );
- #endif
- }
- };
- template<>
- struct error_traits< std::exception_ptr >
- {
- static void rethrow( std::exception_ptr const & /*e*/ )
- {
- #if nsel_CONFIG_NO_EXCEPTIONS_SEH
- RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
- #else
- assert( false && detail::text("throw bad_expected_access<std::exception_ptr>{ e };") );
- #endif
- }
- };
- template<>
- struct error_traits< std::error_code >
- {
- static void rethrow( std::error_code const & /*e*/ )
- {
- #if nsel_CONFIG_NO_EXCEPTIONS_SEH
- RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
- #else
- assert( false && detail::text("throw std::system_error( e );") );
- #endif
- }
- };
- #else // nsel_CONFIG_NO_EXCEPTIONS
- template< typename Error >
- struct error_traits
- {
- static void rethrow( Error const & e )
- {
- throw bad_expected_access<Error>{ e };
- }
- };
- template<>
- struct error_traits< std::exception_ptr >
- {
- static void rethrow( std::exception_ptr const & e )
- {
- std::rethrow_exception( e );
- }
- };
- template<>
- struct error_traits< std::error_code >
- {
- static void rethrow( std::error_code const & e )
- {
- throw std::system_error( e );
- }
- };
- #endif // nsel_CONFIG_NO_EXCEPTIONS
- #if nsel_P2505R >= 3
- namespace detail {
- // from https://en.cppreference.com/w/cpp/utility/expected/unexpected:
- // "the type of the unexpected value. The type must not be an array type, a non-object type, a specialization of std::unexpected, or a cv-qualified type."
- template< typename T >
- struct valid_unexpected_type : std::integral_constant< bool,
- std::is_same< T, typename std20::remove_cvref< T >::type >::value
- && std::is_object< T >::value
- && !std::is_array< T >::value
- > {};
- template< typename T >
- struct valid_unexpected_type< unexpected_type< T > > : std::false_type {};
- } // namespace detail
- #endif // nsel_P2505R >= 3
- } // namespace expected_lite
- // provide nonstd::unexpected_type:
- using expected_lite::unexpected_type;
- namespace expected_lite {
- /// class expected
- #if nsel_P0323R <= 2
- template< typename T, typename E = std::exception_ptr >
- class expected
- #else
- template< typename T, typename E >
- class expected
- #endif // nsel_P0323R
- {
- private:
- template< typename, typename > friend class expected;
- public:
- using value_type = T;
- using error_type = E;
- using unexpected_type = nonstd::unexpected_type<E>;
- template< typename U >
- struct rebind
- {
- using type = expected<U, error_type>;
- };
- // x.x.4.1 constructors
- nsel_REQUIRES_0(
- std::is_default_constructible<T>::value
- )
- nsel_constexpr14 expected()
- : contained( true )
- {
- contained.construct_value();
- }
- nsel_constexpr14 expected( expected const & ) = default;
- nsel_constexpr14 expected( expected && ) = default;
- template< typename U, typename G
- nsel_REQUIRES_T(
- std::is_constructible< T, U const &>::value
- && std::is_constructible<E, G const &>::value
- && !std::is_constructible<T, expected<U, G> & >::value
- && !std::is_constructible<T, expected<U, G> && >::value
- && !std::is_constructible<T, expected<U, G> const & >::value
- && !std::is_constructible<T, expected<U, G> const && >::value
- && !std::is_convertible< expected<U, G> & , T>::value
- && !std::is_convertible< expected<U, G> &&, T>::value
- && !std::is_convertible< expected<U, G> const & , T>::value
- && !std::is_convertible< expected<U, G> const &&, T>::value
- && (!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value ) /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( expected<U, G> const & other )
- : contained( other.has_value() )
- {
- if ( has_value() ) contained.construct_value( T{ other.contained.value() } );
- else contained.construct_error( E{ other.contained.error() } );
- }
- template< typename U, typename G
- nsel_REQUIRES_T(
- std::is_constructible< T, U const &>::value
- && std::is_constructible<E, G const &>::value
- && !std::is_constructible<T, expected<U, G> & >::value
- && !std::is_constructible<T, expected<U, G> && >::value
- && !std::is_constructible<T, expected<U, G> const & >::value
- && !std::is_constructible<T, expected<U, G> const && >::value
- && !std::is_convertible< expected<U, G> & , T>::value
- && !std::is_convertible< expected<U, G> &&, T>::value
- && !std::is_convertible< expected<U, G> const &, T>::value
- && !std::is_convertible< expected<U, G> const &&, T>::value
- && !(!std::is_convertible<U const &, T>::value || !std::is_convertible<G const &, E>::value ) /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( expected<U, G> const & other )
- : contained( other.has_value() )
- {
- if ( has_value() ) contained.construct_value( other.contained.value() );
- else contained.construct_error( other.contained.error() );
- }
- template< typename U, typename G
- nsel_REQUIRES_T(
- std::is_constructible< T, U>::value
- && std::is_constructible<E, G>::value
- && !std::is_constructible<T, expected<U, G> & >::value
- && !std::is_constructible<T, expected<U, G> && >::value
- && !std::is_constructible<T, expected<U, G> const & >::value
- && !std::is_constructible<T, expected<U, G> const && >::value
- && !std::is_convertible< expected<U, G> & , T>::value
- && !std::is_convertible< expected<U, G> &&, T>::value
- && !std::is_convertible< expected<U, G> const & , T>::value
- && !std::is_convertible< expected<U, G> const &&, T>::value
- && (!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value ) /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( expected<U, G> && other )
- : contained( other.has_value() )
- {
- if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } );
- else contained.construct_error( E{ std::move( other.contained.error() ) } );
- }
- template< typename U, typename G
- nsel_REQUIRES_T(
- std::is_constructible< T, U>::value
- && std::is_constructible<E, G>::value
- && !std::is_constructible<T, expected<U, G> & >::value
- && !std::is_constructible<T, expected<U, G> && >::value
- && !std::is_constructible<T, expected<U, G> const & >::value
- && !std::is_constructible<T, expected<U, G> const && >::value
- && !std::is_convertible< expected<U, G> & , T>::value
- && !std::is_convertible< expected<U, G> &&, T>::value
- && !std::is_convertible< expected<U, G> const & , T>::value
- && !std::is_convertible< expected<U, G> const &&, T>::value
- && !(!std::is_convertible<U, T>::value || !std::is_convertible<G, E>::value ) /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( expected<U, G> && other )
- : contained( other.has_value() )
- {
- if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) );
- else contained.construct_error( std::move( other.contained.error() ) );
- }
- template< typename U = T
- nsel_REQUIRES_T(
- std::is_copy_constructible<U>::value
- )
- >
- nsel_constexpr14 expected( value_type const & value )
- : contained( true )
- {
- contained.construct_value( value );
- }
- template< typename U = T
- nsel_REQUIRES_T(
- std::is_constructible<T,U&&>::value
- && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
- && !std::is_same< expected<T,E> , typename std20::remove_cvref<U>::type>::value
- && !std::is_same<nonstd::unexpected_type<E>, typename std20::remove_cvref<U>::type>::value
- && !std::is_convertible<U&&,T>::value /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( U && value ) noexcept
- (
- std::is_nothrow_move_constructible<U>::value &&
- std::is_nothrow_move_constructible<E>::value
- )
- : contained( true )
- {
- contained.construct_value( T{ std::forward<U>( value ) } );
- }
- template< typename U = T
- nsel_REQUIRES_T(
- std::is_constructible<T,U&&>::value
- && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
- && !std::is_same< expected<T,E> , typename std20::remove_cvref<U>::type>::value
- && !std::is_same<nonstd::unexpected_type<E>, typename std20::remove_cvref<U>::type>::value
- && std::is_convertible<U&&,T>::value /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( U && value ) noexcept
- (
- std::is_nothrow_move_constructible<U>::value &&
- std::is_nothrow_move_constructible<E>::value
- )
- : contained( true )
- {
- contained.construct_value( std::forward<U>( value ) );
- }
- // construct error:
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_constructible<E, G const & >::value
- && !std::is_convertible< G const &, E>::value /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> const & error )
- : contained( false )
- {
- contained.construct_error( E{ error.error() } );
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_constructible<E, G const & >::value
- && std::is_convertible< G const &, E>::value /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> const & error )
- : contained( false )
- {
- contained.construct_error( error.error() );
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_constructible<E, G&& >::value
- && !std::is_convertible< G&&, E>::value /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> && error )
- : contained( false )
- {
- contained.construct_error( E{ std::move( error.error() ) } );
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_constructible<E, G&& >::value
- && std::is_convertible< G&&, E>::value /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> && error )
- : contained( false )
- {
- contained.construct_error( std::move( error.error() ) );
- }
- // in-place construction, value
- template< typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<T, Args&&...>::value
- )
- >
- nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), Args&&... args )
- : contained( true )
- {
- contained.emplace_value( std::forward<Args>( args )... );
- }
- template< typename U, typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<T, std::initializer_list<U>, Args&&...>::value
- )
- >
- nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
- : contained( true )
- {
- contained.emplace_value( il, std::forward<Args>( args )... );
- }
- // in-place construction, error
- template< typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<E, Args&&...>::value
- )
- >
- nsel_constexpr14 explicit expected( unexpect_t, Args&&... args )
- : contained( false )
- {
- contained.emplace_error( std::forward<Args>( args )... );
- }
- template< typename U, typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
- )
- >
- nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
- : contained( false )
- {
- contained.emplace_error( il, std::forward<Args>( args )... );
- }
- // x.x.4.2 destructor
- // TODO: ~expected: triviality
- // 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>().
- // 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.
- ~expected()
- {
- if ( has_value() ) contained.destruct_value();
- else contained.destruct_error();
- }
- // x.x.4.3 assignment
- expected & operator=( expected const & other )
- {
- expected( other ).swap( *this );
- return *this;
- }
- expected & operator=( expected && other ) noexcept
- (
- std::is_nothrow_move_constructible< T>::value
- && std::is_nothrow_move_assignable< T>::value
- && std::is_nothrow_move_constructible<E>::value // added for missing
- && std::is_nothrow_move_assignable< E>::value ) // nothrow above
- {
- expected( std::move( other ) ).swap( *this );
- return *this;
- }
- template< typename U
- nsel_REQUIRES_T(
- !std::is_same<expected<T,E>, typename std20::remove_cvref<U>::type>::value
- && std17::conjunction<std::is_scalar<T>, std::is_same<T, std::decay<U>> >::value
- && std::is_constructible<T ,U>::value
- && std::is_assignable< T&,U>::value
- && std::is_nothrow_move_constructible<E>::value )
- >
- expected & operator=( U && value )
- {
- expected( std::forward<U>( value ) ).swap( *this );
- return *this;
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_constructible<E, G const&>::value &&
- std::is_copy_constructible<G>::value // TODO: std::is_nothrow_copy_constructible<G>
- && std::is_copy_assignable<G>::value
- )
- >
- expected & operator=( nonstd::unexpected_type<G> const & error )
- {
- expected( unexpect, error.error() ).swap( *this );
- return *this;
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_constructible<E, G&&>::value &&
- std::is_move_constructible<G>::value // TODO: std::is_nothrow_move_constructible<G>
- && std::is_move_assignable<G>::value
- )
- >
- expected & operator=( nonstd::unexpected_type<G> && error )
- {
- expected( unexpect, std::move( error.error() ) ).swap( *this );
- return *this;
- }
- template< typename... Args
- nsel_REQUIRES_T(
- std::is_nothrow_constructible<T, Args&&...>::value
- )
- >
- value_type & emplace( Args &&... args )
- {
- expected( nonstd_lite_in_place(T), std::forward<Args>(args)... ).swap( *this );
- return value();
- }
- template< typename U, typename... Args
- nsel_REQUIRES_T(
- std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::value
- )
- >
- value_type & emplace( std::initializer_list<U> il, Args &&... args )
- {
- expected( nonstd_lite_in_place(T), il, std::forward<Args>(args)... ).swap( *this );
- return value();
- }
- // x.x.4.4 swap
- template< typename U=T, typename G=E >
- nsel_REQUIRES_R( void,
- std17::is_swappable< U>::value
- && std17::is_swappable<G>::value
- && ( std::is_move_constructible<U>::value || std::is_move_constructible<G>::value )
- )
- swap( expected & other ) noexcept
- (
- std::is_nothrow_move_constructible<T>::value && std17::is_nothrow_swappable<T&>::value &&
- std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
- )
- {
- using std::swap;
- if ( bool(*this) && bool(other) ) { swap( contained.value(), other.contained.value() ); }
- else if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); }
- else if ( bool(*this) && ! bool(other) ) { error_type t( std::move( other.error() ) );
- other.contained.destruct_error();
- other.contained.construct_value( std::move( contained.value() ) );
- contained.destruct_value();
- contained.construct_error( std::move( t ) );
- bool has_value = contained.has_value();
- bool other_has_value = other.has_value();
- other.contained.set_has_value(has_value);
- contained.set_has_value(other_has_value);
- }
- else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); }
- }
- // x.x.4.5 observers
- constexpr value_type const * operator ->() const
- {
- return assert( has_value() ), contained.value_ptr();
- }
- value_type * operator ->()
- {
- return assert( has_value() ), contained.value_ptr();
- }
- constexpr value_type const & operator *() const &
- {
- return assert( has_value() ), contained.value();
- }
- value_type & operator *() &
- {
- return assert( has_value() ), contained.value();
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- constexpr value_type const && operator *() const &&
- {
- return std::move( ( assert( has_value() ), contained.value() ) );
- }
- nsel_constexpr14 value_type && operator *() &&
- {
- return std::move( ( assert( has_value() ), contained.value() ) );
- }
- #endif
- constexpr explicit operator bool() const noexcept
- {
- return has_value();
- }
- constexpr bool has_value() const noexcept
- {
- return contained.has_value();
- }
- nsel_DISABLE_MSVC_WARNINGS( 4702 ) // warning C4702: unreachable code, see issue 65.
- constexpr value_type const & value() const &
- {
- return has_value()
- ? ( contained.value() )
- : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
- }
- value_type & value() &
- {
- return has_value()
- ? ( contained.value() )
- : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() );
- }
- nsel_RESTORE_MSVC_WARNINGS()
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- constexpr value_type const && value() const &&
- {
- return std::move( has_value()
- ? ( contained.value() )
- : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
- }
- nsel_constexpr14 value_type && value() &&
- {
- return std::move( has_value()
- ? ( contained.value() )
- : ( error_traits<error_type>::rethrow( contained.error() ), contained.value() ) );
- }
- #endif
- constexpr error_type const & error() const &
- {
- return assert( ! has_value() ), contained.error();
- }
- error_type & error() &
- {
- return assert( ! has_value() ), contained.error();
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- constexpr error_type const && error() const &&
- {
- return std::move( ( assert( ! has_value() ), contained.error() ) );
- }
- error_type && error() &&
- {
- return std::move( ( assert( ! has_value() ), contained.error() ) );
- }
- #endif
- constexpr unexpected_type get_unexpected() const
- {
- return make_unexpected( contained.error() );
- }
- template< typename Ex >
- bool has_exception() const
- {
- using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
- return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
- }
- template< typename U
- nsel_REQUIRES_T(
- std::is_copy_constructible< T>::value
- && std::is_convertible<U&&, T>::value
- )
- >
- value_type value_or( U && v ) const &
- {
- return has_value()
- ? contained.value()
- : static_cast<T>( std::forward<U>( v ) );
- }
- template< typename U
- nsel_REQUIRES_T(
- std::is_move_constructible< T>::value
- && std::is_convertible<U&&, T>::value
- )
- >
- value_type value_or( U && v ) &&
- {
- return has_value()
- ? std::move( contained.value() )
- : static_cast<T>( std::forward<U>( v ) );
- }
- #if nsel_P2505R >= 4
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_copy_constructible< E >::value
- && std::is_convertible< G, E >::value
- )
- >
- nsel_constexpr error_type error_or( G && e ) const &
- {
- return has_value()
- ? static_cast< E >( std::forward< G >( e ) )
- : contained.error();
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_move_constructible< E >::value
- && std::is_convertible< G, E >::value
- )
- >
- nsel_constexpr14 error_type error_or( G && e ) &&
- {
- return has_value()
- ? static_cast< E >( std::forward< G >( e ) )
- : std::move( contained.error() );
- }
- #endif // nsel_P2505R >= 4
- #if nsel_P2505R >= 3
- // Monadic operations (P2505)
- template< typename F
- nsel_REQUIRES_T(
- detail::is_expected < detail::invoke_result_nocvref_t< F, value_type & > > ::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, value_type & >::error_type, error_type >::value
- && std::is_constructible< error_type, error_type & >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F, value_type & > and_then( F && f ) &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, value_type & >( detail::invoke( std::forward< F >( f ), value() ) )
- : detail::invoke_result_nocvref_t< F, value_type & >( unexpect, error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, const value_type & > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, const value_type & >::error_type, error_type >::value
- && std::is_constructible< error_type, const error_type & >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F, const value_type & > and_then( F && f ) const &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, const value_type & >( detail::invoke( std::forward< F >( f ), value() ) )
- : detail::invoke_result_nocvref_t< F, const value_type & >( unexpect, error() );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, value_type && > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, value_type && >::error_type, error_type >::value
- && std::is_constructible< error_type, error_type && >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F, value_type && > and_then( F && f ) &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, value_type && >( detail::invoke( std::forward< F >( f ), std::move( value() ) ) )
- : detail::invoke_result_nocvref_t< F, value_type && >( unexpect, std::move( error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, const value_type && > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, const value_type & >::error_type, error_type >::value
- && std::is_constructible< error_type, const error_type && >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F, const value_type && > and_then( F && f ) const &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, const value_type && >( detail::invoke( std::forward< F >( f ), std::move( value() ) ) )
- : detail::invoke_result_nocvref_t< F, const value_type && >( unexpect, std::move( error() ) );
- }
- #endif
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, error_type & > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, error_type & >::value_type, value_type >::value
- && std::is_constructible< value_type, value_type & >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type & > or_else( F && f ) &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, error_type & >( value() )
- : detail::invoke_result_nocvref_t< F, error_type & >( detail::invoke( std::forward< F >( f ), error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type & > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, const error_type & >::value_type, value_type >::value
- && std::is_constructible< value_type, const value_type & >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type & > or_else( F && f ) const &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, const error_type & >( value() )
- : detail::invoke_result_nocvref_t< F, const error_type & >( detail::invoke( std::forward< F >( f ), error() ) );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, error_type && > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, error_type && >::value_type, value_type >::value
- && std::is_constructible< value_type, value_type && >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type && > or_else( F && f ) &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, error_type && >( std::move( value() ) )
- : detail::invoke_result_nocvref_t< F, error_type && >( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type && > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F, const error_type && >::value_type, value_type >::value
- && std::is_constructible< value_type, const value_type && >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type && > or_else( F && f ) const &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, const error_type && >( std::move( value() ) )
- : detail::invoke_result_nocvref_t< F, const error_type && >( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- #endif
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type & >::value
- && !std::is_void< detail::transform_invoke_result_t< F, value_type & > >::value
- && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, value_type & > >::value
- )
- >
- nsel_constexpr14 expected< detail::transform_invoke_result_t< F, value_type & >, error_type > transform( F && f ) &
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F, value_type & >, error_type >( detail::invoke( std::forward< F >( f ), **this ) )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type & >::value
- && std::is_void< detail::transform_invoke_result_t< F, value_type & > >::value
- )
- >
- nsel_constexpr14 expected< void, error_type > transform( F && f ) &
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ), **this ), expected< void, error_type >() )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type & >::value
- && !std::is_void< detail::transform_invoke_result_t< F, const value_type & > >::value
- && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, const value_type & > >::value
- )
- >
- nsel_constexpr expected< detail::transform_invoke_result_t< F, const value_type & >, error_type > transform( F && f ) const &
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F, const value_type & >, error_type >( detail::invoke( std::forward< F >( f ), **this ) )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type & >::value
- && std::is_void< detail::transform_invoke_result_t< F, const value_type & > >::value
- )
- >
- nsel_constexpr expected< void, error_type > transform( F && f ) const &
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ), **this ), expected< void, error_type >() )
- : make_unexpected( error() );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type && >::value
- && !std::is_void< detail::transform_invoke_result_t< F, value_type && > >::value
- && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, value_type && > >::value
- )
- >
- nsel_constexpr14 expected< detail::transform_invoke_result_t< F, value_type && >, error_type > transform( F && f ) &&
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F, value_type && >, error_type >( detail::invoke( std::forward< F >( f ), std::move( **this ) ) )
- : make_unexpected( std::move( error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type && >::value
- && std::is_void< detail::transform_invoke_result_t< F, value_type && > >::value
- )
- >
- nsel_constexpr14 expected< void, error_type > transform( F && f ) &&
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ), **this ), expected< void, error_type >() )
- : make_unexpected( std::move( error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type && >::value
- && !std::is_void< detail::transform_invoke_result_t< F, const value_type && > >::value
- && detail::valid_expected_value_type< detail::transform_invoke_result_t< F, const value_type && > >::value
- )
- >
- nsel_constexpr expected< detail::transform_invoke_result_t< F, const value_type && >, error_type > transform( F && f ) const &&
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F, const value_type && >, error_type >( detail::invoke( std::forward< F >( f ), std::move( **this ) ) )
- : make_unexpected( std::move( error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type && >::value
- && std::is_void< detail::transform_invoke_result_t< F, const value_type && > >::value
- )
- >
- nsel_constexpr expected< void, error_type > transform( F && f ) const &&
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ), **this ), expected< void, error_type >() )
- : make_unexpected( std::move( error() ) );
- }
- #endif
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type & > >::value
- && std::is_constructible< value_type, value_type & >::value
- )
- >
- nsel_constexpr14 expected< value_type, detail::transform_invoke_result_t< F, error_type & > > transform_error( F && f ) &
- {
- return has_value()
- ? expected< value_type, detail::transform_invoke_result_t< F, error_type & > >( in_place, **this )
- : make_unexpected( detail::invoke( std::forward< F >( f ), error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type & > >::value
- && std::is_constructible< value_type, const value_type & >::value
- )
- >
- nsel_constexpr expected< value_type, detail::transform_invoke_result_t< F, const error_type & > > transform_error( F && f ) const &
- {
- return has_value()
- ? expected< value_type, detail::transform_invoke_result_t< F, const error_type & > >( in_place, **this )
- : make_unexpected( detail::invoke( std::forward< F >( f ), error() ) );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type && > >::value
- && std::is_constructible< value_type, value_type && >::value
- )
- >
- nsel_constexpr14 expected< value_type, detail::transform_invoke_result_t< F, error_type && > > transform_error( F && f ) &&
- {
- return has_value()
- ? expected< value_type, detail::transform_invoke_result_t< F, error_type && > >( in_place, std::move( **this ) )
- : make_unexpected( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type && > >::value
- && std::is_constructible< value_type, const value_type && >::value
- )
- >
- nsel_constexpr expected< value_type, detail::transform_invoke_result_t< F, const error_type && > > transform_error( F && f ) const &&
- {
- return has_value()
- ? expected< value_type, detail::transform_invoke_result_t< F, const error_type && > >( in_place, std::move( **this ) )
- : make_unexpected( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- #endif
- #endif // nsel_P2505R >= 3
- // unwrap()
- // template <class U, class E>
- // constexpr expected<U,E> expected<expected<U,E>,E>::unwrap() const&;
- // template <class T, class E>
- // constexpr expected<T,E> expected<T,E>::unwrap() const&;
- // template <class U, class E>
- // expected<U,E> expected<expected<U,E>, E>::unwrap() &&;
- // template <class T, class E>
- // template expected<T,E> expected<T,E>::unwrap() &&;
- // factories
- // template< typename Ex, typename F>
- // expected<T,E> catch_exception(F&& f);
- // template< typename F>
- // expected<decltype(func(declval<T>())),E> map(F&& func) ;
- // template< typename F>
- // 'see below' bind(F&& func);
- // template< typename F>
- // expected<T,E> catch_error(F&& f);
- // template< typename F>
- // 'see below' then(F&& func);
- private:
- detail::storage_t
- <
- T
- ,E
- , std::is_copy_constructible<T>::value && std::is_copy_constructible<E>::value
- , std::is_move_constructible<T>::value && std::is_move_constructible<E>::value
- >
- contained;
- };
- /// class expected, void specialization
- template< typename E >
- class expected<void, E>
- {
- private:
- template< typename, typename > friend class expected;
- public:
- using value_type = void;
- using error_type = E;
- using unexpected_type = nonstd::unexpected_type<E>;
- // x.x.4.1 constructors
- constexpr expected() noexcept
- : contained( true )
- {}
- nsel_constexpr14 expected( expected const & other ) = default;
- nsel_constexpr14 expected( expected && other ) = default;
- constexpr explicit expected( nonstd_lite_in_place_t(void) )
- : contained( true )
- {}
- template< typename G = E
- nsel_REQUIRES_T(
- !std::is_convertible<G const &, E>::value /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> const & error )
- : contained( false )
- {
- contained.construct_error( E{ error.error() } );
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_convertible<G const &, E>::value /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> const & error )
- : contained( false )
- {
- contained.construct_error( error.error() );
- }
- template< typename G = E
- nsel_REQUIRES_T(
- !std::is_convertible<G&&, E>::value /*=> explicit */
- )
- >
- nsel_constexpr14 explicit expected( nonstd::unexpected_type<G> && error )
- : contained( false )
- {
- contained.construct_error( E{ std::move( error.error() ) } );
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_convertible<G&&, E>::value /*=> non-explicit */
- )
- >
- nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type<G> && error )
- : contained( false )
- {
- contained.construct_error( std::move( error.error() ) );
- }
- template< typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<E, Args&&...>::value
- )
- >
- nsel_constexpr14 explicit expected( unexpect_t, Args&&... args )
- : contained( false )
- {
- contained.emplace_error( std::forward<Args>( args )... );
- }
- template< typename U, typename... Args
- nsel_REQUIRES_T(
- std::is_constructible<E, std::initializer_list<U>, Args&&...>::value
- )
- >
- nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list<U> il, Args&&... args )
- : contained( false )
- {
- contained.emplace_error( il, std::forward<Args>( args )... );
- }
- // destructor
- ~expected()
- {
- if ( ! has_value() )
- {
- contained.destruct_error();
- }
- }
- // x.x.4.3 assignment
- expected & operator=( expected const & other )
- {
- expected( other ).swap( *this );
- return *this;
- }
- expected & operator=( expected && other ) noexcept
- (
- std::is_nothrow_move_assignable<E>::value &&
- std::is_nothrow_move_constructible<E>::value )
- {
- expected( std::move( other ) ).swap( *this );
- return *this;
- }
- void emplace()
- {
- expected().swap( *this );
- }
- // x.x.4.4 swap
- template< typename G = E >
- nsel_REQUIRES_R( void,
- std17::is_swappable<G>::value
- && std::is_move_constructible<G>::value
- )
- swap( expected & other ) noexcept
- (
- std::is_nothrow_move_constructible<E>::value && std17::is_nothrow_swappable<E&>::value
- )
- {
- using std::swap;
- if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); }
- else if ( bool(*this) && ! bool(other) ) { contained.construct_error( std::move( other.error() ) );
- bool has_value = contained.has_value();
- bool other_has_value = other.has_value();
- other.contained.set_has_value(has_value);
- contained.set_has_value(other_has_value);
- }
- else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); }
- }
- // x.x.4.5 observers
- constexpr explicit operator bool() const noexcept
- {
- return has_value();
- }
- constexpr bool has_value() const noexcept
- {
- return contained.has_value();
- }
- void value() const
- {
- if ( ! has_value() )
- {
- error_traits<error_type>::rethrow( contained.error() );
- }
- }
- constexpr error_type const & error() const &
- {
- return assert( ! has_value() ), contained.error();
- }
- error_type & error() &
- {
- return assert( ! has_value() ), contained.error();
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- constexpr error_type const && error() const &&
- {
- return std::move( ( assert( ! has_value() ), contained.error() ) );
- }
- error_type && error() &&
- {
- return std::move( ( assert( ! has_value() ), contained.error() ) );
- }
- #endif
- constexpr unexpected_type get_unexpected() const
- {
- return make_unexpected( contained.error() );
- }
- template< typename Ex >
- bool has_exception() const
- {
- using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type;
- return ! has_value() && std::is_base_of< Ex, ContainedEx>::value;
- }
- #if nsel_P2505R >= 4
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_copy_constructible< E >::value
- && std::is_convertible< G, E >::value
- )
- >
- nsel_constexpr error_type error_or( G && e ) const &
- {
- return has_value()
- ? static_cast< E >( std::forward< G >( e ) )
- : contained.error();
- }
- template< typename G = E
- nsel_REQUIRES_T(
- std::is_move_constructible< E >::value
- && std::is_convertible< G, E >::value
- )
- >
- nsel_constexpr14 error_type error_or( G && e ) &&
- {
- return has_value()
- ? static_cast< E >( std::forward< G >( e ) )
- : std::move( contained.error() );
- }
- #endif // nsel_P2505R >= 4
- #if nsel_P2505R >= 3
- // Monadic operations (P2505)
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
- && std::is_constructible< error_type, error_type & >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F > and_then( F && f ) &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
- : detail::invoke_result_nocvref_t< F >( unexpect, error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
- && std::is_constructible< error_type, const error_type & >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F > and_then( F && f ) const &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
- : detail::invoke_result_nocvref_t< F >( unexpect, error() );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
- && std::is_constructible< error_type, error_type && >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F > and_then( F && f ) &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
- : detail::invoke_result_nocvref_t< F >( unexpect, std::move( error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F > >::value
- && std::is_same< typename detail::invoke_result_nocvref_t< F >::error_type, error_type >::value
- && std::is_constructible< error_type, const error_type && >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F > and_then( F && f ) const &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F >( detail::invoke( std::forward< F >( f ) ) )
- : detail::invoke_result_nocvref_t< F >( unexpect, std::move( error() ) );
- }
- #endif
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, error_type & > >::value
- && std::is_void< typename detail::invoke_result_nocvref_t< F, error_type & >::value_type >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type & > or_else( F && f ) &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, error_type & >()
- : detail::invoke_result_nocvref_t< F, error_type & >( detail::invoke( std::forward< F >( f ), error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type & > >::value
- && std::is_void< typename detail::invoke_result_nocvref_t< F, const error_type & >::value_type >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type & > or_else( F && f ) const &
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, const error_type & >()
- : detail::invoke_result_nocvref_t< F, const error_type & >( detail::invoke( std::forward< F >( f ), error() ) );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, error_type && > >::value
- && std::is_void< typename detail::invoke_result_nocvref_t< F, error_type && >::value_type >::value
- )
- >
- nsel_constexpr14 detail::invoke_result_nocvref_t< F, error_type && > or_else( F && f ) &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, error_type && >()
- : detail::invoke_result_nocvref_t< F, error_type && >( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::is_expected< detail::invoke_result_nocvref_t< F, const error_type && > >::value
- && std::is_void< typename detail::invoke_result_nocvref_t< F, const error_type && >::value_type >::value
- )
- >
- nsel_constexpr detail::invoke_result_nocvref_t< F, const error_type && > or_else( F && f ) const &&
- {
- return has_value()
- ? detail::invoke_result_nocvref_t< F, const error_type && >()
- : detail::invoke_result_nocvref_t< F, const error_type && >( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- #endif
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type & >::value
- && !std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr14 expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f ) &
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type & >::value
- && std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr14 expected< void, error_type > transform( F && f ) &
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type & >::value
- && !std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f ) const &
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type & >::value
- && std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr expected< void, error_type > transform( F && f ) const &
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
- : make_unexpected( error() );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type && >::value
- && !std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr14 expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f ) &&
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, error_type && >::value
- && std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr14 expected< void, error_type > transform( F && f ) &&
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type && >::value
- && !std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr expected< detail::transform_invoke_result_t< F >, error_type > transform( F && f ) const &&
- {
- return has_value()
- ? expected< detail::transform_invoke_result_t< F >, error_type >( detail::invoke( std::forward< F >( f ) ) )
- : make_unexpected( error() );
- }
- template<typename F
- nsel_REQUIRES_T(
- std::is_constructible< error_type, const error_type && >::value
- && std::is_void< detail::transform_invoke_result_t< F > >::value
- )
- >
- nsel_constexpr expected< void, error_type > transform( F && f ) const &&
- {
- return has_value()
- ? ( detail::invoke( std::forward< F >( f ) ), expected< void, error_type >() )
- : make_unexpected( error() );
- }
- #endif
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type & > >::value
- )
- >
- nsel_constexpr14 expected< void, detail::transform_invoke_result_t< F, error_type & > > transform_error( F && f ) &
- {
- return has_value()
- ? expected< void, detail::transform_invoke_result_t< F, error_type & > >()
- : make_unexpected( detail::invoke( std::forward< F >( f ), error() ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type & > >::value
- )
- >
- nsel_constexpr expected< void, detail::transform_invoke_result_t< F, const error_type & > > transform_error( F && f ) const &
- {
- return has_value()
- ? expected< void, detail::transform_invoke_result_t< F, const error_type & > >()
- : make_unexpected( detail::invoke( std::forward< F >( f ), error() ) );
- }
- #if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, error_type && > >::value
- )
- >
- nsel_constexpr14 expected< void, detail::transform_invoke_result_t< F, error_type && > > transform_error( F && f ) &&
- {
- return has_value()
- ? expected< void, detail::transform_invoke_result_t< F, error_type && > >()
- : make_unexpected( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- template<typename F
- nsel_REQUIRES_T(
- detail::valid_unexpected_type< detail::transform_invoke_result_t< F, const error_type && > >::value
- )
- >
- nsel_constexpr expected< void, detail::transform_invoke_result_t< F, const error_type && > > transform_error( F && f ) const &&
- {
- return has_value()
- ? expected< void, detail::transform_invoke_result_t< F, const error_type && > >()
- : make_unexpected( detail::invoke( std::forward< F >( f ), std::move( error() ) ) );
- }
- #endif
- #endif // nsel_P2505R >= 3
- // template constexpr 'see below' unwrap() const&;
- //
- // template 'see below' unwrap() &&;
- // factories
- // template< typename Ex, typename F>
- // expected<void,E> catch_exception(F&& f);
- //
- // template< typename F>
- // expected<decltype(func()), E> map(F&& func) ;
- //
- // template< typename F>
- // 'see below' bind(F&& func) ;
- //
- // template< typename F>
- // expected<void,E> catch_error(F&& f);
- //
- // template< typename F>
- // 'see below' then(F&& func);
- private:
- detail::storage_t
- <
- void
- , E
- , std::is_copy_constructible<E>::value
- , std::is_move_constructible<E>::value
- >
- contained;
- };
- // x.x.4.6 expected<>: comparison operators
- template< typename T1, typename E1, typename T2, typename E2
- nsel_REQUIRES_T(
- !std::is_void<T1>::value && !std::is_void<T2>::value
- )
- >
- constexpr bool operator==( expected<T1,E1> const & x, expected<T2,E2> const & y )
- {
- return bool(x) != bool(y) ? false : bool(x) ? *x == *y : x.error() == y.error();
- }
- template< typename T1, typename E1, typename T2, typename E2
- nsel_REQUIRES_T(
- std::is_void<T1>::value && std::is_void<T2>::value
- )
- >
- constexpr bool operator==( expected<T1,E1> const & x, expected<T2,E2> const & y )
- {
- return bool(x) != bool(y) ? false : bool(x) || static_cast<bool>( x.error() == y.error() );
- }
- template< typename T1, typename E1, typename T2, typename E2 >
- constexpr bool operator!=( expected<T1,E1> const & x, expected<T2,E2> const & y )
- {
- return !(x == y);
- }
- #if nsel_P0323R <= 2
- template< typename T, typename E >
- constexpr bool operator<( expected<T,E> const & x, expected<T,E> const & y )
- {
- return (!y) ? false : (!x) ? true : *x < *y;
- }
- template< typename T, typename E >
- constexpr bool operator>( expected<T,E> const & x, expected<T,E> const & y )
- {
- return (y < x);
- }
- template< typename T, typename E >
- constexpr bool operator<=( expected<T,E> const & x, expected<T,E> const & y )
- {
- return !(y < x);
- }
- template< typename T, typename E >
- constexpr bool operator>=( expected<T,E> const & x, expected<T,E> const & y )
- {
- return !(x < y);
- }
- #endif
- // x.x.4.7 expected: comparison with T
- template< typename T1, typename E1, typename T2
- nsel_REQUIRES_T(
- !std::is_void<T1>::value
- )
- >
- constexpr bool operator==( expected<T1,E1> const & x, T2 const & v )
- {
- return bool(x) ? *x == v : false;
- }
- template< typename T1, typename E1, typename T2
- nsel_REQUIRES_T(
- !std::is_void<T1>::value
- )
- >
- constexpr bool operator==(T2 const & v, expected<T1,E1> const & x )
- {
- return bool(x) ? v == *x : false;
- }
- template< typename T1, typename E1, typename T2 >
- constexpr bool operator!=( expected<T1,E1> const & x, T2 const & v )
- {
- return bool(x) ? *x != v : true;
- }
- template< typename T1, typename E1, typename T2 >
- constexpr bool operator!=( T2 const & v, expected<T1,E1> const & x )
- {
- return bool(x) ? v != *x : true;
- }
- #if nsel_P0323R <= 2
- template< typename T, typename E >
- constexpr bool operator<( expected<T,E> const & x, T const & v )
- {
- return bool(x) ? *x < v : true;
- }
- template< typename T, typename E >
- constexpr bool operator<( T const & v, expected<T,E> const & x )
- {
- return bool(x) ? v < *x : false;
- }
- template< typename T, typename E >
- constexpr bool operator>( T const & v, expected<T,E> const & x )
- {
- return bool(x) ? *x < v : false;
- }
- template< typename T, typename E >
- constexpr bool operator>( expected<T,E> const & x, T const & v )
- {
- return bool(x) ? v < *x : false;
- }
- template< typename T, typename E >
- constexpr bool operator<=( T const & v, expected<T,E> const & x )
- {
- return bool(x) ? ! ( *x < v ) : false;
- }
- template< typename T, typename E >
- constexpr bool operator<=( expected<T,E> const & x, T const & v )
- {
- return bool(x) ? ! ( v < *x ) : true;
- }
- template< typename T, typename E >
- constexpr bool operator>=( expected<T,E> const & x, T const & v )
- {
- return bool(x) ? ! ( *x < v ) : false;
- }
- template< typename T, typename E >
- constexpr bool operator>=( T const & v, expected<T,E> const & x )
- {
- return bool(x) ? ! ( v < *x ) : true;
- }
- #endif // nsel_P0323R
- // x.x.4.8 expected: comparison with unexpected_type
- template< typename T1, typename E1 , typename E2 >
- constexpr bool operator==( expected<T1,E1> const & x, unexpected_type<E2> const & u )
- {
- return (!x) ? x.get_unexpected() == u : false;
- }
- template< typename T1, typename E1 , typename E2 >
- constexpr bool operator==( unexpected_type<E2> const & u, expected<T1,E1> const & x )
- {
- return ( x == u );
- }
- template< typename T1, typename E1 , typename E2 >
- constexpr bool operator!=( expected<T1,E1> const & x, unexpected_type<E2> const & u )
- {
- return ! ( x == u );
- }
- template< typename T1, typename E1 , typename E2 >
- constexpr bool operator!=( unexpected_type<E2> const & u, expected<T1,E1> const & x )
- {
- return ! ( x == u );
- }
- #if nsel_P0323R <= 2
- template< typename T, typename E >
- constexpr bool operator<( expected<T,E> const & x, unexpected_type<E> const & u )
- {
- return (!x) ? ( x.get_unexpected() < u ) : false;
- }
- template< typename T, typename E >
- constexpr bool operator<( unexpected_type<E> const & u, expected<T,E> const & x )
- {
- return (!x) ? ( u < x.get_unexpected() ) : true ;
- }
- template< typename T, typename E >
- constexpr bool operator>( expected<T,E> const & x, unexpected_type<E> const & u )
- {
- return ( u < x );
- }
- template< typename T, typename E >
- constexpr bool operator>( unexpected_type<E> const & u, expected<T,E> const & x )
- {
- return ( x < u );
- }
- template< typename T, typename E >
- constexpr bool operator<=( expected<T,E> const & x, unexpected_type<E> const & u )
- {
- return ! ( u < x );
- }
- template< typename T, typename E >
- constexpr bool operator<=( unexpected_type<E> const & u, expected<T,E> const & x)
- {
- return ! ( x < u );
- }
- template< typename T, typename E >
- constexpr bool operator>=( expected<T,E> const & x, unexpected_type<E> const & u )
- {
- return ! ( u > x );
- }
- template< typename T, typename E >
- constexpr bool operator>=( unexpected_type<E> const & u, expected<T,E> const & x )
- {
- return ! ( x > u );
- }
- #endif // nsel_P0323R
- /// x.x.x Specialized algorithms
- template< typename T, typename E
- nsel_REQUIRES_T(
- ( std::is_void<T>::value || std::is_move_constructible<T>::value )
- && std::is_move_constructible<E>::value
- && std17::is_swappable<T>::value
- && std17::is_swappable<E>::value )
- >
- void swap( expected<T,E> & x, expected<T,E> & y ) noexcept ( noexcept ( x.swap(y) ) )
- {
- x.swap( y );
- }
- #if nsel_P0323R <= 3
- template< typename T >
- constexpr auto make_expected( T && v ) -> expected< typename std::decay<T>::type >
- {
- return expected< typename std::decay<T>::type >( std::forward<T>( v ) );
- }
- // expected<void> specialization:
- auto inline make_expected() -> expected<void>
- {
- return expected<void>( in_place );
- }
- template< typename T >
- constexpr auto make_expected_from_current_exception() -> expected<T>
- {
- return expected<T>( make_unexpected_from_current_exception() );
- }
- template< typename T >
- auto make_expected_from_exception( std::exception_ptr v ) -> expected<T>
- {
- return expected<T>( unexpected_type<std::exception_ptr>( std::forward<std::exception_ptr>( v ) ) );
- }
- template< typename T, typename E >
- constexpr auto make_expected_from_error( E e ) -> expected<T, typename std::decay<E>::type>
- {
- return expected<T, typename std::decay<E>::type>( make_unexpected( e ) );
- }
- template< typename F
- nsel_REQUIRES_T( ! std::is_same<typename std::result_of<F()>::type, void>::value )
- >
- /*nsel_constexpr14*/
- auto make_expected_from_call( F f ) -> expected< typename std::result_of<F()>::type >
- {
- try
- {
- return make_expected( f() );
- }
- catch (...)
- {
- return make_unexpected_from_current_exception();
- }
- }
- template< typename F
- nsel_REQUIRES_T( std::is_same<typename std::result_of<F()>::type, void>::value )
- >
- /*nsel_constexpr14*/
- auto make_expected_from_call( F f ) -> expected<void>
- {
- try
- {
- f();
- return make_expected();
- }
- catch (...)
- {
- return make_unexpected_from_current_exception();
- }
- }
- #endif // nsel_P0323R
- } // namespace expected_lite
- using namespace expected_lite;
- // using expected_lite::expected;
- // using ...
- } // namespace nonstd
- namespace std {
- // expected: hash support
- template< typename T, typename E >
- struct hash< nonstd::expected<T,E> >
- {
- using result_type = std::size_t;
- using argument_type = nonstd::expected<T,E>;
- constexpr result_type operator()(argument_type const & arg) const
- {
- return arg ? std::hash<T>{}(*arg) : result_type{};
- }
- };
- // TBD - ?? remove? see spec.
- template< typename T, typename E >
- struct hash< nonstd::expected<T&,E> >
- {
- using result_type = std::size_t;
- using argument_type = nonstd::expected<T&,E>;
- constexpr result_type operator()(argument_type const & arg) const
- {
- return arg ? std::hash<T>{}(*arg) : result_type{};
- }
- };
- // TBD - implement
- // bool(e), hash<expected<void,E>>()(e) shall evaluate to the hashing true;
- // otherwise it evaluates to an unspecified value if E is exception_ptr or
- // a combination of hashing false and hash<E>()(e.error()).
- template< typename E >
- struct hash< nonstd::expected<void,E> >
- {
- };
- } // namespace std
- namespace nonstd {
- // void unexpected() is deprecated && removed in C++17
- #if nsel_CPP17_OR_GREATER || nsel_COMPILER_MSVC_VERSION > 141
- template< typename E >
- using unexpected = unexpected_type<E>;
- #endif
- } // namespace nonstd
- #undef nsel_REQUIRES
- #undef nsel_REQUIRES_0
- #undef nsel_REQUIRES_T
- nsel_RESTORE_WARNINGS()
- #endif // nsel_USES_STD_EXPECTED
- #endif // NONSTD_EXPECTED_LITE_HPP
|