30 #ifndef BPSTD_VARIANT_HPP
31 #define BPSTD_VARIANT_HPP
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
37 #include "detail/config.hpp"
38 #include "detail/enable_overload.hpp"
39 #include "detail/nth_type.hpp"
40 #include "detail/variant_base.hpp"
41 #include "detail/variant_visitors.hpp"
42 #include "detail/variant_traits.hpp"
48 #include <initializer_list>
54 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
75 template <
typename...Types>
102 template <
typename...Types>
104 : integral_constant<std::size_t,sizeof...(Types)>{};
108 #if BPSTD_HAS_TEMPLATE_VARIABLES
109 template <
typename T>
127 template <std::
size_t I,
typename T>
130 template <std::
size_t I,
typename T>
132 : add_const<typename variant_alternative<I,T>::type>{};
134 template <std::
size_t I,
typename T>
136 : add_volatile<typename variant_alternative<I,T>::type>{};
138 template <std::
size_t I,
typename T>
140 : add_cv<typename variant_alternative<I,T>::type>{};
142 template <std::size_t I,
typename...Types>
144 : detail::nth_type<I,Types...>{};
154 template <std::
size_t I,
typename T>
164 BPSTD_CPP17_INLINE constexpr
auto variant_npos =
static_cast<std::size_t
>(-1);
197 const char*
what()
const noexcept
override;
206 template <std::size_t I,
typename T,
typename...Ts>
207 struct index_from_impl;
209 template <std::
size_t I,
typename T>
210 struct index_from_impl<I, T>
211 : integral_constant<std::size_t,variant_npos>{};
213 template <std::size_t I,
typename T,
typename T0,
typename...Ts>
214 struct index_from_impl<I,T,T0,Ts...>
215 : index_from_impl<I+1,T,Ts...>{};
217 template <std::size_t I,
typename T,
typename...Ts>
218 struct index_from_impl<I,T,T,Ts...>
219 : integral_constant<std::size_t,I>{};
222 template <
typename T,
typename...Ts>
223 struct index_from : index_from_impl<0,T,Ts...>{};
230 template <
typename T>
231 struct is_not_in_place : true_type{};
233 template <
typename T>
234 struct is_not_in_place<in_place_type_t<T>> : false_type{};
236 template <std::
size_t N>
237 struct is_not_in_place<in_place_index_t<N>> : false_type{};
240 struct is_not_in_place<in_place_t> : false_type{};
246 template <std::size_t I,
typename...Types>
247 struct variant_f_impl;
249 template <std::size_t I,
typename T0,
typename...Types>
250 struct variant_f_impl<I,T0,Types...>
251 : variant_f_impl<I+1,Types...>
253 using variant_f_impl<I+1,Types...>::operator();
255 integral_constant<std::size_t,I> operator()(T0);
259 template <std::size_t I,
typename...Types>
260 struct variant_f_impl<I,bool,Types...>
261 : variant_f_impl<I+1,Types...>
263 using variant_f_impl<I+1,Types...>::operator();
266 template <std::size_t I,
typename...Types>
267 struct variant_f_impl<I,const bool,Types...>
268 : variant_f_impl<I+1,Types...>
270 using variant_f_impl<I+1,Types...>::operator();
273 template <std::size_t I,
typename...Types>
274 struct variant_f_impl<I,volatile bool,Types...>
275 : variant_f_impl<I+1,Types...>
277 using variant_f_impl<I+1,Types...>::operator();
280 template <std::size_t I,
typename...Types>
281 struct variant_f_impl<I,const volatile bool,Types...>
282 : variant_f_impl<I+1,Types...>
284 using variant_f_impl<I+1,Types...>::operator();
287 template <std::
size_t I>
288 struct variant_f_impl<I>
291 integral_constant<std::size_t,variant_npos> operator()(...);
294 template <
typename...Types>
295 struct variant_f : variant_f_impl<0,Types...> {};
307 template <
typename T,
typename...Types>
308 struct index_of_constructible_alternative
310 is_same<remove_cvref_t<T>,bool>::value,
311 index_from<bool, remove_cv_t<Types>...>,
312 decltype(std::declval<variant_f<Types...>>()(std::declval<T>()))
315 template <
typename T,
typename...Types>
316 struct constructible_alternative
317 : nth_type<index_of_constructible_alternative<T, Types...>::value, Types...>{};
319 template <
typename T,
typename...Types>
320 using constructible_alternative_t
321 =
typename constructible_alternative<T, Types...>::type;
329 template <
typename T,
typename...Types>
330 struct has_constructible_alternative
331 : bool_constant<(index_of_constructible_alternative<T,Types...>::value != variant_npos)>{};
333 template <
bool HasConstructibleAlternative,
typename T,
typename...Types>
334 struct can_construct_alternative_impl : false_type{};
336 template <
typename T,
typename...Types>
337 struct can_construct_alternative_impl<true,T,Types...>
338 : is_constructible<constructible_alternative_t<T,Types...>,T>{};
340 template <
typename T,
typename...Types>
341 using can_construct_alternative
342 = can_construct_alternative_impl<has_constructible_alternative<T,Types...>::value,T,Types...>;
344 template <
bool HasConstructibleAlternative,
typename T,
typename...Types>
345 struct can_assign_alternative_impl : false_type{};
347 template <
typename T,
typename...Types>
348 struct can_assign_alternative_impl<true,T,Types...>
349 : is_assignable<constructible_alternative_t<T,Types...>,T>{};
351 template <
typename T,
typename...Types>
352 using can_assign_alternative
353 = can_assign_alternative_impl<has_constructible_alternative<T,Types...>::value,T,Types...>;
388 template <
typename...Types>
390 : detail::variant_base<
391 conjunction<is_trivially_destructible<Types>...>::value,
400 sizeof...(Types) > 0,
401 "A variant of 0 types is ill-formed. Use variant<monostate> instead."
404 conjunction<negation<is_reference<Types>>...>::value,
405 "A variant containing a reference type is ill-formed. Use reference_wrapper"
408 conjunction<negation<is_void<Types>>...>::value,
409 "A variant containing void is ill-formed."
416 using base_type = detail::variant_base<
417 conjunction<is_trivially_destructible<Types>...>::value,
420 using first_type =
typename detail::nth_type_t<0,Types...>;
422 static constexpr
bool is_default_constructible
423 = bpstd::is_default_constructible<first_type>::value;
425 static constexpr
bool is_move_constructible = conjunction<
426 bpstd::is_move_constructible<Types>...
429 static constexpr
bool is_copy_constructible = conjunction<
430 bpstd::is_copy_constructible<Types>...
433 static constexpr
bool is_copy_assignable = conjunction<
434 bpstd::is_copy_constructible<Types>...,
435 bpstd::is_copy_assignable<Types>...
438 static constexpr
bool is_move_assignable = conjunction<
439 bpstd::is_move_constructible<Types>...,
440 bpstd::is_move_assignable<Types>...
443 static constexpr
bool is_nothrow_default_constructible = conjunction<
444 bpstd::is_nothrow_default_constructible<Types>...
447 static constexpr
bool is_nothrow_move_constructible = conjunction<
448 bpstd::is_nothrow_move_constructible<Types>...
451 static constexpr
bool is_nothrow_copy_constructible = conjunction<
452 bpstd::is_nothrow_copy_constructible<Types>...
455 template <std::
size_t I>
456 using i_is_in_range = bool_constant<(I <
sizeof...(Types))>;
458 template <
typename U>
459 using enable_if_convertible =
462 negation<is_same<decay_t<U>,
variant>>,
463 detail::is_not_in_place<decay_t<U>>,
464 detail::has_constructible_alternative<U,Types...>,
465 detail::can_construct_alternative<U,Types...>
469 template <
typename U>
470 using enable_if_convert_assignable =
473 negation<is_same<decay_t<U>,
variant>>,
474 detail::is_not_in_place<decay_t<U>>,
475 detail::has_constructible_alternative<U,Types...>,
476 detail::can_construct_alternative<U,Types...>,
477 detail::can_assign_alternative<U,Types...>
481 template <
typename U>
482 using T_j = detail::constructible_alternative_t<U, Types...>;
484 struct variant_ctor{};
504 constexpr
variant(detail::enable_overload_if_t<is_default_constructible,variant_ctor> = {})
505 noexcept(std::is_nothrow_default_constructible<first_type>::value);
520 variant(detail::enable_overload_if_t<is_copy_constructible,const variant&> other)
522 variant(detail::disable_overload_if_t<is_copy_constructible,const variant&> other) =
delete;
537 variant(detail::enable_overload_if_t<is_move_constructible,variant&&> other)
539 variant(detail::disable_overload_if_t<is_move_constructible,variant&&> other) =
delete;
566 template <
typename T,
typename=enable_if_convertible<T>>
584 template <
typename T,
typename... Args,
585 typename = enable_if_t<bpstd::is_constructible<T,Args...>::value>>
586 constexpr
explicit variant(in_place_type_t<T>, Args&&... args);
601 template <
typename T,
typename U,
typename... Args,
602 typename = enable_if_t<bpstd::is_constructible<T,std::initializer_list<U>,Args...>::value>>
603 constexpr
explicit variant(in_place_type_t<T>,
604 std::initializer_list<U> il, Args&&... args);
620 template <std::size_t I,
typename... Args,
621 typename = enable_if_t<i_is_in_range<I>::value && std::is_constructible<variant_alternative_t<I,variant>,Args...>::value>>
622 constexpr
explicit variant(in_place_index_t<I>, Args&&... args);
640 template <std::size_t I,
typename U,
typename...Args,
641 typename = enable_if_t<i_is_in_range<I>::value && std::is_constructible<variant_alternative_t<I,variant>,std::initializer_list<U>,Args...>::value>>
642 constexpr
explicit variant(in_place_index_t<I>,
643 std::initializer_list<U> il, Args&&... args);
654 variant&
operator=(detail::enable_overload_if_t<is_copy_assignable,const variant&> other);
655 variant&
operator=(detail::disable_overload_if_t<is_copy_assignable,const variant&> other) =
delete;
664 variant&
operator=(detail::enable_overload_if_t<is_move_assignable,variant&&> other)
665 noexcept(conjunction<std::is_nothrow_move_constructible<Types>...,
666 std::is_nothrow_move_assignable<Types>...>::value);
667 variant&
operator=(detail::disable_overload_if_t<is_move_assignable,variant&&> other) =
delete;
669 template <
typename T,
typename = enable_if_convert_assignable<T>>
685 constexpr std::size_t
index() const noexcept;
709 template <typename T, typename...Args,
710 typename=enable_if_t<std::is_constructible<T,Args...>::value>>
726 template <typename T, typename U, typename...Args,
727 typename=enable_if_t<std::is_constructible<T,std::initializer_list<U>&,Args...>::value>>
728 T&
emplace(std::initializer_list<U> il, Args&&... args);
747 template <std::
size_t I, typename... Args,
748 typename=enable_if_t<std::is_constructible<detail::nth_type_t<I,Types...>,Args...>::value>>
770 template <std::
size_t I, typename U, typename... Args,
771 typename=enable_if_t<std::is_constructible<detail::nth_type_t<I,Types...>,std::initializer_list<U>&,Args...>::value>>
772 variant_alternative_t<I,
variant>&
emplace(std::initializer_list<U> il, Args&&... args);
778 noexcept(bpstd::conjunction<bpstd::is_nothrow_move_constructible<Types>...,
779 bpstd::is_nothrow_swappable<Types>...>::value);
787 static
bool alternative_is_nothrow_copy_constructible(std::
size_t i) noexcept;
788 static
bool alternative_is_nothrow_move_constructible(std::
size_t i) noexcept;
798 template <typename...UTypes>
799 friend BPSTD_CPP14_CONSTEXPR
800 bool operator==(const
variant<UTypes...>&,
801 const
variant<UTypes...>&) noexcept;
803 template <typename...UTypes>
804 friend BPSTD_CPP14_CONSTEXPR
805 bool operator!=(const
variant<UTypes...>&,
806 const
variant<UTypes...>&) noexcept;
808 template <typename...UTypes>
809 friend BPSTD_CPP14_CONSTEXPR
810 bool operator<(const
variant<UTypes...>&,
811 const
variant<UTypes...>&) noexcept;
813 template <typename...UTypes>
814 friend BPSTD_CPP14_CONSTEXPR
815 bool operator>(const
variant<UTypes...>&,
816 const
variant<UTypes...>&) noexcept;
818 template <typename...UTypes>
819 friend BPSTD_CPP14_CONSTEXPR
820 bool operator<=(const
variant<UTypes...>&,
821 const
variant<UTypes...>&) noexcept;
823 template <typename...UTypes>
824 friend BPSTD_CPP14_CONSTEXPR
825 bool operator>=(const
variant<UTypes...>&,
826 const
variant<UTypes...>&) noexcept;
828 template <typename Visitor, typename Variant>
829 BPSTD_CPP14_CONSTEXPR
830 friend detail::variant_visitor_invoke_result_t<Visitor,Variant>
831 visit(Visitor&&, Variant&&);
833 template <std::
size_t I, typename...UTypes>
834 friend BPSTD_CPP14_CONSTEXPR
835 variant_alternative_t<I,
variant<UTypes...>>&
838 template <std::
size_t I, typename...UTypes>
839 friend BPSTD_CPP14_CONSTEXPR
840 variant_alternative_t<I,
variant<UTypes...>>&&
843 template <std::
size_t I, typename...UTypes>
844 friend BPSTD_CPP14_CONSTEXPR
845 const variant_alternative_t<I,
variant<UTypes...>>&
846 get(const
variant<UTypes...>&);
848 template <std::
size_t I, typename...UTypes>
849 friend BPSTD_CPP14_CONSTEXPR
850 const variant_alternative_t<I,
variant<UTypes...>>&&
851 get(const
variant<UTypes...>&&);
853 template <std::
size_t I, typename...UTypes>
855 add_pointer_t<variant_alternative_t<I,
variant<UTypes...>>>
856 get_if(
variant<UTypes...>*) noexcept;
858 template <std::
size_t I, typename...UTypes>
860 add_pointer_t<const variant_alternative_t<I,
variant<UTypes...>>>
861 get_if(const
variant<UTypes...>*) noexcept;
873 template <typename...Types>
874 BPSTD_CPP14_CONSTEXPR
875 bool operator==(const
variant<Types...>& lhs,
876 const
variant<Types...>& rhs) noexcept;
877 template <typename...Types>
878 BPSTD_CPP14_CONSTEXPR
879 bool operator!=(const
variant<Types...>& lhs,
880 const
variant<Types...>& rhs) noexcept;
881 template <typename...Types>
882 BPSTD_CPP14_CONSTEXPR
883 bool operator<(const
variant<Types...>& lhs,
884 const
variant<Types...>& rhs) noexcept;
885 template <typename...Types>
886 BPSTD_CPP14_CONSTEXPR
887 bool operator>(const
variant<Types...>& lhs,
888 const
variant<Types...>& rhs) noexcept;
889 template <typename...Types>
890 BPSTD_CPP14_CONSTEXPR
891 bool operator<=(const
variant<Types...>& lhs,
892 const
variant<Types...>& rhs) noexcept;
893 template <typename...Types>
894 BPSTD_CPP14_CONSTEXPR
895 bool operator>=(const
variant<Types...>& lhs,
896 const
variant<Types...>& rhs) noexcept;
906 template <typename...Types>
908 noexcept(noexcept(lhs.
swap(rhs)));
919 template <typename Visitor, typename Variant>
920 BPSTD_CPP14_CONSTEXPR bpstd::detail::variant_visitor_invoke_result_t<Visitor,Variant>
921 visit(Visitor&& visitor, Variant&& v);
929 template <typename Visitor, typename Variant0, typename...Variants>
930 BPSTD_CPP14_CONSTEXPR bpstd::detail::variant_visitor_invoke_result_t<Visitor,Variant0, Variants...>
931 visit(Visitor&& visitor, Variant0&& variant0, Variants&&...variants);
941 template <typename T, typename...Types>
942 constexpr
bool holds_alternative(const
variant<Types...>& v) noexcept;
952 template <std::
size_t I, typename...Types>
953 BPSTD_CPP14_CONSTEXPR variant_alternative_t<I,
variant<Types...>>&
955 template <std::
size_t I, typename...Types>
956 BPSTD_CPP14_CONSTEXPR variant_alternative_t<I,
variant<Types...>>&&
958 template <std::
size_t I, typename...Types>
959 BPSTD_CPP14_CONSTEXPR const variant_alternative_t<I,
variant<Types...>>&
960 get(const
variant<Types...>& v);
961 template <std::
size_t I, typename...Types>
962 BPSTD_CPP14_CONSTEXPR const variant_alternative_t<I,
variant<Types...>>&&
963 get(const
variant<Types...>&& v);
976 template <typename T, typename...Types>
977 BPSTD_CPP14_CONSTEXPR T& get(
variant<Types...>& v);
978 template <typename T, typename...Types>
979 BPSTD_CPP14_CONSTEXPR T&& get(
variant<Types...>&& v);
980 template <typename T, typename...Types>
981 BPSTD_CPP14_CONSTEXPR const T& get(const
variant<Types...>& v);
982 template <typename T, typename...Types>
983 BPSTD_CPP14_CONSTEXPR const T&& get(const
variant<Types...>&& v);
1000 template <std::
size_t I, typename...Types>
1001 constexpr add_pointer_t<variant_alternative_t<I,
variant<Types...>>>
1002 get_if(
variant<Types...>* pv) noexcept;
1003 template <std::
size_t I, typename...Types>
1004 constexpr add_pointer_t<const variant_alternative_t<I,
variant<Types...>>>
1005 get_if(const
variant<Types...>* pv) noexcept;
1019 template <typename T, typename...Types>
1020 constexpr add_pointer_t<T> get_if(
variant<Types...>* pv) noexcept;
1021 template <typename T, typename...Types>
1022 constexpr add_pointer_t<const T> get_if(const
variant<Types...>* pv) noexcept;
1031 inline BPSTD_INLINE_VISIBILITY constexpr
1032 bool bpstd::operator==(monostate, monostate)
1038 inline BPSTD_INLINE_VISIBILITY constexpr
1039 bool bpstd::operator!=(monostate, monostate)
1045 inline BPSTD_INLINE_VISIBILITY constexpr
1046 bool bpstd::operator<(monostate, monostate)
1052 inline BPSTD_INLINE_VISIBILITY constexpr
1053 bool bpstd::operator>(monostate, monostate)
1059 inline BPSTD_INLINE_VISIBILITY constexpr
1060 bool bpstd::operator<=(monostate, monostate)
1066 inline BPSTD_INLINE_VISIBILITY constexpr
1067 bool bpstd::operator>=(monostate, monostate)
1081 return "bad_variant_access";
1092 template <
typename...Types>
1093 inline BPSTD_INLINE_VISIBILITY constexpr
1095 noexcept(std::is_nothrow_default_constructible<first_type>::value)
1096 : base_type{detail::variant_index_tag<0>{}}
1101 template <
typename...Types>
1102 inline BPSTD_INLINE_VISIBILITY
1107 if (other.valueless_by_exception()) {
1110 detail::visit_union(
1111 other.base_type::m_index,
1112 detail::variant_copy_construct_visitor{},
1114 other.base_type::m_union
1116 base_type::m_index = other.base_type::m_index;
1119 template <
typename...Types>
1120 inline BPSTD_INLINE_VISIBILITY
1125 if (other.valueless_by_exception()) {
1128 detail::visit_union(
1129 other.base_type::m_index,
1130 detail::variant_move_construct_visitor{},
1132 bpstd::move(other.base_type::m_union)
1134 base_type::m_index = other.base_type::m_index;
1137 template <
typename...Types>
1138 template <
typename T,
typename>
1139 inline BPSTD_INLINE_VISIBILITY constexpr
1143 detail::variant_index_tag<detail::index_of_constructible_alternative<T, Types...>::value>{},
1144 bpstd::forward<T>(t)
1150 template <
typename...Types>
1151 template <
typename T,
typename... Args,
typename>
1152 inline BPSTD_INLINE_VISIBILITY constexpr
1155 detail::variant_index_tag<detail::index_from<T, Types...>::value>{},
1156 bpstd::forward<Args>(args)...
1162 template <
typename...Types>
1163 template <
typename T,
typename U,
typename... Args,
typename>
1164 inline BPSTD_INLINE_VISIBILITY constexpr
1167 detail::variant_index_tag<detail::index_from<T, Types...>::value>{},
1168 il, bpstd::forward<Args>(args)...
1174 template <
typename...Types>
1175 template <std::size_t I,
typename... Args,
typename>
1176 inline BPSTD_INLINE_VISIBILITY constexpr
1179 detail::variant_index_tag<I>{},
1180 bpstd::forward<Args>(args)...
1186 template <
typename...Types>
1187 template <std::size_t I,
typename U,
typename... Args,
typename>
1188 inline BPSTD_INLINE_VISIBILITY constexpr
1191 detail::variant_index_tag<I>{},
1192 il, bpstd::forward<Args>(args)...
1200 template <
typename...Types>
1201 inline BPSTD_INLINE_VISIBILITY
1205 if (other.valueless_by_exception()) {
1206 base_type::destroy_active_object();
1210 if (other.base_type::m_index == base_type::m_index) {
1211 detail::visit_union(
1212 other.base_type::m_index,
1213 detail::variant_copy_assign_visitor{},
1215 other.base_type::m_union
1220 const auto should_copy =
1221 alternative_is_nothrow_copy_constructible(other.index()) ||
1222 !alternative_is_nothrow_move_constructible(other.index());
1225 base_type::destroy_active_object();
1226 detail::visit_union(
1227 other.base_type::m_index,
1228 detail::variant_copy_construct_visitor{},
1230 other.base_type::m_union
1232 base_type::m_index = other.base_type::m_index;
1236 return this->operator=(
variant(other));
1239 template <
typename...Types>
1240 inline BPSTD_INLINE_VISIBILITY
1243 noexcept(
conjunction<std::is_nothrow_move_constructible<Types>...,
1244 std::is_nothrow_move_assignable<Types>...>::value)
1246 if (other.valueless_by_exception()) {
1247 base_type::destroy_active_object();
1251 if (other.base_type::m_index == base_type::m_index) {
1252 detail::visit_union(
1253 other.base_type::m_index,
1254 detail::variant_move_assign_visitor{},
1256 bpstd::move(other.base_type::m_union)
1261 base_type::destroy_active_object();
1262 detail::visit_union(
1263 other.base_type::m_index,
1264 detail::variant_move_construct_visitor{},
1266 bpstd::move(other.base_type::m_union)
1268 base_type::m_index = other.base_type::m_index;
1273 template <
typename...Types>
1274 template <
typename T,
typename>
1275 inline BPSTD_INLINE_VISIBILITY
1280 static constexpr
auto index = detail::index_of_constructible_alternative<T,Types...>::value;
1282 using type = detail::constructible_alternative_t<T,Types...>;
1284 if (base_type::m_index == index) {
1285 detail::visit_union(
1287 detail::variant_assign_visitor<type,T>{bpstd::forward<T>(t)},
1293 const auto should_emplace =
1294 alternative_is_nothrow_copy_constructible(index) ||
1295 !alternative_is_nothrow_move_constructible(index);
1297 if (should_emplace) {
1298 emplace<index>(bpstd::forward<T>(t));
1302 return this->operator=(variant(bpstd::forward<T>(t)));
1309 template <
typename...Types>
1310 inline BPSTD_INLINE_VISIBILITY constexpr
1314 return base_type::m_index;
1317 template <
typename...Types>
1318 inline BPSTD_INLINE_VISIBILITY constexpr
1329 template <
typename...Types>
1330 template <
typename T,
typename...Args,
typename>
1331 inline BPSTD_INLINE_VISIBILITY
1334 using index_type = detail::index_from<T,Types...>;
1336 static_assert(index_type::value != variant_npos,
"T must be a valid alternative");
1338 return emplace<index_type::value>(bpstd::forward<Args>(args)...);
1341 template <
typename...Types>
1342 template <
typename T,
typename U,
typename...Args,
typename>
1343 inline BPSTD_INLINE_VISIBILITY
1346 using index_type = detail::index_from<T,Types...>;
1348 static_assert(index_type::value != variant_npos,
"T must be a valid alternative");
1350 return emplace<index_type::value>(il, bpstd::forward<Args>(args)...);
1353 template <
typename...Types>
1354 template <std::size_t I,
typename... Args,
typename>
1355 inline BPSTD_INLINE_VISIBILITY
1359 using type = detail::nth_type_t<I,Types...>;
1361 base_type::destroy_active_object();
1363 using tuple_type = decltype(std::forward_as_tuple(bpstd::forward<Args>(args)...));
1365 auto visitor = detail::variant_emplace_visitor<type, tuple_type>(
1366 std::forward_as_tuple(bpstd::forward<Args>(args)...)
1369 detail::visit_union(I, visitor, base_type::m_union);
1370 base_type::m_index = I;
1372 return detail::union_get<I>(base_type::m_union);
1376 template <
typename...Types>
1377 template <std::size_t I,
typename U,
typename... Args,
typename>
1378 inline BPSTD_INLINE_VISIBILITY
1382 using type = detail::nth_type_t<I,Types...>;
1384 base_type::destroy_active_object();
1386 using tuple_type = decltype(std::forward_as_tuple(il, bpstd::forward<Args>(args)...));
1388 auto visitor = detail::variant_emplace_visitor<type, tuple_type>(
1389 std::forward_as_tuple(il, bpstd::forward<Args>(args)...)
1392 detail::visit_union(I, visitor, base_type::m_union);
1393 base_type::m_index = I;
1395 return detail::union_get<I>(base_type::m_union);
1398 template <
typename...Types>
1399 inline BPSTD_INLINE_VISIBILITY
1402 bpstd::is_nothrow_swappable<Types>...>::value)
1405 if (valueless_by_exception() && other.valueless_by_exception()) {
1409 if (base_type::m_index == other.base_type::m_index) {
1410 detail::visit_union(
1412 detail::variant_swap_visitor{},
1417 auto temp = bpstd::move(*
this);
1418 *
this = bpstd::move(other);
1419 other = bpstd::move(temp);
1423 template <
typename...Types>
1424 inline BPSTD_INLINE_VISIBILITY
1428 const bool alternatives[]{bpstd::is_nothrow_copy_constructible<Types>::value...};
1430 return alternatives[i];
1433 template <
typename...Types>
1434 inline BPSTD_INLINE_VISIBILITY
1438 const bool alternatives[]{bpstd::is_nothrow_move_constructible<Types>::value...};
1440 return alternatives[i];
1451 template <
typename...Types>
1452 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1453 bool bpstd::operator==(
const variant<Types...>& lhs,
1454 const variant<Types...>& rhs)
1457 if (lhs.index() != rhs.index()) {
1460 if (lhs.valueless_by_exception()) {
1463 return detail::visit_union(lhs.index(), equal_to<>{}, lhs.m_union, rhs.m_union);
1466 template <
typename...Types>
1467 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1468 bool bpstd::operator!=(
const variant<Types...>& lhs,
1469 const variant<Types...>& rhs)
1472 if (lhs.index() != rhs.index()) {
1475 if (lhs.valueless_by_exception()) {
1478 return detail::visit_union(lhs.index(), not_equal_to<>{}, lhs.m_union, rhs.m_union);
1481 template <
typename...Types>
1482 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1483 bool bpstd::operator<(
const variant<Types...>& lhs,
1484 const variant<Types...>& rhs)
1487 if (rhs.valueless_by_exception()) {
1490 if (lhs.valueless_by_exception()) {
1493 if (lhs.index() < rhs.index()) {
1496 if (lhs.index() > rhs.index()) {
1499 return detail::visit_union(lhs.index(), less<>{}, lhs.m_union, rhs.m_union);
1502 template <
typename...Types>
1503 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1504 bool bpstd::operator>(
const variant<Types...>& lhs,
1505 const variant<Types...>& rhs)
1508 if (lhs.valueless_by_exception()) {
1511 if (rhs.valueless_by_exception()) {
1514 if (lhs.index() > rhs.index()) {
1517 if (lhs.index() < rhs.index()) {
1520 return detail::visit_union(lhs.index(), greater<>{}, lhs.m_union, rhs.m_union);
1523 template <
typename...Types>
1524 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1525 bool bpstd::operator<=(
const variant<Types...>& lhs,
1526 const variant<Types...>& rhs)
1529 if (lhs.valueless_by_exception()) {
1532 if (rhs.valueless_by_exception()) {
1535 if (lhs.index() < rhs.index()) {
1538 if (lhs.index() > rhs.index()) {
1541 return detail::visit_union(lhs.index(), less_equal<>{}, lhs.m_union, rhs.m_union);
1544 template <
typename...Types>
1545 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1546 bool bpstd::operator>=(
const variant<Types...>& lhs,
1547 const variant<Types...>& rhs)
1550 if (rhs.valueless_by_exception()) {
1553 if (lhs.valueless_by_exception()) {
1556 if (lhs.index() > rhs.index()) {
1559 if (lhs.index() < rhs.index()) {
1562 return detail::visit_union(lhs.index(), greater_equal<>{}, lhs.m_union, rhs.m_union);
1569 template <
typename...Types>
1570 inline BPSTD_INLINE_VISIBILITY
1571 void bpstd::swap(variant<Types...>& lhs, variant<Types...>& rhs)
1572 noexcept(noexcept(lhs.swap(rhs)))
1581 template <
typename Visitor,
typename Variant>
1582 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1583 bpstd::detail::variant_visitor_invoke_result_t<Visitor,Variant>
1584 bpstd::visit(Visitor&& visitor, Variant&& v)
1586 using union_type = detail::match_cvref_t<Variant, decltype(v.m_union)>;
1588 if (v.valueless_by_exception()) {
1589 throw bad_variant_access{};
1592 return detail::visit_union(
1594 bpstd::forward<Visitor>(visitor),
1595 static_cast<union_type
>(v.m_union)
1599 namespace bpstd {
namespace detail {
1601 template <
typename Variant0,
typename...Variants>
1602 inline BPSTD_INLINE_VISIBILITY constexpr
1603 bool are_any_valueless_by_exception(
const Variant0& v0,
const Variants&...vs)
1605 return v0.valueless_by_exception() || are_any_valueless_by_exception(vs...);
1608 template <
typename Variant0>
1609 inline BPSTD_INLINE_VISIBILITY constexpr
1610 bool are_any_valueless_by_exception(
const Variant0& v0)
1612 return v0.valueless_by_exception();
1615 template <
typename...Args,
typename T, std::size_t...Idxs>
1616 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1617 std::tuple<Args&&...,T&&> tuple_push_back_aux(std::tuple<Args...>& args, T&& v, index_sequence<Idxs...>)
1620 return std::forward_as_tuple(std::get<Idxs>(bpstd::move(args))..., bpstd::forward<T>(v));
1625 template <
typename...Args,
typename T>
1626 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1627 std::tuple<Args&&...,T&&> tuple_push_back(std::tuple<Args...>& args, T&& t)
1630 conjunction<is_reference<Args>...,true_type>::value,
1631 "'args' must be a forwarding tuple'"
1634 return tuple_push_back_aux(args, bpstd::forward<T>(t), index_sequence_for<Args...>{});
1637 template <
typename Arg0,
typename...Args, std::size_t...Idxs>
1638 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1639 std::tuple<Args...> tuple_pop_front_aux(std::tuple<Arg0,Args...>& args, index_sequence<0, Idxs...>)
1642 return std::forward_as_tuple(std::get<Idxs>(bpstd::move(args))...);
1646 template <
typename Arg0,
typename...Args>
1647 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1648 std::tuple<Args...> tuple_pop_front(std::tuple<Arg0,Args...>& args)
1651 conjunction<is_reference<Arg0>,is_reference<Args>...>::value,
1652 "'args' must be a forwarding tuple'"
1655 return tuple_pop_front_aux(args, index_sequence_for<Arg0,Args...>{});
1658 template <
typename Return,
typename Visitor,
typename Variants,
typename Arguments>
1659 class multi_variant_visitor;
1661 template <
typename T,
typename Visitor,
typename Variants,
typename Arguments>
1662 BPSTD_CPP14_CONSTEXPR
1663 multi_variant_visitor<T, Visitor, remove_cvref_t<Variants>, remove_cvref_t<Arguments>>
1664 make_multi_visitor(Visitor&& vistior, Variants&& variants, Arguments&& args);
1666 template <
typename Return,
typename Visitor,
typename Variant0,
typename...Variants,
typename...Args>
1667 class multi_variant_visitor<Return, Visitor, std::tuple<Variant0,Variants...>, std::tuple<Args...>>
1670 conjunction<is_reference<Variant0>, is_reference<Variants>...>::value,
1671 "All Variants must be captured by reference"
1674 conjunction<is_reference<Args>...,true_type>::value,
1675 "All arguments must be captured by reference"
1679 template <
typename UVisitor,
typename UVariants,
typename Arguments>
1680 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1681 multi_variant_visitor(UVisitor&& visitor, UVariants&& variants, Arguments&& args)
1682 : m_visitor(bpstd::forward<UVisitor>(visitor)),
1683 m_variants(bpstd::forward<UVariants>(variants)),
1684 m_args(bpstd::forward<Arguments>(args))
1689 template <
typename T>
1690 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1691 Return operator()(T&& v)
1696 detail::make_multi_visitor<Return>(
1697 bpstd::forward<Visitor>(m_visitor),
1698 tuple_pop_front(m_variants),
1699 tuple_push_back(m_args, bpstd::forward<T>(v))
1701 std::get<0>(bpstd::move(m_variants))
1708 std::tuple<Variant0, Variants...> m_variants;
1709 std::tuple<Args...> m_args;
1712 template <
typename Return,
typename Visitor,
typename...Args>
1713 class multi_variant_visitor<Return,Visitor,std::tuple<>,std::tuple<Args...>>
1716 conjunction<is_reference<Args>...,true_type>::value,
1717 "All arguments must be captured by reference"
1721 template <
typename UVisitor,
typename Variants,
typename Arguments>
1722 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1723 multi_variant_visitor(UVisitor&& visitor, Variants&&, Arguments&& args)
1724 : m_visitor(bpstd::forward<UVisitor>(visitor)),
1725 m_args(bpstd::forward<Arguments>(args))
1730 template <
typename T>
1731 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1732 Return operator()(T&& v)
1735 bpstd::forward<Visitor>(m_visitor),
1736 tuple_push_back(m_args, bpstd::forward<T>(v))
1743 std::tuple<Args...> m_args;
1746 template <
typename T,
typename Visitor,
typename Variants,
typename Arguments>
1747 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1748 multi_variant_visitor<T,Visitor, remove_cvref_t<Variants>, remove_cvref_t<Arguments>>
1749 make_multi_visitor(Visitor&& visitor, Variants&& variants, Arguments&& args)
1752 bpstd::forward<Visitor>(visitor),
1753 bpstd::forward<Variants>(variants),
1754 bpstd::forward<Arguments>(args)
1760 template <
typename Visitor,
typename Variant0,
typename...Variants>
1761 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1762 bpstd::detail::variant_visitor_invoke_result_t<Visitor,Variant0, Variants...>
1763 bpstd::visit(Visitor&& visitor, Variant0&& variant0, Variants&&...variants)
1765 using type = bpstd::detail::variant_visitor_invoke_result_t<Visitor,Variant0, Variants...>;
1767 if (detail::are_any_valueless_by_exception(variant0, variants...)) {
1768 throw bad_variant_access{};
1772 detail::make_multi_visitor<type>(
1773 bpstd::forward<Visitor>(visitor),
1774 std::forward_as_tuple(bpstd::forward<Variants>(variants)...),
1777 bpstd::forward<Variant0>(variant0)
1783 template <
typename T,
typename...Types>
1784 inline BPSTD_INLINE_VISIBILITY constexpr
1788 return detail::index_from<T,Types...>::value == v.index();
1793 template <std::size_t I,
typename...Types>
1794 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1799 I <
sizeof...(Types),
1800 "I is not a valid index into the variant"
1803 if (v.index() != I) {
1804 throw bad_variant_access{};
1806 return detail::union_get<I>(v.m_union);
1809 template <std::size_t I,
typename...Types>
1810 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1815 I <
sizeof...(Types),
1816 "I is not a valid index into the variant"
1819 if (v.index() != I) {
1820 throw bad_variant_access{};
1822 return bpstd::move(detail::union_get<I>(v.m_union));
1825 template <std::size_t I,
typename...Types>
1826 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1831 I <
sizeof...(Types),
1832 "I is not a valid index into the variant"
1835 if (v.index() != I) {
1836 throw bad_variant_access{};
1838 return detail::union_get<I>(v.m_union);
1841 template <std::size_t I,
typename...Types>
1842 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1847 I <
sizeof...(Types),
1848 "I is not a valid index into the variant"
1851 if (v.index() != I) {
1852 throw bad_variant_access{};
1854 return bpstd::move(detail::union_get<I>(v.m_union));
1859 template <
typename T,
typename...Types>
1860 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1863 using index_type = detail::index_from<T,Types...>;
1865 return get<index_type::value>(v);
1868 template <
typename T,
typename...Types>
1869 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1872 using index_type = detail::index_from<T,Types...>;
1874 return get<index_type::value>(bpstd::move(v));
1877 template <
typename T,
typename...Types>
1878 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1879 const T&
bpstd::get(
const variant<Types...>& v)
1881 using index_type = detail::index_from<T,Types...>;
1883 return get<index_type::value>(v);
1886 template <
typename T,
typename...Types>
1887 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
1888 const T&&
bpstd::get(
const variant<Types...>&& v)
1890 using index_type = detail::index_from<T,Types...>;
1892 return get<index_type::value>(bpstd::move(v));
1898 template <std::size_t I,
typename...Types>
1899 inline BPSTD_INLINE_VISIBILITY constexpr
1905 I <
sizeof...(Types),
1906 "I is not a valid index into the variant"
1909 return (pv ==
nullptr || I != pv->index())
1911 : &detail::union_get<I>(pv->m_union);
1914 template <std::size_t I,
typename...Types>
1915 inline BPSTD_INLINE_VISIBILITY constexpr
1921 I <
sizeof...(Types),
1922 "I is not a valid index into the variant"
1925 return (pv ==
nullptr || I != pv->index())
1927 : &detail::union_get<I>(pv->m_union);
1932 template <
typename T,
typename...Types>
1933 inline BPSTD_INLINE_VISIBILITY constexpr
1934 bpstd::add_pointer_t<T>
1938 using index_type = detail::index_from<T,Types...>;
1940 return get_if<index_type::value>(pv);
1943 template <
typename T,
typename...Types>
1944 inline BPSTD_INLINE_VISIBILITY constexpr
1945 bpstd::add_pointer_t<const T>
1949 using index_type = detail::index_from<T,Types...>;
1951 return get_if<index_type::value>(pv);
1954 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE