@@ -804,6 +804,38 @@ constexpr auto variant_contains_type(std::variant<Ts...>)
804
804
}
805
805
}
806
806
807
+ template <typename C, typename X>
808
+ using constness_like_t =
809
+ std::conditional_t <
810
+ std::is_const_v<
811
+ std::remove_pointer_t <
812
+ std::remove_reference_t <X>
813
+ >
814
+ >,
815
+ std::add_const_t <C>,
816
+ std::remove_const_t <C>
817
+ >;
818
+
819
+ template <class T , class U >
820
+ [[nodiscard]] constexpr auto && forward_like(U&& x) noexcept
821
+ {
822
+ constexpr bool is_adding_const = std::is_const_v<std::remove_reference_t <T>>;
823
+ if constexpr (std::is_lvalue_reference_v<T&&>)
824
+ {
825
+ if constexpr (is_adding_const)
826
+ return std::as_const (x);
827
+ else
828
+ return static_cast <U&>(x);
829
+ }
830
+ else
831
+ {
832
+ if constexpr (is_adding_const)
833
+ return std::move (std::as_const (x));
834
+ else
835
+ return std::move (x);
836
+ }
837
+ }
838
+
807
839
808
840
// -----------------------------------------------------------------------
809
841
//
@@ -1933,6 +1965,7 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
1933
1965
|| std::is_base_of_v<C, CPP2_TYPEOF(x)>
1934
1966
|| std::is_base_of_v<CPP2_TYPEOF(x), C>
1935
1967
|| requires { C{CPP2_FORWARD (x)}; }
1968
+ || specialization_of_template<CPP2_TYPEOF(x), std::variant>
1936
1969
)
1937
1970
{
1938
1971
if constexpr (
@@ -2005,6 +2038,17 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
2005
2038
}
2006
2039
return C{CPP2_FORWARD (x)};
2007
2040
}
2041
+ else if constexpr (specialization_of_template<decltype (x), std::variant>) {
2042
+ constness_like_t <C, decltype (x)>* ptr = nullptr ;
2043
+ type_find_if (CPP2_FORWARD (x), [&]<typename It>(It const &) -> bool {
2044
+ if constexpr (It::index < 20 ) {
2045
+ if constexpr (std::is_same_v< typename It::type, C >) { if (CPP2_FORWARD (x).index () == It::index ) { ptr = &std::get<It::index >(x); return true ; } };
2046
+ }
2047
+ return false ;
2048
+ });
2049
+ if (!ptr) { Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" ); }
2050
+ return forward_like<decltype (x)>(*ptr);
2051
+ }
2008
2052
else {
2009
2053
return nonesuch;
2010
2054
}
@@ -2017,111 +2061,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
2017
2061
2018
2062
// Common internal helper
2019
2063
//
2020
- template <std::size_t I, typename ... Ts>
2021
- constexpr auto operator_as ( std::variant<Ts...> && x ) -> decltype(auto ) {
2022
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
2023
- return std::get<I>( x );
2024
- }
2025
- else {
2026
- return nonesuch;
2027
- }
2028
- }
2029
-
2030
- template <std::size_t I, typename ... Ts>
2031
- constexpr auto operator_as ( std::variant<Ts...> & x ) -> decltype(auto ) {
2032
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
2033
- return std::get<I>( x );
2034
- }
2035
- else {
2036
- return nonesuch;
2037
- }
2038
- }
2039
-
2040
- template <std::size_t I, typename ... Ts>
2041
- constexpr auto operator_as ( std::variant<Ts...> const & x ) -> decltype(auto ) {
2042
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
2043
- return std::get<I>( x );
2044
- }
2045
- else {
2046
- return nonesuch;
2047
- }
2048
- }
2049
-
2050
-
2051
- template <typename T, typename ... Ts>
2052
- auto as ( std::variant<Ts...> && x ) -> decltype(auto ) {
2053
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 0 >(x)), T >) { if (x.index () == 0 ) return operator_as<0 >(x); }
2054
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 1 >(x)), T >) { if (x.index () == 1 ) return operator_as<1 >(x); }
2055
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 2 >(x)), T >) { if (x.index () == 2 ) return operator_as<2 >(x); }
2056
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 3 >(x)), T >) { if (x.index () == 3 ) return operator_as<3 >(x); }
2057
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 4 >(x)), T >) { if (x.index () == 4 ) return operator_as<4 >(x); }
2058
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 5 >(x)), T >) { if (x.index () == 5 ) return operator_as<5 >(x); }
2059
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 6 >(x)), T >) { if (x.index () == 6 ) return operator_as<6 >(x); }
2060
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 7 >(x)), T >) { if (x.index () == 7 ) return operator_as<7 >(x); }
2061
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 8 >(x)), T >) { if (x.index () == 8 ) return operator_as<8 >(x); }
2062
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 9 >(x)), T >) { if (x.index () == 9 ) return operator_as<9 >(x); }
2063
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<10 >(x)), T >) { if (x.index () == 10 ) return operator_as<10 >(x); }
2064
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<11 >(x)), T >) { if (x.index () == 11 ) return operator_as<11 >(x); }
2065
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<12 >(x)), T >) { if (x.index () == 12 ) return operator_as<12 >(x); }
2066
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<13 >(x)), T >) { if (x.index () == 13 ) return operator_as<13 >(x); }
2067
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<14 >(x)), T >) { if (x.index () == 14 ) return operator_as<14 >(x); }
2068
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<15 >(x)), T >) { if (x.index () == 15 ) return operator_as<15 >(x); }
2069
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<16 >(x)), T >) { if (x.index () == 16 ) return operator_as<16 >(x); }
2070
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<17 >(x)), T >) { if (x.index () == 17 ) return operator_as<17 >(x); }
2071
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<18 >(x)), T >) { if (x.index () == 18 ) return operator_as<18 >(x); }
2072
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<19 >(x)), T >) { if (x.index () == 19 ) return operator_as<19 >(x); }
2073
- Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" );
2074
- }
2075
-
2076
- template <typename T, typename ... Ts>
2077
- auto as ( std::variant<Ts...> & x ) -> decltype(auto ) {
2078
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 0 >(x)), T >) { if (x.index () == 0 ) return operator_as<0 >(x); }
2079
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 1 >(x)), T >) { if (x.index () == 1 ) return operator_as<1 >(x); }
2080
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 2 >(x)), T >) { if (x.index () == 2 ) return operator_as<2 >(x); }
2081
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 3 >(x)), T >) { if (x.index () == 3 ) return operator_as<3 >(x); }
2082
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 4 >(x)), T >) { if (x.index () == 4 ) return operator_as<4 >(x); }
2083
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 5 >(x)), T >) { if (x.index () == 5 ) return operator_as<5 >(x); }
2084
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 6 >(x)), T >) { if (x.index () == 6 ) return operator_as<6 >(x); }
2085
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 7 >(x)), T >) { if (x.index () == 7 ) return operator_as<7 >(x); }
2086
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 8 >(x)), T >) { if (x.index () == 8 ) return operator_as<8 >(x); }
2087
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 9 >(x)), T >) { if (x.index () == 9 ) return operator_as<9 >(x); }
2088
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<10 >(x)), T >) { if (x.index () == 10 ) return operator_as<10 >(x); }
2089
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<11 >(x)), T >) { if (x.index () == 11 ) return operator_as<11 >(x); }
2090
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<12 >(x)), T >) { if (x.index () == 12 ) return operator_as<12 >(x); }
2091
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<13 >(x)), T >) { if (x.index () == 13 ) return operator_as<13 >(x); }
2092
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<14 >(x)), T >) { if (x.index () == 14 ) return operator_as<14 >(x); }
2093
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<15 >(x)), T >) { if (x.index () == 15 ) return operator_as<15 >(x); }
2094
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<16 >(x)), T >) { if (x.index () == 16 ) return operator_as<16 >(x); }
2095
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<17 >(x)), T >) { if (x.index () == 17 ) return operator_as<17 >(x); }
2096
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<18 >(x)), T >) { if (x.index () == 18 ) return operator_as<18 >(x); }
2097
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<19 >(x)), T >) { if (x.index () == 19 ) return operator_as<19 >(x); }
2098
- Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" );
2099
- }
2100
-
2101
- template <typename T, typename ... Ts>
2102
- auto as ( std::variant<Ts...> const & x ) -> decltype(auto ) {
2103
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 0 >(x)), T >) { if (x.index () == 0 ) return operator_as<0 >(x); }
2104
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 1 >(x)), T >) { if (x.index () == 1 ) return operator_as<1 >(x); }
2105
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 2 >(x)), T >) { if (x.index () == 2 ) return operator_as<2 >(x); }
2106
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 3 >(x)), T >) { if (x.index () == 3 ) return operator_as<3 >(x); }
2107
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 4 >(x)), T >) { if (x.index () == 4 ) return operator_as<4 >(x); }
2108
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 5 >(x)), T >) { if (x.index () == 5 ) return operator_as<5 >(x); }
2109
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 6 >(x)), T >) { if (x.index () == 6 ) return operator_as<6 >(x); }
2110
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 7 >(x)), T >) { if (x.index () == 7 ) return operator_as<7 >(x); }
2111
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 8 >(x)), T >) { if (x.index () == 8 ) return operator_as<8 >(x); }
2112
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 9 >(x)), T >) { if (x.index () == 9 ) return operator_as<9 >(x); }
2113
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<10 >(x)), T >) { if (x.index () == 10 ) return operator_as<10 >(x); }
2114
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<11 >(x)), T >) { if (x.index () == 11 ) return operator_as<11 >(x); }
2115
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<12 >(x)), T >) { if (x.index () == 12 ) return operator_as<12 >(x); }
2116
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<13 >(x)), T >) { if (x.index () == 13 ) return operator_as<13 >(x); }
2117
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<14 >(x)), T >) { if (x.index () == 14 ) return operator_as<14 >(x); }
2118
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<15 >(x)), T >) { if (x.index () == 15 ) return operator_as<15 >(x); }
2119
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<16 >(x)), T >) { if (x.index () == 16 ) return operator_as<16 >(x); }
2120
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<17 >(x)), T >) { if (x.index () == 17 ) return operator_as<17 >(x); }
2121
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<18 >(x)), T >) { if (x.index () == 18 ) return operator_as<18 >(x); }
2122
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<19 >(x)), T >) { if (x.index () == 19 ) return operator_as<19 >(x); }
2123
- Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" );
2124
- }
2125
2064
2126
2065
2127
2066
// -------------------------------------------------------------------------------------------------------------
0 commit comments