@@ -671,57 +671,38 @@ auto as( X const* x ) -> C const* {
671
671
// -------------------------------------------------------------------------------------------------------------
672
672
// std::variant is and as
673
673
//
674
- template <typename ... Ts>
675
- constexpr auto operator_is ( std::variant<Ts...> const & x ) {
676
- return x.index ();
677
- }
678
-
679
- template <size_t I, typename ... Ts>
680
- constexpr auto operator_as ( std::variant<Ts...> const & x ) -> auto&& {
681
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
682
- return std::get<I>( x );
683
- }
684
- else {
685
- return nonesuch;
686
- }
687
- }
688
674
689
675
// A helper for is...
690
676
template <class T , class ... Ts>
691
677
inline constexpr auto is_any = std::disjunction_v<std::is_same<T, Ts>...>;
692
678
679
+ template <typename T, typename ... Types>
680
+ inline constexpr std::ptrdiff_t count_t = ( std::ptrdiff_t {std::is_same_v<T, Types>} + ... );
681
+
693
682
template <typename T, typename ... Ts>
694
- auto is ( std::variant<Ts...> const & x ) {
695
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<0 >(x)), T >) if (x.index () == 0 ) return true ;
696
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<1 >(x)), T >) if (x.index () == 1 ) return true ;
697
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<2 >(x)), T >) if (x.index () == 2 ) return true ;
698
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<3 >(x)), T >) if (x.index () == 3 ) return true ;
699
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<4 >(x)), T >) if (x.index () == 4 ) return true ;
700
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<5 >(x)), T >) if (x.index () == 5 ) return true ;
701
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<6 >(x)), T >) if (x.index () == 6 ) return true ;
702
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<7 >(x)), T >) if (x.index () == 7 ) return true ;
703
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<8 >(x)), T >) if (x.index () == 8 ) return true ;
704
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<9 >(x)), T >) if (x.index () == 9 ) return true ;
705
- if constexpr (std::is_same_v< T, empty > ) {
706
- if (x.valueless_by_exception ()) return true ;
707
- // Need to guard this with is_any otherwise the get_if is illegal
708
- if constexpr (is_any<std::monostate, Ts...>) return std::get_if<std::monostate>(&x) != nullptr ;
683
+ constexpr auto is ( std::variant<Ts...> const & x ) {
684
+ if constexpr (std::is_same_v< T, empty >) {
685
+ if constexpr (is_any<std::monostate, Ts...>) {
686
+ return std::holds_alternative<std::monostate>(x);
687
+ } else {
688
+ return x.valueless_by_exception ();
689
+ }
690
+ } else {
691
+ // std::holds_alternative is ill-formed if T does not appear exactly once in Ts
692
+ if constexpr (count_t <T, Ts...> == 1 ) {
693
+ return std::holds_alternative<T>(x);
694
+ }
695
+ return false ;
709
696
}
710
- return false ;
711
697
}
712
698
713
699
template <typename T, typename ... Ts>
714
- auto as ( std::variant<Ts...> const & x ) {
715
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<0 >(x)), T >) if (x.index () == 0 ) return operator_as<0 >(x);
716
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<1 >(x)), T >) if (x.index () == 1 ) return operator_as<1 >(x);
717
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<2 >(x)), T >) if (x.index () == 2 ) return operator_as<2 >(x);
718
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<3 >(x)), T >) if (x.index () == 3 ) return operator_as<3 >(x);
719
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<4 >(x)), T >) if (x.index () == 4 ) return operator_as<4 >(x);
720
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<5 >(x)), T >) if (x.index () == 5 ) return operator_as<5 >(x);
721
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<6 >(x)), T >) if (x.index () == 6 ) return operator_as<6 >(x);
722
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<7 >(x)), T >) if (x.index () == 7 ) return operator_as<7 >(x);
723
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<8 >(x)), T >) if (x.index () == 8 ) return operator_as<8 >(x);
724
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<9 >(x)), T >) if (x.index () == 9 ) return operator_as<9 >(x);
700
+ constexpr auto as ( std::variant<Ts...> const & x ) {
701
+ // std::holds_alternative is ill-formed if T does not appear exactly once in Ts
702
+ if constexpr (count_t <T, Ts...> == 1 ) {
703
+ if (std::holds_alternative<T>(x))
704
+ return std::get<T>(x);
705
+ }
725
706
throw std::bad_variant_access ();
726
707
}
727
708
0 commit comments