1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025 |
- // MPark.Variant
- //
- // Copyright Michael Park, 2015-2017
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.md or copy at
- // http://boost.org/LICENSE_1_0.txt)
- //
- // From https://github.com/mpark/variant
- //
- // C10
- // - Move to `c10` namespace.
- // - Rename namespace `detail` to `detail_`, to not conflict with existing
- // c10 implementations in `detail` namespace.
- // - In two functions, the template name reference `I` is changed to
- // `detail_::best_match<Arg, Ts...>::value` to work around gcc 7.3.1 bug.
- // However, this workaround also limits the use cases of `c10::variant`.
- // Please see NOTE [gcc 7.3.1 bug workaround] for details.
- // - The following code is moved to `c10/util/in_place.h`:
- // ```
- // struct in_place_t { explicit in_place_t() = default; };
- //
- // template <std::size_t I>
- // struct in_place_index_t { explicit in_place_index_t() = default; };
- //
- // template <typename T>
- // struct in_place_type_t { explicit in_place_type_t() = default; };
- //
- // constexpr in_place_t in_place{};
- // ```
- // so that they can also be used in `c10/util/Optional.h`.
- #ifndef C10_UTIL_VARIANT_H_
- #define C10_UTIL_VARIANT_H_
- /*
- variant synopsis
- namespace std {
- // 20.7.2, class template variant
- template <class... Types>
- class variant {
- public:
- // 20.7.2.1, constructors
- constexpr variant() noexcept(see below);
- variant(const variant&);
- variant(variant&&) noexcept(see below);
- template <class T> constexpr variant(T&&) noexcept(see below);
- template <class T, class... Args>
- constexpr explicit variant(in_place_type_t<T>, Args&&...);
- template <class T, class U, class... Args>
- constexpr explicit variant(
- in_place_type_t<T>, initializer_list<U>, Args&&...);
- template <size_t I, class... Args>
- constexpr explicit variant(in_place_index_t<I>, Args&&...);
- template <size_t I, class U, class... Args>
- constexpr explicit variant(
- in_place_index_t<I>, initializer_list<U>, Args&&...);
- // 20.7.2.2, destructor
- ~variant();
- // 20.7.2.3, assignment
- variant& operator=(const variant&);
- variant& operator=(variant&&) noexcept(see below);
- template <class T> variant& operator=(T&&) noexcept(see below);
- // 20.7.2.4, modifiers
- template <class T, class... Args>
- T& emplace(Args&&...);
- template <class T, class U, class... Args>
- T& emplace(initializer_list<U>, Args&&...);
- template <size_t I, class... Args>
- variant_alternative<I, variant>& emplace(Args&&...);
- template <size_t I, class U, class... Args>
- variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
- // 20.7.2.5, value status
- constexpr bool valueless_by_exception() const noexcept;
- constexpr size_t index() const noexcept;
- // 20.7.2.6, swap
- void swap(variant&) noexcept(see below);
- };
- // 20.7.3, variant helper classes
- template <class T> struct variant_size; // undefined
- template <class T>
- constexpr size_t variant_size_v = variant_size<T>::value;
- template <class T> struct variant_size<const T>;
- template <class T> struct variant_size<volatile T>;
- template <class T> struct variant_size<const volatile T>;
- template <class... Types>
- struct variant_size<variant<Types...>>;
- template <size_t I, class T> struct variant_alternative; // undefined
- template <size_t I, class T>
- using variant_alternative_t = typename variant_alternative<I, T>::type;
- template <size_t I, class T> struct variant_alternative<I, const T>;
- template <size_t I, class T> struct variant_alternative<I, volatile T>;
- template <size_t I, class T> struct variant_alternative<I, const volatile T>;
- template <size_t I, class... Types>
- struct variant_alternative<I, variant<Types...>>;
- constexpr size_t variant_npos = -1;
- // 20.7.4, value access
- template <class T, class... Types>
- constexpr bool holds_alternative(const variant<Types...>&) noexcept;
- template <size_t I, class... Types>
- constexpr variant_alternative_t<I, variant<Types...>>&
- get(variant<Types...>&);
- template <size_t I, class... Types>
- constexpr variant_alternative_t<I, variant<Types...>>&&
- get(variant<Types...>&&);
- template <size_t I, class... Types>
- constexpr variant_alternative_t<I, variant<Types...>> const&
- get(const variant<Types...>&);
- template <size_t I, class... Types>
- constexpr variant_alternative_t<I, variant<Types...>> const&&
- get(const variant<Types...>&&);
- template <class T, class... Types>
- constexpr T& get(variant<Types...>&);
- template <class T, class... Types>
- constexpr T&& get(variant<Types...>&&);
- template <class T, class... Types>
- constexpr const T& get(const variant<Types...>&);
- template <class T, class... Types>
- constexpr const T&& get(const variant<Types...>&&);
- template <size_t I, class... Types>
- constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
- get_if(variant<Types...>*) noexcept;
- template <size_t I, class... Types>
- constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
- get_if(const variant<Types...>*) noexcept;
- template <class T, class... Types>
- constexpr add_pointer_t<T>
- get_if(variant<Types...>*) noexcept;
- template <class T, class... Types>
- constexpr add_pointer_t<const T>
- get_if(const variant<Types...>*) noexcept;
- // 20.7.5, relational operators
- template <class... Types>
- constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
- template <class... Types>
- constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
- template <class... Types>
- constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
- template <class... Types>
- constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
- template <class... Types>
- constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
- template <class... Types>
- constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
- // 20.7.6, visitation
- template <class Visitor, class... Variants>
- constexpr see below visit(Visitor&&, Variants&&...);
- // 20.7.7, class monostate
- struct monostate;
- // 20.7.8, monostate relational operators
- constexpr bool operator<(monostate, monostate) noexcept;
- constexpr bool operator>(monostate, monostate) noexcept;
- constexpr bool operator<=(monostate, monostate) noexcept;
- constexpr bool operator>=(monostate, monostate) noexcept;
- constexpr bool operator==(monostate, monostate) noexcept;
- constexpr bool operator!=(monostate, monostate) noexcept;
- // 20.7.9, specialized algorithms
- template <class... Types>
- void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
- // 20.7.10, class bad_variant_access
- class bad_variant_access;
- // 20.7.11, hash support
- template <class T> struct hash;
- template <class... Types> struct hash<variant<Types...>>;
- template <> struct hash<monostate>;
- } // namespace std
- */
- #include <cstddef>
- #include <exception>
- #include <functional>
- #include <initializer_list>
- #include <new>
- #include <type_traits>
- #include <utility>
- // MPark.Variant
- //
- // Copyright Michael Park, 2015-2017
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.md or copy at
- // http://boost.org/LICENSE_1_0.txt)
- #ifndef C10_MPARK_CONFIG_HPP
- #define C10_MPARK_CONFIG_HPP
- // MSVC 2015 Update 3.
- #if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
- #error "MPark.Variant requires C++11 support."
- #endif
- #ifndef __has_attribute
- #define __has_attribute(x) 0
- #endif
- #ifndef __has_builtin
- #define __has_builtin(x) 0
- #endif
- #ifndef __has_include
- #define __has_include(x) 0
- #endif
- #ifndef __has_feature
- #define __has_feature(x) 0
- #endif
- #if __has_attribute(always_inline) || defined(__GNUC__)
- #define C10_MPARK_ALWAYS_INLINE __attribute__((__always_inline__)) inline
- #elif defined(_MSC_VER)
- #define C10_MPARK_ALWAYS_INLINE __forceinline
- #else
- #define C10_MPARK_ALWAYS_INLINE inline
- #endif
- #if __has_builtin(__builtin_addressof) || \
- (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
- #define C10_MPARK_BUILTIN_ADDRESSOF
- #endif
- #if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
- #define C10_MPARK_BUILTIN_UNREACHABLE __builtin_unreachable()
- #elif defined(_MSC_VER)
- #define C10_MPARK_BUILTIN_UNREACHABLE __assume(false)
- #else
- #define C10_MPARK_BUILTIN_UNREACHABLE
- #endif
- // NOTE [nvcc bug workaround]
- //
- // The original line `typename Front = lib::type_pack_element_t<0, Ts...>,`
- // throws the following compiler error on nvcc:
- // ```
- // c10/util/variant.h(2367): error: parameter pack "Ts" was referenced but not
- // expanded
- // ```
- // As a workaround, we skip defining C10_MPARK_TYPE_PACK_ELEMENT for nvcc
- // compiler
- //
- // See the following issues for more context:
- // https://github.com/pytorch/extension-cpp/issues/58
- // https://github.com/mpark/variant/issues/77
- #if __has_builtin(__type_pack_element) && !defined(__CUDACC__)
- #define C10_MPARK_TYPE_PACK_ELEMENT
- #endif
- #if defined(__cpp_constexpr) && __cpp_constexpr >= 200704 && \
- !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 9)
- #define C10_MPARK_CPP11_CONSTEXPR
- #endif
- #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
- #define C10_MPARK_CPP14_CONSTEXPR
- #endif
- #if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
- (defined(_MSC_VER) && defined(_CPPUNWIND))
- #define C10_MPARK_EXCEPTIONS
- #endif
- #if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
- #define C10_MPARK_GENERIC_LAMBDAS
- #endif
- #if defined(__cpp_lib_integer_sequence)
- #define C10_MPARK_INTEGER_SEQUENCE
- #endif
- #if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
- #define C10_MPARK_RETURN_TYPE_DEDUCTION
- #endif
- #if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
- #define C10_MPARK_TRANSPARENT_OPERATORS
- #endif
- #if defined(__cpp_variable_templates) || defined(_MSC_VER)
- #define C10_MPARK_VARIABLE_TEMPLATES
- #endif
- #if !defined(__GLIBCXX__) || __has_include(<codecvt>) // >= libstdc++-5
- #define C10_MPARK_TRIVIALITY_TYPE_TRAITS
- #define C10_MPARK_INCOMPLETE_TYPE_TRAITS
- #endif
- #ifdef _WIN32
- #define C10_MPARK_VISIBILITY_HIDDEN
- #else
- #define C10_MPARK_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
- #endif
- #endif // C10_MPARK_CONFIG_HPP
- // MPark.Variant
- //
- // Copyright Michael Park, 2015-2017
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.md or copy at
- // http://boost.org/LICENSE_1_0.txt)
- #ifndef C10_MPARK_IN_PLACE_HPP
- #define C10_MPARK_IN_PLACE_HPP
- #include <c10/util/in_place.h>
- #include <cstddef>
- namespace c10 {
- #ifdef C10_MPARK_VARIABLE_TEMPLATES
- template <std::size_t I>
- constexpr in_place_index_t<I> in_place_index{};
- template <typename T>
- constexpr in_place_type_t<T> in_place_type{};
- #endif
- } // namespace c10
- #endif // C10_MPARK_IN_PLACE_HPP
- // MPark.Variant
- //
- // Copyright Michael Park, 2015-2017
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE.md or copy at
- // http://boost.org/LICENSE_1_0.txt)
- #ifndef C10_MPARK_LIB_HPP
- #define C10_MPARK_LIB_HPP
- #include <functional>
- #include <memory>
- #include <type_traits>
- #include <utility>
- #define C10_MPARK_RETURN(...) \
- noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) { \
- return __VA_ARGS__; \
- }
- namespace c10 {
- namespace lib {
- template <typename T>
- struct identity {
- using type = T;
- };
- inline namespace cpp14 {
- template <typename T, std::size_t N>
- struct array {
- constexpr const T& operator[](std::size_t index) const {
- return data[index];
- }
- T data[N == 0 ? 1 : N];
- };
- template <typename T>
- using add_pointer_t = typename std::add_pointer<T>::type;
- template <typename... Ts>
- using common_type_t = typename std::common_type<Ts...>::type;
- template <typename T>
- using decay_t = typename std::decay<T>::type;
- template <bool B, typename T = void>
- using enable_if_t = typename std::enable_if<B, T>::type;
- template <typename T>
- using remove_const_t = typename std::remove_const<T>::type;
- template <typename T>
- using remove_reference_t = typename std::remove_reference<T>::type;
- template <typename T>
- inline constexpr T&& forward(remove_reference_t<T>& t) noexcept {
- return static_cast<T&&>(t);
- }
- template <typename T>
- inline constexpr T&& forward(remove_reference_t<T>&& t) noexcept {
- static_assert(
- !std::is_lvalue_reference<T>::value,
- "can not forward an rvalue as an lvalue");
- return static_cast<T&&>(t);
- }
- template <typename T>
- inline constexpr remove_reference_t<T>&& move(T&& t) noexcept {
- return static_cast<remove_reference_t<T>&&>(t);
- }
- #ifdef C10_MPARK_INTEGER_SEQUENCE
- using std::index_sequence;
- using std::index_sequence_for;
- using std::integer_sequence;
- using std::make_index_sequence;
- #else
- template <typename T, T... Is>
- struct integer_sequence {
- using value_type = T;
- static constexpr std::size_t size() noexcept {
- return sizeof...(Is);
- }
- };
- template <std::size_t... Is>
- using index_sequence = integer_sequence<std::size_t, Is...>;
- template <typename Lhs, typename Rhs>
- struct make_index_sequence_concat;
- template <std::size_t... Lhs, std::size_t... Rhs>
- struct make_index_sequence_concat<
- index_sequence<Lhs...>,
- index_sequence<Rhs...>>
- : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
- template <std::size_t N>
- struct make_index_sequence_impl;
- template <std::size_t N>
- using make_index_sequence = typename make_index_sequence_impl<N>::type;
- template <std::size_t N>
- struct make_index_sequence_impl : make_index_sequence_concat<
- make_index_sequence<N / 2>,
- make_index_sequence<N - (N / 2)>> {};
- template <>
- struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
- template <>
- struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
- template <typename... Ts>
- using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
- #endif
- // <functional>
- #ifdef C10_MPARK_TRANSPARENT_OPERATORS
- using equal_to = std::equal_to<>;
- #else
- struct equal_to {
- template <typename Lhs, typename Rhs>
- inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
- C10_MPARK_RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
- };
- #endif
- #ifdef C10_MPARK_TRANSPARENT_OPERATORS
- using not_equal_to = std::not_equal_to<>;
- #else
- struct not_equal_to {
- template <typename Lhs, typename Rhs>
- inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
- C10_MPARK_RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
- };
- #endif
- #ifdef C10_MPARK_TRANSPARENT_OPERATORS
- using less = std::less<>;
- #else
- struct less {
- template <typename Lhs, typename Rhs>
- inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
- C10_MPARK_RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
- };
- #endif
- #ifdef C10_MPARK_TRANSPARENT_OPERATORS
- using greater = std::greater<>;
- #else
- struct greater {
- template <typename Lhs, typename Rhs>
- inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
- C10_MPARK_RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
- };
- #endif
- #ifdef C10_MPARK_TRANSPARENT_OPERATORS
- using less_equal = std::less_equal<>;
- #else
- struct less_equal {
- template <typename Lhs, typename Rhs>
- inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
- C10_MPARK_RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
- };
- #endif
- #ifdef C10_MPARK_TRANSPARENT_OPERATORS
- using greater_equal = std::greater_equal<>;
- #else
- struct greater_equal {
- template <typename Lhs, typename Rhs>
- inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
- C10_MPARK_RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
- };
- #endif
- } // namespace cpp14
- inline namespace cpp17 {
- // <type_traits>
- template <bool B>
- using bool_constant = std::integral_constant<bool, B>;
- template <typename...>
- struct voider : identity<void> {};
- template <typename... Ts>
- using void_t = typename voider<Ts...>::type;
- namespace detail_ {
- namespace swappable {
- using std::swap;
- template <typename T>
- struct is_swappable {
- private:
- template <
- typename U,
- typename = decltype(swap(std::declval<U&>(), std::declval<U&>()))>
- inline static std::true_type test(int);
- template <typename U>
- inline static std::false_type test(...);
- public:
- static constexpr bool value = decltype(test<T>(0))::value;
- };
- template <bool IsSwappable, typename T>
- struct is_nothrow_swappable {
- static constexpr bool value =
- noexcept(swap(std::declval<T&>(), std::declval<T&>()));
- };
- template <typename T>
- struct is_nothrow_swappable<false, T> : std::false_type {};
- } // namespace swappable
- } // namespace detail_
- using detail_::swappable::is_swappable;
- template <typename T>
- using is_nothrow_swappable =
- detail_::swappable::is_nothrow_swappable<is_swappable<T>::value, T>;
- // <functional>
- namespace detail_ {
- template <typename T>
- struct is_reference_wrapper : std::false_type {};
- template <typename T>
- struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
- template <bool, int>
- struct Invoke;
- template <>
- struct Invoke<true /* pmf */, 0 /* is_base_of */> {
- template <typename R, typename T, typename Arg, typename... Args>
- inline static constexpr auto invoke(R T::*pmf, Arg&& arg, Args&&... args)
- C10_MPARK_RETURN(
- (lib::forward<Arg>(arg).*pmf)(lib::forward<Args>(args)...))
- };
- template <>
- struct Invoke<true /* pmf */, 1 /* is_reference_wrapper */> {
- template <typename R, typename T, typename Arg, typename... Args>
- inline static constexpr auto invoke(R T::*pmf, Arg&& arg, Args&&... args)
- C10_MPARK_RETURN(
- (lib::forward<Arg>(arg).get().*pmf)(lib::forward<Args>(args)...))
- };
- template <>
- struct Invoke<true /* pmf */, 2 /* otherwise */> {
- template <typename R, typename T, typename Arg, typename... Args>
- inline static constexpr auto invoke(R T::*pmf, Arg&& arg, Args&&... args)
- C10_MPARK_RETURN(
- ((*lib::forward<Arg>(arg)).*pmf)(lib::forward<Args>(args)...))
- };
- template <>
- struct Invoke<false /* pmo */, 0 /* is_base_of */> {
- template <typename R, typename T, typename Arg>
- inline static constexpr auto invoke(R T::*pmo, Arg&& arg)
- C10_MPARK_RETURN(lib::forward<Arg>(arg).*pmo)
- };
- template <>
- struct Invoke<false /* pmo */, 1 /* is_reference_wrapper */> {
- template <typename R, typename T, typename Arg>
- inline static constexpr auto invoke(R T::*pmo, Arg&& arg)
- C10_MPARK_RETURN(lib::forward<Arg>(arg).get().*pmo)
- };
- template <>
- struct Invoke<false /* pmo */, 2 /* otherwise */> {
- template <typename R, typename T, typename Arg>
- inline static constexpr auto invoke(R T::*pmo, Arg&& arg)
- C10_MPARK_RETURN((*lib::forward<Arg>(arg)).*pmo)
- };
- template <typename R, typename T, typename Arg, typename... Args>
- inline constexpr auto invoke(R T::*f, Arg&& arg, Args&&... args)
- C10_MPARK_RETURN(
- Invoke<
- std::is_function<R>::value,
- (std::is_base_of<T, lib::decay_t<Arg>>::value ? 0
- : is_reference_wrapper<lib::decay_t<Arg>>::value ? 1
- : 2)>::
- invoke(f, lib::forward<Arg>(arg), lib::forward<Args>(args)...))
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable : 4100)
- #endif
- template <typename F, typename... Args>
- inline constexpr auto invoke(F&& f, Args&&... args)
- C10_MPARK_RETURN(lib::forward<F>(f)(lib::forward<Args>(args)...))
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- } // namespace detail_
- template <typename F, typename... Args>
- inline constexpr auto invoke(F&& f, Args&&... args) C10_MPARK_RETURN(
- detail_::invoke(lib::forward<F>(f), lib::forward<Args>(args)...))
- namespace detail_ {
- template <typename Void, typename, typename...>
- struct invoke_result {};
- template <typename F, typename... Args>
- struct invoke_result<
- void_t<decltype(lib::invoke(std::declval<F>(), std::declval<Args>()...))>,
- F,
- Args...>
- : identity<decltype(lib::invoke(
- std::declval<F>(), std::declval<Args>()...))> {};
- } // namespace detail_
- template <typename F, typename... Args>
- using invoke_result = detail_::invoke_result<void, F, Args...>;
- template <typename F, typename... Args>
- using invoke_result_t = typename invoke_result<F, Args...>::type;
- namespace detail_ {
- template <typename Void, typename, typename...>
- struct is_invocable : std::false_type {};
- template <typename F, typename... Args>
- struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
- : std::true_type {};
- template <typename Void, typename, typename, typename...>
- struct is_invocable_r : std::false_type {};
- template <typename R, typename F, typename... Args>
- struct is_invocable_r<void_t<invoke_result_t<F, Args...>>, R, F, Args...>
- : std::is_convertible<invoke_result_t<F, Args...>, R> {};
- } // namespace detail_
- template <typename F, typename... Args>
- using is_invocable = detail_::is_invocable<void, F, Args...>;
- template <typename R, typename F, typename... Args>
- using is_invocable_r = detail_::is_invocable_r<void, R, F, Args...>;
- namespace detail_ {
- template <bool Invocable, typename F, typename... Args>
- struct is_nothrow_invocable {
- static constexpr bool value =
- noexcept(lib::invoke(std::declval<F>(), std::declval<Args>()...));
- };
- template <typename F, typename... Args>
- struct is_nothrow_invocable<false, F, Args...> : std::false_type {};
- template <bool Invocable, typename R, typename F, typename... Args>
- struct is_nothrow_invocable_r {
- private:
- inline static R impl() {
- return lib::invoke(std::declval<F>(), std::declval<Args>()...);
- }
- public:
- static constexpr bool value = noexcept(impl());
- };
- template <typename R, typename F, typename... Args>
- struct is_nothrow_invocable_r<false, R, F, Args...> : std::false_type {};
- } // namespace detail_
- template <typename F, typename... Args>
- using is_nothrow_invocable =
- detail_::is_nothrow_invocable<is_invocable<F, Args...>::value, F, Args...>;
- template <typename R, typename F, typename... Args>
- using is_nothrow_invocable_r = detail_::
- is_nothrow_invocable_r<is_invocable_r<R, F, Args...>::value, R, F, Args...>;
- // <memory>
- #ifdef C10_MPARK_BUILTIN_ADDRESSOF
- template <typename T>
- inline constexpr T* addressof(T& arg) noexcept {
- return __builtin_addressof(arg);
- }
- #else
- namespace detail_ {
- namespace has_addressof_impl {
- struct fail;
- template <typename T>
- inline fail operator&(T&&);
- template <typename T>
- inline static constexpr bool impl() {
- return (std::is_class<T>::value || std::is_union<T>::value) &&
- !std::is_same<decltype(&std::declval<T&>()), fail>::value;
- }
- } // namespace has_addressof_impl
- template <typename T>
- using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
- template <typename T>
- inline constexpr T* addressof(T& arg, std::true_type) noexcept {
- return std::addressof(arg);
- }
- template <typename T>
- inline constexpr T* addressof(T& arg, std::false_type) noexcept {
- return &arg;
- }
- } // namespace detail_
- template <typename T>
- inline constexpr T* addressof(T& arg) noexcept {
- return detail_::addressof(arg, detail_::has_addressof<T>{});
- }
- #endif
- template <typename T>
- inline constexpr T* addressof(const T&&) = delete;
- } // namespace cpp17
- template <typename T>
- struct remove_all_extents : identity<T> {};
- template <typename T, std::size_t N>
- struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
- template <typename T>
- using remove_all_extents_t = typename remove_all_extents<T>::type;
- template <std::size_t N>
- using size_constant = std::integral_constant<std::size_t, N>;
- template <std::size_t I, typename T>
- struct indexed_type : size_constant<I> {
- using type = T;
- };
- template <bool... Bs>
- using all = std::is_same<
- integer_sequence<bool, true, Bs...>,
- integer_sequence<bool, Bs..., true>>;
- #ifdef C10_MPARK_TYPE_PACK_ELEMENT
- template <std::size_t I, typename... Ts>
- using type_pack_element_t = __type_pack_element<I, Ts...>;
- #else
- template <std::size_t I, typename... Ts>
- struct type_pack_element_impl {
- private:
- template <typename>
- struct set;
- template <std::size_t... Is>
- struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
- template <typename T>
- inline static std::enable_if<true, T> impl(indexed_type<I, T>);
- inline static std::enable_if<false> impl(...);
- public:
- using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
- };
- template <std::size_t I, typename... Ts>
- using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
- template <std::size_t I, typename... Ts>
- using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
- #endif
- #ifdef C10_MPARK_TRIVIALITY_TYPE_TRAITS
- using std::is_trivially_copy_assignable;
- using std::is_trivially_copy_constructible;
- using std::is_trivially_move_assignable;
- using std::is_trivially_move_constructible;
- #else
- template <typename T>
- struct is_trivially_copy_constructible
- : bool_constant<std::is_copy_constructible<T>::value&& __has_trivial_copy(
- T)> {};
- template <typename T>
- struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
- template <typename T>
- struct is_trivially_copy_assignable
- : bool_constant<std::is_copy_assignable<T>::value&& __has_trivial_assign(
- T)> {};
- template <typename T>
- struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
- #endif
- template <typename T, bool>
- struct dependent_type : T {};
- template <typename Is, std::size_t J>
- struct push_back;
- template <typename Is, std::size_t J>
- using push_back_t = typename push_back<Is, J>::type;
- template <std::size_t... Is, std::size_t J>
- struct push_back<index_sequence<Is...>, J> {
- using type = index_sequence<Is..., J>;
- };
- } // namespace lib
- } // namespace c10
- #undef C10_MPARK_RETURN
- #endif // C10_MPARK_LIB_HPP
- namespace c10 {
- #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
- #define AUTO auto
- #define AUTO_RETURN(...) \
- { return __VA_ARGS__; }
- #define AUTO_REFREF auto&&
- #define AUTO_REFREF_RETURN(...) \
- { return __VA_ARGS__; }
- #define DECLTYPE_AUTO decltype(auto)
- #define DECLTYPE_AUTO_RETURN(...) \
- { return __VA_ARGS__; }
- #else
- #define AUTO auto
- #define AUTO_RETURN(...) \
- ->lib::decay_t<decltype(__VA_ARGS__)> { \
- return __VA_ARGS__; \
- }
- #define AUTO_REFREF auto
- #define AUTO_REFREF_RETURN(...) \
- ->decltype((__VA_ARGS__)) { \
- static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
- return __VA_ARGS__; \
- }
- #define DECLTYPE_AUTO auto
- #define DECLTYPE_AUTO_RETURN(...) \
- ->decltype(__VA_ARGS__) { \
- return __VA_ARGS__; \
- }
- #endif
- class bad_variant_access : public std::exception {
- public:
- const char* what() const noexcept override {
- return "bad_variant_access";
- }
- };
- [[noreturn]] inline void throw_bad_variant_access() {
- #ifdef C10_MPARK_EXCEPTIONS
- throw bad_variant_access{};
- #else
- std::terminate();
- C10_MPARK_BUILTIN_UNREACHABLE;
- #endif
- }
- template <typename... Ts>
- class variant;
- template <typename T>
- struct variant_size;
- #ifdef C10_MPARK_VARIABLE_TEMPLATES
- template <typename T>
- constexpr std::size_t variant_size_v = variant_size<T>::value;
- #endif
- template <typename T>
- struct variant_size<const T> : variant_size<T> {};
- template <typename T>
- struct variant_size<volatile T> : variant_size<T> {};
- template <typename T>
- struct variant_size<const volatile T> : variant_size<T> {};
- template <typename... Ts>
- struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
- template <std::size_t I, typename T>
- struct variant_alternative;
- template <std::size_t I, typename T>
- using variant_alternative_t = typename variant_alternative<I, T>::type;
- template <std::size_t I, typename T>
- struct variant_alternative<I, const T>
- : std::add_const<variant_alternative_t<I, T>> {};
- template <std::size_t I, typename T>
- struct variant_alternative<I, volatile T>
- : std::add_volatile<variant_alternative_t<I, T>> {};
- template <std::size_t I, typename T>
- struct variant_alternative<I, const volatile T>
- : std::add_cv<variant_alternative_t<I, T>> {};
- template <std::size_t I, typename... Ts>
- struct variant_alternative<I, variant<Ts...>> {
- static_assert(
- I < sizeof...(Ts),
- "index out of bounds in `std::variant_alternative<>`");
- using type = lib::type_pack_element_t<I, Ts...>;
- };
- constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
- namespace detail_ {
- constexpr std::size_t not_found = static_cast<std::size_t>(-1);
- constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- template <typename T, typename... Ts>
- inline constexpr std::size_t find_index() {
- constexpr lib::array<bool, sizeof...(Ts)> matches = {
- {std::is_same<T, Ts>::value...}};
- std::size_t result = not_found;
- for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
- if (matches[i]) {
- if (result != not_found) {
- return ambiguous;
- }
- result = i;
- }
- }
- return result;
- }
- #else
- inline constexpr std::size_t find_index_impl(std::size_t result, std::size_t) {
- return result;
- }
- template <typename... Bs>
- inline constexpr std::size_t find_index_impl(
- std::size_t result,
- std::size_t idx,
- bool b,
- Bs... bs) {
- return b
- ? (result != not_found ? ambiguous : find_index_impl(idx, idx + 1, bs...))
- : find_index_impl(result, idx + 1, bs...);
- }
- template <typename T, typename... Ts>
- inline constexpr std::size_t find_index() {
- return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
- }
- #endif
- template <std::size_t I>
- using find_index_sfinae_impl =
- lib::enable_if_t<I != not_found && I != ambiguous, lib::size_constant<I>>;
- template <typename T, typename... Ts>
- using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
- template <std::size_t I>
- struct find_index_checked_impl : lib::size_constant<I> {
- static_assert(I != not_found, "the specified type is not found.");
- static_assert(I != ambiguous, "the specified type is ambiguous.");
- };
- template <typename T, typename... Ts>
- using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
- struct valueless_t {};
- enum class Trait { TriviallyAvailable, Available, Unavailable };
- template <
- typename T,
- template <typename>
- class IsTriviallyAvailable,
- template <typename>
- class IsAvailable>
- inline constexpr Trait trait() {
- return IsTriviallyAvailable<T>::value ? Trait::TriviallyAvailable
- : IsAvailable<T>::value ? Trait::Available
- : Trait::Unavailable;
- }
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- template <typename... Traits>
- inline constexpr Trait common_trait(Traits... traits_) {
- Trait result = Trait::TriviallyAvailable;
- lib::array<Trait, sizeof...(Traits)> traits = {{traits_...}};
- for (std::size_t i = 0; i < sizeof...(Traits); ++i) {
- Trait t = traits[i];
- if (static_cast<int>(t) > static_cast<int>(result)) {
- result = t;
- }
- }
- return result;
- }
- #else
- inline constexpr Trait common_trait_impl(Trait result) {
- return result;
- }
- template <typename... Traits>
- inline constexpr Trait common_trait_impl(Trait result, Trait t, Traits... ts) {
- return static_cast<int>(t) > static_cast<int>(result)
- ? common_trait_impl(t, ts...)
- : common_trait_impl(result, ts...);
- }
- template <typename... Traits>
- inline constexpr Trait common_trait(Traits... ts) {
- return common_trait_impl(Trait::TriviallyAvailable, ts...);
- }
- #endif
- template <typename... Ts>
- struct traits {
- static constexpr Trait copy_constructible_trait =
- common_trait(trait<
- Ts,
- lib::is_trivially_copy_constructible,
- std::is_copy_constructible>()...);
- static constexpr Trait move_constructible_trait =
- common_trait(trait<
- Ts,
- lib::is_trivially_move_constructible,
- std::is_move_constructible>()...);
- static constexpr Trait copy_assignable_trait = common_trait(
- copy_constructible_trait,
- trait<
- Ts,
- lib::is_trivially_copy_assignable,
- std::is_copy_assignable>()...);
- static constexpr Trait move_assignable_trait = common_trait(
- move_constructible_trait,
- trait<
- Ts,
- lib::is_trivially_move_assignable,
- std::is_move_assignable>()...);
- static constexpr Trait destructible_trait = common_trait(
- trait<Ts, std::is_trivially_destructible, std::is_destructible>()...);
- };
- namespace access {
- struct recursive_union {
- #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
- template <typename V>
- inline static constexpr auto&& get_alt(V&& v, in_place_index_t<0>) {
- return lib::forward<V>(v).head_;
- }
- template <typename V, std::size_t I>
- inline static constexpr auto&& get_alt(V&& v, in_place_index_t<I>) {
- return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
- }
- #else
- template <std::size_t I, bool Dummy = true>
- struct get_alt_impl {
- template <typename V>
- inline constexpr AUTO_REFREF operator()(V&& v) const
- AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
- };
- template <bool Dummy>
- struct get_alt_impl<0, Dummy> {
- template <typename V>
- inline constexpr AUTO_REFREF operator()(V&& v) const
- AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
- };
- template <typename V, std::size_t I>
- inline static constexpr AUTO_REFREF get_alt(V&& v, in_place_index_t<I>)
- AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
- #endif
- };
- struct base {
- template <std::size_t I, typename V>
- inline static constexpr AUTO_REFREF get_alt(V&& v)
- #ifdef _MSC_VER
- AUTO_REFREF_RETURN(recursive_union::get_alt(
- lib::forward<V>(v).data_,
- in_place_index_t<I>{}))
- #else
- AUTO_REFREF_RETURN(recursive_union::get_alt(
- data(lib::forward<V>(v)),
- in_place_index_t<I>{}))
- #endif
- };
- struct variant {
- template <std::size_t I, typename V>
- inline static constexpr AUTO_REFREF get_alt(V&& v)
- AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
- };
- } // namespace access
- namespace visitation {
- #if defined(C10_MPARK_CPP14_CONSTEXPR) && !defined(_MSC_VER)
- #define C10_MPARK_VARIANT_SWITCH_VISIT
- #endif
- struct base {
- template <typename Visitor, typename... Vs>
- using dispatch_result_t = decltype(lib::invoke(
- std::declval<Visitor>(),
- access::base::get_alt<0>(std::declval<Vs>())...));
- template <typename Expected>
- struct expected {
- template <typename Actual>
- inline static constexpr bool but_got() {
- return std::is_same<Expected, Actual>::value;
- }
- };
- template <typename Expected, typename Actual>
- struct visit_return_type_check {
- static_assert(
- expected<Expected>::template but_got<Actual>(),
- "`visit` requires the visitor to have a single return type");
- template <typename Visitor, typename... Alts>
- inline static constexpr DECLTYPE_AUTO invoke(
- Visitor&& visitor,
- Alts&&... alts)
- DECLTYPE_AUTO_RETURN(lib::invoke(
- lib::forward<Visitor>(visitor),
- lib::forward<Alts>(alts)...))
- };
- #ifdef C10_MPARK_VARIANT_SWITCH_VISIT
- template <bool B, typename R, typename... ITs>
- struct dispatcher;
- template <typename R, typename... ITs>
- struct dispatcher<false, R, ITs...> {
- template <std::size_t B, typename F, typename... Vs>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch(
- F&&,
- typename ITs::type&&...,
- Vs&&...) {
- C10_MPARK_BUILTIN_UNREACHABLE;
- }
- template <std::size_t I, typename F, typename... Vs>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F&&, Vs&&...) {
- C10_MPARK_BUILTIN_UNREACHABLE;
- }
- template <std::size_t B, typename F, typename... Vs>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_at(
- std::size_t,
- F&&,
- Vs&&...) {
- C10_MPARK_BUILTIN_UNREACHABLE;
- }
- };
- template <typename R, typename... ITs>
- struct dispatcher<true, R, ITs...> {
- template <std::size_t B, typename F>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch(
- F&& f,
- typename ITs::type&&... visited_vs) {
- using Expected = R;
- using Actual = decltype(lib::invoke(
- lib::forward<F>(f),
- access::base::get_alt<ITs::value>(
- lib::forward<typename ITs::type>(visited_vs))...));
- return visit_return_type_check<Expected, Actual>::invoke(
- lib::forward<F>(f),
- access::base::get_alt<ITs::value>(
- lib::forward<typename ITs::type>(visited_vs))...);
- }
- template <std::size_t B, typename F, typename V, typename... Vs>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch(
- F&& f,
- typename ITs::type&&... visited_vs,
- V&& v,
- Vs&&... vs) {
- #define C10_MPARK_DISPATCH(I) \
- dispatcher< \
- (I < lib::decay_t<V>::size()), \
- R, \
- ITs..., \
- lib::indexed_type<I, V>>:: \
- template dispatch<0>( \
- lib::forward<F>(f), \
- lib::forward<typename ITs::type>(visited_vs)..., \
- lib::forward<V>(v), \
- lib::forward<Vs>(vs)...)
- #define C10_MPARK_DEFAULT(I) \
- dispatcher<(I < lib::decay_t<V>::size()), R, ITs...>::template dispatch<I>( \
- lib::forward<F>(f), \
- lib::forward<typename ITs::type>(visited_vs)..., \
- lib::forward<V>(v), \
- lib::forward<Vs>(vs)...)
- switch (v.index()) {
- case B + 0:
- return C10_MPARK_DISPATCH(B + 0);
- case B + 1:
- return C10_MPARK_DISPATCH(B + 1);
- case B + 2:
- return C10_MPARK_DISPATCH(B + 2);
- case B + 3:
- return C10_MPARK_DISPATCH(B + 3);
- case B + 4:
- return C10_MPARK_DISPATCH(B + 4);
- case B + 5:
- return C10_MPARK_DISPATCH(B + 5);
- case B + 6:
- return C10_MPARK_DISPATCH(B + 6);
- case B + 7:
- return C10_MPARK_DISPATCH(B + 7);
- case B + 8:
- return C10_MPARK_DISPATCH(B + 8);
- case B + 9:
- return C10_MPARK_DISPATCH(B + 9);
- case B + 10:
- return C10_MPARK_DISPATCH(B + 10);
- case B + 11:
- return C10_MPARK_DISPATCH(B + 11);
- case B + 12:
- return C10_MPARK_DISPATCH(B + 12);
- case B + 13:
- return C10_MPARK_DISPATCH(B + 13);
- case B + 14:
- return C10_MPARK_DISPATCH(B + 14);
- case B + 15:
- return C10_MPARK_DISPATCH(B + 15);
- case B + 16:
- return C10_MPARK_DISPATCH(B + 16);
- case B + 17:
- return C10_MPARK_DISPATCH(B + 17);
- case B + 18:
- return C10_MPARK_DISPATCH(B + 18);
- case B + 19:
- return C10_MPARK_DISPATCH(B + 19);
- case B + 20:
- return C10_MPARK_DISPATCH(B + 20);
- case B + 21:
- return C10_MPARK_DISPATCH(B + 21);
- case B + 22:
- return C10_MPARK_DISPATCH(B + 22);
- case B + 23:
- return C10_MPARK_DISPATCH(B + 23);
- case B + 24:
- return C10_MPARK_DISPATCH(B + 24);
- case B + 25:
- return C10_MPARK_DISPATCH(B + 25);
- case B + 26:
- return C10_MPARK_DISPATCH(B + 26);
- case B + 27:
- return C10_MPARK_DISPATCH(B + 27);
- case B + 28:
- return C10_MPARK_DISPATCH(B + 28);
- case B + 29:
- return C10_MPARK_DISPATCH(B + 29);
- case B + 30:
- return C10_MPARK_DISPATCH(B + 30);
- case B + 31:
- return C10_MPARK_DISPATCH(B + 31);
- default:
- return C10_MPARK_DEFAULT(B + 32);
- }
- #undef C10_MPARK_DEFAULT
- #undef C10_MPARK_DISPATCH
- }
- template <std::size_t I, typename F, typename... Vs>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_case(
- F&& f,
- Vs&&... vs) {
- using Expected = R;
- using Actual = decltype(lib::invoke(
- lib::forward<F>(f),
- access::base::get_alt<I>(lib::forward<Vs>(vs))...));
- return visit_return_type_check<Expected, Actual>::invoke(
- lib::forward<F>(f),
- access::base::get_alt<I>(lib::forward<Vs>(vs))...);
- }
- template <std::size_t B, typename F, typename V, typename... Vs>
- C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_at(
- std::size_t index,
- F&& f,
- V&& v,
- Vs&&... vs) {
- static_assert(
- lib::all<(
- lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...>::value,
- "all of the variants must be the same size.");
- #define C10_MPARK_DISPATCH_AT(I) \
- dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_case<I>( \
- lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
- #define C10_MPARK_DEFAULT(I) \
- dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_at<I>( \
- index, lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
- switch (index) {
- case B + 0:
- return C10_MPARK_DISPATCH_AT(B + 0);
- case B + 1:
- return C10_MPARK_DISPATCH_AT(B + 1);
- case B + 2:
- return C10_MPARK_DISPATCH_AT(B + 2);
- case B + 3:
- return C10_MPARK_DISPATCH_AT(B + 3);
- case B + 4:
- return C10_MPARK_DISPATCH_AT(B + 4);
- case B + 5:
- return C10_MPARK_DISPATCH_AT(B + 5);
- case B + 6:
- return C10_MPARK_DISPATCH_AT(B + 6);
- case B + 7:
- return C10_MPARK_DISPATCH_AT(B + 7);
- case B + 8:
- return C10_MPARK_DISPATCH_AT(B + 8);
- case B + 9:
- return C10_MPARK_DISPATCH_AT(B + 9);
- case B + 10:
- return C10_MPARK_DISPATCH_AT(B + 10);
- case B + 11:
- return C10_MPARK_DISPATCH_AT(B + 11);
- case B + 12:
- return C10_MPARK_DISPATCH_AT(B + 12);
- case B + 13:
- return C10_MPARK_DISPATCH_AT(B + 13);
- case B + 14:
- return C10_MPARK_DISPATCH_AT(B + 14);
- case B + 15:
- return C10_MPARK_DISPATCH_AT(B + 15);
- case B + 16:
- return C10_MPARK_DISPATCH_AT(B + 16);
- case B + 17:
- return C10_MPARK_DISPATCH_AT(B + 17);
- case B + 18:
- return C10_MPARK_DISPATCH_AT(B + 18);
- case B + 19:
- return C10_MPARK_DISPATCH_AT(B + 19);
- case B + 20:
- return C10_MPARK_DISPATCH_AT(B + 20);
- case B + 21:
- return C10_MPARK_DISPATCH_AT(B + 21);
- case B + 22:
- return C10_MPARK_DISPATCH_AT(B + 22);
- case B + 23:
- return C10_MPARK_DISPATCH_AT(B + 23);
- case B + 24:
- return C10_MPARK_DISPATCH_AT(B + 24);
- case B + 25:
- return C10_MPARK_DISPATCH_AT(B + 25);
- case B + 26:
- return C10_MPARK_DISPATCH_AT(B + 26);
- case B + 27:
- return C10_MPARK_DISPATCH_AT(B + 27);
- case B + 28:
- return C10_MPARK_DISPATCH_AT(B + 28);
- case B + 29:
- return C10_MPARK_DISPATCH_AT(B + 29);
- case B + 30:
- return C10_MPARK_DISPATCH_AT(B + 30);
- case B + 31:
- return C10_MPARK_DISPATCH_AT(B + 31);
- default:
- return C10_MPARK_DEFAULT(B + 32);
- }
- #undef C10_MPARK_DEFAULT
- #undef C10_MPARK_DISPATCH_AT
- }
- };
- #else
- template <typename T>
- inline static constexpr const T& at(const T& elem) noexcept {
- return elem;
- }
- template <typename T, std::size_t N, typename... Is>
- inline static constexpr const lib::remove_all_extents_t<T>& at(
- const lib::array<T, N>& elems,
- std::size_t i,
- Is... is) noexcept {
- return at(elems[i], is...);
- }
- template <typename F, typename... Fs>
- inline static constexpr lib::array<lib::decay_t<F>, sizeof...(Fs) + 1>
- make_farray(F&& f, Fs&&... fs) {
- return {{lib::forward<F>(f), lib::forward<Fs>(fs)...}};
- }
- template <typename F, typename... Vs>
- struct make_fmatrix_impl {
- template <std::size_t... Is>
- inline static constexpr dispatch_result_t<F, Vs...> dispatch(
- F&& f,
- Vs&&... vs) {
- using Expected = dispatch_result_t<F, Vs...>;
- using Actual = decltype(lib::invoke(
- lib::forward<F>(f),
- access::base::get_alt<Is>(lib::forward<Vs>(vs))...));
- return visit_return_type_check<Expected, Actual>::invoke(
- lib::forward<F>(f),
- access::base::get_alt<Is>(lib::forward<Vs>(vs))...);
- }
- #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
- template <std::size_t... Is>
- inline static constexpr auto impl(lib::index_sequence<Is...>) {
- return &dispatch<Is...>;
- }
- template <typename Is, std::size_t... Js, typename... Ls>
- inline static constexpr auto impl(
- Is,
- lib::index_sequence<Js...>,
- Ls... ls) {
- return make_farray(impl(lib::push_back_t<Is, Js>{}, ls...)...);
- }
- #else
- template <typename...>
- struct impl;
- template <std::size_t... Is>
- struct impl<lib::index_sequence<Is...>> {
- inline constexpr AUTO operator()() const AUTO_RETURN(&dispatch<Is...>)
- };
- template <typename Is, std::size_t... Js, typename... Ls>
- struct impl<Is, lib::index_sequence<Js...>, Ls...> {
- inline constexpr AUTO operator()() const
- AUTO_RETURN(make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
- };
- #endif
- };
- #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
- template <typename F, typename... Vs>
- inline static constexpr auto make_fmatrix() {
- return make_fmatrix_impl<F, Vs...>::impl(
- lib::index_sequence<>{},
- lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
- }
- #else
- template <typename F, typename... Vs>
- inline static constexpr AUTO make_fmatrix()
- AUTO_RETURN(typename make_fmatrix_impl<F, Vs...>::template impl<
- lib::index_sequence<>,
- lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
- #endif
- template <typename F, typename... Vs>
- struct make_fdiagonal_impl {
- template <std::size_t I>
- inline static constexpr dispatch_result_t<F, Vs...> dispatch(
- F&& f,
- Vs&&... vs) {
- using Expected = dispatch_result_t<F, Vs...>;
- using Actual = decltype(lib::invoke(
- lib::forward<F>(f),
- access::base::get_alt<I>(lib::forward<Vs>(vs))...));
- return visit_return_type_check<Expected, Actual>::invoke(
- lib::forward<F>(f),
- access::base::get_alt<I>(lib::forward<Vs>(vs))...);
- }
- template <std::size_t... Is>
- inline static constexpr AUTO impl(lib::index_sequence<Is...>)
- AUTO_RETURN(make_farray(&dispatch<Is>...))
- };
- template <typename F, typename V, typename... Vs>
- inline static constexpr auto make_fdiagonal()
- -> decltype(make_fdiagonal_impl<F, V, Vs...>::impl(
- lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
- static_assert(
- lib::all<(
- lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...>::value,
- "all of the variants must be the same size.");
- return make_fdiagonal_impl<F, V, Vs...>::impl(
- lib::make_index_sequence<lib::decay_t<V>::size()>{});
- }
- #endif
- };
- #if !defined(C10_MPARK_VARIANT_SWITCH_VISIT) && \
- (!defined(_MSC_VER) || _MSC_VER >= 1910)
- template <typename F, typename... Vs>
- using fmatrix_t = decltype(base::make_fmatrix<F, Vs...>());
- template <typename F, typename... Vs>
- struct fmatrix {
- static constexpr fmatrix_t<F, Vs...> value = base::make_fmatrix<F, Vs...>();
- };
- template <typename F, typename... Vs>
- constexpr fmatrix_t<F, Vs...> fmatrix<F, Vs...>::value;
- template <typename F, typename... Vs>
- using fdiagonal_t = decltype(base::make_fdiagonal<F, Vs...>());
- template <typename F, typename... Vs>
- struct fdiagonal {
- static constexpr fdiagonal_t<F, Vs...> value =
- base::make_fdiagonal<F, Vs...>();
- };
- template <typename F, typename... Vs>
- constexpr fdiagonal_t<F, Vs...> fdiagonal<F, Vs...>::value;
- #endif
- struct alt {
- template <typename Visitor, typename... Vs>
- inline static constexpr DECLTYPE_AUTO visit_alt(Visitor&& visitor, Vs&&... vs)
- #ifdef C10_MPARK_VARIANT_SWITCH_VISIT
- DECLTYPE_AUTO_RETURN(base::dispatcher<
- true,
- base::dispatch_result_t<
- Visitor,
- decltype(as_base(lib::forward<Vs>(vs)))...>>::
- template dispatch<0>(
- lib::forward<Visitor>(visitor),
- as_base(lib::forward<Vs>(vs))...))
- #elif !defined(_MSC_VER) || _MSC_VER >= 1910
- DECLTYPE_AUTO_RETURN(base::at(
- fmatrix<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::value,
- vs.index()...)(
- lib::forward<Visitor>(visitor),
- as_base(lib::forward<Vs>(vs))...))
- #else
- DECLTYPE_AUTO_RETURN(base::at(
- base::make_fmatrix<
- Visitor&&,
- decltype(as_base(lib::forward<Vs>(vs)))...>(),
- vs.index()...)(
- lib::forward<Visitor>(visitor),
- as_base(lib::forward<Vs>(vs))...))
- #endif
- template <typename Visitor, typename... Vs>
- inline static constexpr DECLTYPE_AUTO
- visit_alt_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
- #ifdef C10_MPARK_VARIANT_SWITCH_VISIT
- DECLTYPE_AUTO_RETURN(
- base::dispatcher<
- true,
- base::dispatch_result_t<
- Visitor,
- decltype(as_base(lib::forward<Vs>(vs)))...>>::
- template dispatch_at<0>(
- index,
- lib::forward<Visitor>(visitor),
- as_base(lib::forward<Vs>(vs))...))
- #elif !defined(_MSC_VER) || _MSC_VER >= 1910
- DECLTYPE_AUTO_RETURN(base::at(
- fdiagonal<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::
- value,
- index)(
- lib::forward<Visitor>(visitor),
- as_base(lib::forward<Vs>(vs))...))
- #else
- DECLTYPE_AUTO_RETURN(base::at(
- base::make_fdiagonal<
- Visitor&&,
- decltype(as_base(lib::forward<Vs>(vs)))...>(),
- index)(
- lib::forward<Visitor>(visitor),
- as_base(lib::forward<Vs>(vs))...))
- #endif
- };
- struct variant {
- private:
- template <typename Visitor>
- struct visitor {
- template <typename... Values>
- inline static constexpr bool does_not_handle() {
- return lib::is_invocable<Visitor, Values...>::value;
- }
- };
- template <typename Visitor, typename... Values>
- struct visit_exhaustiveness_check {
- static_assert(
- visitor<Visitor>::template does_not_handle<Values...>(),
- "`visit` requires the visitor to be exhaustive.");
- inline static constexpr DECLTYPE_AUTO invoke(
- Visitor&& visitor,
- Values&&... values)
- DECLTYPE_AUTO_RETURN(lib::invoke(
- lib::forward<Visitor>(visitor),
- lib::forward<Values>(values)...))
- };
- template <typename Visitor>
- struct C10_MPARK_VISIBILITY_HIDDEN value_visitor {
- Visitor&& visitor_;
- template <typename... Alts>
- inline constexpr DECLTYPE_AUTO operator()(Alts&&... alts) const
- DECLTYPE_AUTO_RETURN(visit_exhaustiveness_check<
- Visitor,
- decltype((lib::forward<Alts>(alts).value))...>::
- invoke(
- lib::forward<Visitor>(visitor_),
- lib::forward<Alts>(alts).value...))
- };
- template <typename Visitor>
- inline static constexpr AUTO make_value_visitor(Visitor&& visitor)
- AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
- public
- : template <typename Visitor, typename... Vs>
- inline static constexpr DECLTYPE_AUTO
- visit_alt(Visitor&& visitor, Vs&&... vs)
- DECLTYPE_AUTO_RETURN(alt::visit_alt(
- lib::forward<Visitor>(visitor),
- lib::forward<Vs>(vs).impl_...))
- template <typename Visitor, typename... Vs>
- inline static constexpr DECLTYPE_AUTO
- visit_alt_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
- DECLTYPE_AUTO_RETURN(alt::visit_alt_at(
- index,
- lib::forward<Visitor>(visitor),
- lib::forward<Vs>(vs).impl_...))
- template <typename Visitor, typename... Vs>
- inline static constexpr DECLTYPE_AUTO
- visit_value(Visitor&& visitor, Vs&&... vs)
- DECLTYPE_AUTO_RETURN(visit_alt(
- make_value_visitor(lib::forward<Visitor>(visitor)),
- lib::forward<Vs>(vs)...))
- template <typename Visitor, typename... Vs>
- inline static constexpr DECLTYPE_AUTO
- visit_value_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
- DECLTYPE_AUTO_RETURN(visit_alt_at(
- index,
- make_value_visitor(lib::forward<Visitor>(visitor)),
- lib::forward<Vs>(vs)...))
- };
- } // namespace visitation
- template <std::size_t Index, typename T>
- struct alt {
- using value_type = T;
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable : 4244)
- #endif
- template <typename... Args>
- inline explicit constexpr alt(in_place_t, Args&&... args)
- : value(lib::forward<Args>(args)...) {}
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- T value;
- };
- template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
- union recursive_union;
- template <Trait DestructibleTrait, std::size_t Index>
- union recursive_union<DestructibleTrait, Index> {};
- #define C10_MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor) \
- template <std::size_t Index, typename T, typename... Ts> \
- union recursive_union<destructible_trait, Index, T, Ts...> { \
- public: \
- inline explicit constexpr recursive_union(valueless_t) noexcept \
- : dummy_{} {} \
- \
- template <typename... Args> \
- inline explicit constexpr recursive_union( \
- in_place_index_t<0>, \
- Args&&... args) \
- : head_(in_place_t{}, lib::forward<Args>(args)...) {} \
- \
- template <std::size_t I, typename... Args> \
- inline explicit constexpr recursive_union( \
- in_place_index_t<I>, \
- Args&&... args) \
- : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
- \
- recursive_union(const recursive_union&) = default; \
- recursive_union(recursive_union&&) = default; \
- \
- destructor \
- \
- recursive_union& \
- operator=(const recursive_union&) = default; \
- recursive_union& operator=(recursive_union&&) = default; \
- \
- private: \
- char dummy_; \
- alt<Index, T> head_; \
- recursive_union<destructible_trait, Index + 1, Ts...> tail_; \
- \
- friend struct access::recursive_union; \
- }
- C10_MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
- ~recursive_union() = default;);
- C10_MPARK_VARIANT_RECURSIVE_UNION(Trait::Available, ~recursive_union(){});
- C10_MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
- ~recursive_union() = delete;);
- #undef C10_MPARK_VARIANT_RECURSIVE_UNION
- using index_t = unsigned int;
- template <Trait DestructibleTrait, typename... Ts>
- class base {
- public:
- inline explicit constexpr base(valueless_t tag) noexcept
- : data_(tag), index_(static_cast<index_t>(-1)) {}
- template <std::size_t I, typename... Args>
- inline explicit constexpr base(in_place_index_t<I>, Args&&... args)
- : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...), index_(I) {}
- inline constexpr bool valueless_by_exception() const noexcept {
- return index_ == static_cast<index_t>(-1);
- }
- inline constexpr std::size_t index() const noexcept {
- return valueless_by_exception() ? variant_npos : index_;
- }
- protected:
- using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
- friend inline constexpr base& as_base(base& b) {
- return b;
- }
- friend inline constexpr const base& as_base(const base& b) {
- return b;
- }
- friend inline constexpr base&& as_base(base&& b) {
- return lib::move(b);
- }
- friend inline constexpr const base&& as_base(const base&& b) {
- return lib::move(b);
- }
- friend inline constexpr data_t& data(base& b) {
- return b.data_;
- }
- friend inline constexpr const data_t& data(const base& b) {
- return b.data_;
- }
- friend inline constexpr data_t&& data(base&& b) {
- return lib::move(b).data_;
- }
- friend inline constexpr const data_t&& data(const base&& b) {
- return lib::move(b).data_;
- }
- inline static constexpr std::size_t size() {
- return sizeof...(Ts);
- }
- data_t data_;
- index_t index_;
- friend struct access::base;
- friend struct visitation::base;
- };
- struct dtor {
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable : 4100)
- #endif
- template <typename Alt>
- inline void operator()(Alt& alt) const noexcept {
- alt.~Alt();
- }
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- };
- #if !defined(_MSC_VER) || _MSC_VER >= 1910
- #define C10_MPARK_INHERITING_CTOR(type, base) using base::base;
- #else
- #define C10_MPARK_INHERITING_CTOR(type, base) \
- template <typename... Args> \
- inline explicit constexpr type(Args&&... args) \
- : base(lib::forward<Args>(args)...) {}
- #endif
- template <typename Traits, Trait = Traits::destructible_trait>
- class destructor;
- #define C10_MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
- template <typename... Ts> \
- class destructor<traits<Ts...>, destructible_trait> \
- : public base<destructible_trait, Ts...> { \
- using super = base<destructible_trait, Ts...>; \
- \
- public: \
- C10_MPARK_INHERITING_CTOR(destructor, super) \
- using super::operator=; \
- \
- destructor(const destructor&) = default; \
- destructor(destructor&&) = default; \
- definition destructor& operator=(const destructor&) = default; \
- destructor& operator=(destructor&&) = default; \
- \
- protected: \
- destroy \
- }
- C10_MPARK_VARIANT_DESTRUCTOR(
- Trait::TriviallyAvailable, ~destructor() = default;
- , inline void destroy() noexcept {
- this->index_ = static_cast<index_t>(-1);
- });
- C10_MPARK_VARIANT_DESTRUCTOR(
- Trait::Available,
- ~destructor() { destroy(); },
- inline void destroy() noexcept {
- if (!this->valueless_by_exception()) {
- visitation::alt::visit_alt(dtor{}, *this);
- }
- this->index_ = static_cast<index_t>(-1);
- });
- C10_MPARK_VARIANT_DESTRUCTOR(Trait::Unavailable, ~destructor() = delete;
- , inline void destroy() noexcept = delete;);
- #undef C10_MPARK_VARIANT_DESTRUCTOR
- template <typename Traits>
- class constructor : public destructor<Traits> {
- using super = destructor<Traits>;
- public:
- C10_MPARK_INHERITING_CTOR(constructor, super)
- using super::operator=;
- protected:
- #ifndef C10_MPARK_GENERIC_LAMBDAS
- struct ctor {
- template <typename LhsAlt, typename RhsAlt>
- inline void operator()(LhsAlt& lhs_alt, RhsAlt&& rhs_alt) const {
- constructor::construct_alt(lhs_alt, lib::forward<RhsAlt>(rhs_alt).value);
- }
- };
- #endif
- template <std::size_t I, typename T, typename... Args>
- inline static T& construct_alt(alt<I, T>& a, Args&&... args) {
- auto* result = ::new (static_cast<void*>(lib::addressof(a)))
- alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
- return result->value;
- }
- template <typename Rhs>
- inline static void generic_construct(constructor& lhs, Rhs&& rhs) {
- lhs.destroy();
- if (!rhs.valueless_by_exception()) {
- visitation::alt::visit_alt_at(
- rhs.index(),
- #ifdef C10_MPARK_GENERIC_LAMBDAS
- [](auto& lhs_alt, auto&& rhs_alt) {
- constructor::construct_alt(
- lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
- }
- #else
- ctor {}
- #endif
- ,
- lhs,
- lib::forward<Rhs>(rhs));
- lhs.index_ = rhs.index_;
- }
- }
- };
- template <typename Traits, Trait = Traits::move_constructible_trait>
- class move_constructor;
- #define C10_MPARK_VARIANT_MOVE_CONSTRUCTOR( \
- move_constructible_trait, definition) \
- template <typename... Ts> \
- class move_constructor<traits<Ts...>, move_constructible_trait> \
- : public constructor<traits<Ts...>> { \
- using super = constructor<traits<Ts...>>; \
- \
- public: \
- C10_MPARK_INHERITING_CTOR(move_constructor, super) \
- using super::operator=; \
- \
- move_constructor(const move_constructor&) = default; \
- definition ~move_constructor() = default; \
- move_constructor& operator=(const move_constructor&) = default; \
- move_constructor& operator=(move_constructor&&) = default; \
- }
- C10_MPARK_VARIANT_MOVE_CONSTRUCTOR(
- Trait::TriviallyAvailable,
- move_constructor(move_constructor&& that) = default;);
- C10_MPARK_VARIANT_MOVE_CONSTRUCTOR(
- Trait::Available,
- move_constructor(move_constructor&& that) noexcept(
- lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
- : move_constructor(valueless_t{}) {
- this->generic_construct(*this, lib::move(that));
- });
- C10_MPARK_VARIANT_MOVE_CONSTRUCTOR(
- Trait::Unavailable, move_constructor(move_constructor&&) = delete;);
- #undef C10_MPARK_VARIANT_MOVE_CONSTRUCTOR
- template <typename Traits, Trait = Traits::copy_constructible_trait>
- class copy_constructor;
- #define C10_MPARK_VARIANT_COPY_CONSTRUCTOR( \
- copy_constructible_trait, definition) \
- template <typename... Ts> \
- class copy_constructor<traits<Ts...>, copy_constructible_trait> \
- : public move_constructor<traits<Ts...>> { \
- using super = move_constructor<traits<Ts...>>; \
- \
- public: \
- C10_MPARK_INHERITING_CTOR(copy_constructor, super) \
- using super::operator=; \
- \
- definition copy_constructor(copy_constructor&&) = default; \
- ~copy_constructor() = default; \
- copy_constructor& operator=(const copy_constructor&) = default; \
- copy_constructor& operator=(copy_constructor&&) = default; \
- }
- C10_MPARK_VARIANT_COPY_CONSTRUCTOR(
- Trait::TriviallyAvailable,
- copy_constructor(const copy_constructor& that) = default;);
- C10_MPARK_VARIANT_COPY_CONSTRUCTOR(
- Trait::Available, copy_constructor(const copy_constructor& that)
- : copy_constructor(valueless_t{}) {
- this->generic_construct(*this, that);
- });
- C10_MPARK_VARIANT_COPY_CONSTRUCTOR(
- Trait::Unavailable, copy_constructor(const copy_constructor&) = delete;);
- #undef C10_MPARK_VARIANT_COPY_CONSTRUCTOR
- template <typename Traits>
- class assignment : public copy_constructor<Traits> {
- using super = copy_constructor<Traits>;
- public:
- C10_MPARK_INHERITING_CTOR(assignment, super)
- using super::operator=;
- template <std::size_t I, typename... Args>
- inline /* auto & */ auto emplace(Args&&... args)
- -> decltype(this->construct_alt(
- access::base::get_alt<I>(*this),
- lib::forward<Args>(args)...)) {
- this->destroy();
- auto& result = this->construct_alt(
- access::base::get_alt<I>(*this), lib::forward<Args>(args)...);
- this->index_ = I;
- return result;
- }
- protected:
- #ifndef C10_MPARK_GENERIC_LAMBDAS
- template <typename That>
- struct assigner {
- template <typename ThisAlt, typename ThatAlt>
- inline void operator()(ThisAlt& this_alt, ThatAlt&& that_alt) const {
- self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
- }
- assignment* self;
- };
- #endif
- template <std::size_t I, typename T, typename Arg>
- inline void assign_alt(alt<I, T>& a, Arg&& arg) {
- if (this->index() == I) {
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable : 4244)
- #endif
- a.value = lib::forward<Arg>(arg);
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- } else {
- struct {
- void operator()(std::true_type) const {
- this_->emplace<I>(lib::forward<Arg>(arg_));
- }
- void operator()(std::false_type) const {
- this_->emplace<I>(T(lib::forward<Arg>(arg_)));
- }
- assignment* this_;
- Arg&& arg_;
- } impl{this, lib::forward<Arg>(arg)};
- impl(
- lib::bool_constant < std::is_nothrow_constructible<T, Arg>::value ||
- !std::is_nothrow_move_constructible<T>::value > {});
- }
- }
- template <typename That>
- inline void generic_assign(That&& that) {
- if (this->valueless_by_exception() && that.valueless_by_exception()) {
- // do nothing.
- } else if (that.valueless_by_exception()) {
- this->destroy();
- } else {
- visitation::alt::visit_alt_at(
- that.index(),
- #ifdef C10_MPARK_GENERIC_LAMBDAS
- [this](auto& this_alt, auto&& that_alt) {
- this->assign_alt(
- this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
- }
- #else
- assigner<That> { this }
- #endif
- ,
- *this,
- lib::forward<That>(that));
- }
- }
- };
- template <typename Traits, Trait = Traits::move_assignable_trait>
- class move_assignment;
- #define C10_MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
- template <typename... Ts> \
- class move_assignment<traits<Ts...>, move_assignable_trait> \
- : public assignment<traits<Ts...>> { \
- using super = assignment<traits<Ts...>>; \
- \
- public: \
- C10_MPARK_INHERITING_CTOR(move_assignment, super) \
- using super::operator=; \
- \
- move_assignment(const move_assignment&) = default; \
- move_assignment(move_assignment&&) = default; \
- ~move_assignment() = default; \
- move_assignment& operator=(const move_assignment&) = default; \
- definition \
- }
- C10_MPARK_VARIANT_MOVE_ASSIGNMENT(
- Trait::TriviallyAvailable,
- move_assignment& operator=(move_assignment&& that) = default;);
- C10_MPARK_VARIANT_MOVE_ASSIGNMENT(
- Trait::Available,
- move_assignment&
- operator=(move_assignment&& that) noexcept(
- lib::all<
- (std::is_nothrow_move_constructible<Ts>::value &&
- std::is_nothrow_move_assignable<Ts>::value)...>::value) {
- this->generic_assign(lib::move(that));
- return *this;
- });
- C10_MPARK_VARIANT_MOVE_ASSIGNMENT(
- Trait::Unavailable,
- move_assignment& operator=(move_assignment&&) = delete;);
- #undef C10_MPARK_VARIANT_MOVE_ASSIGNMENT
- template <typename Traits, Trait = Traits::copy_assignable_trait>
- class copy_assignment;
- #define C10_MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
- template <typename... Ts> \
- class copy_assignment<traits<Ts...>, copy_assignable_trait> \
- : public move_assignment<traits<Ts...>> { \
- using super = move_assignment<traits<Ts...>>; \
- \
- public: \
- C10_MPARK_INHERITING_CTOR(copy_assignment, super) \
- using super::operator=; \
- \
- copy_assignment(const copy_assignment&) = default; \
- copy_assignment(copy_assignment&&) = default; \
- ~copy_assignment() = default; \
- definition copy_assignment& operator=(copy_assignment&&) = default; \
- }
- C10_MPARK_VARIANT_COPY_ASSIGNMENT(
- Trait::TriviallyAvailable,
- copy_assignment& operator=(const copy_assignment& that) = default;);
- C10_MPARK_VARIANT_COPY_ASSIGNMENT(
- Trait::Available,
- copy_assignment&
- operator=(const copy_assignment& that) {
- this->generic_assign(that);
- return *this;
- });
- C10_MPARK_VARIANT_COPY_ASSIGNMENT(
- Trait::Unavailable,
- copy_assignment& operator=(const copy_assignment&) = delete;);
- #undef C10_MPARK_VARIANT_COPY_ASSIGNMENT
- template <typename... Ts>
- class impl : public copy_assignment<traits<Ts...>> {
- using super = copy_assignment<traits<Ts...>>;
- public:
- C10_MPARK_INHERITING_CTOR(impl, super)
- template <std::size_t I, typename Arg>
- inline void assign(Arg&& arg) {
- this->assign_alt(access::base::get_alt<I>(*this), lib::forward<Arg>(arg));
- }
- inline void swap(impl& that) {
- if (this->valueless_by_exception() && that.valueless_by_exception()) {
- // do nothing.
- } else if (this->index() == that.index()) {
- visitation::alt::visit_alt_at(
- this->index(),
- #ifdef C10_MPARK_GENERIC_LAMBDAS
- [](auto& this_alt, auto& that_alt) {
- using std::swap;
- swap(this_alt.value, that_alt.value);
- }
- #else
- swapper {}
- #endif
- ,
- *this,
- that);
- } else {
- impl* lhs = this;
- impl* rhs = lib::addressof(that);
- if (lhs->move_nothrow() && !rhs->move_nothrow()) {
- std::swap(lhs, rhs);
- }
- impl tmp(lib::move(*rhs));
- #ifdef C10_MPARK_EXCEPTIONS
- // EXTENSION: When the move construction of `lhs` into `rhs` throws
- // and `tmp` is nothrow move constructible then we move `tmp` back
- // into `rhs` and provide the strong exception safety guarantee.
- try {
- this->generic_construct(*rhs, lib::move(*lhs));
- } catch (...) {
- if (tmp.move_nothrow()) {
- this->generic_construct(*rhs, lib::move(tmp));
- }
- throw;
- }
- #else
- this->generic_construct(*rhs, lib::move(*lhs));
- #endif
- this->generic_construct(*lhs, lib::move(tmp));
- }
- }
- private:
- #ifndef C10_MPARK_GENERIC_LAMBDAS
- struct swapper {
- template <typename ThisAlt, typename ThatAlt>
- inline void operator()(ThisAlt& this_alt, ThatAlt& that_alt) const {
- using std::swap;
- swap(this_alt.value, that_alt.value);
- }
- };
- #endif
- inline constexpr bool move_nothrow() const {
- return this->valueless_by_exception() ||
- lib::array<bool, sizeof...(Ts)>{
- {std::is_nothrow_move_constructible<Ts>::value...}}[this->index()];
- }
- };
- #undef C10_MPARK_INHERITING_CTOR
- template <std::size_t I, typename T>
- struct overload_leaf {
- using F = lib::size_constant<I> (*)(T);
- operator F() const {
- return nullptr;
- }
- };
- template <typename... Ts>
- struct overload_impl {
- private:
- template <typename>
- struct impl;
- template <std::size_t... Is>
- struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
- public:
- using type = impl<lib::index_sequence_for<Ts...>>;
- };
- template <typename... Ts>
- using overload = typename overload_impl<Ts...>::type;
- template <typename T, typename... Ts>
- using best_match = lib::invoke_result_t<overload<Ts...>, T&&>;
- template <typename T>
- struct is_in_place_index : std::false_type {};
- template <std::size_t I>
- struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
- template <typename T>
- struct is_in_place_type : std::false_type {};
- template <typename T>
- struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
- } // namespace detail_
- template <typename... Ts>
- class variant {
- static_assert(
- 0 < sizeof...(Ts),
- "variant must consist of at least one alternative.");
- static_assert(
- lib::all<!std::is_array<Ts>::value...>::value,
- "variant can not have an array type as an alternative.");
- static_assert(
- lib::all<!std::is_reference<Ts>::value...>::value,
- "variant can not have a reference type as an alternative.");
- static_assert(
- lib::all<!std::is_void<Ts>::value...>::value,
- "variant can not have a void type as an alternative.");
- public:
- template <
- typename Front = lib::type_pack_element_t<0, Ts...>,
- lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
- inline constexpr variant() noexcept(
- std::is_nothrow_default_constructible<Front>::value)
- : impl_(in_place_index_t<0>{}) {}
- variant(const variant&) = default;
- variant(variant&&) = default;
- // NOTE [gcc 7.3.1 bug workaround]
- //
- // The original line `typename T = lib::type_pack_element_t<I, Ts...>`
- // throws the following compiler error on gcc 7.3.1:
- // ```
- // ../c10/util/variant.h:2250:9: internal compiler error:
- // unexpected expression ‘I’ of kind template_parm_index
- // typename T = lib::type_pack_element_t<I, Ts...>,
- // ^~~~~~~~
- // ```
- // As a workaround, `I` is changed to `detail_::best_match<Arg,
- // Ts...>::value`, which is the default value for `I` in this template. Note
- // that this workaround effectively disallows setting `I` to any other
- // non-default value, and we add a `static_assert` in the function body to
- // check for this.
- //
- // See the following issues for more context:
- // - https://github.com/mpark/variant/issues/43
- // - https://github.com/eggs-cpp/variant/issues/31
- template <
- typename Arg,
- typename Decayed = lib::decay_t<Arg>,
- lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
- lib::enable_if_t<!detail_::is_in_place_index<Decayed>::value, int> = 0,
- lib::enable_if_t<!detail_::is_in_place_type<Decayed>::value, int> = 0,
- std::size_t I = detail_::best_match<Arg, Ts...>::value,
- typename T = lib::
- type_pack_element_t<detail_::best_match<Arg, Ts...>::value, Ts...>,
- lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
- inline constexpr variant(Arg&& arg) noexcept(
- std::is_nothrow_constructible<T, Arg>::value)
- : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {
- static_assert(
- I == detail_::best_match<Arg, Ts...>::value,
- "Setting template parameter `I` to a custom non-default value is not supported. "
- "Please file a feature request if you see this.");
- }
- template <
- std::size_t I,
- typename... Args,
- typename T = lib::type_pack_element_t<I, Ts...>,
- lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
- inline explicit constexpr variant(
- in_place_index_t<I>,
- Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value)
- : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
- template <
- std::size_t I,
- typename Up,
- typename... Args,
- typename T = lib::type_pack_element_t<I, Ts...>,
- lib::enable_if_t<
- std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
- int> = 0>
- inline explicit constexpr variant(
- in_place_index_t<I>,
- std::initializer_list<Up> il,
- Args&&... args) noexcept(std::
- is_nothrow_constructible<
- T,
- std::initializer_list<Up>&,
- Args...>::value)
- : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
- template <
- typename T,
- typename... Args,
- std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
- lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
- inline explicit constexpr variant(
- in_place_type_t<T>,
- Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value)
- : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
- template <
- typename T,
- typename Up,
- typename... Args,
- std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
- lib::enable_if_t<
- std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
- int> = 0>
- inline explicit constexpr variant(
- in_place_type_t<T>,
- std::initializer_list<Up> il,
- Args&&... args) noexcept(std::
- is_nothrow_constructible<
- T,
- std::initializer_list<Up>&,
- Args...>::value)
- : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
- ~variant() = default;
- variant& operator=(const variant&) = default;
- variant& operator=(variant&&) = default;
- // NOTE: See NOTE [gcc 7.3.1 bug workaround] for the changes made to this
- // function.
- template <
- typename Arg,
- lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value, int> =
- 0,
- std::size_t I = detail_::best_match<Arg, Ts...>::value,
- typename T = lib::
- type_pack_element_t<detail_::best_match<Arg, Ts...>::value, Ts...>,
- lib::enable_if_t<
- (std::is_assignable<T&, Arg>::value &&
- std::is_constructible<T, Arg>::value),
- int> = 0>
- inline variant& operator=(Arg&& arg) noexcept(
- (std::is_nothrow_assignable<T&, Arg>::value &&
- std::is_nothrow_constructible<T, Arg>::value)) {
- static_assert(
- I == detail_::best_match<Arg, Ts...>::value,
- "Setting template parameter `I` to a custom non-default value is not supported. "
- "Please file a feature request if you see this.");
- impl_.template assign<I>(lib::forward<Arg>(arg));
- return *this;
- }
- template <
- std::size_t I,
- typename... Args,
- typename T = lib::type_pack_element_t<I, Ts...>,
- lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
- inline T& emplace(Args&&... args) {
- return impl_.template emplace<I>(lib::forward<Args>(args)...);
- }
- template <
- std::size_t I,
- typename Up,
- typename... Args,
- typename T = lib::type_pack_element_t<I, Ts...>,
- lib::enable_if_t<
- std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
- int> = 0>
- inline T& emplace(std::initializer_list<Up> il, Args&&... args) {
- return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
- }
- template <
- typename T,
- typename... Args,
- std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
- lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
- inline T& emplace(Args&&... args) {
- return impl_.template emplace<I>(lib::forward<Args>(args)...);
- }
- template <
- typename T,
- typename Up,
- typename... Args,
- std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
- lib::enable_if_t<
- std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
- int> = 0>
- inline T& emplace(std::initializer_list<Up> il, Args&&... args) {
- return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
- }
- inline constexpr bool valueless_by_exception() const noexcept {
- return impl_.valueless_by_exception();
- }
- inline constexpr std::size_t index() const noexcept {
- return impl_.index();
- }
- template <
- bool Dummy = true,
- lib::enable_if_t<
- lib::all<
- Dummy,
- (lib::dependent_type<std::is_move_constructible<Ts>, Dummy>::
- value &&
- lib::dependent_type<lib::is_swappable<Ts>, Dummy>::value)...>::
- value,
- int> = 0>
- inline void swap(variant& that) noexcept(
- lib::all<
- (std::is_nothrow_move_constructible<Ts>::value &&
- lib::is_nothrow_swappable<Ts>::value)...>::value) {
- impl_.swap(that.impl_);
- }
- private:
- detail_::impl<Ts...> impl_;
- friend struct detail_::access::variant;
- friend struct detail_::visitation::variant;
- };
- template <std::size_t I, typename... Ts>
- inline constexpr bool holds_alternative(const variant<Ts...>& v) noexcept {
- return v.index() == I;
- }
- template <typename T, typename... Ts>
- inline constexpr bool holds_alternative(const variant<Ts...>& v) noexcept {
- return holds_alternative<detail_::find_index_checked<T, Ts...>::value>(v);
- }
- namespace detail_ {
- template <std::size_t I, typename V>
- struct generic_get_impl {
- constexpr generic_get_impl(int) noexcept {}
- constexpr AUTO_REFREF operator()(V&& v) const
- AUTO_REFREF_RETURN(access::variant::get_alt<I>(lib::forward<V>(v)).value)
- };
- template <std::size_t I, typename V>
- inline constexpr AUTO_REFREF generic_get(V&& v)
- AUTO_REFREF_RETURN(generic_get_impl<I, V>(
- holds_alternative<I>(v)
- ? 0
- : (throw_bad_variant_access(), 0))(lib::forward<V>(v)))
- } // namespace detail_
- template <std::size_t I, typename... Ts>
- inline constexpr variant_alternative_t<I, variant<Ts...>>& get(
- variant<Ts...>& v) {
- return detail_::generic_get<I>(v);
- }
- template <std::size_t I, typename... Ts>
- inline constexpr variant_alternative_t<I, variant<Ts...>>&& get(
- variant<Ts...>&& v) {
- return detail_::generic_get<I>(lib::move(v));
- }
- template <std::size_t I, typename... Ts>
- inline constexpr const variant_alternative_t<I, variant<Ts...>>& get(
- const variant<Ts...>& v) {
- return detail_::generic_get<I>(v);
- }
- template <std::size_t I, typename... Ts>
- inline constexpr const variant_alternative_t<I, variant<Ts...>>&& get(
- const variant<Ts...>&& v) {
- return detail_::generic_get<I>(lib::move(v));
- }
- template <typename T, typename... Ts>
- inline constexpr T& get(variant<Ts...>& v) {
- return get<detail_::find_index_checked<T, Ts...>::value>(v);
- }
- template <typename T, typename... Ts>
- inline constexpr T&& get(variant<Ts...>&& v) {
- return get<detail_::find_index_checked<T, Ts...>::value>(lib::move(v));
- }
- template <typename T, typename... Ts>
- inline constexpr const T& get(const variant<Ts...>& v) {
- return get<detail_::find_index_checked<T, Ts...>::value>(v);
- }
- template <typename T, typename... Ts>
- inline constexpr const T&& get(const variant<Ts...>&& v) {
- return get<detail_::find_index_checked<T, Ts...>::value>(lib::move(v));
- }
- namespace detail_ {
- template <std::size_t I, typename V>
- inline constexpr /* auto * */ AUTO generic_get_if(V* v) noexcept AUTO_RETURN(
- v&& holds_alternative<I>(*v)
- ? lib::addressof(access::variant::get_alt<I>(*v).value)
- : nullptr)
- } // namespace detail_
- template <std::size_t I, typename... Ts>
- inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
- get_if(variant<Ts...>* v) noexcept {
- return detail_::generic_get_if<I>(v);
- }
- template <std::size_t I, typename... Ts>
- inline constexpr lib::add_pointer_t<
- const variant_alternative_t<I, variant<Ts...>>>
- get_if(const variant<Ts...>* v) noexcept {
- return detail_::generic_get_if<I>(v);
- }
- template <typename T, typename... Ts>
- inline constexpr lib::add_pointer_t<T> get_if(variant<Ts...>* v) noexcept {
- return get_if<detail_::find_index_checked<T, Ts...>::value>(v);
- }
- template <typename T, typename... Ts>
- inline constexpr lib::add_pointer_t<const T> get_if(
- const variant<Ts...>* v) noexcept {
- return get_if<detail_::find_index_checked<T, Ts...>::value>(v);
- }
- namespace detail_ {
- template <typename RelOp>
- struct convert_to_bool {
- template <typename Lhs, typename Rhs>
- inline constexpr bool operator()(Lhs&& lhs, Rhs&& rhs) const {
- static_assert(
- std::is_convertible<lib::invoke_result_t<RelOp, Lhs, Rhs>, bool>::value,
- "relational operators must return a type"
- " implicitly convertible to bool");
- return lib::invoke(RelOp{}, lib::forward<Lhs>(lhs), lib::forward<Rhs>(rhs));
- }
- };
- } // namespace detail_
- template <typename... Ts>
- inline constexpr bool operator==(
- const variant<Ts...>& lhs,
- const variant<Ts...>& rhs) {
- using detail_::visitation::variant;
- using equal_to = detail_::convert_to_bool<lib::equal_to>;
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- if (lhs.index() != rhs.index())
- return false;
- if (lhs.valueless_by_exception())
- return true;
- return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
- #else
- return lhs.index() == rhs.index() &&
- (lhs.valueless_by_exception() ||
- variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
- #endif
- }
- template <typename... Ts>
- inline constexpr bool operator!=(
- const variant<Ts...>& lhs,
- const variant<Ts...>& rhs) {
- using detail_::visitation::variant;
- using not_equal_to = detail_::convert_to_bool<lib::not_equal_to>;
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- if (lhs.index() != rhs.index())
- return true;
- if (lhs.valueless_by_exception())
- return false;
- return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
- #else
- return lhs.index() != rhs.index() ||
- (!lhs.valueless_by_exception() &&
- variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
- #endif
- }
- template <typename... Ts>
- inline constexpr bool operator<(
- const variant<Ts...>& lhs,
- const variant<Ts...>& rhs) {
- using detail_::visitation::variant;
- using less = detail_::convert_to_bool<lib::less>;
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- if (rhs.valueless_by_exception())
- return false;
- if (lhs.valueless_by_exception())
- return true;
- if (lhs.index() < rhs.index())
- return true;
- if (lhs.index() > rhs.index())
- return false;
- return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
- #else
- return !rhs.valueless_by_exception() &&
- (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
- (lhs.index() == rhs.index() &&
- variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
- #endif
- }
- template <typename... Ts>
- inline constexpr bool operator>(
- const variant<Ts...>& lhs,
- const variant<Ts...>& rhs) {
- using detail_::visitation::variant;
- using greater = detail_::convert_to_bool<lib::greater>;
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- if (lhs.valueless_by_exception())
- return false;
- if (rhs.valueless_by_exception())
- return true;
- if (lhs.index() > rhs.index())
- return true;
- if (lhs.index() < rhs.index())
- return false;
- return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
- #else
- return !lhs.valueless_by_exception() &&
- (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
- (lhs.index() == rhs.index() &&
- variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
- #endif
- }
- template <typename... Ts>
- inline constexpr bool operator<=(
- const variant<Ts...>& lhs,
- const variant<Ts...>& rhs) {
- using detail_::visitation::variant;
- using less_equal = detail_::convert_to_bool<lib::less_equal>;
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- if (lhs.valueless_by_exception())
- return true;
- if (rhs.valueless_by_exception())
- return false;
- if (lhs.index() < rhs.index())
- return true;
- if (lhs.index() > rhs.index())
- return false;
- return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
- #else
- return lhs.valueless_by_exception() ||
- (!rhs.valueless_by_exception() &&
- (lhs.index() < rhs.index() ||
- (lhs.index() == rhs.index() &&
- variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
- #endif
- }
- template <typename... Ts>
- inline constexpr bool operator>=(
- const variant<Ts...>& lhs,
- const variant<Ts...>& rhs) {
- using detail_::visitation::variant;
- using greater_equal = detail_::convert_to_bool<lib::greater_equal>;
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- if (rhs.valueless_by_exception())
- return true;
- if (lhs.valueless_by_exception())
- return false;
- if (lhs.index() > rhs.index())
- return true;
- if (lhs.index() < rhs.index())
- return false;
- return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
- #else
- return rhs.valueless_by_exception() ||
- (!lhs.valueless_by_exception() &&
- (lhs.index() > rhs.index() ||
- (lhs.index() == rhs.index() &&
- variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs))));
- #endif
- }
- struct monostate {};
- inline constexpr bool operator<(monostate, monostate) noexcept {
- return false;
- }
- inline constexpr bool operator>(monostate, monostate) noexcept {
- return false;
- }
- inline constexpr bool operator<=(monostate, monostate) noexcept {
- return true;
- }
- inline constexpr bool operator>=(monostate, monostate) noexcept {
- return true;
- }
- inline constexpr bool operator==(monostate, monostate) noexcept {
- return true;
- }
- inline constexpr bool operator!=(monostate, monostate) noexcept {
- return false;
- }
- #ifdef C10_MPARK_CPP14_CONSTEXPR
- namespace detail_ {
- inline constexpr bool any(std::initializer_list<bool> bs) {
- for (bool b : bs) {
- if (b) {
- return true;
- }
- }
- return false;
- }
- } // namespace detail_
- template <typename Visitor, typename... Vs>
- inline constexpr decltype(auto) visit(Visitor&& visitor, Vs&&... vs) {
- return (!detail_::any({vs.valueless_by_exception()...})
- ? (void)0
- : throw_bad_variant_access()),
- detail_::visitation::variant::visit_value(
- lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
- }
- #else
- namespace detail_ {
- template <std::size_t N>
- inline constexpr bool all_impl(const lib::array<bool, N>& bs, std::size_t idx) {
- return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
- }
- template <std::size_t N>
- inline constexpr bool all(const lib::array<bool, N>& bs) {
- return all_impl(bs, 0);
- }
- } // namespace detail_
- template <typename Visitor, typename... Vs>
- inline constexpr DECLTYPE_AUTO visit(Visitor&& visitor, Vs&&... vs)
- DECLTYPE_AUTO_RETURN(
- (detail_::all(lib::array<bool, sizeof...(Vs)>{
- {!vs.valueless_by_exception()...}})
- ? (void)0
- : throw_bad_variant_access()),
- detail_::visitation::variant::visit_value(
- lib::forward<Visitor>(visitor),
- lib::forward<Vs>(vs)...))
- #endif
- template <typename... Ts>
- inline auto swap(variant<Ts...>& lhs, variant<Ts...>& rhs) noexcept(
- noexcept(lhs.swap(rhs))) -> decltype(lhs.swap(rhs)) {
- lhs.swap(rhs);
- }
- namespace detail_ {
- template <typename T, typename...>
- using enabled_type = T;
- namespace hash {
- template <typename H, typename K>
- constexpr bool meets_requirements() noexcept {
- return std::is_copy_constructible<H>::value &&
- std::is_move_constructible<H>::value &&
- lib::is_invocable_r<std::size_t, H, const K&>::value;
- }
- template <typename K>
- constexpr bool is_enabled() noexcept {
- using H = std::hash<K>;
- return meets_requirements<H, K>() &&
- std::is_default_constructible<H>::value &&
- std::is_copy_assignable<H>::value && std::is_move_assignable<H>::value;
- }
- } // namespace hash
- } // namespace detail_
- #undef AUTO
- #undef AUTO_RETURN
- #undef AUTO_REFREF
- #undef AUTO_REFREF_RETURN
- #undef DECLTYPE_AUTO
- #undef DECLTYPE_AUTO_RETURN
- } // namespace c10
- namespace std {
- template <typename... Ts>
- struct hash<c10::detail_::enabled_type<
- c10::variant<Ts...>,
- c10::lib::enable_if_t<c10::lib::all<c10::detail_::hash::is_enabled<
- c10::lib::remove_const_t<Ts>>()...>::value>>> {
- using argument_type = c10::variant<Ts...>;
- using result_type = std::size_t;
- inline result_type operator()(const argument_type& v) const {
- using c10::detail_::visitation::variant;
- std::size_t result = v.valueless_by_exception()
- ? 299792458 // Random value chosen by the universe upon creation
- : variant::visit_alt(
- #ifdef C10_MPARK_GENERIC_LAMBDAS
- [](const auto& alt) {
- using alt_type = c10::lib::decay_t<decltype(alt)>;
- using value_type =
- c10::lib::remove_const_t<typename alt_type::value_type>;
- return hash<value_type>{}(alt.value);
- }
- #else
- hasher {}
- #endif
- ,
- v);
- return hash_combine(result, hash<std::size_t>{}(v.index()));
- }
- private:
- #ifndef C10_MPARK_GENERIC_LAMBDAS
- struct hasher {
- template <typename Alt>
- inline std::size_t operator()(const Alt& alt) const {
- using alt_type = c10::lib::decay_t<Alt>;
- using value_type =
- c10::lib::remove_const_t<typename alt_type::value_type>;
- return hash<value_type>{}(alt.value);
- }
- };
- #endif
- static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
- return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
- }
- };
- template <>
- struct hash<c10::monostate> {
- using argument_type = c10::monostate;
- using result_type = std::size_t;
- inline result_type operator()(const argument_type&) const noexcept {
- return 66740831; // return a fundamentally attractive random value.
- }
- };
- } // namespace std
- #endif // C10_UTIL_VARIANT_H_
|