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