variant.h 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025
  1. // MPark.Variant
  2. //
  3. // Copyright Michael Park, 2015-2017
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE.md or copy at
  7. // http://boost.org/LICENSE_1_0.txt)
  8. //
  9. // From https://github.com/mpark/variant
  10. //
  11. // C10
  12. // - Move to `c10` namespace.
  13. // - Rename namespace `detail` to `detail_`, to not conflict with existing
  14. // c10 implementations in `detail` namespace.
  15. // - In two functions, the template name reference `I` is changed to
  16. // `detail_::best_match<Arg, Ts...>::value` to work around gcc 7.3.1 bug.
  17. // However, this workaround also limits the use cases of `c10::variant`.
  18. // Please see NOTE [gcc 7.3.1 bug workaround] for details.
  19. // - The following code is moved to `c10/util/in_place.h`:
  20. // ```
  21. // struct in_place_t { explicit in_place_t() = default; };
  22. //
  23. // template <std::size_t I>
  24. // struct in_place_index_t { explicit in_place_index_t() = default; };
  25. //
  26. // template <typename T>
  27. // struct in_place_type_t { explicit in_place_type_t() = default; };
  28. //
  29. // constexpr in_place_t in_place{};
  30. // ```
  31. // so that they can also be used in `c10/util/Optional.h`.
  32. #ifndef C10_UTIL_VARIANT_H_
  33. #define C10_UTIL_VARIANT_H_
  34. /*
  35. variant synopsis
  36. namespace std {
  37. // 20.7.2, class template variant
  38. template <class... Types>
  39. class variant {
  40. public:
  41. // 20.7.2.1, constructors
  42. constexpr variant() noexcept(see below);
  43. variant(const variant&);
  44. variant(variant&&) noexcept(see below);
  45. template <class T> constexpr variant(T&&) noexcept(see below);
  46. template <class T, class... Args>
  47. constexpr explicit variant(in_place_type_t<T>, Args&&...);
  48. template <class T, class U, class... Args>
  49. constexpr explicit variant(
  50. in_place_type_t<T>, initializer_list<U>, Args&&...);
  51. template <size_t I, class... Args>
  52. constexpr explicit variant(in_place_index_t<I>, Args&&...);
  53. template <size_t I, class U, class... Args>
  54. constexpr explicit variant(
  55. in_place_index_t<I>, initializer_list<U>, Args&&...);
  56. // 20.7.2.2, destructor
  57. ~variant();
  58. // 20.7.2.3, assignment
  59. variant& operator=(const variant&);
  60. variant& operator=(variant&&) noexcept(see below);
  61. template <class T> variant& operator=(T&&) noexcept(see below);
  62. // 20.7.2.4, modifiers
  63. template <class T, class... Args>
  64. T& emplace(Args&&...);
  65. template <class T, class U, class... Args>
  66. T& emplace(initializer_list<U>, Args&&...);
  67. template <size_t I, class... Args>
  68. variant_alternative<I, variant>& emplace(Args&&...);
  69. template <size_t I, class U, class... Args>
  70. variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
  71. // 20.7.2.5, value status
  72. constexpr bool valueless_by_exception() const noexcept;
  73. constexpr size_t index() const noexcept;
  74. // 20.7.2.6, swap
  75. void swap(variant&) noexcept(see below);
  76. };
  77. // 20.7.3, variant helper classes
  78. template <class T> struct variant_size; // undefined
  79. template <class T>
  80. constexpr size_t variant_size_v = variant_size<T>::value;
  81. template <class T> struct variant_size<const T>;
  82. template <class T> struct variant_size<volatile T>;
  83. template <class T> struct variant_size<const volatile T>;
  84. template <class... Types>
  85. struct variant_size<variant<Types...>>;
  86. template <size_t I, class T> struct variant_alternative; // undefined
  87. template <size_t I, class T>
  88. using variant_alternative_t = typename variant_alternative<I, T>::type;
  89. template <size_t I, class T> struct variant_alternative<I, const T>;
  90. template <size_t I, class T> struct variant_alternative<I, volatile T>;
  91. template <size_t I, class T> struct variant_alternative<I, const volatile T>;
  92. template <size_t I, class... Types>
  93. struct variant_alternative<I, variant<Types...>>;
  94. constexpr size_t variant_npos = -1;
  95. // 20.7.4, value access
  96. template <class T, class... Types>
  97. constexpr bool holds_alternative(const variant<Types...>&) noexcept;
  98. template <size_t I, class... Types>
  99. constexpr variant_alternative_t<I, variant<Types...>>&
  100. get(variant<Types...>&);
  101. template <size_t I, class... Types>
  102. constexpr variant_alternative_t<I, variant<Types...>>&&
  103. get(variant<Types...>&&);
  104. template <size_t I, class... Types>
  105. constexpr variant_alternative_t<I, variant<Types...>> const&
  106. get(const variant<Types...>&);
  107. template <size_t I, class... Types>
  108. constexpr variant_alternative_t<I, variant<Types...>> const&&
  109. get(const variant<Types...>&&);
  110. template <class T, class... Types>
  111. constexpr T& get(variant<Types...>&);
  112. template <class T, class... Types>
  113. constexpr T&& get(variant<Types...>&&);
  114. template <class T, class... Types>
  115. constexpr const T& get(const variant<Types...>&);
  116. template <class T, class... Types>
  117. constexpr const T&& get(const variant<Types...>&&);
  118. template <size_t I, class... Types>
  119. constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
  120. get_if(variant<Types...>*) noexcept;
  121. template <size_t I, class... Types>
  122. constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
  123. get_if(const variant<Types...>*) noexcept;
  124. template <class T, class... Types>
  125. constexpr add_pointer_t<T>
  126. get_if(variant<Types...>*) noexcept;
  127. template <class T, class... Types>
  128. constexpr add_pointer_t<const T>
  129. get_if(const variant<Types...>*) noexcept;
  130. // 20.7.5, relational operators
  131. template <class... Types>
  132. constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
  133. template <class... Types>
  134. constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
  135. template <class... Types>
  136. constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
  137. template <class... Types>
  138. constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
  139. template <class... Types>
  140. constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
  141. template <class... Types>
  142. constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
  143. // 20.7.6, visitation
  144. template <class Visitor, class... Variants>
  145. constexpr see below visit(Visitor&&, Variants&&...);
  146. // 20.7.7, class monostate
  147. struct monostate;
  148. // 20.7.8, monostate relational operators
  149. constexpr bool operator<(monostate, monostate) noexcept;
  150. constexpr bool operator>(monostate, monostate) noexcept;
  151. constexpr bool operator<=(monostate, monostate) noexcept;
  152. constexpr bool operator>=(monostate, monostate) noexcept;
  153. constexpr bool operator==(monostate, monostate) noexcept;
  154. constexpr bool operator!=(monostate, monostate) noexcept;
  155. // 20.7.9, specialized algorithms
  156. template <class... Types>
  157. void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
  158. // 20.7.10, class bad_variant_access
  159. class bad_variant_access;
  160. // 20.7.11, hash support
  161. template <class T> struct hash;
  162. template <class... Types> struct hash<variant<Types...>>;
  163. template <> struct hash<monostate>;
  164. } // namespace std
  165. */
  166. #include <cstddef>
  167. #include <exception>
  168. #include <functional>
  169. #include <initializer_list>
  170. #include <new>
  171. #include <type_traits>
  172. #include <utility>
  173. // MPark.Variant
  174. //
  175. // Copyright Michael Park, 2015-2017
  176. //
  177. // Distributed under the Boost Software License, Version 1.0.
  178. // (See accompanying file LICENSE.md or copy at
  179. // http://boost.org/LICENSE_1_0.txt)
  180. #ifndef C10_MPARK_CONFIG_HPP
  181. #define C10_MPARK_CONFIG_HPP
  182. // MSVC 2015 Update 3.
  183. #if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
  184. #error "MPark.Variant requires C++11 support."
  185. #endif
  186. #ifndef __has_attribute
  187. #define __has_attribute(x) 0
  188. #endif
  189. #ifndef __has_builtin
  190. #define __has_builtin(x) 0
  191. #endif
  192. #ifndef __has_include
  193. #define __has_include(x) 0
  194. #endif
  195. #ifndef __has_feature
  196. #define __has_feature(x) 0
  197. #endif
  198. #if __has_attribute(always_inline) || defined(__GNUC__)
  199. #define C10_MPARK_ALWAYS_INLINE __attribute__((__always_inline__)) inline
  200. #elif defined(_MSC_VER)
  201. #define C10_MPARK_ALWAYS_INLINE __forceinline
  202. #else
  203. #define C10_MPARK_ALWAYS_INLINE inline
  204. #endif
  205. #if __has_builtin(__builtin_addressof) || \
  206. (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
  207. #define C10_MPARK_BUILTIN_ADDRESSOF
  208. #endif
  209. #if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
  210. #define C10_MPARK_BUILTIN_UNREACHABLE __builtin_unreachable()
  211. #elif defined(_MSC_VER)
  212. #define C10_MPARK_BUILTIN_UNREACHABLE __assume(false)
  213. #else
  214. #define C10_MPARK_BUILTIN_UNREACHABLE
  215. #endif
  216. // NOTE [nvcc bug workaround]
  217. //
  218. // The original line `typename Front = lib::type_pack_element_t<0, Ts...>,`
  219. // throws the following compiler error on nvcc:
  220. // ```
  221. // c10/util/variant.h(2367): error: parameter pack "Ts" was referenced but not
  222. // expanded
  223. // ```
  224. // As a workaround, we skip defining C10_MPARK_TYPE_PACK_ELEMENT for nvcc
  225. // compiler
  226. //
  227. // See the following issues for more context:
  228. // https://github.com/pytorch/extension-cpp/issues/58
  229. // https://github.com/mpark/variant/issues/77
  230. #if __has_builtin(__type_pack_element) && !defined(__CUDACC__)
  231. #define C10_MPARK_TYPE_PACK_ELEMENT
  232. #endif
  233. #if defined(__cpp_constexpr) && __cpp_constexpr >= 200704 && \
  234. !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 9)
  235. #define C10_MPARK_CPP11_CONSTEXPR
  236. #endif
  237. #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
  238. #define C10_MPARK_CPP14_CONSTEXPR
  239. #endif
  240. #if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
  241. (defined(_MSC_VER) && defined(_CPPUNWIND))
  242. #define C10_MPARK_EXCEPTIONS
  243. #endif
  244. #if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
  245. #define C10_MPARK_GENERIC_LAMBDAS
  246. #endif
  247. #if defined(__cpp_lib_integer_sequence)
  248. #define C10_MPARK_INTEGER_SEQUENCE
  249. #endif
  250. #if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
  251. #define C10_MPARK_RETURN_TYPE_DEDUCTION
  252. #endif
  253. #if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
  254. #define C10_MPARK_TRANSPARENT_OPERATORS
  255. #endif
  256. #if defined(__cpp_variable_templates) || defined(_MSC_VER)
  257. #define C10_MPARK_VARIABLE_TEMPLATES
  258. #endif
  259. #if !defined(__GLIBCXX__) || __has_include(<codecvt>) // >= libstdc++-5
  260. #define C10_MPARK_TRIVIALITY_TYPE_TRAITS
  261. #define C10_MPARK_INCOMPLETE_TYPE_TRAITS
  262. #endif
  263. #ifdef _WIN32
  264. #define C10_MPARK_VISIBILITY_HIDDEN
  265. #else
  266. #define C10_MPARK_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
  267. #endif
  268. #endif // C10_MPARK_CONFIG_HPP
  269. // MPark.Variant
  270. //
  271. // Copyright Michael Park, 2015-2017
  272. //
  273. // Distributed under the Boost Software License, Version 1.0.
  274. // (See accompanying file LICENSE.md or copy at
  275. // http://boost.org/LICENSE_1_0.txt)
  276. #ifndef C10_MPARK_IN_PLACE_HPP
  277. #define C10_MPARK_IN_PLACE_HPP
  278. #include <c10/util/in_place.h>
  279. #include <cstddef>
  280. namespace c10 {
  281. #ifdef C10_MPARK_VARIABLE_TEMPLATES
  282. template <std::size_t I>
  283. constexpr in_place_index_t<I> in_place_index{};
  284. template <typename T>
  285. constexpr in_place_type_t<T> in_place_type{};
  286. #endif
  287. } // namespace c10
  288. #endif // C10_MPARK_IN_PLACE_HPP
  289. // MPark.Variant
  290. //
  291. // Copyright Michael Park, 2015-2017
  292. //
  293. // Distributed under the Boost Software License, Version 1.0.
  294. // (See accompanying file LICENSE.md or copy at
  295. // http://boost.org/LICENSE_1_0.txt)
  296. #ifndef C10_MPARK_LIB_HPP
  297. #define C10_MPARK_LIB_HPP
  298. #include <functional>
  299. #include <memory>
  300. #include <type_traits>
  301. #include <utility>
  302. #define C10_MPARK_RETURN(...) \
  303. noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) { \
  304. return __VA_ARGS__; \
  305. }
  306. namespace c10 {
  307. namespace lib {
  308. template <typename T>
  309. struct identity {
  310. using type = T;
  311. };
  312. inline namespace cpp14 {
  313. template <typename T, std::size_t N>
  314. struct array {
  315. constexpr const T& operator[](std::size_t index) const {
  316. return data[index];
  317. }
  318. T data[N == 0 ? 1 : N];
  319. };
  320. template <typename T>
  321. using add_pointer_t = typename std::add_pointer<T>::type;
  322. template <typename... Ts>
  323. using common_type_t = typename std::common_type<Ts...>::type;
  324. template <typename T>
  325. using decay_t = typename std::decay<T>::type;
  326. template <bool B, typename T = void>
  327. using enable_if_t = typename std::enable_if<B, T>::type;
  328. template <typename T>
  329. using remove_const_t = typename std::remove_const<T>::type;
  330. template <typename T>
  331. using remove_reference_t = typename std::remove_reference<T>::type;
  332. template <typename T>
  333. inline constexpr T&& forward(remove_reference_t<T>& t) noexcept {
  334. return static_cast<T&&>(t);
  335. }
  336. template <typename T>
  337. inline constexpr T&& forward(remove_reference_t<T>&& t) noexcept {
  338. static_assert(
  339. !std::is_lvalue_reference<T>::value,
  340. "can not forward an rvalue as an lvalue");
  341. return static_cast<T&&>(t);
  342. }
  343. template <typename T>
  344. inline constexpr remove_reference_t<T>&& move(T&& t) noexcept {
  345. return static_cast<remove_reference_t<T>&&>(t);
  346. }
  347. #ifdef C10_MPARK_INTEGER_SEQUENCE
  348. using std::index_sequence;
  349. using std::index_sequence_for;
  350. using std::integer_sequence;
  351. using std::make_index_sequence;
  352. #else
  353. template <typename T, T... Is>
  354. struct integer_sequence {
  355. using value_type = T;
  356. static constexpr std::size_t size() noexcept {
  357. return sizeof...(Is);
  358. }
  359. };
  360. template <std::size_t... Is>
  361. using index_sequence = integer_sequence<std::size_t, Is...>;
  362. template <typename Lhs, typename Rhs>
  363. struct make_index_sequence_concat;
  364. template <std::size_t... Lhs, std::size_t... Rhs>
  365. struct make_index_sequence_concat<
  366. index_sequence<Lhs...>,
  367. index_sequence<Rhs...>>
  368. : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
  369. template <std::size_t N>
  370. struct make_index_sequence_impl;
  371. template <std::size_t N>
  372. using make_index_sequence = typename make_index_sequence_impl<N>::type;
  373. template <std::size_t N>
  374. struct make_index_sequence_impl : make_index_sequence_concat<
  375. make_index_sequence<N / 2>,
  376. make_index_sequence<N - (N / 2)>> {};
  377. template <>
  378. struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
  379. template <>
  380. struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
  381. template <typename... Ts>
  382. using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
  383. #endif
  384. // <functional>
  385. #ifdef C10_MPARK_TRANSPARENT_OPERATORS
  386. using equal_to = std::equal_to<>;
  387. #else
  388. struct equal_to {
  389. template <typename Lhs, typename Rhs>
  390. inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
  391. C10_MPARK_RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
  392. };
  393. #endif
  394. #ifdef C10_MPARK_TRANSPARENT_OPERATORS
  395. using not_equal_to = std::not_equal_to<>;
  396. #else
  397. struct not_equal_to {
  398. template <typename Lhs, typename Rhs>
  399. inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
  400. C10_MPARK_RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
  401. };
  402. #endif
  403. #ifdef C10_MPARK_TRANSPARENT_OPERATORS
  404. using less = std::less<>;
  405. #else
  406. struct less {
  407. template <typename Lhs, typename Rhs>
  408. inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
  409. C10_MPARK_RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
  410. };
  411. #endif
  412. #ifdef C10_MPARK_TRANSPARENT_OPERATORS
  413. using greater = std::greater<>;
  414. #else
  415. struct greater {
  416. template <typename Lhs, typename Rhs>
  417. inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
  418. C10_MPARK_RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
  419. };
  420. #endif
  421. #ifdef C10_MPARK_TRANSPARENT_OPERATORS
  422. using less_equal = std::less_equal<>;
  423. #else
  424. struct less_equal {
  425. template <typename Lhs, typename Rhs>
  426. inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
  427. C10_MPARK_RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
  428. };
  429. #endif
  430. #ifdef C10_MPARK_TRANSPARENT_OPERATORS
  431. using greater_equal = std::greater_equal<>;
  432. #else
  433. struct greater_equal {
  434. template <typename Lhs, typename Rhs>
  435. inline constexpr auto operator()(Lhs&& lhs, Rhs&& rhs) const
  436. C10_MPARK_RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
  437. };
  438. #endif
  439. } // namespace cpp14
  440. inline namespace cpp17 {
  441. // <type_traits>
  442. template <bool B>
  443. using bool_constant = std::integral_constant<bool, B>;
  444. template <typename...>
  445. struct voider : identity<void> {};
  446. template <typename... Ts>
  447. using void_t = typename voider<Ts...>::type;
  448. namespace detail_ {
  449. namespace swappable {
  450. using std::swap;
  451. template <typename T>
  452. struct is_swappable {
  453. private:
  454. template <
  455. typename U,
  456. typename = decltype(swap(std::declval<U&>(), std::declval<U&>()))>
  457. inline static std::true_type test(int);
  458. template <typename U>
  459. inline static std::false_type test(...);
  460. public:
  461. static constexpr bool value = decltype(test<T>(0))::value;
  462. };
  463. template <bool IsSwappable, typename T>
  464. struct is_nothrow_swappable {
  465. static constexpr bool value =
  466. noexcept(swap(std::declval<T&>(), std::declval<T&>()));
  467. };
  468. template <typename T>
  469. struct is_nothrow_swappable<false, T> : std::false_type {};
  470. } // namespace swappable
  471. } // namespace detail_
  472. using detail_::swappable::is_swappable;
  473. template <typename T>
  474. using is_nothrow_swappable =
  475. detail_::swappable::is_nothrow_swappable<is_swappable<T>::value, T>;
  476. // <functional>
  477. namespace detail_ {
  478. template <typename T>
  479. struct is_reference_wrapper : std::false_type {};
  480. template <typename T>
  481. struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
  482. template <bool, int>
  483. struct Invoke;
  484. template <>
  485. struct Invoke<true /* pmf */, 0 /* is_base_of */> {
  486. template <typename R, typename T, typename Arg, typename... Args>
  487. inline static constexpr auto invoke(R T::*pmf, Arg&& arg, Args&&... args)
  488. C10_MPARK_RETURN(
  489. (lib::forward<Arg>(arg).*pmf)(lib::forward<Args>(args)...))
  490. };
  491. template <>
  492. struct Invoke<true /* pmf */, 1 /* is_reference_wrapper */> {
  493. template <typename R, typename T, typename Arg, typename... Args>
  494. inline static constexpr auto invoke(R T::*pmf, Arg&& arg, Args&&... args)
  495. C10_MPARK_RETURN(
  496. (lib::forward<Arg>(arg).get().*pmf)(lib::forward<Args>(args)...))
  497. };
  498. template <>
  499. struct Invoke<true /* pmf */, 2 /* otherwise */> {
  500. template <typename R, typename T, typename Arg, typename... Args>
  501. inline static constexpr auto invoke(R T::*pmf, Arg&& arg, Args&&... args)
  502. C10_MPARK_RETURN(
  503. ((*lib::forward<Arg>(arg)).*pmf)(lib::forward<Args>(args)...))
  504. };
  505. template <>
  506. struct Invoke<false /* pmo */, 0 /* is_base_of */> {
  507. template <typename R, typename T, typename Arg>
  508. inline static constexpr auto invoke(R T::*pmo, Arg&& arg)
  509. C10_MPARK_RETURN(lib::forward<Arg>(arg).*pmo)
  510. };
  511. template <>
  512. struct Invoke<false /* pmo */, 1 /* is_reference_wrapper */> {
  513. template <typename R, typename T, typename Arg>
  514. inline static constexpr auto invoke(R T::*pmo, Arg&& arg)
  515. C10_MPARK_RETURN(lib::forward<Arg>(arg).get().*pmo)
  516. };
  517. template <>
  518. struct Invoke<false /* pmo */, 2 /* otherwise */> {
  519. template <typename R, typename T, typename Arg>
  520. inline static constexpr auto invoke(R T::*pmo, Arg&& arg)
  521. C10_MPARK_RETURN((*lib::forward<Arg>(arg)).*pmo)
  522. };
  523. template <typename R, typename T, typename Arg, typename... Args>
  524. inline constexpr auto invoke(R T::*f, Arg&& arg, Args&&... args)
  525. C10_MPARK_RETURN(
  526. Invoke<
  527. std::is_function<R>::value,
  528. (std::is_base_of<T, lib::decay_t<Arg>>::value ? 0
  529. : is_reference_wrapper<lib::decay_t<Arg>>::value ? 1
  530. : 2)>::
  531. invoke(f, lib::forward<Arg>(arg), lib::forward<Args>(args)...))
  532. #ifdef _MSC_VER
  533. #pragma warning(push)
  534. #pragma warning(disable : 4100)
  535. #endif
  536. template <typename F, typename... Args>
  537. inline constexpr auto invoke(F&& f, Args&&... args)
  538. C10_MPARK_RETURN(lib::forward<F>(f)(lib::forward<Args>(args)...))
  539. #ifdef _MSC_VER
  540. #pragma warning(pop)
  541. #endif
  542. } // namespace detail_
  543. template <typename F, typename... Args>
  544. inline constexpr auto invoke(F&& f, Args&&... args) C10_MPARK_RETURN(
  545. detail_::invoke(lib::forward<F>(f), lib::forward<Args>(args)...))
  546. namespace detail_ {
  547. template <typename Void, typename, typename...>
  548. struct invoke_result {};
  549. template <typename F, typename... Args>
  550. struct invoke_result<
  551. void_t<decltype(lib::invoke(std::declval<F>(), std::declval<Args>()...))>,
  552. F,
  553. Args...>
  554. : identity<decltype(lib::invoke(
  555. std::declval<F>(), std::declval<Args>()...))> {};
  556. } // namespace detail_
  557. template <typename F, typename... Args>
  558. using invoke_result = detail_::invoke_result<void, F, Args...>;
  559. template <typename F, typename... Args>
  560. using invoke_result_t = typename invoke_result<F, Args...>::type;
  561. namespace detail_ {
  562. template <typename Void, typename, typename...>
  563. struct is_invocable : std::false_type {};
  564. template <typename F, typename... Args>
  565. struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
  566. : std::true_type {};
  567. template <typename Void, typename, typename, typename...>
  568. struct is_invocable_r : std::false_type {};
  569. template <typename R, typename F, typename... Args>
  570. struct is_invocable_r<void_t<invoke_result_t<F, Args...>>, R, F, Args...>
  571. : std::is_convertible<invoke_result_t<F, Args...>, R> {};
  572. } // namespace detail_
  573. template <typename F, typename... Args>
  574. using is_invocable = detail_::is_invocable<void, F, Args...>;
  575. template <typename R, typename F, typename... Args>
  576. using is_invocable_r = detail_::is_invocable_r<void, R, F, Args...>;
  577. namespace detail_ {
  578. template <bool Invocable, typename F, typename... Args>
  579. struct is_nothrow_invocable {
  580. static constexpr bool value =
  581. noexcept(lib::invoke(std::declval<F>(), std::declval<Args>()...));
  582. };
  583. template <typename F, typename... Args>
  584. struct is_nothrow_invocable<false, F, Args...> : std::false_type {};
  585. template <bool Invocable, typename R, typename F, typename... Args>
  586. struct is_nothrow_invocable_r {
  587. private:
  588. inline static R impl() {
  589. return lib::invoke(std::declval<F>(), std::declval<Args>()...);
  590. }
  591. public:
  592. static constexpr bool value = noexcept(impl());
  593. };
  594. template <typename R, typename F, typename... Args>
  595. struct is_nothrow_invocable_r<false, R, F, Args...> : std::false_type {};
  596. } // namespace detail_
  597. template <typename F, typename... Args>
  598. using is_nothrow_invocable =
  599. detail_::is_nothrow_invocable<is_invocable<F, Args...>::value, F, Args...>;
  600. template <typename R, typename F, typename... Args>
  601. using is_nothrow_invocable_r = detail_::
  602. is_nothrow_invocable_r<is_invocable_r<R, F, Args...>::value, R, F, Args...>;
  603. // <memory>
  604. #ifdef C10_MPARK_BUILTIN_ADDRESSOF
  605. template <typename T>
  606. inline constexpr T* addressof(T& arg) noexcept {
  607. return __builtin_addressof(arg);
  608. }
  609. #else
  610. namespace detail_ {
  611. namespace has_addressof_impl {
  612. struct fail;
  613. template <typename T>
  614. inline fail operator&(T&&);
  615. template <typename T>
  616. inline static constexpr bool impl() {
  617. return (std::is_class<T>::value || std::is_union<T>::value) &&
  618. !std::is_same<decltype(&std::declval<T&>()), fail>::value;
  619. }
  620. } // namespace has_addressof_impl
  621. template <typename T>
  622. using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
  623. template <typename T>
  624. inline constexpr T* addressof(T& arg, std::true_type) noexcept {
  625. return std::addressof(arg);
  626. }
  627. template <typename T>
  628. inline constexpr T* addressof(T& arg, std::false_type) noexcept {
  629. return &arg;
  630. }
  631. } // namespace detail_
  632. template <typename T>
  633. inline constexpr T* addressof(T& arg) noexcept {
  634. return detail_::addressof(arg, detail_::has_addressof<T>{});
  635. }
  636. #endif
  637. template <typename T>
  638. inline constexpr T* addressof(const T&&) = delete;
  639. } // namespace cpp17
  640. template <typename T>
  641. struct remove_all_extents : identity<T> {};
  642. template <typename T, std::size_t N>
  643. struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
  644. template <typename T>
  645. using remove_all_extents_t = typename remove_all_extents<T>::type;
  646. template <std::size_t N>
  647. using size_constant = std::integral_constant<std::size_t, N>;
  648. template <std::size_t I, typename T>
  649. struct indexed_type : size_constant<I> {
  650. using type = T;
  651. };
  652. template <bool... Bs>
  653. using all = std::is_same<
  654. integer_sequence<bool, true, Bs...>,
  655. integer_sequence<bool, Bs..., true>>;
  656. #ifdef C10_MPARK_TYPE_PACK_ELEMENT
  657. template <std::size_t I, typename... Ts>
  658. using type_pack_element_t = __type_pack_element<I, Ts...>;
  659. #else
  660. template <std::size_t I, typename... Ts>
  661. struct type_pack_element_impl {
  662. private:
  663. template <typename>
  664. struct set;
  665. template <std::size_t... Is>
  666. struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
  667. template <typename T>
  668. inline static std::enable_if<true, T> impl(indexed_type<I, T>);
  669. inline static std::enable_if<false> impl(...);
  670. public:
  671. using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
  672. };
  673. template <std::size_t I, typename... Ts>
  674. using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
  675. template <std::size_t I, typename... Ts>
  676. using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
  677. #endif
  678. #ifdef C10_MPARK_TRIVIALITY_TYPE_TRAITS
  679. using std::is_trivially_copy_assignable;
  680. using std::is_trivially_copy_constructible;
  681. using std::is_trivially_move_assignable;
  682. using std::is_trivially_move_constructible;
  683. #else
  684. template <typename T>
  685. struct is_trivially_copy_constructible
  686. : bool_constant<std::is_copy_constructible<T>::value&& __has_trivial_copy(
  687. T)> {};
  688. template <typename T>
  689. struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
  690. template <typename T>
  691. struct is_trivially_copy_assignable
  692. : bool_constant<std::is_copy_assignable<T>::value&& __has_trivial_assign(
  693. T)> {};
  694. template <typename T>
  695. struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
  696. #endif
  697. template <typename T, bool>
  698. struct dependent_type : T {};
  699. template <typename Is, std::size_t J>
  700. struct push_back;
  701. template <typename Is, std::size_t J>
  702. using push_back_t = typename push_back<Is, J>::type;
  703. template <std::size_t... Is, std::size_t J>
  704. struct push_back<index_sequence<Is...>, J> {
  705. using type = index_sequence<Is..., J>;
  706. };
  707. } // namespace lib
  708. } // namespace c10
  709. #undef C10_MPARK_RETURN
  710. #endif // C10_MPARK_LIB_HPP
  711. namespace c10 {
  712. #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
  713. #define AUTO auto
  714. #define AUTO_RETURN(...) \
  715. { return __VA_ARGS__; }
  716. #define AUTO_REFREF auto&&
  717. #define AUTO_REFREF_RETURN(...) \
  718. { return __VA_ARGS__; }
  719. #define DECLTYPE_AUTO decltype(auto)
  720. #define DECLTYPE_AUTO_RETURN(...) \
  721. { return __VA_ARGS__; }
  722. #else
  723. #define AUTO auto
  724. #define AUTO_RETURN(...) \
  725. ->lib::decay_t<decltype(__VA_ARGS__)> { \
  726. return __VA_ARGS__; \
  727. }
  728. #define AUTO_REFREF auto
  729. #define AUTO_REFREF_RETURN(...) \
  730. ->decltype((__VA_ARGS__)) { \
  731. static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
  732. return __VA_ARGS__; \
  733. }
  734. #define DECLTYPE_AUTO auto
  735. #define DECLTYPE_AUTO_RETURN(...) \
  736. ->decltype(__VA_ARGS__) { \
  737. return __VA_ARGS__; \
  738. }
  739. #endif
  740. class bad_variant_access : public std::exception {
  741. public:
  742. const char* what() const noexcept override {
  743. return "bad_variant_access";
  744. }
  745. };
  746. [[noreturn]] inline void throw_bad_variant_access() {
  747. #ifdef C10_MPARK_EXCEPTIONS
  748. throw bad_variant_access{};
  749. #else
  750. std::terminate();
  751. C10_MPARK_BUILTIN_UNREACHABLE;
  752. #endif
  753. }
  754. template <typename... Ts>
  755. class variant;
  756. template <typename T>
  757. struct variant_size;
  758. #ifdef C10_MPARK_VARIABLE_TEMPLATES
  759. template <typename T>
  760. constexpr std::size_t variant_size_v = variant_size<T>::value;
  761. #endif
  762. template <typename T>
  763. struct variant_size<const T> : variant_size<T> {};
  764. template <typename T>
  765. struct variant_size<volatile T> : variant_size<T> {};
  766. template <typename T>
  767. struct variant_size<const volatile T> : variant_size<T> {};
  768. template <typename... Ts>
  769. struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
  770. template <std::size_t I, typename T>
  771. struct variant_alternative;
  772. template <std::size_t I, typename T>
  773. using variant_alternative_t = typename variant_alternative<I, T>::type;
  774. template <std::size_t I, typename T>
  775. struct variant_alternative<I, const T>
  776. : std::add_const<variant_alternative_t<I, T>> {};
  777. template <std::size_t I, typename T>
  778. struct variant_alternative<I, volatile T>
  779. : std::add_volatile<variant_alternative_t<I, T>> {};
  780. template <std::size_t I, typename T>
  781. struct variant_alternative<I, const volatile T>
  782. : std::add_cv<variant_alternative_t<I, T>> {};
  783. template <std::size_t I, typename... Ts>
  784. struct variant_alternative<I, variant<Ts...>> {
  785. static_assert(
  786. I < sizeof...(Ts),
  787. "index out of bounds in `std::variant_alternative<>`");
  788. using type = lib::type_pack_element_t<I, Ts...>;
  789. };
  790. constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
  791. namespace detail_ {
  792. constexpr std::size_t not_found = static_cast<std::size_t>(-1);
  793. constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
  794. #ifdef C10_MPARK_CPP14_CONSTEXPR
  795. template <typename T, typename... Ts>
  796. inline constexpr std::size_t find_index() {
  797. constexpr lib::array<bool, sizeof...(Ts)> matches = {
  798. {std::is_same<T, Ts>::value...}};
  799. std::size_t result = not_found;
  800. for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
  801. if (matches[i]) {
  802. if (result != not_found) {
  803. return ambiguous;
  804. }
  805. result = i;
  806. }
  807. }
  808. return result;
  809. }
  810. #else
  811. inline constexpr std::size_t find_index_impl(std::size_t result, std::size_t) {
  812. return result;
  813. }
  814. template <typename... Bs>
  815. inline constexpr std::size_t find_index_impl(
  816. std::size_t result,
  817. std::size_t idx,
  818. bool b,
  819. Bs... bs) {
  820. return b
  821. ? (result != not_found ? ambiguous : find_index_impl(idx, idx + 1, bs...))
  822. : find_index_impl(result, idx + 1, bs...);
  823. }
  824. template <typename T, typename... Ts>
  825. inline constexpr std::size_t find_index() {
  826. return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
  827. }
  828. #endif
  829. template <std::size_t I>
  830. using find_index_sfinae_impl =
  831. lib::enable_if_t<I != not_found && I != ambiguous, lib::size_constant<I>>;
  832. template <typename T, typename... Ts>
  833. using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
  834. template <std::size_t I>
  835. struct find_index_checked_impl : lib::size_constant<I> {
  836. static_assert(I != not_found, "the specified type is not found.");
  837. static_assert(I != ambiguous, "the specified type is ambiguous.");
  838. };
  839. template <typename T, typename... Ts>
  840. using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
  841. struct valueless_t {};
  842. enum class Trait { TriviallyAvailable, Available, Unavailable };
  843. template <
  844. typename T,
  845. template <typename>
  846. class IsTriviallyAvailable,
  847. template <typename>
  848. class IsAvailable>
  849. inline constexpr Trait trait() {
  850. return IsTriviallyAvailable<T>::value ? Trait::TriviallyAvailable
  851. : IsAvailable<T>::value ? Trait::Available
  852. : Trait::Unavailable;
  853. }
  854. #ifdef C10_MPARK_CPP14_CONSTEXPR
  855. template <typename... Traits>
  856. inline constexpr Trait common_trait(Traits... traits_) {
  857. Trait result = Trait::TriviallyAvailable;
  858. lib::array<Trait, sizeof...(Traits)> traits = {{traits_...}};
  859. for (std::size_t i = 0; i < sizeof...(Traits); ++i) {
  860. Trait t = traits[i];
  861. if (static_cast<int>(t) > static_cast<int>(result)) {
  862. result = t;
  863. }
  864. }
  865. return result;
  866. }
  867. #else
  868. inline constexpr Trait common_trait_impl(Trait result) {
  869. return result;
  870. }
  871. template <typename... Traits>
  872. inline constexpr Trait common_trait_impl(Trait result, Trait t, Traits... ts) {
  873. return static_cast<int>(t) > static_cast<int>(result)
  874. ? common_trait_impl(t, ts...)
  875. : common_trait_impl(result, ts...);
  876. }
  877. template <typename... Traits>
  878. inline constexpr Trait common_trait(Traits... ts) {
  879. return common_trait_impl(Trait::TriviallyAvailable, ts...);
  880. }
  881. #endif
  882. template <typename... Ts>
  883. struct traits {
  884. static constexpr Trait copy_constructible_trait =
  885. common_trait(trait<
  886. Ts,
  887. lib::is_trivially_copy_constructible,
  888. std::is_copy_constructible>()...);
  889. static constexpr Trait move_constructible_trait =
  890. common_trait(trait<
  891. Ts,
  892. lib::is_trivially_move_constructible,
  893. std::is_move_constructible>()...);
  894. static constexpr Trait copy_assignable_trait = common_trait(
  895. copy_constructible_trait,
  896. trait<
  897. Ts,
  898. lib::is_trivially_copy_assignable,
  899. std::is_copy_assignable>()...);
  900. static constexpr Trait move_assignable_trait = common_trait(
  901. move_constructible_trait,
  902. trait<
  903. Ts,
  904. lib::is_trivially_move_assignable,
  905. std::is_move_assignable>()...);
  906. static constexpr Trait destructible_trait = common_trait(
  907. trait<Ts, std::is_trivially_destructible, std::is_destructible>()...);
  908. };
  909. namespace access {
  910. struct recursive_union {
  911. #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
  912. template <typename V>
  913. inline static constexpr auto&& get_alt(V&& v, in_place_index_t<0>) {
  914. return lib::forward<V>(v).head_;
  915. }
  916. template <typename V, std::size_t I>
  917. inline static constexpr auto&& get_alt(V&& v, in_place_index_t<I>) {
  918. return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
  919. }
  920. #else
  921. template <std::size_t I, bool Dummy = true>
  922. struct get_alt_impl {
  923. template <typename V>
  924. inline constexpr AUTO_REFREF operator()(V&& v) const
  925. AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
  926. };
  927. template <bool Dummy>
  928. struct get_alt_impl<0, Dummy> {
  929. template <typename V>
  930. inline constexpr AUTO_REFREF operator()(V&& v) const
  931. AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
  932. };
  933. template <typename V, std::size_t I>
  934. inline static constexpr AUTO_REFREF get_alt(V&& v, in_place_index_t<I>)
  935. AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
  936. #endif
  937. };
  938. struct base {
  939. template <std::size_t I, typename V>
  940. inline static constexpr AUTO_REFREF get_alt(V&& v)
  941. #ifdef _MSC_VER
  942. AUTO_REFREF_RETURN(recursive_union::get_alt(
  943. lib::forward<V>(v).data_,
  944. in_place_index_t<I>{}))
  945. #else
  946. AUTO_REFREF_RETURN(recursive_union::get_alt(
  947. data(lib::forward<V>(v)),
  948. in_place_index_t<I>{}))
  949. #endif
  950. };
  951. struct variant {
  952. template <std::size_t I, typename V>
  953. inline static constexpr AUTO_REFREF get_alt(V&& v)
  954. AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
  955. };
  956. } // namespace access
  957. namespace visitation {
  958. #if defined(C10_MPARK_CPP14_CONSTEXPR) && !defined(_MSC_VER)
  959. #define C10_MPARK_VARIANT_SWITCH_VISIT
  960. #endif
  961. struct base {
  962. template <typename Visitor, typename... Vs>
  963. using dispatch_result_t = decltype(lib::invoke(
  964. std::declval<Visitor>(),
  965. access::base::get_alt<0>(std::declval<Vs>())...));
  966. template <typename Expected>
  967. struct expected {
  968. template <typename Actual>
  969. inline static constexpr bool but_got() {
  970. return std::is_same<Expected, Actual>::value;
  971. }
  972. };
  973. template <typename Expected, typename Actual>
  974. struct visit_return_type_check {
  975. static_assert(
  976. expected<Expected>::template but_got<Actual>(),
  977. "`visit` requires the visitor to have a single return type");
  978. template <typename Visitor, typename... Alts>
  979. inline static constexpr DECLTYPE_AUTO invoke(
  980. Visitor&& visitor,
  981. Alts&&... alts)
  982. DECLTYPE_AUTO_RETURN(lib::invoke(
  983. lib::forward<Visitor>(visitor),
  984. lib::forward<Alts>(alts)...))
  985. };
  986. #ifdef C10_MPARK_VARIANT_SWITCH_VISIT
  987. template <bool B, typename R, typename... ITs>
  988. struct dispatcher;
  989. template <typename R, typename... ITs>
  990. struct dispatcher<false, R, ITs...> {
  991. template <std::size_t B, typename F, typename... Vs>
  992. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch(
  993. F&&,
  994. typename ITs::type&&...,
  995. Vs&&...) {
  996. C10_MPARK_BUILTIN_UNREACHABLE;
  997. }
  998. template <std::size_t I, typename F, typename... Vs>
  999. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F&&, Vs&&...) {
  1000. C10_MPARK_BUILTIN_UNREACHABLE;
  1001. }
  1002. template <std::size_t B, typename F, typename... Vs>
  1003. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_at(
  1004. std::size_t,
  1005. F&&,
  1006. Vs&&...) {
  1007. C10_MPARK_BUILTIN_UNREACHABLE;
  1008. }
  1009. };
  1010. template <typename R, typename... ITs>
  1011. struct dispatcher<true, R, ITs...> {
  1012. template <std::size_t B, typename F>
  1013. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch(
  1014. F&& f,
  1015. typename ITs::type&&... visited_vs) {
  1016. using Expected = R;
  1017. using Actual = decltype(lib::invoke(
  1018. lib::forward<F>(f),
  1019. access::base::get_alt<ITs::value>(
  1020. lib::forward<typename ITs::type>(visited_vs))...));
  1021. return visit_return_type_check<Expected, Actual>::invoke(
  1022. lib::forward<F>(f),
  1023. access::base::get_alt<ITs::value>(
  1024. lib::forward<typename ITs::type>(visited_vs))...);
  1025. }
  1026. template <std::size_t B, typename F, typename V, typename... Vs>
  1027. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch(
  1028. F&& f,
  1029. typename ITs::type&&... visited_vs,
  1030. V&& v,
  1031. Vs&&... vs) {
  1032. #define C10_MPARK_DISPATCH(I) \
  1033. dispatcher< \
  1034. (I < lib::decay_t<V>::size()), \
  1035. R, \
  1036. ITs..., \
  1037. lib::indexed_type<I, V>>:: \
  1038. template dispatch<0>( \
  1039. lib::forward<F>(f), \
  1040. lib::forward<typename ITs::type>(visited_vs)..., \
  1041. lib::forward<V>(v), \
  1042. lib::forward<Vs>(vs)...)
  1043. #define C10_MPARK_DEFAULT(I) \
  1044. dispatcher<(I < lib::decay_t<V>::size()), R, ITs...>::template dispatch<I>( \
  1045. lib::forward<F>(f), \
  1046. lib::forward<typename ITs::type>(visited_vs)..., \
  1047. lib::forward<V>(v), \
  1048. lib::forward<Vs>(vs)...)
  1049. switch (v.index()) {
  1050. case B + 0:
  1051. return C10_MPARK_DISPATCH(B + 0);
  1052. case B + 1:
  1053. return C10_MPARK_DISPATCH(B + 1);
  1054. case B + 2:
  1055. return C10_MPARK_DISPATCH(B + 2);
  1056. case B + 3:
  1057. return C10_MPARK_DISPATCH(B + 3);
  1058. case B + 4:
  1059. return C10_MPARK_DISPATCH(B + 4);
  1060. case B + 5:
  1061. return C10_MPARK_DISPATCH(B + 5);
  1062. case B + 6:
  1063. return C10_MPARK_DISPATCH(B + 6);
  1064. case B + 7:
  1065. return C10_MPARK_DISPATCH(B + 7);
  1066. case B + 8:
  1067. return C10_MPARK_DISPATCH(B + 8);
  1068. case B + 9:
  1069. return C10_MPARK_DISPATCH(B + 9);
  1070. case B + 10:
  1071. return C10_MPARK_DISPATCH(B + 10);
  1072. case B + 11:
  1073. return C10_MPARK_DISPATCH(B + 11);
  1074. case B + 12:
  1075. return C10_MPARK_DISPATCH(B + 12);
  1076. case B + 13:
  1077. return C10_MPARK_DISPATCH(B + 13);
  1078. case B + 14:
  1079. return C10_MPARK_DISPATCH(B + 14);
  1080. case B + 15:
  1081. return C10_MPARK_DISPATCH(B + 15);
  1082. case B + 16:
  1083. return C10_MPARK_DISPATCH(B + 16);
  1084. case B + 17:
  1085. return C10_MPARK_DISPATCH(B + 17);
  1086. case B + 18:
  1087. return C10_MPARK_DISPATCH(B + 18);
  1088. case B + 19:
  1089. return C10_MPARK_DISPATCH(B + 19);
  1090. case B + 20:
  1091. return C10_MPARK_DISPATCH(B + 20);
  1092. case B + 21:
  1093. return C10_MPARK_DISPATCH(B + 21);
  1094. case B + 22:
  1095. return C10_MPARK_DISPATCH(B + 22);
  1096. case B + 23:
  1097. return C10_MPARK_DISPATCH(B + 23);
  1098. case B + 24:
  1099. return C10_MPARK_DISPATCH(B + 24);
  1100. case B + 25:
  1101. return C10_MPARK_DISPATCH(B + 25);
  1102. case B + 26:
  1103. return C10_MPARK_DISPATCH(B + 26);
  1104. case B + 27:
  1105. return C10_MPARK_DISPATCH(B + 27);
  1106. case B + 28:
  1107. return C10_MPARK_DISPATCH(B + 28);
  1108. case B + 29:
  1109. return C10_MPARK_DISPATCH(B + 29);
  1110. case B + 30:
  1111. return C10_MPARK_DISPATCH(B + 30);
  1112. case B + 31:
  1113. return C10_MPARK_DISPATCH(B + 31);
  1114. default:
  1115. return C10_MPARK_DEFAULT(B + 32);
  1116. }
  1117. #undef C10_MPARK_DEFAULT
  1118. #undef C10_MPARK_DISPATCH
  1119. }
  1120. template <std::size_t I, typename F, typename... Vs>
  1121. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_case(
  1122. F&& f,
  1123. Vs&&... vs) {
  1124. using Expected = R;
  1125. using Actual = decltype(lib::invoke(
  1126. lib::forward<F>(f),
  1127. access::base::get_alt<I>(lib::forward<Vs>(vs))...));
  1128. return visit_return_type_check<Expected, Actual>::invoke(
  1129. lib::forward<F>(f),
  1130. access::base::get_alt<I>(lib::forward<Vs>(vs))...);
  1131. }
  1132. template <std::size_t B, typename F, typename V, typename... Vs>
  1133. C10_MPARK_ALWAYS_INLINE static constexpr R dispatch_at(
  1134. std::size_t index,
  1135. F&& f,
  1136. V&& v,
  1137. Vs&&... vs) {
  1138. static_assert(
  1139. lib::all<(
  1140. lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...>::value,
  1141. "all of the variants must be the same size.");
  1142. #define C10_MPARK_DISPATCH_AT(I) \
  1143. dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_case<I>( \
  1144. lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
  1145. #define C10_MPARK_DEFAULT(I) \
  1146. dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_at<I>( \
  1147. index, lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
  1148. switch (index) {
  1149. case B + 0:
  1150. return C10_MPARK_DISPATCH_AT(B + 0);
  1151. case B + 1:
  1152. return C10_MPARK_DISPATCH_AT(B + 1);
  1153. case B + 2:
  1154. return C10_MPARK_DISPATCH_AT(B + 2);
  1155. case B + 3:
  1156. return C10_MPARK_DISPATCH_AT(B + 3);
  1157. case B + 4:
  1158. return C10_MPARK_DISPATCH_AT(B + 4);
  1159. case B + 5:
  1160. return C10_MPARK_DISPATCH_AT(B + 5);
  1161. case B + 6:
  1162. return C10_MPARK_DISPATCH_AT(B + 6);
  1163. case B + 7:
  1164. return C10_MPARK_DISPATCH_AT(B + 7);
  1165. case B + 8:
  1166. return C10_MPARK_DISPATCH_AT(B + 8);
  1167. case B + 9:
  1168. return C10_MPARK_DISPATCH_AT(B + 9);
  1169. case B + 10:
  1170. return C10_MPARK_DISPATCH_AT(B + 10);
  1171. case B + 11:
  1172. return C10_MPARK_DISPATCH_AT(B + 11);
  1173. case B + 12:
  1174. return C10_MPARK_DISPATCH_AT(B + 12);
  1175. case B + 13:
  1176. return C10_MPARK_DISPATCH_AT(B + 13);
  1177. case B + 14:
  1178. return C10_MPARK_DISPATCH_AT(B + 14);
  1179. case B + 15:
  1180. return C10_MPARK_DISPATCH_AT(B + 15);
  1181. case B + 16:
  1182. return C10_MPARK_DISPATCH_AT(B + 16);
  1183. case B + 17:
  1184. return C10_MPARK_DISPATCH_AT(B + 17);
  1185. case B + 18:
  1186. return C10_MPARK_DISPATCH_AT(B + 18);
  1187. case B + 19:
  1188. return C10_MPARK_DISPATCH_AT(B + 19);
  1189. case B + 20:
  1190. return C10_MPARK_DISPATCH_AT(B + 20);
  1191. case B + 21:
  1192. return C10_MPARK_DISPATCH_AT(B + 21);
  1193. case B + 22:
  1194. return C10_MPARK_DISPATCH_AT(B + 22);
  1195. case B + 23:
  1196. return C10_MPARK_DISPATCH_AT(B + 23);
  1197. case B + 24:
  1198. return C10_MPARK_DISPATCH_AT(B + 24);
  1199. case B + 25:
  1200. return C10_MPARK_DISPATCH_AT(B + 25);
  1201. case B + 26:
  1202. return C10_MPARK_DISPATCH_AT(B + 26);
  1203. case B + 27:
  1204. return C10_MPARK_DISPATCH_AT(B + 27);
  1205. case B + 28:
  1206. return C10_MPARK_DISPATCH_AT(B + 28);
  1207. case B + 29:
  1208. return C10_MPARK_DISPATCH_AT(B + 29);
  1209. case B + 30:
  1210. return C10_MPARK_DISPATCH_AT(B + 30);
  1211. case B + 31:
  1212. return C10_MPARK_DISPATCH_AT(B + 31);
  1213. default:
  1214. return C10_MPARK_DEFAULT(B + 32);
  1215. }
  1216. #undef C10_MPARK_DEFAULT
  1217. #undef C10_MPARK_DISPATCH_AT
  1218. }
  1219. };
  1220. #else
  1221. template <typename T>
  1222. inline static constexpr const T& at(const T& elem) noexcept {
  1223. return elem;
  1224. }
  1225. template <typename T, std::size_t N, typename... Is>
  1226. inline static constexpr const lib::remove_all_extents_t<T>& at(
  1227. const lib::array<T, N>& elems,
  1228. std::size_t i,
  1229. Is... is) noexcept {
  1230. return at(elems[i], is...);
  1231. }
  1232. template <typename F, typename... Fs>
  1233. inline static constexpr lib::array<lib::decay_t<F>, sizeof...(Fs) + 1>
  1234. make_farray(F&& f, Fs&&... fs) {
  1235. return {{lib::forward<F>(f), lib::forward<Fs>(fs)...}};
  1236. }
  1237. template <typename F, typename... Vs>
  1238. struct make_fmatrix_impl {
  1239. template <std::size_t... Is>
  1240. inline static constexpr dispatch_result_t<F, Vs...> dispatch(
  1241. F&& f,
  1242. Vs&&... vs) {
  1243. using Expected = dispatch_result_t<F, Vs...>;
  1244. using Actual = decltype(lib::invoke(
  1245. lib::forward<F>(f),
  1246. access::base::get_alt<Is>(lib::forward<Vs>(vs))...));
  1247. return visit_return_type_check<Expected, Actual>::invoke(
  1248. lib::forward<F>(f),
  1249. access::base::get_alt<Is>(lib::forward<Vs>(vs))...);
  1250. }
  1251. #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
  1252. template <std::size_t... Is>
  1253. inline static constexpr auto impl(lib::index_sequence<Is...>) {
  1254. return &dispatch<Is...>;
  1255. }
  1256. template <typename Is, std::size_t... Js, typename... Ls>
  1257. inline static constexpr auto impl(
  1258. Is,
  1259. lib::index_sequence<Js...>,
  1260. Ls... ls) {
  1261. return make_farray(impl(lib::push_back_t<Is, Js>{}, ls...)...);
  1262. }
  1263. #else
  1264. template <typename...>
  1265. struct impl;
  1266. template <std::size_t... Is>
  1267. struct impl<lib::index_sequence<Is...>> {
  1268. inline constexpr AUTO operator()() const AUTO_RETURN(&dispatch<Is...>)
  1269. };
  1270. template <typename Is, std::size_t... Js, typename... Ls>
  1271. struct impl<Is, lib::index_sequence<Js...>, Ls...> {
  1272. inline constexpr AUTO operator()() const
  1273. AUTO_RETURN(make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
  1274. };
  1275. #endif
  1276. };
  1277. #ifdef C10_MPARK_RETURN_TYPE_DEDUCTION
  1278. template <typename F, typename... Vs>
  1279. inline static constexpr auto make_fmatrix() {
  1280. return make_fmatrix_impl<F, Vs...>::impl(
  1281. lib::index_sequence<>{},
  1282. lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
  1283. }
  1284. #else
  1285. template <typename F, typename... Vs>
  1286. inline static constexpr AUTO make_fmatrix()
  1287. AUTO_RETURN(typename make_fmatrix_impl<F, Vs...>::template impl<
  1288. lib::index_sequence<>,
  1289. lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
  1290. #endif
  1291. template <typename F, typename... Vs>
  1292. struct make_fdiagonal_impl {
  1293. template <std::size_t I>
  1294. inline static constexpr dispatch_result_t<F, Vs...> dispatch(
  1295. F&& f,
  1296. Vs&&... vs) {
  1297. using Expected = dispatch_result_t<F, Vs...>;
  1298. using Actual = decltype(lib::invoke(
  1299. lib::forward<F>(f),
  1300. access::base::get_alt<I>(lib::forward<Vs>(vs))...));
  1301. return visit_return_type_check<Expected, Actual>::invoke(
  1302. lib::forward<F>(f),
  1303. access::base::get_alt<I>(lib::forward<Vs>(vs))...);
  1304. }
  1305. template <std::size_t... Is>
  1306. inline static constexpr AUTO impl(lib::index_sequence<Is...>)
  1307. AUTO_RETURN(make_farray(&dispatch<Is>...))
  1308. };
  1309. template <typename F, typename V, typename... Vs>
  1310. inline static constexpr auto make_fdiagonal()
  1311. -> decltype(make_fdiagonal_impl<F, V, Vs...>::impl(
  1312. lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
  1313. static_assert(
  1314. lib::all<(
  1315. lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...>::value,
  1316. "all of the variants must be the same size.");
  1317. return make_fdiagonal_impl<F, V, Vs...>::impl(
  1318. lib::make_index_sequence<lib::decay_t<V>::size()>{});
  1319. }
  1320. #endif
  1321. };
  1322. #if !defined(C10_MPARK_VARIANT_SWITCH_VISIT) && \
  1323. (!defined(_MSC_VER) || _MSC_VER >= 1910)
  1324. template <typename F, typename... Vs>
  1325. using fmatrix_t = decltype(base::make_fmatrix<F, Vs...>());
  1326. template <typename F, typename... Vs>
  1327. struct fmatrix {
  1328. static constexpr fmatrix_t<F, Vs...> value = base::make_fmatrix<F, Vs...>();
  1329. };
  1330. template <typename F, typename... Vs>
  1331. constexpr fmatrix_t<F, Vs...> fmatrix<F, Vs...>::value;
  1332. template <typename F, typename... Vs>
  1333. using fdiagonal_t = decltype(base::make_fdiagonal<F, Vs...>());
  1334. template <typename F, typename... Vs>
  1335. struct fdiagonal {
  1336. static constexpr fdiagonal_t<F, Vs...> value =
  1337. base::make_fdiagonal<F, Vs...>();
  1338. };
  1339. template <typename F, typename... Vs>
  1340. constexpr fdiagonal_t<F, Vs...> fdiagonal<F, Vs...>::value;
  1341. #endif
  1342. struct alt {
  1343. template <typename Visitor, typename... Vs>
  1344. inline static constexpr DECLTYPE_AUTO visit_alt(Visitor&& visitor, Vs&&... vs)
  1345. #ifdef C10_MPARK_VARIANT_SWITCH_VISIT
  1346. DECLTYPE_AUTO_RETURN(base::dispatcher<
  1347. true,
  1348. base::dispatch_result_t<
  1349. Visitor,
  1350. decltype(as_base(lib::forward<Vs>(vs)))...>>::
  1351. template dispatch<0>(
  1352. lib::forward<Visitor>(visitor),
  1353. as_base(lib::forward<Vs>(vs))...))
  1354. #elif !defined(_MSC_VER) || _MSC_VER >= 1910
  1355. DECLTYPE_AUTO_RETURN(base::at(
  1356. fmatrix<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::value,
  1357. vs.index()...)(
  1358. lib::forward<Visitor>(visitor),
  1359. as_base(lib::forward<Vs>(vs))...))
  1360. #else
  1361. DECLTYPE_AUTO_RETURN(base::at(
  1362. base::make_fmatrix<
  1363. Visitor&&,
  1364. decltype(as_base(lib::forward<Vs>(vs)))...>(),
  1365. vs.index()...)(
  1366. lib::forward<Visitor>(visitor),
  1367. as_base(lib::forward<Vs>(vs))...))
  1368. #endif
  1369. template <typename Visitor, typename... Vs>
  1370. inline static constexpr DECLTYPE_AUTO
  1371. visit_alt_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
  1372. #ifdef C10_MPARK_VARIANT_SWITCH_VISIT
  1373. DECLTYPE_AUTO_RETURN(
  1374. base::dispatcher<
  1375. true,
  1376. base::dispatch_result_t<
  1377. Visitor,
  1378. decltype(as_base(lib::forward<Vs>(vs)))...>>::
  1379. template dispatch_at<0>(
  1380. index,
  1381. lib::forward<Visitor>(visitor),
  1382. as_base(lib::forward<Vs>(vs))...))
  1383. #elif !defined(_MSC_VER) || _MSC_VER >= 1910
  1384. DECLTYPE_AUTO_RETURN(base::at(
  1385. fdiagonal<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::
  1386. value,
  1387. index)(
  1388. lib::forward<Visitor>(visitor),
  1389. as_base(lib::forward<Vs>(vs))...))
  1390. #else
  1391. DECLTYPE_AUTO_RETURN(base::at(
  1392. base::make_fdiagonal<
  1393. Visitor&&,
  1394. decltype(as_base(lib::forward<Vs>(vs)))...>(),
  1395. index)(
  1396. lib::forward<Visitor>(visitor),
  1397. as_base(lib::forward<Vs>(vs))...))
  1398. #endif
  1399. };
  1400. struct variant {
  1401. private:
  1402. template <typename Visitor>
  1403. struct visitor {
  1404. template <typename... Values>
  1405. inline static constexpr bool does_not_handle() {
  1406. return lib::is_invocable<Visitor, Values...>::value;
  1407. }
  1408. };
  1409. template <typename Visitor, typename... Values>
  1410. struct visit_exhaustiveness_check {
  1411. static_assert(
  1412. visitor<Visitor>::template does_not_handle<Values...>(),
  1413. "`visit` requires the visitor to be exhaustive.");
  1414. inline static constexpr DECLTYPE_AUTO invoke(
  1415. Visitor&& visitor,
  1416. Values&&... values)
  1417. DECLTYPE_AUTO_RETURN(lib::invoke(
  1418. lib::forward<Visitor>(visitor),
  1419. lib::forward<Values>(values)...))
  1420. };
  1421. template <typename Visitor>
  1422. struct C10_MPARK_VISIBILITY_HIDDEN value_visitor {
  1423. Visitor&& visitor_;
  1424. template <typename... Alts>
  1425. inline constexpr DECLTYPE_AUTO operator()(Alts&&... alts) const
  1426. DECLTYPE_AUTO_RETURN(visit_exhaustiveness_check<
  1427. Visitor,
  1428. decltype((lib::forward<Alts>(alts).value))...>::
  1429. invoke(
  1430. lib::forward<Visitor>(visitor_),
  1431. lib::forward<Alts>(alts).value...))
  1432. };
  1433. template <typename Visitor>
  1434. inline static constexpr AUTO make_value_visitor(Visitor&& visitor)
  1435. AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
  1436. public
  1437. : template <typename Visitor, typename... Vs>
  1438. inline static constexpr DECLTYPE_AUTO
  1439. visit_alt(Visitor&& visitor, Vs&&... vs)
  1440. DECLTYPE_AUTO_RETURN(alt::visit_alt(
  1441. lib::forward<Visitor>(visitor),
  1442. lib::forward<Vs>(vs).impl_...))
  1443. template <typename Visitor, typename... Vs>
  1444. inline static constexpr DECLTYPE_AUTO
  1445. visit_alt_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
  1446. DECLTYPE_AUTO_RETURN(alt::visit_alt_at(
  1447. index,
  1448. lib::forward<Visitor>(visitor),
  1449. lib::forward<Vs>(vs).impl_...))
  1450. template <typename Visitor, typename... Vs>
  1451. inline static constexpr DECLTYPE_AUTO
  1452. visit_value(Visitor&& visitor, Vs&&... vs)
  1453. DECLTYPE_AUTO_RETURN(visit_alt(
  1454. make_value_visitor(lib::forward<Visitor>(visitor)),
  1455. lib::forward<Vs>(vs)...))
  1456. template <typename Visitor, typename... Vs>
  1457. inline static constexpr DECLTYPE_AUTO
  1458. visit_value_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
  1459. DECLTYPE_AUTO_RETURN(visit_alt_at(
  1460. index,
  1461. make_value_visitor(lib::forward<Visitor>(visitor)),
  1462. lib::forward<Vs>(vs)...))
  1463. };
  1464. } // namespace visitation
  1465. template <std::size_t Index, typename T>
  1466. struct alt {
  1467. using value_type = T;
  1468. #ifdef _MSC_VER
  1469. #pragma warning(push)
  1470. #pragma warning(disable : 4244)
  1471. #endif
  1472. template <typename... Args>
  1473. inline explicit constexpr alt(in_place_t, Args&&... args)
  1474. : value(lib::forward<Args>(args)...) {}
  1475. #ifdef _MSC_VER
  1476. #pragma warning(pop)
  1477. #endif
  1478. T value;
  1479. };
  1480. template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
  1481. union recursive_union;
  1482. template <Trait DestructibleTrait, std::size_t Index>
  1483. union recursive_union<DestructibleTrait, Index> {};
  1484. #define C10_MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor) \
  1485. template <std::size_t Index, typename T, typename... Ts> \
  1486. union recursive_union<destructible_trait, Index, T, Ts...> { \
  1487. public: \
  1488. inline explicit constexpr recursive_union(valueless_t) noexcept \
  1489. : dummy_{} {} \
  1490. \
  1491. template <typename... Args> \
  1492. inline explicit constexpr recursive_union( \
  1493. in_place_index_t<0>, \
  1494. Args&&... args) \
  1495. : head_(in_place_t{}, lib::forward<Args>(args)...) {} \
  1496. \
  1497. template <std::size_t I, typename... Args> \
  1498. inline explicit constexpr recursive_union( \
  1499. in_place_index_t<I>, \
  1500. Args&&... args) \
  1501. : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
  1502. \
  1503. recursive_union(const recursive_union&) = default; \
  1504. recursive_union(recursive_union&&) = default; \
  1505. \
  1506. destructor \
  1507. \
  1508. recursive_union& \
  1509. operator=(const recursive_union&) = default; \
  1510. recursive_union& operator=(recursive_union&&) = default; \
  1511. \
  1512. private: \
  1513. char dummy_; \
  1514. alt<Index, T> head_; \
  1515. recursive_union<destructible_trait, Index + 1, Ts...> tail_; \
  1516. \
  1517. friend struct access::recursive_union; \
  1518. }
  1519. C10_MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
  1520. ~recursive_union() = default;);
  1521. C10_MPARK_VARIANT_RECURSIVE_UNION(Trait::Available, ~recursive_union(){});
  1522. C10_MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
  1523. ~recursive_union() = delete;);
  1524. #undef C10_MPARK_VARIANT_RECURSIVE_UNION
  1525. using index_t = unsigned int;
  1526. template <Trait DestructibleTrait, typename... Ts>
  1527. class base {
  1528. public:
  1529. inline explicit constexpr base(valueless_t tag) noexcept
  1530. : data_(tag), index_(static_cast<index_t>(-1)) {}
  1531. template <std::size_t I, typename... Args>
  1532. inline explicit constexpr base(in_place_index_t<I>, Args&&... args)
  1533. : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...), index_(I) {}
  1534. inline constexpr bool valueless_by_exception() const noexcept {
  1535. return index_ == static_cast<index_t>(-1);
  1536. }
  1537. inline constexpr std::size_t index() const noexcept {
  1538. return valueless_by_exception() ? variant_npos : index_;
  1539. }
  1540. protected:
  1541. using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
  1542. friend inline constexpr base& as_base(base& b) {
  1543. return b;
  1544. }
  1545. friend inline constexpr const base& as_base(const base& b) {
  1546. return b;
  1547. }
  1548. friend inline constexpr base&& as_base(base&& b) {
  1549. return lib::move(b);
  1550. }
  1551. friend inline constexpr const base&& as_base(const base&& b) {
  1552. return lib::move(b);
  1553. }
  1554. friend inline constexpr data_t& data(base& b) {
  1555. return b.data_;
  1556. }
  1557. friend inline constexpr const data_t& data(const base& b) {
  1558. return b.data_;
  1559. }
  1560. friend inline constexpr data_t&& data(base&& b) {
  1561. return lib::move(b).data_;
  1562. }
  1563. friend inline constexpr const data_t&& data(const base&& b) {
  1564. return lib::move(b).data_;
  1565. }
  1566. inline static constexpr std::size_t size() {
  1567. return sizeof...(Ts);
  1568. }
  1569. data_t data_;
  1570. index_t index_;
  1571. friend struct access::base;
  1572. friend struct visitation::base;
  1573. };
  1574. struct dtor {
  1575. #ifdef _MSC_VER
  1576. #pragma warning(push)
  1577. #pragma warning(disable : 4100)
  1578. #endif
  1579. template <typename Alt>
  1580. inline void operator()(Alt& alt) const noexcept {
  1581. alt.~Alt();
  1582. }
  1583. #ifdef _MSC_VER
  1584. #pragma warning(pop)
  1585. #endif
  1586. };
  1587. #if !defined(_MSC_VER) || _MSC_VER >= 1910
  1588. #define C10_MPARK_INHERITING_CTOR(type, base) using base::base;
  1589. #else
  1590. #define C10_MPARK_INHERITING_CTOR(type, base) \
  1591. template <typename... Args> \
  1592. inline explicit constexpr type(Args&&... args) \
  1593. : base(lib::forward<Args>(args)...) {}
  1594. #endif
  1595. template <typename Traits, Trait = Traits::destructible_trait>
  1596. class destructor;
  1597. #define C10_MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
  1598. template <typename... Ts> \
  1599. class destructor<traits<Ts...>, destructible_trait> \
  1600. : public base<destructible_trait, Ts...> { \
  1601. using super = base<destructible_trait, Ts...>; \
  1602. \
  1603. public: \
  1604. C10_MPARK_INHERITING_CTOR(destructor, super) \
  1605. using super::operator=; \
  1606. \
  1607. destructor(const destructor&) = default; \
  1608. destructor(destructor&&) = default; \
  1609. definition destructor& operator=(const destructor&) = default; \
  1610. destructor& operator=(destructor&&) = default; \
  1611. \
  1612. protected: \
  1613. destroy \
  1614. }
  1615. C10_MPARK_VARIANT_DESTRUCTOR(
  1616. Trait::TriviallyAvailable, ~destructor() = default;
  1617. , inline void destroy() noexcept {
  1618. this->index_ = static_cast<index_t>(-1);
  1619. });
  1620. C10_MPARK_VARIANT_DESTRUCTOR(
  1621. Trait::Available,
  1622. ~destructor() { destroy(); },
  1623. inline void destroy() noexcept {
  1624. if (!this->valueless_by_exception()) {
  1625. visitation::alt::visit_alt(dtor{}, *this);
  1626. }
  1627. this->index_ = static_cast<index_t>(-1);
  1628. });
  1629. C10_MPARK_VARIANT_DESTRUCTOR(Trait::Unavailable, ~destructor() = delete;
  1630. , inline void destroy() noexcept = delete;);
  1631. #undef C10_MPARK_VARIANT_DESTRUCTOR
  1632. template <typename Traits>
  1633. class constructor : public destructor<Traits> {
  1634. using super = destructor<Traits>;
  1635. public:
  1636. C10_MPARK_INHERITING_CTOR(constructor, super)
  1637. using super::operator=;
  1638. protected:
  1639. #ifndef C10_MPARK_GENERIC_LAMBDAS
  1640. struct ctor {
  1641. template <typename LhsAlt, typename RhsAlt>
  1642. inline void operator()(LhsAlt& lhs_alt, RhsAlt&& rhs_alt) const {
  1643. constructor::construct_alt(lhs_alt, lib::forward<RhsAlt>(rhs_alt).value);
  1644. }
  1645. };
  1646. #endif
  1647. template <std::size_t I, typename T, typename... Args>
  1648. inline static T& construct_alt(alt<I, T>& a, Args&&... args) {
  1649. auto* result = ::new (static_cast<void*>(lib::addressof(a)))
  1650. alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
  1651. return result->value;
  1652. }
  1653. template <typename Rhs>
  1654. inline static void generic_construct(constructor& lhs, Rhs&& rhs) {
  1655. lhs.destroy();
  1656. if (!rhs.valueless_by_exception()) {
  1657. visitation::alt::visit_alt_at(
  1658. rhs.index(),
  1659. #ifdef C10_MPARK_GENERIC_LAMBDAS
  1660. [](auto& lhs_alt, auto&& rhs_alt) {
  1661. constructor::construct_alt(
  1662. lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
  1663. }
  1664. #else
  1665. ctor {}
  1666. #endif
  1667. ,
  1668. lhs,
  1669. lib::forward<Rhs>(rhs));
  1670. lhs.index_ = rhs.index_;
  1671. }
  1672. }
  1673. };
  1674. template <typename Traits, Trait = Traits::move_constructible_trait>
  1675. class move_constructor;
  1676. #define C10_MPARK_VARIANT_MOVE_CONSTRUCTOR( \
  1677. move_constructible_trait, definition) \
  1678. template <typename... Ts> \
  1679. class move_constructor<traits<Ts...>, move_constructible_trait> \
  1680. : public constructor<traits<Ts...>> { \
  1681. using super = constructor<traits<Ts...>>; \
  1682. \
  1683. public: \
  1684. C10_MPARK_INHERITING_CTOR(move_constructor, super) \
  1685. using super::operator=; \
  1686. \
  1687. move_constructor(const move_constructor&) = default; \
  1688. definition ~move_constructor() = default; \
  1689. move_constructor& operator=(const move_constructor&) = default; \
  1690. move_constructor& operator=(move_constructor&&) = default; \
  1691. }
  1692. C10_MPARK_VARIANT_MOVE_CONSTRUCTOR(
  1693. Trait::TriviallyAvailable,
  1694. move_constructor(move_constructor&& that) = default;);
  1695. C10_MPARK_VARIANT_MOVE_CONSTRUCTOR(
  1696. Trait::Available,
  1697. move_constructor(move_constructor&& that) noexcept(
  1698. lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
  1699. : move_constructor(valueless_t{}) {
  1700. this->generic_construct(*this, lib::move(that));
  1701. });
  1702. C10_MPARK_VARIANT_MOVE_CONSTRUCTOR(
  1703. Trait::Unavailable, move_constructor(move_constructor&&) = delete;);
  1704. #undef C10_MPARK_VARIANT_MOVE_CONSTRUCTOR
  1705. template <typename Traits, Trait = Traits::copy_constructible_trait>
  1706. class copy_constructor;
  1707. #define C10_MPARK_VARIANT_COPY_CONSTRUCTOR( \
  1708. copy_constructible_trait, definition) \
  1709. template <typename... Ts> \
  1710. class copy_constructor<traits<Ts...>, copy_constructible_trait> \
  1711. : public move_constructor<traits<Ts...>> { \
  1712. using super = move_constructor<traits<Ts...>>; \
  1713. \
  1714. public: \
  1715. C10_MPARK_INHERITING_CTOR(copy_constructor, super) \
  1716. using super::operator=; \
  1717. \
  1718. definition copy_constructor(copy_constructor&&) = default; \
  1719. ~copy_constructor() = default; \
  1720. copy_constructor& operator=(const copy_constructor&) = default; \
  1721. copy_constructor& operator=(copy_constructor&&) = default; \
  1722. }
  1723. C10_MPARK_VARIANT_COPY_CONSTRUCTOR(
  1724. Trait::TriviallyAvailable,
  1725. copy_constructor(const copy_constructor& that) = default;);
  1726. C10_MPARK_VARIANT_COPY_CONSTRUCTOR(
  1727. Trait::Available, copy_constructor(const copy_constructor& that)
  1728. : copy_constructor(valueless_t{}) {
  1729. this->generic_construct(*this, that);
  1730. });
  1731. C10_MPARK_VARIANT_COPY_CONSTRUCTOR(
  1732. Trait::Unavailable, copy_constructor(const copy_constructor&) = delete;);
  1733. #undef C10_MPARK_VARIANT_COPY_CONSTRUCTOR
  1734. template <typename Traits>
  1735. class assignment : public copy_constructor<Traits> {
  1736. using super = copy_constructor<Traits>;
  1737. public:
  1738. C10_MPARK_INHERITING_CTOR(assignment, super)
  1739. using super::operator=;
  1740. template <std::size_t I, typename... Args>
  1741. inline /* auto & */ auto emplace(Args&&... args)
  1742. -> decltype(this->construct_alt(
  1743. access::base::get_alt<I>(*this),
  1744. lib::forward<Args>(args)...)) {
  1745. this->destroy();
  1746. auto& result = this->construct_alt(
  1747. access::base::get_alt<I>(*this), lib::forward<Args>(args)...);
  1748. this->index_ = I;
  1749. return result;
  1750. }
  1751. protected:
  1752. #ifndef C10_MPARK_GENERIC_LAMBDAS
  1753. template <typename That>
  1754. struct assigner {
  1755. template <typename ThisAlt, typename ThatAlt>
  1756. inline void operator()(ThisAlt& this_alt, ThatAlt&& that_alt) const {
  1757. self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
  1758. }
  1759. assignment* self;
  1760. };
  1761. #endif
  1762. template <std::size_t I, typename T, typename Arg>
  1763. inline void assign_alt(alt<I, T>& a, Arg&& arg) {
  1764. if (this->index() == I) {
  1765. #ifdef _MSC_VER
  1766. #pragma warning(push)
  1767. #pragma warning(disable : 4244)
  1768. #endif
  1769. a.value = lib::forward<Arg>(arg);
  1770. #ifdef _MSC_VER
  1771. #pragma warning(pop)
  1772. #endif
  1773. } else {
  1774. struct {
  1775. void operator()(std::true_type) const {
  1776. this_->emplace<I>(lib::forward<Arg>(arg_));
  1777. }
  1778. void operator()(std::false_type) const {
  1779. this_->emplace<I>(T(lib::forward<Arg>(arg_)));
  1780. }
  1781. assignment* this_;
  1782. Arg&& arg_;
  1783. } impl{this, lib::forward<Arg>(arg)};
  1784. impl(
  1785. lib::bool_constant < std::is_nothrow_constructible<T, Arg>::value ||
  1786. !std::is_nothrow_move_constructible<T>::value > {});
  1787. }
  1788. }
  1789. template <typename That>
  1790. inline void generic_assign(That&& that) {
  1791. if (this->valueless_by_exception() && that.valueless_by_exception()) {
  1792. // do nothing.
  1793. } else if (that.valueless_by_exception()) {
  1794. this->destroy();
  1795. } else {
  1796. visitation::alt::visit_alt_at(
  1797. that.index(),
  1798. #ifdef C10_MPARK_GENERIC_LAMBDAS
  1799. [this](auto& this_alt, auto&& that_alt) {
  1800. this->assign_alt(
  1801. this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
  1802. }
  1803. #else
  1804. assigner<That> { this }
  1805. #endif
  1806. ,
  1807. *this,
  1808. lib::forward<That>(that));
  1809. }
  1810. }
  1811. };
  1812. template <typename Traits, Trait = Traits::move_assignable_trait>
  1813. class move_assignment;
  1814. #define C10_MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
  1815. template <typename... Ts> \
  1816. class move_assignment<traits<Ts...>, move_assignable_trait> \
  1817. : public assignment<traits<Ts...>> { \
  1818. using super = assignment<traits<Ts...>>; \
  1819. \
  1820. public: \
  1821. C10_MPARK_INHERITING_CTOR(move_assignment, super) \
  1822. using super::operator=; \
  1823. \
  1824. move_assignment(const move_assignment&) = default; \
  1825. move_assignment(move_assignment&&) = default; \
  1826. ~move_assignment() = default; \
  1827. move_assignment& operator=(const move_assignment&) = default; \
  1828. definition \
  1829. }
  1830. C10_MPARK_VARIANT_MOVE_ASSIGNMENT(
  1831. Trait::TriviallyAvailable,
  1832. move_assignment& operator=(move_assignment&& that) = default;);
  1833. C10_MPARK_VARIANT_MOVE_ASSIGNMENT(
  1834. Trait::Available,
  1835. move_assignment&
  1836. operator=(move_assignment&& that) noexcept(
  1837. lib::all<
  1838. (std::is_nothrow_move_constructible<Ts>::value &&
  1839. std::is_nothrow_move_assignable<Ts>::value)...>::value) {
  1840. this->generic_assign(lib::move(that));
  1841. return *this;
  1842. });
  1843. C10_MPARK_VARIANT_MOVE_ASSIGNMENT(
  1844. Trait::Unavailable,
  1845. move_assignment& operator=(move_assignment&&) = delete;);
  1846. #undef C10_MPARK_VARIANT_MOVE_ASSIGNMENT
  1847. template <typename Traits, Trait = Traits::copy_assignable_trait>
  1848. class copy_assignment;
  1849. #define C10_MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
  1850. template <typename... Ts> \
  1851. class copy_assignment<traits<Ts...>, copy_assignable_trait> \
  1852. : public move_assignment<traits<Ts...>> { \
  1853. using super = move_assignment<traits<Ts...>>; \
  1854. \
  1855. public: \
  1856. C10_MPARK_INHERITING_CTOR(copy_assignment, super) \
  1857. using super::operator=; \
  1858. \
  1859. copy_assignment(const copy_assignment&) = default; \
  1860. copy_assignment(copy_assignment&&) = default; \
  1861. ~copy_assignment() = default; \
  1862. definition copy_assignment& operator=(copy_assignment&&) = default; \
  1863. }
  1864. C10_MPARK_VARIANT_COPY_ASSIGNMENT(
  1865. Trait::TriviallyAvailable,
  1866. copy_assignment& operator=(const copy_assignment& that) = default;);
  1867. C10_MPARK_VARIANT_COPY_ASSIGNMENT(
  1868. Trait::Available,
  1869. copy_assignment&
  1870. operator=(const copy_assignment& that) {
  1871. this->generic_assign(that);
  1872. return *this;
  1873. });
  1874. C10_MPARK_VARIANT_COPY_ASSIGNMENT(
  1875. Trait::Unavailable,
  1876. copy_assignment& operator=(const copy_assignment&) = delete;);
  1877. #undef C10_MPARK_VARIANT_COPY_ASSIGNMENT
  1878. template <typename... Ts>
  1879. class impl : public copy_assignment<traits<Ts...>> {
  1880. using super = copy_assignment<traits<Ts...>>;
  1881. public:
  1882. C10_MPARK_INHERITING_CTOR(impl, super)
  1883. template <std::size_t I, typename Arg>
  1884. inline void assign(Arg&& arg) {
  1885. this->assign_alt(access::base::get_alt<I>(*this), lib::forward<Arg>(arg));
  1886. }
  1887. inline void swap(impl& that) {
  1888. if (this->valueless_by_exception() && that.valueless_by_exception()) {
  1889. // do nothing.
  1890. } else if (this->index() == that.index()) {
  1891. visitation::alt::visit_alt_at(
  1892. this->index(),
  1893. #ifdef C10_MPARK_GENERIC_LAMBDAS
  1894. [](auto& this_alt, auto& that_alt) {
  1895. using std::swap;
  1896. swap(this_alt.value, that_alt.value);
  1897. }
  1898. #else
  1899. swapper {}
  1900. #endif
  1901. ,
  1902. *this,
  1903. that);
  1904. } else {
  1905. impl* lhs = this;
  1906. impl* rhs = lib::addressof(that);
  1907. if (lhs->move_nothrow() && !rhs->move_nothrow()) {
  1908. std::swap(lhs, rhs);
  1909. }
  1910. impl tmp(lib::move(*rhs));
  1911. #ifdef C10_MPARK_EXCEPTIONS
  1912. // EXTENSION: When the move construction of `lhs` into `rhs` throws
  1913. // and `tmp` is nothrow move constructible then we move `tmp` back
  1914. // into `rhs` and provide the strong exception safety guarantee.
  1915. try {
  1916. this->generic_construct(*rhs, lib::move(*lhs));
  1917. } catch (...) {
  1918. if (tmp.move_nothrow()) {
  1919. this->generic_construct(*rhs, lib::move(tmp));
  1920. }
  1921. throw;
  1922. }
  1923. #else
  1924. this->generic_construct(*rhs, lib::move(*lhs));
  1925. #endif
  1926. this->generic_construct(*lhs, lib::move(tmp));
  1927. }
  1928. }
  1929. private:
  1930. #ifndef C10_MPARK_GENERIC_LAMBDAS
  1931. struct swapper {
  1932. template <typename ThisAlt, typename ThatAlt>
  1933. inline void operator()(ThisAlt& this_alt, ThatAlt& that_alt) const {
  1934. using std::swap;
  1935. swap(this_alt.value, that_alt.value);
  1936. }
  1937. };
  1938. #endif
  1939. inline constexpr bool move_nothrow() const {
  1940. return this->valueless_by_exception() ||
  1941. lib::array<bool, sizeof...(Ts)>{
  1942. {std::is_nothrow_move_constructible<Ts>::value...}}[this->index()];
  1943. }
  1944. };
  1945. #undef C10_MPARK_INHERITING_CTOR
  1946. template <std::size_t I, typename T>
  1947. struct overload_leaf {
  1948. using F = lib::size_constant<I> (*)(T);
  1949. operator F() const {
  1950. return nullptr;
  1951. }
  1952. };
  1953. template <typename... Ts>
  1954. struct overload_impl {
  1955. private:
  1956. template <typename>
  1957. struct impl;
  1958. template <std::size_t... Is>
  1959. struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
  1960. public:
  1961. using type = impl<lib::index_sequence_for<Ts...>>;
  1962. };
  1963. template <typename... Ts>
  1964. using overload = typename overload_impl<Ts...>::type;
  1965. template <typename T, typename... Ts>
  1966. using best_match = lib::invoke_result_t<overload<Ts...>, T&&>;
  1967. template <typename T>
  1968. struct is_in_place_index : std::false_type {};
  1969. template <std::size_t I>
  1970. struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
  1971. template <typename T>
  1972. struct is_in_place_type : std::false_type {};
  1973. template <typename T>
  1974. struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
  1975. } // namespace detail_
  1976. template <typename... Ts>
  1977. class variant {
  1978. static_assert(
  1979. 0 < sizeof...(Ts),
  1980. "variant must consist of at least one alternative.");
  1981. static_assert(
  1982. lib::all<!std::is_array<Ts>::value...>::value,
  1983. "variant can not have an array type as an alternative.");
  1984. static_assert(
  1985. lib::all<!std::is_reference<Ts>::value...>::value,
  1986. "variant can not have a reference type as an alternative.");
  1987. static_assert(
  1988. lib::all<!std::is_void<Ts>::value...>::value,
  1989. "variant can not have a void type as an alternative.");
  1990. public:
  1991. template <
  1992. typename Front = lib::type_pack_element_t<0, Ts...>,
  1993. lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
  1994. inline constexpr variant() noexcept(
  1995. std::is_nothrow_default_constructible<Front>::value)
  1996. : impl_(in_place_index_t<0>{}) {}
  1997. variant(const variant&) = default;
  1998. variant(variant&&) = default;
  1999. // NOTE [gcc 7.3.1 bug workaround]
  2000. //
  2001. // The original line `typename T = lib::type_pack_element_t<I, Ts...>`
  2002. // throws the following compiler error on gcc 7.3.1:
  2003. // ```
  2004. // ../c10/util/variant.h:2250:9: internal compiler error:
  2005. // unexpected expression ‘I’ of kind template_parm_index
  2006. // typename T = lib::type_pack_element_t<I, Ts...>,
  2007. // ^~~~~~~~
  2008. // ```
  2009. // As a workaround, `I` is changed to `detail_::best_match<Arg,
  2010. // Ts...>::value`, which is the default value for `I` in this template. Note
  2011. // that this workaround effectively disallows setting `I` to any other
  2012. // non-default value, and we add a `static_assert` in the function body to
  2013. // check for this.
  2014. //
  2015. // See the following issues for more context:
  2016. // - https://github.com/mpark/variant/issues/43
  2017. // - https://github.com/eggs-cpp/variant/issues/31
  2018. template <
  2019. typename Arg,
  2020. typename Decayed = lib::decay_t<Arg>,
  2021. lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
  2022. lib::enable_if_t<!detail_::is_in_place_index<Decayed>::value, int> = 0,
  2023. lib::enable_if_t<!detail_::is_in_place_type<Decayed>::value, int> = 0,
  2024. std::size_t I = detail_::best_match<Arg, Ts...>::value,
  2025. typename T = lib::
  2026. type_pack_element_t<detail_::best_match<Arg, Ts...>::value, Ts...>,
  2027. lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
  2028. inline constexpr variant(Arg&& arg) noexcept(
  2029. std::is_nothrow_constructible<T, Arg>::value)
  2030. : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {
  2031. static_assert(
  2032. I == detail_::best_match<Arg, Ts...>::value,
  2033. "Setting template parameter `I` to a custom non-default value is not supported. "
  2034. "Please file a feature request if you see this.");
  2035. }
  2036. template <
  2037. std::size_t I,
  2038. typename... Args,
  2039. typename T = lib::type_pack_element_t<I, Ts...>,
  2040. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  2041. inline explicit constexpr variant(
  2042. in_place_index_t<I>,
  2043. Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value)
  2044. : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
  2045. template <
  2046. std::size_t I,
  2047. typename Up,
  2048. typename... Args,
  2049. typename T = lib::type_pack_element_t<I, Ts...>,
  2050. lib::enable_if_t<
  2051. std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
  2052. int> = 0>
  2053. inline explicit constexpr variant(
  2054. in_place_index_t<I>,
  2055. std::initializer_list<Up> il,
  2056. Args&&... args) noexcept(std::
  2057. is_nothrow_constructible<
  2058. T,
  2059. std::initializer_list<Up>&,
  2060. Args...>::value)
  2061. : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
  2062. template <
  2063. typename T,
  2064. typename... Args,
  2065. std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
  2066. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  2067. inline explicit constexpr variant(
  2068. in_place_type_t<T>,
  2069. Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value)
  2070. : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
  2071. template <
  2072. typename T,
  2073. typename Up,
  2074. typename... Args,
  2075. std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
  2076. lib::enable_if_t<
  2077. std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
  2078. int> = 0>
  2079. inline explicit constexpr variant(
  2080. in_place_type_t<T>,
  2081. std::initializer_list<Up> il,
  2082. Args&&... args) noexcept(std::
  2083. is_nothrow_constructible<
  2084. T,
  2085. std::initializer_list<Up>&,
  2086. Args...>::value)
  2087. : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
  2088. ~variant() = default;
  2089. variant& operator=(const variant&) = default;
  2090. variant& operator=(variant&&) = default;
  2091. // NOTE: See NOTE [gcc 7.3.1 bug workaround] for the changes made to this
  2092. // function.
  2093. template <
  2094. typename Arg,
  2095. lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value, int> =
  2096. 0,
  2097. std::size_t I = detail_::best_match<Arg, Ts...>::value,
  2098. typename T = lib::
  2099. type_pack_element_t<detail_::best_match<Arg, Ts...>::value, Ts...>,
  2100. lib::enable_if_t<
  2101. (std::is_assignable<T&, Arg>::value &&
  2102. std::is_constructible<T, Arg>::value),
  2103. int> = 0>
  2104. inline variant& operator=(Arg&& arg) noexcept(
  2105. (std::is_nothrow_assignable<T&, Arg>::value &&
  2106. std::is_nothrow_constructible<T, Arg>::value)) {
  2107. static_assert(
  2108. I == detail_::best_match<Arg, Ts...>::value,
  2109. "Setting template parameter `I` to a custom non-default value is not supported. "
  2110. "Please file a feature request if you see this.");
  2111. impl_.template assign<I>(lib::forward<Arg>(arg));
  2112. return *this;
  2113. }
  2114. template <
  2115. std::size_t I,
  2116. typename... Args,
  2117. typename T = lib::type_pack_element_t<I, Ts...>,
  2118. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  2119. inline T& emplace(Args&&... args) {
  2120. return impl_.template emplace<I>(lib::forward<Args>(args)...);
  2121. }
  2122. template <
  2123. std::size_t I,
  2124. typename Up,
  2125. typename... Args,
  2126. typename T = lib::type_pack_element_t<I, Ts...>,
  2127. lib::enable_if_t<
  2128. std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
  2129. int> = 0>
  2130. inline T& emplace(std::initializer_list<Up> il, Args&&... args) {
  2131. return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
  2132. }
  2133. template <
  2134. typename T,
  2135. typename... Args,
  2136. std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
  2137. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  2138. inline T& emplace(Args&&... args) {
  2139. return impl_.template emplace<I>(lib::forward<Args>(args)...);
  2140. }
  2141. template <
  2142. typename T,
  2143. typename Up,
  2144. typename... Args,
  2145. std::size_t I = detail_::find_index_sfinae<T, Ts...>::value,
  2146. lib::enable_if_t<
  2147. std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
  2148. int> = 0>
  2149. inline T& emplace(std::initializer_list<Up> il, Args&&... args) {
  2150. return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
  2151. }
  2152. inline constexpr bool valueless_by_exception() const noexcept {
  2153. return impl_.valueless_by_exception();
  2154. }
  2155. inline constexpr std::size_t index() const noexcept {
  2156. return impl_.index();
  2157. }
  2158. template <
  2159. bool Dummy = true,
  2160. lib::enable_if_t<
  2161. lib::all<
  2162. Dummy,
  2163. (lib::dependent_type<std::is_move_constructible<Ts>, Dummy>::
  2164. value &&
  2165. lib::dependent_type<lib::is_swappable<Ts>, Dummy>::value)...>::
  2166. value,
  2167. int> = 0>
  2168. inline void swap(variant& that) noexcept(
  2169. lib::all<
  2170. (std::is_nothrow_move_constructible<Ts>::value &&
  2171. lib::is_nothrow_swappable<Ts>::value)...>::value) {
  2172. impl_.swap(that.impl_);
  2173. }
  2174. private:
  2175. detail_::impl<Ts...> impl_;
  2176. friend struct detail_::access::variant;
  2177. friend struct detail_::visitation::variant;
  2178. };
  2179. template <std::size_t I, typename... Ts>
  2180. inline constexpr bool holds_alternative(const variant<Ts...>& v) noexcept {
  2181. return v.index() == I;
  2182. }
  2183. template <typename T, typename... Ts>
  2184. inline constexpr bool holds_alternative(const variant<Ts...>& v) noexcept {
  2185. return holds_alternative<detail_::find_index_checked<T, Ts...>::value>(v);
  2186. }
  2187. namespace detail_ {
  2188. template <std::size_t I, typename V>
  2189. struct generic_get_impl {
  2190. constexpr generic_get_impl(int) noexcept {}
  2191. constexpr AUTO_REFREF operator()(V&& v) const
  2192. AUTO_REFREF_RETURN(access::variant::get_alt<I>(lib::forward<V>(v)).value)
  2193. };
  2194. template <std::size_t I, typename V>
  2195. inline constexpr AUTO_REFREF generic_get(V&& v)
  2196. AUTO_REFREF_RETURN(generic_get_impl<I, V>(
  2197. holds_alternative<I>(v)
  2198. ? 0
  2199. : (throw_bad_variant_access(), 0))(lib::forward<V>(v)))
  2200. } // namespace detail_
  2201. template <std::size_t I, typename... Ts>
  2202. inline constexpr variant_alternative_t<I, variant<Ts...>>& get(
  2203. variant<Ts...>& v) {
  2204. return detail_::generic_get<I>(v);
  2205. }
  2206. template <std::size_t I, typename... Ts>
  2207. inline constexpr variant_alternative_t<I, variant<Ts...>>&& get(
  2208. variant<Ts...>&& v) {
  2209. return detail_::generic_get<I>(lib::move(v));
  2210. }
  2211. template <std::size_t I, typename... Ts>
  2212. inline constexpr const variant_alternative_t<I, variant<Ts...>>& get(
  2213. const variant<Ts...>& v) {
  2214. return detail_::generic_get<I>(v);
  2215. }
  2216. template <std::size_t I, typename... Ts>
  2217. inline constexpr const variant_alternative_t<I, variant<Ts...>>&& get(
  2218. const variant<Ts...>&& v) {
  2219. return detail_::generic_get<I>(lib::move(v));
  2220. }
  2221. template <typename T, typename... Ts>
  2222. inline constexpr T& get(variant<Ts...>& v) {
  2223. return get<detail_::find_index_checked<T, Ts...>::value>(v);
  2224. }
  2225. template <typename T, typename... Ts>
  2226. inline constexpr T&& get(variant<Ts...>&& v) {
  2227. return get<detail_::find_index_checked<T, Ts...>::value>(lib::move(v));
  2228. }
  2229. template <typename T, typename... Ts>
  2230. inline constexpr const T& get(const variant<Ts...>& v) {
  2231. return get<detail_::find_index_checked<T, Ts...>::value>(v);
  2232. }
  2233. template <typename T, typename... Ts>
  2234. inline constexpr const T&& get(const variant<Ts...>&& v) {
  2235. return get<detail_::find_index_checked<T, Ts...>::value>(lib::move(v));
  2236. }
  2237. namespace detail_ {
  2238. template <std::size_t I, typename V>
  2239. inline constexpr /* auto * */ AUTO generic_get_if(V* v) noexcept AUTO_RETURN(
  2240. v&& holds_alternative<I>(*v)
  2241. ? lib::addressof(access::variant::get_alt<I>(*v).value)
  2242. : nullptr)
  2243. } // namespace detail_
  2244. template <std::size_t I, typename... Ts>
  2245. inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
  2246. get_if(variant<Ts...>* v) noexcept {
  2247. return detail_::generic_get_if<I>(v);
  2248. }
  2249. template <std::size_t I, typename... Ts>
  2250. inline constexpr lib::add_pointer_t<
  2251. const variant_alternative_t<I, variant<Ts...>>>
  2252. get_if(const variant<Ts...>* v) noexcept {
  2253. return detail_::generic_get_if<I>(v);
  2254. }
  2255. template <typename T, typename... Ts>
  2256. inline constexpr lib::add_pointer_t<T> get_if(variant<Ts...>* v) noexcept {
  2257. return get_if<detail_::find_index_checked<T, Ts...>::value>(v);
  2258. }
  2259. template <typename T, typename... Ts>
  2260. inline constexpr lib::add_pointer_t<const T> get_if(
  2261. const variant<Ts...>* v) noexcept {
  2262. return get_if<detail_::find_index_checked<T, Ts...>::value>(v);
  2263. }
  2264. namespace detail_ {
  2265. template <typename RelOp>
  2266. struct convert_to_bool {
  2267. template <typename Lhs, typename Rhs>
  2268. inline constexpr bool operator()(Lhs&& lhs, Rhs&& rhs) const {
  2269. static_assert(
  2270. std::is_convertible<lib::invoke_result_t<RelOp, Lhs, Rhs>, bool>::value,
  2271. "relational operators must return a type"
  2272. " implicitly convertible to bool");
  2273. return lib::invoke(RelOp{}, lib::forward<Lhs>(lhs), lib::forward<Rhs>(rhs));
  2274. }
  2275. };
  2276. } // namespace detail_
  2277. template <typename... Ts>
  2278. inline constexpr bool operator==(
  2279. const variant<Ts...>& lhs,
  2280. const variant<Ts...>& rhs) {
  2281. using detail_::visitation::variant;
  2282. using equal_to = detail_::convert_to_bool<lib::equal_to>;
  2283. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2284. if (lhs.index() != rhs.index())
  2285. return false;
  2286. if (lhs.valueless_by_exception())
  2287. return true;
  2288. return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
  2289. #else
  2290. return lhs.index() == rhs.index() &&
  2291. (lhs.valueless_by_exception() ||
  2292. variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
  2293. #endif
  2294. }
  2295. template <typename... Ts>
  2296. inline constexpr bool operator!=(
  2297. const variant<Ts...>& lhs,
  2298. const variant<Ts...>& rhs) {
  2299. using detail_::visitation::variant;
  2300. using not_equal_to = detail_::convert_to_bool<lib::not_equal_to>;
  2301. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2302. if (lhs.index() != rhs.index())
  2303. return true;
  2304. if (lhs.valueless_by_exception())
  2305. return false;
  2306. return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
  2307. #else
  2308. return lhs.index() != rhs.index() ||
  2309. (!lhs.valueless_by_exception() &&
  2310. variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
  2311. #endif
  2312. }
  2313. template <typename... Ts>
  2314. inline constexpr bool operator<(
  2315. const variant<Ts...>& lhs,
  2316. const variant<Ts...>& rhs) {
  2317. using detail_::visitation::variant;
  2318. using less = detail_::convert_to_bool<lib::less>;
  2319. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2320. if (rhs.valueless_by_exception())
  2321. return false;
  2322. if (lhs.valueless_by_exception())
  2323. return true;
  2324. if (lhs.index() < rhs.index())
  2325. return true;
  2326. if (lhs.index() > rhs.index())
  2327. return false;
  2328. return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
  2329. #else
  2330. return !rhs.valueless_by_exception() &&
  2331. (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
  2332. (lhs.index() == rhs.index() &&
  2333. variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
  2334. #endif
  2335. }
  2336. template <typename... Ts>
  2337. inline constexpr bool operator>(
  2338. const variant<Ts...>& lhs,
  2339. const variant<Ts...>& rhs) {
  2340. using detail_::visitation::variant;
  2341. using greater = detail_::convert_to_bool<lib::greater>;
  2342. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2343. if (lhs.valueless_by_exception())
  2344. return false;
  2345. if (rhs.valueless_by_exception())
  2346. return true;
  2347. if (lhs.index() > rhs.index())
  2348. return true;
  2349. if (lhs.index() < rhs.index())
  2350. return false;
  2351. return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
  2352. #else
  2353. return !lhs.valueless_by_exception() &&
  2354. (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
  2355. (lhs.index() == rhs.index() &&
  2356. variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
  2357. #endif
  2358. }
  2359. template <typename... Ts>
  2360. inline constexpr bool operator<=(
  2361. const variant<Ts...>& lhs,
  2362. const variant<Ts...>& rhs) {
  2363. using detail_::visitation::variant;
  2364. using less_equal = detail_::convert_to_bool<lib::less_equal>;
  2365. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2366. if (lhs.valueless_by_exception())
  2367. return true;
  2368. if (rhs.valueless_by_exception())
  2369. return false;
  2370. if (lhs.index() < rhs.index())
  2371. return true;
  2372. if (lhs.index() > rhs.index())
  2373. return false;
  2374. return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
  2375. #else
  2376. return lhs.valueless_by_exception() ||
  2377. (!rhs.valueless_by_exception() &&
  2378. (lhs.index() < rhs.index() ||
  2379. (lhs.index() == rhs.index() &&
  2380. variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
  2381. #endif
  2382. }
  2383. template <typename... Ts>
  2384. inline constexpr bool operator>=(
  2385. const variant<Ts...>& lhs,
  2386. const variant<Ts...>& rhs) {
  2387. using detail_::visitation::variant;
  2388. using greater_equal = detail_::convert_to_bool<lib::greater_equal>;
  2389. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2390. if (rhs.valueless_by_exception())
  2391. return true;
  2392. if (lhs.valueless_by_exception())
  2393. return false;
  2394. if (lhs.index() > rhs.index())
  2395. return true;
  2396. if (lhs.index() < rhs.index())
  2397. return false;
  2398. return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
  2399. #else
  2400. return rhs.valueless_by_exception() ||
  2401. (!lhs.valueless_by_exception() &&
  2402. (lhs.index() > rhs.index() ||
  2403. (lhs.index() == rhs.index() &&
  2404. variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs))));
  2405. #endif
  2406. }
  2407. struct monostate {};
  2408. inline constexpr bool operator<(monostate, monostate) noexcept {
  2409. return false;
  2410. }
  2411. inline constexpr bool operator>(monostate, monostate) noexcept {
  2412. return false;
  2413. }
  2414. inline constexpr bool operator<=(monostate, monostate) noexcept {
  2415. return true;
  2416. }
  2417. inline constexpr bool operator>=(monostate, monostate) noexcept {
  2418. return true;
  2419. }
  2420. inline constexpr bool operator==(monostate, monostate) noexcept {
  2421. return true;
  2422. }
  2423. inline constexpr bool operator!=(monostate, monostate) noexcept {
  2424. return false;
  2425. }
  2426. #ifdef C10_MPARK_CPP14_CONSTEXPR
  2427. namespace detail_ {
  2428. inline constexpr bool any(std::initializer_list<bool> bs) {
  2429. for (bool b : bs) {
  2430. if (b) {
  2431. return true;
  2432. }
  2433. }
  2434. return false;
  2435. }
  2436. } // namespace detail_
  2437. template <typename Visitor, typename... Vs>
  2438. inline constexpr decltype(auto) visit(Visitor&& visitor, Vs&&... vs) {
  2439. return (!detail_::any({vs.valueless_by_exception()...})
  2440. ? (void)0
  2441. : throw_bad_variant_access()),
  2442. detail_::visitation::variant::visit_value(
  2443. lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
  2444. }
  2445. #else
  2446. namespace detail_ {
  2447. template <std::size_t N>
  2448. inline constexpr bool all_impl(const lib::array<bool, N>& bs, std::size_t idx) {
  2449. return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
  2450. }
  2451. template <std::size_t N>
  2452. inline constexpr bool all(const lib::array<bool, N>& bs) {
  2453. return all_impl(bs, 0);
  2454. }
  2455. } // namespace detail_
  2456. template <typename Visitor, typename... Vs>
  2457. inline constexpr DECLTYPE_AUTO visit(Visitor&& visitor, Vs&&... vs)
  2458. DECLTYPE_AUTO_RETURN(
  2459. (detail_::all(lib::array<bool, sizeof...(Vs)>{
  2460. {!vs.valueless_by_exception()...}})
  2461. ? (void)0
  2462. : throw_bad_variant_access()),
  2463. detail_::visitation::variant::visit_value(
  2464. lib::forward<Visitor>(visitor),
  2465. lib::forward<Vs>(vs)...))
  2466. #endif
  2467. template <typename... Ts>
  2468. inline auto swap(variant<Ts...>& lhs, variant<Ts...>& rhs) noexcept(
  2469. noexcept(lhs.swap(rhs))) -> decltype(lhs.swap(rhs)) {
  2470. lhs.swap(rhs);
  2471. }
  2472. namespace detail_ {
  2473. template <typename T, typename...>
  2474. using enabled_type = T;
  2475. namespace hash {
  2476. template <typename H, typename K>
  2477. constexpr bool meets_requirements() noexcept {
  2478. return std::is_copy_constructible<H>::value &&
  2479. std::is_move_constructible<H>::value &&
  2480. lib::is_invocable_r<std::size_t, H, const K&>::value;
  2481. }
  2482. template <typename K>
  2483. constexpr bool is_enabled() noexcept {
  2484. using H = std::hash<K>;
  2485. return meets_requirements<H, K>() &&
  2486. std::is_default_constructible<H>::value &&
  2487. std::is_copy_assignable<H>::value && std::is_move_assignable<H>::value;
  2488. }
  2489. } // namespace hash
  2490. } // namespace detail_
  2491. #undef AUTO
  2492. #undef AUTO_RETURN
  2493. #undef AUTO_REFREF
  2494. #undef AUTO_REFREF_RETURN
  2495. #undef DECLTYPE_AUTO
  2496. #undef DECLTYPE_AUTO_RETURN
  2497. } // namespace c10
  2498. namespace std {
  2499. template <typename... Ts>
  2500. struct hash<c10::detail_::enabled_type<
  2501. c10::variant<Ts...>,
  2502. c10::lib::enable_if_t<c10::lib::all<c10::detail_::hash::is_enabled<
  2503. c10::lib::remove_const_t<Ts>>()...>::value>>> {
  2504. using argument_type = c10::variant<Ts...>;
  2505. using result_type = std::size_t;
  2506. inline result_type operator()(const argument_type& v) const {
  2507. using c10::detail_::visitation::variant;
  2508. std::size_t result = v.valueless_by_exception()
  2509. ? 299792458 // Random value chosen by the universe upon creation
  2510. : variant::visit_alt(
  2511. #ifdef C10_MPARK_GENERIC_LAMBDAS
  2512. [](const auto& alt) {
  2513. using alt_type = c10::lib::decay_t<decltype(alt)>;
  2514. using value_type =
  2515. c10::lib::remove_const_t<typename alt_type::value_type>;
  2516. return hash<value_type>{}(alt.value);
  2517. }
  2518. #else
  2519. hasher {}
  2520. #endif
  2521. ,
  2522. v);
  2523. return hash_combine(result, hash<std::size_t>{}(v.index()));
  2524. }
  2525. private:
  2526. #ifndef C10_MPARK_GENERIC_LAMBDAS
  2527. struct hasher {
  2528. template <typename Alt>
  2529. inline std::size_t operator()(const Alt& alt) const {
  2530. using alt_type = c10::lib::decay_t<Alt>;
  2531. using value_type =
  2532. c10::lib::remove_const_t<typename alt_type::value_type>;
  2533. return hash<value_type>{}(alt.value);
  2534. }
  2535. };
  2536. #endif
  2537. static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
  2538. return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
  2539. }
  2540. };
  2541. template <>
  2542. struct hash<c10::monostate> {
  2543. using argument_type = c10::monostate;
  2544. using result_type = std::size_t;
  2545. inline result_type operator()(const argument_type&) const noexcept {
  2546. return 66740831; // return a fundamentally attractive random value.
  2547. }
  2548. };
  2549. } // namespace std
  2550. #endif // C10_UTIL_VARIANT_H_