xvariant_impl.hpp 100 KB

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