@@ -653,57 +653,38 @@ auto as( X const* x ) -> C const* {
653
653
// -------------------------------------------------------------------------------------------------------------
654
654
// std::variant is and as
655
655
//
656
- template <typename ... Ts>
657
- constexpr auto operator_is ( std::variant<Ts...> const & x ) {
658
- return x.index ();
659
- }
660
-
661
- template <size_t I, typename ... Ts>
662
- constexpr auto operator_as ( std::variant<Ts...> const & x ) -> auto&& {
663
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
664
- return std::get<I>( x );
665
- }
666
- else {
667
- return nonesuch;
668
- }
669
- }
670
656
671
657
// A helper for is...
672
658
template <class T , class ... Ts>
673
659
inline constexpr auto is_any = std::disjunction_v<std::is_same<T, Ts>...>;
674
660
661
+ template <typename T, typename ... Types>
662
+ inline constexpr std::ptrdiff_t count_t = ( std::ptrdiff_t {std::is_same_v<T, Types>} + ... );
663
+
675
664
template <typename T, typename ... Ts>
676
- auto is ( std::variant<Ts...> const & x ) {
677
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<0 >(x)), T >) if (x.index () == 0 ) return true ;
678
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<1 >(x)), T >) if (x.index () == 1 ) return true ;
679
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<2 >(x)), T >) if (x.index () == 2 ) return true ;
680
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<3 >(x)), T >) if (x.index () == 3 ) return true ;
681
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<4 >(x)), T >) if (x.index () == 4 ) return true ;
682
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<5 >(x)), T >) if (x.index () == 5 ) return true ;
683
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<6 >(x)), T >) if (x.index () == 6 ) return true ;
684
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<7 >(x)), T >) if (x.index () == 7 ) return true ;
685
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<8 >(x)), T >) if (x.index () == 8 ) return true ;
686
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<9 >(x)), T >) if (x.index () == 9 ) return true ;
687
- if constexpr (std::is_same_v< T, empty > ) {
688
- if (x.valueless_by_exception ()) return true ;
689
- // Need to guard this with is_any otherwise the get_if is illegal
690
- if constexpr (is_any<std::monostate, Ts...>) return std::get_if<std::monostate>(&x) != nullptr ;
665
+ constexpr auto is ( std::variant<Ts...> const & x ) {
666
+ if constexpr (std::is_same_v< T, empty >) {
667
+ if constexpr (is_any<std::monostate, Ts...>) {
668
+ return std::holds_alternative<std::monostate>(x);
669
+ } else {
670
+ return x.valueless_by_exception ();
671
+ }
672
+ } else {
673
+ // std::holds_alternative is ill-formed if T does not appear exactly once in Ts
674
+ if constexpr (count_t <T, Ts...> == 1 ) {
675
+ return std::holds_alternative<T>(x);
676
+ }
677
+ return false ;
691
678
}
692
- return false ;
693
679
}
694
680
695
681
template <typename T, typename ... Ts>
696
- auto as ( std::variant<Ts...> const & x ) {
697
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<0 >(x)), T >) if (x.index () == 0 ) return operator_as<0 >(x);
698
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<1 >(x)), T >) if (x.index () == 1 ) return operator_as<1 >(x);
699
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<2 >(x)), T >) if (x.index () == 2 ) return operator_as<2 >(x);
700
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<3 >(x)), T >) if (x.index () == 3 ) return operator_as<3 >(x);
701
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<4 >(x)), T >) if (x.index () == 4 ) return operator_as<4 >(x);
702
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<5 >(x)), T >) if (x.index () == 5 ) return operator_as<5 >(x);
703
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<6 >(x)), T >) if (x.index () == 6 ) return operator_as<6 >(x);
704
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<7 >(x)), T >) if (x.index () == 7 ) return operator_as<7 >(x);
705
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<8 >(x)), T >) if (x.index () == 8 ) return operator_as<8 >(x);
706
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<9 >(x)), T >) if (x.index () == 9 ) return operator_as<9 >(x);
682
+ constexpr auto as ( std::variant<Ts...> const & x ) {
683
+ // std::holds_alternative is ill-formed if T does not appear exactly once in Ts
684
+ if constexpr (count_t <T, Ts...> == 1 ) {
685
+ if (std::holds_alternative<T>(x))
686
+ return std::get<T>(x);
687
+ }
707
688
throw std::bad_variant_access ();
708
689
}
709
690
0 commit comments