variant.hpp 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147
  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. #ifndef MPARK_VARIANT_HPP
  8. #define MPARK_VARIANT_HPP
  9. /*
  10. variant synopsis
  11. namespace std {
  12. // 20.7.2, class template variant
  13. template <class... Types>
  14. class variant {
  15. public:
  16. // 20.7.2.1, constructors
  17. constexpr variant() noexcept(see below);
  18. variant(const variant&);
  19. variant(variant&&) noexcept(see below);
  20. template <class T> constexpr variant(T&&) noexcept(see below);
  21. template <class T, class... Args>
  22. constexpr explicit variant(in_place_type_t<T>, Args&&...);
  23. template <class T, class U, class... Args>
  24. constexpr explicit variant(
  25. in_place_type_t<T>, initializer_list<U>, Args&&...);
  26. template <size_t I, class... Args>
  27. constexpr explicit variant(in_place_index_t<I>, Args&&...);
  28. template <size_t I, class U, class... Args>
  29. constexpr explicit variant(
  30. in_place_index_t<I>, initializer_list<U>, Args&&...);
  31. // 20.7.2.2, destructor
  32. ~variant();
  33. // 20.7.2.3, assignment
  34. variant& operator=(const variant&);
  35. variant& operator=(variant&&) noexcept(see below);
  36. template <class T> variant& operator=(T&&) noexcept(see below);
  37. // 20.7.2.4, modifiers
  38. template <class T, class... Args>
  39. T& emplace(Args&&...);
  40. template <class T, class U, class... Args>
  41. T& emplace(initializer_list<U>, Args&&...);
  42. template <size_t I, class... Args>
  43. variant_alternative<I, variant>& emplace(Args&&...);
  44. template <size_t I, class U, class... Args>
  45. variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
  46. // 20.7.2.5, value status
  47. constexpr bool valueless_by_exception() const noexcept;
  48. constexpr size_t index() const noexcept;
  49. // 20.7.2.6, swap
  50. void swap(variant&) noexcept(see below);
  51. };
  52. // 20.7.3, variant helper classes
  53. template <class T> struct variant_size; // undefined
  54. template <class T>
  55. constexpr size_t variant_size_v = variant_size<T>::value;
  56. template <class T> struct variant_size<const T>;
  57. template <class T> struct variant_size<volatile T>;
  58. template <class T> struct variant_size<const volatile T>;
  59. template <class... Types>
  60. struct variant_size<variant<Types...>>;
  61. template <size_t I, class T> struct variant_alternative; // undefined
  62. template <size_t I, class T>
  63. using variant_alternative_t = typename variant_alternative<I, T>::type;
  64. template <size_t I, class T> struct variant_alternative<I, const T>;
  65. template <size_t I, class T> struct variant_alternative<I, volatile T>;
  66. template <size_t I, class T> struct variant_alternative<I, const volatile T>;
  67. template <size_t I, class... Types>
  68. struct variant_alternative<I, variant<Types...>>;
  69. constexpr size_t variant_npos = -1;
  70. // 20.7.4, value access
  71. template <class T, class... Types>
  72. constexpr bool holds_alternative(const variant<Types...>&) noexcept;
  73. template <size_t I, class... Types>
  74. constexpr variant_alternative_t<I, variant<Types...>>&
  75. get(variant<Types...>&);
  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...>> const&
  81. get(const 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 <class T, class... Types>
  86. constexpr T& get(variant<Types...>&);
  87. template <class T, class... Types>
  88. constexpr T&& get(variant<Types...>&&);
  89. template <class T, class... Types>
  90. constexpr const T& get(const variant<Types...>&);
  91. template <class T, class... Types>
  92. constexpr const T&& get(const variant<Types...>&&);
  93. template <size_t I, class... Types>
  94. constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
  95. get_if(variant<Types...>*) noexcept;
  96. template <size_t I, class... Types>
  97. constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
  98. get_if(const variant<Types...>*) noexcept;
  99. template <class T, class... Types>
  100. constexpr add_pointer_t<T>
  101. get_if(variant<Types...>*) noexcept;
  102. template <class T, class... Types>
  103. constexpr add_pointer_t<const T>
  104. get_if(const variant<Types...>*) noexcept;
  105. // 20.7.5, relational operators
  106. template <class... Types>
  107. constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
  108. template <class... Types>
  109. constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
  110. template <class... Types>
  111. constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
  112. template <class... Types>
  113. constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
  114. template <class... Types>
  115. constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
  116. template <class... Types>
  117. constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
  118. // 20.7.6, visitation
  119. template <class Visitor, class... Variants>
  120. constexpr see below visit(Visitor&&, Variants&&...);
  121. // 20.7.7, class monostate
  122. struct monostate;
  123. // 20.7.8, monostate relational operators
  124. constexpr bool operator<(monostate, monostate) noexcept;
  125. constexpr bool operator>(monostate, monostate) noexcept;
  126. constexpr bool operator<=(monostate, monostate) noexcept;
  127. constexpr bool operator>=(monostate, monostate) noexcept;
  128. constexpr bool operator==(monostate, monostate) noexcept;
  129. constexpr bool operator!=(monostate, monostate) noexcept;
  130. // 20.7.9, specialized algorithms
  131. template <class... Types>
  132. void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
  133. // 20.7.10, class bad_variant_access
  134. class bad_variant_access;
  135. // 20.7.11, hash support
  136. template <class T> struct hash;
  137. template <class... Types> struct hash<variant<Types...>>;
  138. template <> struct hash<monostate>;
  139. } // namespace std
  140. */
  141. #include <cstddef>
  142. #include <exception>
  143. #include <functional>
  144. #include <initializer_list>
  145. #include <new>
  146. #include <type_traits>
  147. #include <utility>
  148. #include "config.hpp"
  149. #include "in_place.hpp"
  150. #include "lib.hpp"
  151. namespace mpark {
  152. #ifdef MPARK_RETURN_TYPE_DEDUCTION
  153. #define AUTO auto
  154. #define AUTO_RETURN(...) { return __VA_ARGS__; }
  155. #define AUTO_REFREF auto &&
  156. #define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
  157. #define DECLTYPE_AUTO decltype(auto)
  158. #define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
  159. #else
  160. #define AUTO auto
  161. #define AUTO_RETURN(...) \
  162. -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
  163. #define AUTO_REFREF auto
  164. #define AUTO_REFREF_RETURN(...) \
  165. -> decltype((__VA_ARGS__)) { \
  166. static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
  167. return __VA_ARGS__; \
  168. }
  169. #define DECLTYPE_AUTO auto
  170. #define DECLTYPE_AUTO_RETURN(...) \
  171. -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
  172. #endif
  173. class bad_variant_access : public std::exception {
  174. public:
  175. virtual const char *what() const noexcept override { return "bad_variant_access"; }
  176. };
  177. [[noreturn]] inline void throw_bad_variant_access() {
  178. #ifdef MPARK_EXCEPTIONS
  179. throw bad_variant_access{};
  180. #else
  181. std::terminate();
  182. MPARK_BUILTIN_UNREACHABLE;
  183. #endif
  184. }
  185. template <typename... Ts>
  186. class variant;
  187. template <typename T>
  188. struct variant_size;
  189. #ifdef MPARK_VARIABLE_TEMPLATES
  190. template <typename T>
  191. constexpr std::size_t variant_size_v = variant_size<T>::value;
  192. #endif
  193. template <typename T>
  194. struct variant_size<const T> : variant_size<T> {};
  195. template <typename T>
  196. struct variant_size<volatile T> : variant_size<T> {};
  197. template <typename T>
  198. struct variant_size<const volatile T> : variant_size<T> {};
  199. template <typename... Ts>
  200. struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
  201. template <std::size_t I, typename T>
  202. struct variant_alternative;
  203. template <std::size_t I, typename T>
  204. using variant_alternative_t = typename variant_alternative<I, T>::type;
  205. template <std::size_t I, typename T>
  206. struct variant_alternative<I, const T>
  207. : std::add_const<variant_alternative_t<I, T>> {};
  208. template <std::size_t I, typename T>
  209. struct variant_alternative<I, volatile T>
  210. : std::add_volatile<variant_alternative_t<I, T>> {};
  211. template <std::size_t I, typename T>
  212. struct variant_alternative<I, const volatile T>
  213. : std::add_cv<variant_alternative_t<I, T>> {};
  214. template <std::size_t I, typename... Ts>
  215. struct variant_alternative<I, variant<Ts...>> {
  216. static_assert(I < sizeof...(Ts),
  217. "index out of bounds in `std::variant_alternative<>`");
  218. using type = lib::type_pack_element_t<I, Ts...>;
  219. };
  220. constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
  221. namespace detail {
  222. constexpr std::size_t not_found = static_cast<std::size_t>(-1);
  223. constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
  224. #ifdef MPARK_CPP14_CONSTEXPR
  225. template <typename T, typename... Ts>
  226. inline constexpr std::size_t find_index() {
  227. constexpr lib::array<bool, sizeof...(Ts)> matches = {
  228. {std::is_same<T, Ts>::value...}
  229. };
  230. std::size_t result = not_found;
  231. for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
  232. if (matches[i]) {
  233. if (result != not_found) {
  234. return ambiguous;
  235. }
  236. result = i;
  237. }
  238. }
  239. return result;
  240. }
  241. #else
  242. inline constexpr std::size_t find_index_impl(std::size_t result,
  243. std::size_t) {
  244. return result;
  245. }
  246. template <typename... Bs>
  247. inline constexpr std::size_t find_index_impl(std::size_t result,
  248. std::size_t idx,
  249. bool b,
  250. Bs... bs) {
  251. return b ? (result != not_found ? ambiguous
  252. : find_index_impl(idx, idx + 1, bs...))
  253. : find_index_impl(result, idx + 1, bs...);
  254. }
  255. template <typename T, typename... Ts>
  256. inline constexpr std::size_t find_index() {
  257. return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
  258. }
  259. #endif
  260. template <std::size_t I>
  261. using find_index_sfinae_impl =
  262. lib::enable_if_t<I != not_found && I != ambiguous,
  263. lib::size_constant<I>>;
  264. template <typename T, typename... Ts>
  265. using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
  266. template <std::size_t I>
  267. struct find_index_checked_impl : lib::size_constant<I> {
  268. static_assert(I != not_found, "the specified type is not found.");
  269. static_assert(I != ambiguous, "the specified type is ambiguous.");
  270. };
  271. template <typename T, typename... Ts>
  272. using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
  273. struct valueless_t {};
  274. enum class Trait { TriviallyAvailable, Available, Unavailable };
  275. template <typename T,
  276. template <typename> class IsTriviallyAvailable,
  277. template <typename> class IsAvailable>
  278. inline constexpr Trait trait() {
  279. return IsTriviallyAvailable<T>::value
  280. ? Trait::TriviallyAvailable
  281. : IsAvailable<T>::value ? Trait::Available
  282. : Trait::Unavailable;
  283. }
  284. #ifdef MPARK_CPP14_CONSTEXPR
  285. template <typename... Traits>
  286. inline constexpr Trait common_trait(Traits... traits_) {
  287. Trait result = Trait::TriviallyAvailable;
  288. lib::array<Trait, sizeof...(Traits)> traits = {{traits_...}};
  289. for (std::size_t i = 0; i < sizeof...(Traits); ++i) {
  290. Trait t = traits[i];
  291. if (static_cast<int>(t) > static_cast<int>(result)) {
  292. result = t;
  293. }
  294. }
  295. return result;
  296. }
  297. #else
  298. inline constexpr Trait common_trait_impl(Trait result) { return result; }
  299. template <typename... Traits>
  300. inline constexpr Trait common_trait_impl(Trait result,
  301. Trait t,
  302. Traits... ts) {
  303. return static_cast<int>(t) > static_cast<int>(result)
  304. ? common_trait_impl(t, ts...)
  305. : common_trait_impl(result, ts...);
  306. }
  307. template <typename... Traits>
  308. inline constexpr Trait common_trait(Traits... ts) {
  309. return common_trait_impl(Trait::TriviallyAvailable, ts...);
  310. }
  311. #endif
  312. template <typename... Ts>
  313. struct traits {
  314. static constexpr Trait copy_constructible_trait =
  315. common_trait(trait<Ts,
  316. lib::is_trivially_copy_constructible,
  317. std::is_copy_constructible>()...);
  318. static constexpr Trait move_constructible_trait =
  319. common_trait(trait<Ts,
  320. lib::is_trivially_move_constructible,
  321. std::is_move_constructible>()...);
  322. static constexpr Trait copy_assignable_trait =
  323. common_trait(copy_constructible_trait,
  324. trait<Ts,
  325. lib::is_trivially_copy_assignable,
  326. std::is_copy_assignable>()...);
  327. static constexpr Trait move_assignable_trait =
  328. common_trait(move_constructible_trait,
  329. trait<Ts,
  330. lib::is_trivially_move_assignable,
  331. std::is_move_assignable>()...);
  332. static constexpr Trait destructible_trait =
  333. common_trait(trait<Ts,
  334. std::is_trivially_destructible,
  335. std::is_destructible>()...);
  336. };
  337. namespace access {
  338. struct recursive_union {
  339. #ifdef MPARK_RETURN_TYPE_DEDUCTION
  340. template <typename V>
  341. inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
  342. return lib::forward<V>(v).head_;
  343. }
  344. template <typename V, std::size_t I>
  345. inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
  346. return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
  347. }
  348. #else
  349. template <std::size_t I, bool Dummy = true>
  350. struct get_alt_impl {
  351. template <typename V>
  352. inline constexpr AUTO_REFREF operator()(V &&v) const
  353. AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
  354. };
  355. template <bool Dummy>
  356. struct get_alt_impl<0, Dummy> {
  357. template <typename V>
  358. inline constexpr AUTO_REFREF operator()(V &&v) const
  359. AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
  360. };
  361. template <typename V, std::size_t I>
  362. inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
  363. AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
  364. #endif
  365. };
  366. struct base {
  367. template <std::size_t I, typename V>
  368. inline static constexpr AUTO_REFREF get_alt(V &&v)
  369. #ifdef _MSC_VER
  370. AUTO_REFREF_RETURN(recursive_union::get_alt(
  371. lib::forward<V>(v).data_, in_place_index_t<I>{}))
  372. #else
  373. AUTO_REFREF_RETURN(recursive_union::get_alt(
  374. data(lib::forward<V>(v)), in_place_index_t<I>{}))
  375. #endif
  376. };
  377. struct variant {
  378. template <std::size_t I, typename V>
  379. inline static constexpr AUTO_REFREF get_alt(V &&v)
  380. AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
  381. };
  382. } // namespace access
  383. namespace visitation {
  384. #if defined(MPARK_CPP14_CONSTEXPR) && !defined(_MSC_VER)
  385. #define MPARK_VARIANT_SWITCH_VISIT
  386. #endif
  387. struct base {
  388. template <typename Visitor, typename... Vs>
  389. using dispatch_result_t = decltype(
  390. lib::invoke(std::declval<Visitor>(),
  391. access::base::get_alt<0>(std::declval<Vs>())...));
  392. template <typename Expected>
  393. struct expected {
  394. template <typename Actual>
  395. inline static constexpr bool but_got() {
  396. return std::is_same<Expected, Actual>::value;
  397. }
  398. };
  399. template <typename Expected, typename Actual>
  400. struct visit_return_type_check {
  401. static_assert(
  402. expected<Expected>::template but_got<Actual>(),
  403. "`visit` requires the visitor to have a single return type");
  404. template <typename Visitor, typename... Alts>
  405. inline static constexpr DECLTYPE_AUTO invoke(Visitor &&visitor,
  406. Alts &&... alts)
  407. DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
  408. lib::forward<Alts>(alts)...))
  409. };
  410. #ifdef MPARK_VARIANT_SWITCH_VISIT
  411. template <bool B, typename R, typename... ITs>
  412. struct dispatcher;
  413. template <typename R, typename... ITs>
  414. struct dispatcher<false, R, ITs...> {
  415. template <std::size_t B, typename F, typename... Vs>
  416. MPARK_ALWAYS_INLINE static constexpr R dispatch(
  417. F &&, typename ITs::type &&..., Vs &&...) {
  418. MPARK_BUILTIN_UNREACHABLE;
  419. }
  420. template <std::size_t I, typename F, typename... Vs>
  421. MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F &&, Vs &&...) {
  422. MPARK_BUILTIN_UNREACHABLE;
  423. }
  424. template <std::size_t B, typename F, typename... Vs>
  425. MPARK_ALWAYS_INLINE static constexpr R dispatch_at(std::size_t,
  426. F &&,
  427. Vs &&...) {
  428. MPARK_BUILTIN_UNREACHABLE;
  429. }
  430. };
  431. template <typename R, typename... ITs>
  432. struct dispatcher<true, R, ITs...> {
  433. template <std::size_t B, typename F>
  434. MPARK_ALWAYS_INLINE static constexpr R dispatch(
  435. F &&f, typename ITs::type &&... visited_vs) {
  436. using Expected = R;
  437. using Actual = decltype(lib::invoke(
  438. lib::forward<F>(f),
  439. access::base::get_alt<ITs::value>(
  440. lib::forward<typename ITs::type>(visited_vs))...));
  441. return visit_return_type_check<Expected, Actual>::invoke(
  442. lib::forward<F>(f),
  443. access::base::get_alt<ITs::value>(
  444. lib::forward<typename ITs::type>(visited_vs))...);
  445. }
  446. template <std::size_t B, typename F, typename V, typename... Vs>
  447. MPARK_ALWAYS_INLINE static constexpr R dispatch(
  448. F &&f, typename ITs::type &&... visited_vs, V &&v, Vs &&... vs) {
  449. #define MPARK_DISPATCH(I) \
  450. dispatcher<(I < lib::decay_t<V>::size()), \
  451. R, \
  452. ITs..., \
  453. lib::indexed_type<I, V>>:: \
  454. template dispatch<0>(lib::forward<F>(f), \
  455. lib::forward<typename ITs::type>(visited_vs)..., \
  456. lib::forward<V>(v), \
  457. lib::forward<Vs>(vs)...)
  458. #define MPARK_DEFAULT(I) \
  459. dispatcher<(I < lib::decay_t<V>::size()), R, ITs...>::template dispatch<I>( \
  460. lib::forward<F>(f), \
  461. lib::forward<typename ITs::type>(visited_vs)..., \
  462. lib::forward<V>(v), \
  463. lib::forward<Vs>(vs)...)
  464. switch (v.index()) {
  465. case B + 0: return MPARK_DISPATCH(B + 0);
  466. case B + 1: return MPARK_DISPATCH(B + 1);
  467. case B + 2: return MPARK_DISPATCH(B + 2);
  468. case B + 3: return MPARK_DISPATCH(B + 3);
  469. case B + 4: return MPARK_DISPATCH(B + 4);
  470. case B + 5: return MPARK_DISPATCH(B + 5);
  471. case B + 6: return MPARK_DISPATCH(B + 6);
  472. case B + 7: return MPARK_DISPATCH(B + 7);
  473. case B + 8: return MPARK_DISPATCH(B + 8);
  474. case B + 9: return MPARK_DISPATCH(B + 9);
  475. case B + 10: return MPARK_DISPATCH(B + 10);
  476. case B + 11: return MPARK_DISPATCH(B + 11);
  477. case B + 12: return MPARK_DISPATCH(B + 12);
  478. case B + 13: return MPARK_DISPATCH(B + 13);
  479. case B + 14: return MPARK_DISPATCH(B + 14);
  480. case B + 15: return MPARK_DISPATCH(B + 15);
  481. case B + 16: return MPARK_DISPATCH(B + 16);
  482. case B + 17: return MPARK_DISPATCH(B + 17);
  483. case B + 18: return MPARK_DISPATCH(B + 18);
  484. case B + 19: return MPARK_DISPATCH(B + 19);
  485. case B + 20: return MPARK_DISPATCH(B + 20);
  486. case B + 21: return MPARK_DISPATCH(B + 21);
  487. case B + 22: return MPARK_DISPATCH(B + 22);
  488. case B + 23: return MPARK_DISPATCH(B + 23);
  489. case B + 24: return MPARK_DISPATCH(B + 24);
  490. case B + 25: return MPARK_DISPATCH(B + 25);
  491. case B + 26: return MPARK_DISPATCH(B + 26);
  492. case B + 27: return MPARK_DISPATCH(B + 27);
  493. case B + 28: return MPARK_DISPATCH(B + 28);
  494. case B + 29: return MPARK_DISPATCH(B + 29);
  495. case B + 30: return MPARK_DISPATCH(B + 30);
  496. case B + 31: return MPARK_DISPATCH(B + 31);
  497. default: return MPARK_DEFAULT(B + 32);
  498. }
  499. #undef MPARK_DEFAULT
  500. #undef MPARK_DISPATCH
  501. }
  502. template <std::size_t I, typename F, typename... Vs>
  503. MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F &&f,
  504. Vs &&... vs) {
  505. using Expected = R;
  506. using Actual = decltype(
  507. lib::invoke(lib::forward<F>(f),
  508. access::base::get_alt<I>(lib::forward<Vs>(vs))...));
  509. return visit_return_type_check<Expected, Actual>::invoke(
  510. lib::forward<F>(f),
  511. access::base::get_alt<I>(lib::forward<Vs>(vs))...);
  512. }
  513. template <std::size_t B, typename F, typename V, typename... Vs>
  514. MPARK_ALWAYS_INLINE static constexpr R dispatch_at(std::size_t index,
  515. F &&f,
  516. V &&v,
  517. Vs &&... vs) {
  518. static_assert(lib::all<(lib::decay_t<V>::size() ==
  519. lib::decay_t<Vs>::size())...>::value,
  520. "all of the variants must be the same size.");
  521. #define MPARK_DISPATCH_AT(I) \
  522. dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_case<I>( \
  523. lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
  524. #define MPARK_DEFAULT(I) \
  525. dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_at<I>( \
  526. index, lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
  527. switch (index) {
  528. case B + 0: return MPARK_DISPATCH_AT(B + 0);
  529. case B + 1: return MPARK_DISPATCH_AT(B + 1);
  530. case B + 2: return MPARK_DISPATCH_AT(B + 2);
  531. case B + 3: return MPARK_DISPATCH_AT(B + 3);
  532. case B + 4: return MPARK_DISPATCH_AT(B + 4);
  533. case B + 5: return MPARK_DISPATCH_AT(B + 5);
  534. case B + 6: return MPARK_DISPATCH_AT(B + 6);
  535. case B + 7: return MPARK_DISPATCH_AT(B + 7);
  536. case B + 8: return MPARK_DISPATCH_AT(B + 8);
  537. case B + 9: return MPARK_DISPATCH_AT(B + 9);
  538. case B + 10: return MPARK_DISPATCH_AT(B + 10);
  539. case B + 11: return MPARK_DISPATCH_AT(B + 11);
  540. case B + 12: return MPARK_DISPATCH_AT(B + 12);
  541. case B + 13: return MPARK_DISPATCH_AT(B + 13);
  542. case B + 14: return MPARK_DISPATCH_AT(B + 14);
  543. case B + 15: return MPARK_DISPATCH_AT(B + 15);
  544. case B + 16: return MPARK_DISPATCH_AT(B + 16);
  545. case B + 17: return MPARK_DISPATCH_AT(B + 17);
  546. case B + 18: return MPARK_DISPATCH_AT(B + 18);
  547. case B + 19: return MPARK_DISPATCH_AT(B + 19);
  548. case B + 20: return MPARK_DISPATCH_AT(B + 20);
  549. case B + 21: return MPARK_DISPATCH_AT(B + 21);
  550. case B + 22: return MPARK_DISPATCH_AT(B + 22);
  551. case B + 23: return MPARK_DISPATCH_AT(B + 23);
  552. case B + 24: return MPARK_DISPATCH_AT(B + 24);
  553. case B + 25: return MPARK_DISPATCH_AT(B + 25);
  554. case B + 26: return MPARK_DISPATCH_AT(B + 26);
  555. case B + 27: return MPARK_DISPATCH_AT(B + 27);
  556. case B + 28: return MPARK_DISPATCH_AT(B + 28);
  557. case B + 29: return MPARK_DISPATCH_AT(B + 29);
  558. case B + 30: return MPARK_DISPATCH_AT(B + 30);
  559. case B + 31: return MPARK_DISPATCH_AT(B + 31);
  560. default: return MPARK_DEFAULT(B + 32);
  561. }
  562. #undef MPARK_DEFAULT
  563. #undef MPARK_DISPATCH_AT
  564. }
  565. };
  566. #else
  567. template <typename T>
  568. inline static constexpr const T &at(const T &elem) noexcept {
  569. return elem;
  570. }
  571. template <typename T, std::size_t N, typename... Is>
  572. inline static constexpr const lib::remove_all_extents_t<T> &at(
  573. const lib::array<T, N> &elems, std::size_t i, Is... is) noexcept {
  574. return at(elems[i], is...);
  575. }
  576. template <typename F, typename... Fs>
  577. inline static constexpr lib::array<lib::decay_t<F>, sizeof...(Fs) + 1>
  578. make_farray(F &&f, Fs &&... fs) {
  579. return {{lib::forward<F>(f), lib::forward<Fs>(fs)...}};
  580. }
  581. template <typename F, typename... Vs>
  582. struct make_fmatrix_impl {
  583. template <std::size_t... Is>
  584. inline static constexpr dispatch_result_t<F, Vs...> dispatch(
  585. F &&f, Vs &&... vs) {
  586. using Expected = dispatch_result_t<F, Vs...>;
  587. using Actual = decltype(lib::invoke(
  588. lib::forward<F>(f),
  589. access::base::get_alt<Is>(lib::forward<Vs>(vs))...));
  590. return visit_return_type_check<Expected, Actual>::invoke(
  591. lib::forward<F>(f),
  592. access::base::get_alt<Is>(lib::forward<Vs>(vs))...);
  593. }
  594. #ifdef MPARK_RETURN_TYPE_DEDUCTION
  595. template <std::size_t... Is>
  596. inline static constexpr auto impl(lib::index_sequence<Is...>) {
  597. return &dispatch<Is...>;
  598. }
  599. template <typename Is, std::size_t... Js, typename... Ls>
  600. inline static constexpr auto impl(Is,
  601. lib::index_sequence<Js...>,
  602. Ls... ls) {
  603. return make_farray(impl(lib::push_back_t<Is, Js>{}, ls...)...);
  604. }
  605. #else
  606. template <typename...>
  607. struct impl;
  608. template <std::size_t... Is>
  609. struct impl<lib::index_sequence<Is...>> {
  610. inline constexpr AUTO operator()() const
  611. AUTO_RETURN(&dispatch<Is...>)
  612. };
  613. template <typename Is, std::size_t... Js, typename... Ls>
  614. struct impl<Is, lib::index_sequence<Js...>, Ls...> {
  615. inline constexpr AUTO operator()() const
  616. AUTO_RETURN(
  617. make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
  618. };
  619. #endif
  620. };
  621. #ifdef MPARK_RETURN_TYPE_DEDUCTION
  622. template <typename F, typename... Vs>
  623. inline static constexpr auto make_fmatrix() {
  624. return make_fmatrix_impl<F, Vs...>::impl(
  625. lib::index_sequence<>{},
  626. lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
  627. }
  628. #else
  629. template <typename F, typename... Vs>
  630. inline static constexpr AUTO make_fmatrix()
  631. AUTO_RETURN(
  632. typename make_fmatrix_impl<F, Vs...>::template impl<
  633. lib::index_sequence<>,
  634. lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
  635. #endif
  636. template <typename F, typename... Vs>
  637. struct make_fdiagonal_impl {
  638. template <std::size_t I>
  639. inline static constexpr dispatch_result_t<F, Vs...> dispatch(
  640. F &&f, Vs &&... vs) {
  641. using Expected = dispatch_result_t<F, Vs...>;
  642. using Actual = decltype(
  643. lib::invoke(lib::forward<F>(f),
  644. access::base::get_alt<I>(lib::forward<Vs>(vs))...));
  645. return visit_return_type_check<Expected, Actual>::invoke(
  646. lib::forward<F>(f),
  647. access::base::get_alt<I>(lib::forward<Vs>(vs))...);
  648. }
  649. template <std::size_t... Is>
  650. inline static constexpr AUTO impl(lib::index_sequence<Is...>)
  651. AUTO_RETURN(make_farray(&dispatch<Is>...))
  652. };
  653. template <typename F, typename V, typename... Vs>
  654. inline static constexpr auto make_fdiagonal()
  655. -> decltype(make_fdiagonal_impl<F, V, Vs...>::impl(
  656. lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
  657. static_assert(lib::all<(lib::decay_t<V>::size() ==
  658. lib::decay_t<Vs>::size())...>::value,
  659. "all of the variants must be the same size.");
  660. return make_fdiagonal_impl<F, V, Vs...>::impl(
  661. lib::make_index_sequence<lib::decay_t<V>::size()>{});
  662. }
  663. #endif
  664. };
  665. #if !defined(MPARK_VARIANT_SWITCH_VISIT) && \
  666. (!defined(_MSC_VER) || _MSC_VER >= 1910)
  667. template <typename F, typename... Vs>
  668. using fmatrix_t = decltype(base::make_fmatrix<F, Vs...>());
  669. template <typename F, typename... Vs>
  670. struct fmatrix {
  671. static constexpr fmatrix_t<F, Vs...> value =
  672. base::make_fmatrix<F, Vs...>();
  673. };
  674. template <typename F, typename... Vs>
  675. constexpr fmatrix_t<F, Vs...> fmatrix<F, Vs...>::value;
  676. template <typename F, typename... Vs>
  677. using fdiagonal_t = decltype(base::make_fdiagonal<F, Vs...>());
  678. template <typename F, typename... Vs>
  679. struct fdiagonal {
  680. static constexpr fdiagonal_t<F, Vs...> value =
  681. base::make_fdiagonal<F, Vs...>();
  682. };
  683. template <typename F, typename... Vs>
  684. constexpr fdiagonal_t<F, Vs...> fdiagonal<F, Vs...>::value;
  685. #endif
  686. struct alt {
  687. template <typename Visitor, typename... Vs>
  688. inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
  689. Vs &&... vs)
  690. #ifdef MPARK_VARIANT_SWITCH_VISIT
  691. DECLTYPE_AUTO_RETURN(
  692. base::dispatcher<
  693. true,
  694. base::dispatch_result_t<Visitor,
  695. decltype(as_base(
  696. lib::forward<Vs>(vs)))...>>::
  697. template dispatch<0>(lib::forward<Visitor>(visitor),
  698. as_base(lib::forward<Vs>(vs))...))
  699. #elif !defined(_MSC_VER) || _MSC_VER >= 1910
  700. DECLTYPE_AUTO_RETURN(base::at(
  701. fmatrix<Visitor &&,
  702. decltype(as_base(lib::forward<Vs>(vs)))...>::value,
  703. vs.index()...)(lib::forward<Visitor>(visitor),
  704. as_base(lib::forward<Vs>(vs))...))
  705. #else
  706. DECLTYPE_AUTO_RETURN(base::at(
  707. base::make_fmatrix<Visitor &&,
  708. decltype(as_base(lib::forward<Vs>(vs)))...>(),
  709. vs.index()...)(lib::forward<Visitor>(visitor),
  710. as_base(lib::forward<Vs>(vs))...))
  711. #endif
  712. template <typename Visitor, typename... Vs>
  713. inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
  714. Visitor &&visitor,
  715. Vs &&... vs)
  716. #ifdef MPARK_VARIANT_SWITCH_VISIT
  717. DECLTYPE_AUTO_RETURN(
  718. base::dispatcher<
  719. true,
  720. base::dispatch_result_t<Visitor,
  721. decltype(as_base(
  722. lib::forward<Vs>(vs)))...>>::
  723. template dispatch_at<0>(index,
  724. lib::forward<Visitor>(visitor),
  725. as_base(lib::forward<Vs>(vs))...))
  726. #elif !defined(_MSC_VER) || _MSC_VER >= 1910
  727. DECLTYPE_AUTO_RETURN(base::at(
  728. fdiagonal<Visitor &&,
  729. decltype(as_base(lib::forward<Vs>(vs)))...>::value,
  730. index)(lib::forward<Visitor>(visitor),
  731. as_base(lib::forward<Vs>(vs))...))
  732. #else
  733. DECLTYPE_AUTO_RETURN(base::at(
  734. base::make_fdiagonal<Visitor &&,
  735. decltype(as_base(lib::forward<Vs>(vs)))...>(),
  736. index)(lib::forward<Visitor>(visitor),
  737. as_base(lib::forward<Vs>(vs))...))
  738. #endif
  739. };
  740. struct variant {
  741. private:
  742. template <typename Visitor>
  743. struct visitor {
  744. template <typename... Values>
  745. inline static constexpr bool does_not_handle() {
  746. return lib::is_invocable<Visitor, Values...>::value;
  747. }
  748. };
  749. template <typename Visitor, typename... Values>
  750. struct visit_exhaustiveness_check {
  751. static_assert(visitor<Visitor>::template does_not_handle<Values...>(),
  752. "`visit` requires the visitor to be exhaustive.");
  753. inline static constexpr DECLTYPE_AUTO invoke(Visitor &&visitor,
  754. Values &&... values)
  755. DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
  756. lib::forward<Values>(values)...))
  757. };
  758. template <typename Visitor>
  759. struct value_visitor {
  760. Visitor &&visitor_;
  761. template <typename... Alts>
  762. inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
  763. DECLTYPE_AUTO_RETURN(
  764. visit_exhaustiveness_check<
  765. Visitor,
  766. decltype((lib::forward<Alts>(alts).value))...>::
  767. invoke(lib::forward<Visitor>(visitor_),
  768. lib::forward<Alts>(alts).value...))
  769. };
  770. template <typename Visitor>
  771. inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
  772. AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
  773. public:
  774. template <typename Visitor, typename... Vs>
  775. inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
  776. Vs &&... vs)
  777. DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor),
  778. lib::forward<Vs>(vs).impl_...))
  779. template <typename Visitor, typename... Vs>
  780. inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
  781. Visitor &&visitor,
  782. Vs &&... vs)
  783. DECLTYPE_AUTO_RETURN(
  784. alt::visit_alt_at(index,
  785. lib::forward<Visitor>(visitor),
  786. lib::forward<Vs>(vs).impl_...))
  787. template <typename Visitor, typename... Vs>
  788. inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
  789. Vs &&... vs)
  790. DECLTYPE_AUTO_RETURN(
  791. visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
  792. lib::forward<Vs>(vs)...))
  793. template <typename Visitor, typename... Vs>
  794. inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
  795. Visitor &&visitor,
  796. Vs &&... vs)
  797. DECLTYPE_AUTO_RETURN(
  798. visit_alt_at(index,
  799. make_value_visitor(lib::forward<Visitor>(visitor)),
  800. lib::forward<Vs>(vs)...))
  801. };
  802. } // namespace visitation
  803. template <std::size_t Index, typename T>
  804. struct alt {
  805. using value_type = T;
  806. #ifdef _MSC_VER
  807. #pragma warning(push)
  808. #pragma warning(disable : 4244)
  809. #endif
  810. template <typename... Args>
  811. inline explicit constexpr alt(in_place_t, Args &&... args)
  812. : value(lib::forward<Args>(args)...) {}
  813. #ifdef _MSC_VER
  814. #pragma warning(pop)
  815. #endif
  816. T value;
  817. };
  818. template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
  819. union recursive_union;
  820. template <Trait DestructibleTrait, std::size_t Index>
  821. union recursive_union<DestructibleTrait, Index> {};
  822. #define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor) \
  823. template <std::size_t Index, typename T, typename... Ts> \
  824. union recursive_union<destructible_trait, Index, T, Ts...> { \
  825. public: \
  826. inline explicit constexpr recursive_union(valueless_t) noexcept \
  827. : dummy_{} {} \
  828. \
  829. template <typename... Args> \
  830. inline explicit constexpr recursive_union(in_place_index_t<0>, \
  831. Args &&... args) \
  832. : head_(in_place_t{}, lib::forward<Args>(args)...) {} \
  833. \
  834. template <std::size_t I, typename... Args> \
  835. inline explicit constexpr recursive_union(in_place_index_t<I>, \
  836. Args &&... args) \
  837. : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
  838. \
  839. recursive_union(const recursive_union &) = default; \
  840. recursive_union(recursive_union &&) = default; \
  841. \
  842. destructor \
  843. \
  844. recursive_union &operator=(const recursive_union &) = default; \
  845. recursive_union &operator=(recursive_union &&) = default; \
  846. \
  847. private: \
  848. char dummy_; \
  849. alt<Index, T> head_; \
  850. recursive_union<destructible_trait, Index + 1, Ts...> tail_; \
  851. \
  852. friend struct access::recursive_union; \
  853. }
  854. MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
  855. ~recursive_union() = default;);
  856. MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
  857. ~recursive_union() {});
  858. MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
  859. ~recursive_union() = delete;);
  860. #undef MPARK_VARIANT_RECURSIVE_UNION
  861. using index_t = unsigned int;
  862. template <Trait DestructibleTrait, typename... Ts>
  863. class base {
  864. public:
  865. inline explicit constexpr base(valueless_t tag) noexcept
  866. : data_(tag), index_(static_cast<index_t>(-1)) {}
  867. template <std::size_t I, typename... Args>
  868. inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
  869. : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
  870. index_(I) {}
  871. inline constexpr bool valueless_by_exception() const noexcept {
  872. return index_ == static_cast<index_t>(-1);
  873. }
  874. inline constexpr std::size_t index() const noexcept {
  875. return valueless_by_exception() ? variant_npos : index_;
  876. }
  877. protected:
  878. using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
  879. friend inline constexpr base &as_base(base &b) { return b; }
  880. friend inline constexpr const base &as_base(const base &b) { return b; }
  881. friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
  882. friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
  883. friend inline constexpr data_t &data(base &b) { return b.data_; }
  884. friend inline constexpr const data_t &data(const base &b) { return b.data_; }
  885. friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
  886. friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
  887. inline static constexpr std::size_t size() { return sizeof...(Ts); }
  888. data_t data_;
  889. index_t index_;
  890. friend struct access::base;
  891. friend struct visitation::base;
  892. };
  893. struct dtor {
  894. #ifdef _MSC_VER
  895. #pragma warning(push)
  896. #pragma warning(disable : 4100)
  897. #endif
  898. template <typename Alt>
  899. inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
  900. #ifdef _MSC_VER
  901. #pragma warning(pop)
  902. #endif
  903. };
  904. #if !defined(_MSC_VER) || _MSC_VER >= 1910
  905. #define MPARK_INHERITING_CTOR(type, base) using base::base;
  906. #else
  907. #define MPARK_INHERITING_CTOR(type, base) \
  908. template <typename... Args> \
  909. inline explicit constexpr type(Args &&... args) \
  910. : base(lib::forward<Args>(args)...) {}
  911. #endif
  912. template <typename Traits, Trait = Traits::destructible_trait>
  913. class destructor;
  914. #define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
  915. template <typename... Ts> \
  916. class destructor<traits<Ts...>, destructible_trait> \
  917. : public base<destructible_trait, Ts...> { \
  918. using super = base<destructible_trait, Ts...>; \
  919. \
  920. public: \
  921. MPARK_INHERITING_CTOR(destructor, super) \
  922. using super::operator=; \
  923. \
  924. destructor(const destructor &) = default; \
  925. destructor(destructor &&) = default; \
  926. definition \
  927. destructor &operator=(const destructor &) = default; \
  928. destructor &operator=(destructor &&) = default; \
  929. \
  930. protected: \
  931. destroy \
  932. }
  933. MPARK_VARIANT_DESTRUCTOR(
  934. Trait::TriviallyAvailable,
  935. ~destructor() = default;,
  936. inline void destroy() noexcept {
  937. this->index_ = static_cast<index_t>(-1);
  938. });
  939. MPARK_VARIANT_DESTRUCTOR(
  940. Trait::Available,
  941. ~destructor() { destroy(); },
  942. inline void destroy() noexcept {
  943. if (!this->valueless_by_exception()) {
  944. visitation::alt::visit_alt(dtor{}, *this);
  945. }
  946. this->index_ = static_cast<index_t>(-1);
  947. });
  948. MPARK_VARIANT_DESTRUCTOR(
  949. Trait::Unavailable,
  950. ~destructor() = delete;,
  951. inline void destroy() noexcept = delete;);
  952. #undef MPARK_VARIANT_DESTRUCTOR
  953. template <typename Traits>
  954. class constructor : public destructor<Traits> {
  955. using super = destructor<Traits>;
  956. public:
  957. MPARK_INHERITING_CTOR(constructor, super)
  958. using super::operator=;
  959. protected:
  960. #ifndef MPARK_GENERIC_LAMBDAS
  961. struct ctor {
  962. template <typename LhsAlt, typename RhsAlt>
  963. inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
  964. constructor::construct_alt(lhs_alt,
  965. lib::forward<RhsAlt>(rhs_alt).value);
  966. }
  967. };
  968. #endif
  969. template <std::size_t I, typename T, typename... Args>
  970. inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
  971. auto *result = ::new (static_cast<void *>(lib::addressof(a)))
  972. alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
  973. return result->value;
  974. }
  975. template <typename Rhs>
  976. inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
  977. lhs.destroy();
  978. if (!rhs.valueless_by_exception()) {
  979. visitation::alt::visit_alt_at(
  980. rhs.index(),
  981. #ifdef MPARK_GENERIC_LAMBDAS
  982. [](auto &lhs_alt, auto &&rhs_alt) {
  983. constructor::construct_alt(
  984. lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
  985. }
  986. #else
  987. ctor{}
  988. #endif
  989. ,
  990. lhs,
  991. lib::forward<Rhs>(rhs));
  992. lhs.index_ = rhs.index_;
  993. }
  994. }
  995. };
  996. template <typename Traits, Trait = Traits::move_constructible_trait>
  997. class move_constructor;
  998. #define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
  999. template <typename... Ts> \
  1000. class move_constructor<traits<Ts...>, move_constructible_trait> \
  1001. : public constructor<traits<Ts...>> { \
  1002. using super = constructor<traits<Ts...>>; \
  1003. \
  1004. public: \
  1005. MPARK_INHERITING_CTOR(move_constructor, super) \
  1006. using super::operator=; \
  1007. \
  1008. move_constructor(const move_constructor &) = default; \
  1009. definition \
  1010. ~move_constructor() = default; \
  1011. move_constructor &operator=(const move_constructor &) = default; \
  1012. move_constructor &operator=(move_constructor &&) = default; \
  1013. }
  1014. MPARK_VARIANT_MOVE_CONSTRUCTOR(
  1015. Trait::TriviallyAvailable,
  1016. move_constructor(move_constructor &&that) = default;);
  1017. MPARK_VARIANT_MOVE_CONSTRUCTOR(
  1018. Trait::Available,
  1019. move_constructor(move_constructor &&that) noexcept(
  1020. lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
  1021. : move_constructor(valueless_t{}) {
  1022. this->generic_construct(*this, lib::move(that));
  1023. });
  1024. MPARK_VARIANT_MOVE_CONSTRUCTOR(
  1025. Trait::Unavailable,
  1026. move_constructor(move_constructor &&) = delete;);
  1027. #undef MPARK_VARIANT_MOVE_CONSTRUCTOR
  1028. template <typename Traits, Trait = Traits::copy_constructible_trait>
  1029. class copy_constructor;
  1030. #define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
  1031. template <typename... Ts> \
  1032. class copy_constructor<traits<Ts...>, copy_constructible_trait> \
  1033. : public move_constructor<traits<Ts...>> { \
  1034. using super = move_constructor<traits<Ts...>>; \
  1035. \
  1036. public: \
  1037. MPARK_INHERITING_CTOR(copy_constructor, super) \
  1038. using super::operator=; \
  1039. \
  1040. definition \
  1041. copy_constructor(copy_constructor &&) = default; \
  1042. ~copy_constructor() = default; \
  1043. copy_constructor &operator=(const copy_constructor &) = default; \
  1044. copy_constructor &operator=(copy_constructor &&) = default; \
  1045. }
  1046. MPARK_VARIANT_COPY_CONSTRUCTOR(
  1047. Trait::TriviallyAvailable,
  1048. copy_constructor(const copy_constructor &that) = default;);
  1049. MPARK_VARIANT_COPY_CONSTRUCTOR(
  1050. Trait::Available,
  1051. copy_constructor(const copy_constructor &that)
  1052. : copy_constructor(valueless_t{}) {
  1053. this->generic_construct(*this, that);
  1054. });
  1055. MPARK_VARIANT_COPY_CONSTRUCTOR(
  1056. Trait::Unavailable,
  1057. copy_constructor(const copy_constructor &) = delete;);
  1058. #undef MPARK_VARIANT_COPY_CONSTRUCTOR
  1059. template <typename Traits>
  1060. class assignment : public copy_constructor<Traits> {
  1061. using super = copy_constructor<Traits>;
  1062. public:
  1063. MPARK_INHERITING_CTOR(assignment, super)
  1064. using super::operator=;
  1065. template <std::size_t I, typename... Args>
  1066. inline /* auto & */ auto emplace(Args &&... args)
  1067. -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
  1068. lib::forward<Args>(args)...)) {
  1069. this->destroy();
  1070. auto &result = this->construct_alt(access::base::get_alt<I>(*this),
  1071. lib::forward<Args>(args)...);
  1072. this->index_ = I;
  1073. return result;
  1074. }
  1075. protected:
  1076. #ifndef MPARK_GENERIC_LAMBDAS
  1077. template <typename That>
  1078. struct assigner {
  1079. template <typename ThisAlt, typename ThatAlt>
  1080. inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
  1081. self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
  1082. }
  1083. assignment *self;
  1084. };
  1085. #endif
  1086. template <std::size_t I, typename T, typename Arg>
  1087. inline void assign_alt(alt<I, T> &a, Arg &&arg) {
  1088. if (this->index() == I) {
  1089. #ifdef _MSC_VER
  1090. #pragma warning(push)
  1091. #pragma warning(disable : 4244)
  1092. #endif
  1093. a.value = lib::forward<Arg>(arg);
  1094. #ifdef _MSC_VER
  1095. #pragma warning(pop)
  1096. #endif
  1097. } else {
  1098. struct {
  1099. void operator()(std::true_type) const {
  1100. this_->emplace<I>(lib::forward<Arg>(arg_));
  1101. }
  1102. void operator()(std::false_type) const {
  1103. this_->emplace<I>(T(lib::forward<Arg>(arg_)));
  1104. }
  1105. assignment *this_;
  1106. Arg &&arg_;
  1107. } impl{this, lib::forward<Arg>(arg)};
  1108. impl(lib::bool_constant<
  1109. std::is_nothrow_constructible<T, Arg>::value ||
  1110. !std::is_nothrow_move_constructible<T>::value>{});
  1111. }
  1112. }
  1113. template <typename That>
  1114. inline void generic_assign(That &&that) {
  1115. if (this->valueless_by_exception() && that.valueless_by_exception()) {
  1116. // do nothing.
  1117. } else if (that.valueless_by_exception()) {
  1118. this->destroy();
  1119. } else {
  1120. visitation::alt::visit_alt_at(
  1121. that.index(),
  1122. #ifdef MPARK_GENERIC_LAMBDAS
  1123. [this](auto &this_alt, auto &&that_alt) {
  1124. this->assign_alt(
  1125. this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
  1126. }
  1127. #else
  1128. assigner<That>{this}
  1129. #endif
  1130. ,
  1131. *this,
  1132. lib::forward<That>(that));
  1133. }
  1134. }
  1135. };
  1136. template <typename Traits, Trait = Traits::move_assignable_trait>
  1137. class move_assignment;
  1138. #define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
  1139. template <typename... Ts> \
  1140. class move_assignment<traits<Ts...>, move_assignable_trait> \
  1141. : public assignment<traits<Ts...>> { \
  1142. using super = assignment<traits<Ts...>>; \
  1143. \
  1144. public: \
  1145. MPARK_INHERITING_CTOR(move_assignment, super) \
  1146. using super::operator=; \
  1147. \
  1148. move_assignment(const move_assignment &) = default; \
  1149. move_assignment(move_assignment &&) = default; \
  1150. ~move_assignment() = default; \
  1151. move_assignment &operator=(const move_assignment &) = default; \
  1152. definition \
  1153. }
  1154. MPARK_VARIANT_MOVE_ASSIGNMENT(
  1155. Trait::TriviallyAvailable,
  1156. move_assignment &operator=(move_assignment &&that) = default;);
  1157. MPARK_VARIANT_MOVE_ASSIGNMENT(
  1158. Trait::Available,
  1159. move_assignment &
  1160. operator=(move_assignment &&that) noexcept(
  1161. lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
  1162. std::is_nothrow_move_assignable<Ts>::value)...>::value) {
  1163. this->generic_assign(lib::move(that));
  1164. return *this;
  1165. });
  1166. MPARK_VARIANT_MOVE_ASSIGNMENT(
  1167. Trait::Unavailable,
  1168. move_assignment &operator=(move_assignment &&) = delete;);
  1169. #undef MPARK_VARIANT_MOVE_ASSIGNMENT
  1170. template <typename Traits, Trait = Traits::copy_assignable_trait>
  1171. class copy_assignment;
  1172. #define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
  1173. template <typename... Ts> \
  1174. class copy_assignment<traits<Ts...>, copy_assignable_trait> \
  1175. : public move_assignment<traits<Ts...>> { \
  1176. using super = move_assignment<traits<Ts...>>; \
  1177. \
  1178. public: \
  1179. MPARK_INHERITING_CTOR(copy_assignment, super) \
  1180. using super::operator=; \
  1181. \
  1182. copy_assignment(const copy_assignment &) = default; \
  1183. copy_assignment(copy_assignment &&) = default; \
  1184. ~copy_assignment() = default; \
  1185. definition \
  1186. copy_assignment &operator=(copy_assignment &&) = default; \
  1187. }
  1188. MPARK_VARIANT_COPY_ASSIGNMENT(
  1189. Trait::TriviallyAvailable,
  1190. copy_assignment &operator=(const copy_assignment &that) = default;);
  1191. MPARK_VARIANT_COPY_ASSIGNMENT(
  1192. Trait::Available,
  1193. copy_assignment &operator=(const copy_assignment &that) {
  1194. this->generic_assign(that);
  1195. return *this;
  1196. });
  1197. MPARK_VARIANT_COPY_ASSIGNMENT(
  1198. Trait::Unavailable,
  1199. copy_assignment &operator=(const copy_assignment &) = delete;);
  1200. #undef MPARK_VARIANT_COPY_ASSIGNMENT
  1201. template <typename... Ts>
  1202. class impl : public copy_assignment<traits<Ts...>> {
  1203. using super = copy_assignment<traits<Ts...>>;
  1204. public:
  1205. MPARK_INHERITING_CTOR(impl, super)
  1206. using super::operator=;
  1207. template <std::size_t I, typename Arg>
  1208. inline void assign(Arg &&arg) {
  1209. this->assign_alt(access::base::get_alt<I>(*this),
  1210. lib::forward<Arg>(arg));
  1211. }
  1212. inline void swap(impl &that) {
  1213. if (this->valueless_by_exception() && that.valueless_by_exception()) {
  1214. // do nothing.
  1215. } else if (this->index() == that.index()) {
  1216. visitation::alt::visit_alt_at(this->index(),
  1217. #ifdef MPARK_GENERIC_LAMBDAS
  1218. [](auto &this_alt, auto &that_alt) {
  1219. using std::swap;
  1220. swap(this_alt.value,
  1221. that_alt.value);
  1222. }
  1223. #else
  1224. swapper{}
  1225. #endif
  1226. ,
  1227. *this,
  1228. that);
  1229. } else {
  1230. impl *lhs = this;
  1231. impl *rhs = lib::addressof(that);
  1232. if (lhs->move_nothrow() && !rhs->move_nothrow()) {
  1233. std::swap(lhs, rhs);
  1234. }
  1235. impl tmp(lib::move(*rhs));
  1236. #ifdef MPARK_EXCEPTIONS
  1237. // EXTENSION: When the move construction of `lhs` into `rhs` throws
  1238. // and `tmp` is nothrow move constructible then we move `tmp` back
  1239. // into `rhs` and provide the strong exception safety guarantee.
  1240. try {
  1241. this->generic_construct(*rhs, lib::move(*lhs));
  1242. } catch (...) {
  1243. if (tmp.move_nothrow()) {
  1244. this->generic_construct(*rhs, lib::move(tmp));
  1245. }
  1246. throw;
  1247. }
  1248. #else
  1249. this->generic_construct(*rhs, lib::move(*lhs));
  1250. #endif
  1251. this->generic_construct(*lhs, lib::move(tmp));
  1252. }
  1253. }
  1254. private:
  1255. #ifndef MPARK_GENERIC_LAMBDAS
  1256. struct swapper {
  1257. template <typename ThisAlt, typename ThatAlt>
  1258. inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
  1259. using std::swap;
  1260. swap(this_alt.value, that_alt.value);
  1261. }
  1262. };
  1263. #endif
  1264. inline constexpr bool move_nothrow() const {
  1265. return this->valueless_by_exception() ||
  1266. lib::array<bool, sizeof...(Ts)>{
  1267. {std::is_nothrow_move_constructible<Ts>::value...}
  1268. }[this->index()];
  1269. }
  1270. };
  1271. #undef MPARK_INHERITING_CTOR
  1272. template <std::size_t I, typename T>
  1273. struct overload_leaf {
  1274. using F = lib::size_constant<I> (*)(T);
  1275. operator F() const { return nullptr; }
  1276. };
  1277. template <typename... Ts>
  1278. struct overload_impl {
  1279. private:
  1280. template <typename>
  1281. struct impl;
  1282. template <std::size_t... Is>
  1283. struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
  1284. public:
  1285. using type = impl<lib::index_sequence_for<Ts...>>;
  1286. };
  1287. template <typename... Ts>
  1288. using overload = typename overload_impl<Ts...>::type;
  1289. template <typename T, typename... Ts>
  1290. using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
  1291. template <typename T>
  1292. struct is_in_place_index : std::false_type {};
  1293. template <std::size_t I>
  1294. struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
  1295. template <typename T>
  1296. struct is_in_place_type : std::false_type {};
  1297. template <typename T>
  1298. struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
  1299. } // detail
  1300. template <typename... Ts>
  1301. class variant {
  1302. static_assert(0 < sizeof...(Ts),
  1303. "variant must consist of at least one alternative.");
  1304. static_assert(lib::all<!std::is_array<Ts>::value...>::value,
  1305. "variant can not have an array type as an alternative.");
  1306. static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
  1307. "variant can not have a reference type as an alternative.");
  1308. static_assert(lib::all<!std::is_void<Ts>::value...>::value,
  1309. "variant can not have a void type as an alternative.");
  1310. public:
  1311. template <
  1312. typename Front = lib::type_pack_element_t<0, Ts...>,
  1313. lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
  1314. inline constexpr variant() noexcept(
  1315. std::is_nothrow_default_constructible<Front>::value)
  1316. : impl_(in_place_index_t<0>{}) {}
  1317. variant(const variant &) = default;
  1318. variant(variant &&) = default;
  1319. template <
  1320. typename Arg,
  1321. typename Decayed = lib::decay_t<Arg>,
  1322. lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
  1323. lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
  1324. lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
  1325. std::size_t I = detail::best_match<Arg, Ts...>::value,
  1326. typename T = lib::type_pack_element_t<I, Ts...>,
  1327. lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
  1328. inline constexpr variant(Arg &&arg) noexcept(
  1329. std::is_nothrow_constructible<T, Arg>::value)
  1330. : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
  1331. template <
  1332. std::size_t I,
  1333. typename... Args,
  1334. typename T = lib::type_pack_element_t<I, Ts...>,
  1335. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  1336. inline explicit constexpr variant(
  1337. in_place_index_t<I>,
  1338. Args &&... args) noexcept(std::is_nothrow_constructible<T,
  1339. Args...>::value)
  1340. : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
  1341. template <
  1342. std::size_t I,
  1343. typename Up,
  1344. typename... Args,
  1345. typename T = lib::type_pack_element_t<I, Ts...>,
  1346. lib::enable_if_t<std::is_constructible<T,
  1347. std::initializer_list<Up> &,
  1348. Args...>::value,
  1349. int> = 0>
  1350. inline explicit constexpr variant(
  1351. in_place_index_t<I>,
  1352. std::initializer_list<Up> il,
  1353. Args &&... args) noexcept(std::
  1354. is_nothrow_constructible<
  1355. T,
  1356. std::initializer_list<Up> &,
  1357. Args...>::value)
  1358. : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
  1359. template <
  1360. typename T,
  1361. typename... Args,
  1362. std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
  1363. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  1364. inline explicit constexpr variant(
  1365. in_place_type_t<T>,
  1366. Args &&... args) noexcept(std::is_nothrow_constructible<T,
  1367. Args...>::value)
  1368. : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
  1369. template <
  1370. typename T,
  1371. typename Up,
  1372. typename... Args,
  1373. std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
  1374. lib::enable_if_t<std::is_constructible<T,
  1375. std::initializer_list<Up> &,
  1376. Args...>::value,
  1377. int> = 0>
  1378. inline explicit constexpr variant(
  1379. in_place_type_t<T>,
  1380. std::initializer_list<Up> il,
  1381. Args &&... args) noexcept(std::
  1382. is_nothrow_constructible<
  1383. T,
  1384. std::initializer_list<Up> &,
  1385. Args...>::value)
  1386. : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
  1387. ~variant() = default;
  1388. variant &operator=(const variant &) = default;
  1389. variant &operator=(variant &&) = default;
  1390. template <typename Arg,
  1391. lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
  1392. int> = 0,
  1393. std::size_t I = detail::best_match<Arg, Ts...>::value,
  1394. typename T = lib::type_pack_element_t<I, Ts...>,
  1395. lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
  1396. std::is_constructible<T, Arg>::value),
  1397. int> = 0>
  1398. inline variant &operator=(Arg &&arg) noexcept(
  1399. (std::is_nothrow_assignable<T &, Arg>::value &&
  1400. std::is_nothrow_constructible<T, Arg>::value)) {
  1401. impl_.template assign<I>(lib::forward<Arg>(arg));
  1402. return *this;
  1403. }
  1404. template <
  1405. std::size_t I,
  1406. typename... Args,
  1407. typename T = lib::type_pack_element_t<I, Ts...>,
  1408. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  1409. inline T &emplace(Args &&... args) {
  1410. return impl_.template emplace<I>(lib::forward<Args>(args)...);
  1411. }
  1412. template <
  1413. std::size_t I,
  1414. typename Up,
  1415. typename... Args,
  1416. typename T = lib::type_pack_element_t<I, Ts...>,
  1417. lib::enable_if_t<std::is_constructible<T,
  1418. std::initializer_list<Up> &,
  1419. Args...>::value,
  1420. int> = 0>
  1421. inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
  1422. return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
  1423. }
  1424. template <
  1425. typename T,
  1426. typename... Args,
  1427. std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
  1428. lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
  1429. inline T &emplace(Args &&... args) {
  1430. return impl_.template emplace<I>(lib::forward<Args>(args)...);
  1431. }
  1432. template <
  1433. typename T,
  1434. typename Up,
  1435. typename... Args,
  1436. std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
  1437. lib::enable_if_t<std::is_constructible<T,
  1438. std::initializer_list<Up> &,
  1439. Args...>::value,
  1440. int> = 0>
  1441. inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
  1442. return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
  1443. }
  1444. inline constexpr bool valueless_by_exception() const noexcept {
  1445. return impl_.valueless_by_exception();
  1446. }
  1447. inline constexpr std::size_t index() const noexcept {
  1448. return impl_.index();
  1449. }
  1450. template <bool Dummy = true,
  1451. lib::enable_if_t<
  1452. lib::all<Dummy,
  1453. (lib::dependent_type<std::is_move_constructible<Ts>,
  1454. Dummy>::value &&
  1455. lib::dependent_type<lib::is_swappable<Ts>,
  1456. Dummy>::value)...>::value,
  1457. int> = 0>
  1458. inline void swap(variant &that) noexcept(
  1459. lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
  1460. lib::is_nothrow_swappable<Ts>::value)...>::value) {
  1461. impl_.swap(that.impl_);
  1462. }
  1463. private:
  1464. detail::impl<Ts...> impl_;
  1465. friend struct detail::access::variant;
  1466. friend struct detail::visitation::variant;
  1467. };
  1468. template <std::size_t I, typename... Ts>
  1469. inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
  1470. return v.index() == I;
  1471. }
  1472. template <typename T, typename... Ts>
  1473. inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
  1474. return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
  1475. }
  1476. namespace detail {
  1477. template <std::size_t I, typename V>
  1478. struct generic_get_impl {
  1479. constexpr generic_get_impl(int) noexcept {}
  1480. constexpr AUTO_REFREF operator()(V &&v) const
  1481. AUTO_REFREF_RETURN(
  1482. access::variant::get_alt<I>(lib::forward<V>(v)).value)
  1483. };
  1484. template <std::size_t I, typename V>
  1485. inline constexpr AUTO_REFREF generic_get(V &&v)
  1486. AUTO_REFREF_RETURN(generic_get_impl<I, V>(
  1487. holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
  1488. lib::forward<V>(v)))
  1489. } // namespace detail
  1490. template <std::size_t I, typename... Ts>
  1491. inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
  1492. variant<Ts...> &v) {
  1493. return detail::generic_get<I>(v);
  1494. }
  1495. template <std::size_t I, typename... Ts>
  1496. inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
  1497. variant<Ts...> &&v) {
  1498. return detail::generic_get<I>(lib::move(v));
  1499. }
  1500. template <std::size_t I, typename... Ts>
  1501. inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
  1502. const variant<Ts...> &v) {
  1503. return detail::generic_get<I>(v);
  1504. }
  1505. template <std::size_t I, typename... Ts>
  1506. inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
  1507. const variant<Ts...> &&v) {
  1508. return detail::generic_get<I>(lib::move(v));
  1509. }
  1510. template <typename T, typename... Ts>
  1511. inline constexpr T &get(variant<Ts...> &v) {
  1512. return get<detail::find_index_checked<T, Ts...>::value>(v);
  1513. }
  1514. template <typename T, typename... Ts>
  1515. inline constexpr T &&get(variant<Ts...> &&v) {
  1516. return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
  1517. }
  1518. template <typename T, typename... Ts>
  1519. inline constexpr const T &get(const variant<Ts...> &v) {
  1520. return get<detail::find_index_checked<T, Ts...>::value>(v);
  1521. }
  1522. template <typename T, typename... Ts>
  1523. inline constexpr const T &&get(const variant<Ts...> &&v) {
  1524. return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
  1525. }
  1526. namespace detail {
  1527. template <std::size_t I, typename V>
  1528. inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
  1529. AUTO_RETURN(v && holds_alternative<I>(*v)
  1530. ? lib::addressof(access::variant::get_alt<I>(*v).value)
  1531. : nullptr)
  1532. } // namespace detail
  1533. template <std::size_t I, typename... Ts>
  1534. inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
  1535. get_if(variant<Ts...> *v) noexcept {
  1536. return detail::generic_get_if<I>(v);
  1537. }
  1538. template <std::size_t I, typename... Ts>
  1539. inline constexpr lib::add_pointer_t<
  1540. const variant_alternative_t<I, variant<Ts...>>>
  1541. get_if(const variant<Ts...> *v) noexcept {
  1542. return detail::generic_get_if<I>(v);
  1543. }
  1544. template <typename T, typename... Ts>
  1545. inline constexpr lib::add_pointer_t<T>
  1546. get_if(variant<Ts...> *v) noexcept {
  1547. return get_if<detail::find_index_checked<T, Ts...>::value>(v);
  1548. }
  1549. template <typename T, typename... Ts>
  1550. inline constexpr lib::add_pointer_t<const T>
  1551. get_if(const variant<Ts...> *v) noexcept {
  1552. return get_if<detail::find_index_checked<T, Ts...>::value>(v);
  1553. }
  1554. namespace detail {
  1555. template <typename RelOp>
  1556. struct convert_to_bool {
  1557. template <typename Lhs, typename Rhs>
  1558. inline constexpr bool operator()(Lhs &&lhs, Rhs &&rhs) const {
  1559. static_assert(std::is_convertible<lib::invoke_result_t<RelOp, Lhs, Rhs>,
  1560. bool>::value,
  1561. "relational operators must return a type"
  1562. " implicitly convertible to bool");
  1563. return lib::invoke(
  1564. RelOp{}, lib::forward<Lhs>(lhs), lib::forward<Rhs>(rhs));
  1565. }
  1566. };
  1567. } // namespace detail
  1568. template <typename... Ts>
  1569. inline constexpr bool operator==(const variant<Ts...> &lhs,
  1570. const variant<Ts...> &rhs) {
  1571. using detail::visitation::variant;
  1572. using equal_to = detail::convert_to_bool<lib::equal_to>;
  1573. #ifdef MPARK_CPP14_CONSTEXPR
  1574. if (lhs.index() != rhs.index()) return false;
  1575. if (lhs.valueless_by_exception()) return true;
  1576. return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
  1577. #else
  1578. return lhs.index() == rhs.index() &&
  1579. (lhs.valueless_by_exception() ||
  1580. variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
  1581. #endif
  1582. }
  1583. template <typename... Ts>
  1584. inline constexpr bool operator!=(const variant<Ts...> &lhs,
  1585. const variant<Ts...> &rhs) {
  1586. using detail::visitation::variant;
  1587. using not_equal_to = detail::convert_to_bool<lib::not_equal_to>;
  1588. #ifdef MPARK_CPP14_CONSTEXPR
  1589. if (lhs.index() != rhs.index()) return true;
  1590. if (lhs.valueless_by_exception()) return false;
  1591. return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
  1592. #else
  1593. return lhs.index() != rhs.index() ||
  1594. (!lhs.valueless_by_exception() &&
  1595. variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
  1596. #endif
  1597. }
  1598. template <typename... Ts>
  1599. inline constexpr bool operator<(const variant<Ts...> &lhs,
  1600. const variant<Ts...> &rhs) {
  1601. using detail::visitation::variant;
  1602. using less = detail::convert_to_bool<lib::less>;
  1603. #ifdef MPARK_CPP14_CONSTEXPR
  1604. if (rhs.valueless_by_exception()) return false;
  1605. if (lhs.valueless_by_exception()) return true;
  1606. if (lhs.index() < rhs.index()) return true;
  1607. if (lhs.index() > rhs.index()) return false;
  1608. return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
  1609. #else
  1610. return !rhs.valueless_by_exception() &&
  1611. (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
  1612. (lhs.index() == rhs.index() &&
  1613. variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
  1614. #endif
  1615. }
  1616. template <typename... Ts>
  1617. inline constexpr bool operator>(const variant<Ts...> &lhs,
  1618. const variant<Ts...> &rhs) {
  1619. using detail::visitation::variant;
  1620. using greater = detail::convert_to_bool<lib::greater>;
  1621. #ifdef MPARK_CPP14_CONSTEXPR
  1622. if (lhs.valueless_by_exception()) return false;
  1623. if (rhs.valueless_by_exception()) return true;
  1624. if (lhs.index() > rhs.index()) return true;
  1625. if (lhs.index() < rhs.index()) return false;
  1626. return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
  1627. #else
  1628. return !lhs.valueless_by_exception() &&
  1629. (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
  1630. (lhs.index() == rhs.index() &&
  1631. variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
  1632. #endif
  1633. }
  1634. template <typename... Ts>
  1635. inline constexpr bool operator<=(const variant<Ts...> &lhs,
  1636. const variant<Ts...> &rhs) {
  1637. using detail::visitation::variant;
  1638. using less_equal = detail::convert_to_bool<lib::less_equal>;
  1639. #ifdef MPARK_CPP14_CONSTEXPR
  1640. if (lhs.valueless_by_exception()) return true;
  1641. if (rhs.valueless_by_exception()) return false;
  1642. if (lhs.index() < rhs.index()) return true;
  1643. if (lhs.index() > rhs.index()) return false;
  1644. return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
  1645. #else
  1646. return lhs.valueless_by_exception() ||
  1647. (!rhs.valueless_by_exception() &&
  1648. (lhs.index() < rhs.index() ||
  1649. (lhs.index() == rhs.index() &&
  1650. variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
  1651. #endif
  1652. }
  1653. template <typename... Ts>
  1654. inline constexpr bool operator>=(const variant<Ts...> &lhs,
  1655. const variant<Ts...> &rhs) {
  1656. using detail::visitation::variant;
  1657. using greater_equal = detail::convert_to_bool<lib::greater_equal>;
  1658. #ifdef MPARK_CPP14_CONSTEXPR
  1659. if (rhs.valueless_by_exception()) return true;
  1660. if (lhs.valueless_by_exception()) return false;
  1661. if (lhs.index() > rhs.index()) return true;
  1662. if (lhs.index() < rhs.index()) return false;
  1663. return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
  1664. #else
  1665. return rhs.valueless_by_exception() ||
  1666. (!lhs.valueless_by_exception() &&
  1667. (lhs.index() > rhs.index() ||
  1668. (lhs.index() == rhs.index() &&
  1669. variant::visit_value_at(
  1670. lhs.index(), greater_equal{}, lhs, rhs))));
  1671. #endif
  1672. }
  1673. struct monostate {};
  1674. inline constexpr bool operator<(monostate, monostate) noexcept {
  1675. return false;
  1676. }
  1677. inline constexpr bool operator>(monostate, monostate) noexcept {
  1678. return false;
  1679. }
  1680. inline constexpr bool operator<=(monostate, monostate) noexcept {
  1681. return true;
  1682. }
  1683. inline constexpr bool operator>=(monostate, monostate) noexcept {
  1684. return true;
  1685. }
  1686. inline constexpr bool operator==(monostate, monostate) noexcept {
  1687. return true;
  1688. }
  1689. inline constexpr bool operator!=(monostate, monostate) noexcept {
  1690. return false;
  1691. }
  1692. #ifdef MPARK_CPP14_CONSTEXPR
  1693. namespace detail {
  1694. inline constexpr bool all(std::initializer_list<bool> bs) {
  1695. for (bool b : bs) {
  1696. if (!b) {
  1697. return false;
  1698. }
  1699. }
  1700. return true;
  1701. }
  1702. } // namespace detail
  1703. template <typename Visitor, typename... Vs>
  1704. inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
  1705. return (detail::all({!vs.valueless_by_exception()...})
  1706. ? (void)0
  1707. : throw_bad_variant_access()),
  1708. detail::visitation::variant::visit_value(
  1709. lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
  1710. }
  1711. #else
  1712. namespace detail {
  1713. template <std::size_t N>
  1714. inline constexpr bool all_impl(const lib::array<bool, N> &bs,
  1715. std::size_t idx) {
  1716. return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
  1717. }
  1718. template <std::size_t N>
  1719. inline constexpr bool all(const lib::array<bool, N> &bs) {
  1720. return all_impl(bs, 0);
  1721. }
  1722. } // namespace detail
  1723. template <typename Visitor, typename... Vs>
  1724. inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
  1725. DECLTYPE_AUTO_RETURN(
  1726. (detail::all(
  1727. lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
  1728. ? (void)0
  1729. : throw_bad_variant_access()),
  1730. detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
  1731. lib::forward<Vs>(vs)...))
  1732. #endif
  1733. template <typename... Ts>
  1734. inline auto swap(variant<Ts...> &lhs,
  1735. variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
  1736. -> decltype(lhs.swap(rhs)) {
  1737. lhs.swap(rhs);
  1738. }
  1739. namespace detail {
  1740. template <typename T, typename...>
  1741. using enabled_type = T;
  1742. namespace hash {
  1743. template <typename H, typename K>
  1744. constexpr bool meets_requirements() noexcept {
  1745. return std::is_copy_constructible<H>::value &&
  1746. std::is_move_constructible<H>::value &&
  1747. lib::is_invocable_r<std::size_t, H, const K &>::value;
  1748. }
  1749. template <typename K>
  1750. constexpr bool is_enabled() noexcept {
  1751. using H = std::hash<K>;
  1752. return meets_requirements<H, K>() &&
  1753. std::is_default_constructible<H>::value &&
  1754. std::is_copy_assignable<H>::value &&
  1755. std::is_move_assignable<H>::value;
  1756. }
  1757. } // namespace hash
  1758. } // namespace detail
  1759. #undef AUTO
  1760. #undef AUTO_RETURN
  1761. #undef AUTO_REFREF
  1762. #undef AUTO_REFREF_RETURN
  1763. #undef DECLTYPE_AUTO
  1764. #undef DECLTYPE_AUTO_RETURN
  1765. } // namespace mpark
  1766. namespace std {
  1767. template <typename... Ts>
  1768. struct hash<mpark::detail::enabled_type<
  1769. mpark::variant<Ts...>,
  1770. mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
  1771. mpark::lib::remove_const_t<Ts>>()...>::value>>> {
  1772. using argument_type = mpark::variant<Ts...>;
  1773. using result_type = std::size_t;
  1774. inline result_type operator()(const argument_type &v) const {
  1775. using mpark::detail::visitation::variant;
  1776. std::size_t result =
  1777. v.valueless_by_exception()
  1778. ? 299792458 // Random value chosen by the universe upon creation
  1779. : variant::visit_alt(
  1780. #ifdef MPARK_GENERIC_LAMBDAS
  1781. [](const auto &alt) {
  1782. using alt_type = mpark::lib::decay_t<decltype(alt)>;
  1783. using value_type = mpark::lib::remove_const_t<
  1784. typename alt_type::value_type>;
  1785. return hash<value_type>{}(alt.value);
  1786. }
  1787. #else
  1788. hasher{}
  1789. #endif
  1790. ,
  1791. v);
  1792. return hash_combine(result, hash<std::size_t>{}(v.index()));
  1793. }
  1794. private:
  1795. #ifndef MPARK_GENERIC_LAMBDAS
  1796. struct hasher {
  1797. template <typename Alt>
  1798. inline std::size_t operator()(const Alt &alt) const {
  1799. using alt_type = mpark::lib::decay_t<Alt>;
  1800. using value_type =
  1801. mpark::lib::remove_const_t<typename alt_type::value_type>;
  1802. return hash<value_type>{}(alt.value);
  1803. }
  1804. };
  1805. #endif
  1806. static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
  1807. return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
  1808. }
  1809. };
  1810. template <>
  1811. struct hash<mpark::monostate> {
  1812. using argument_type = mpark::monostate;
  1813. using result_type = std::size_t;
  1814. inline result_type operator()(const argument_type &) const noexcept {
  1815. return 66740831; // return a fundamentally attractive random value.
  1816. }
  1817. };
  1818. } // namespace std
  1819. #endif // MPARK_VARIANT_HPP