@@ -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
//
@@ -1906,6 +1938,7 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
1906
1938
|| std::is_base_of_v<C, CPP2_TYPEOF(x)>
1907
1939
|| std::is_base_of_v<CPP2_TYPEOF(x), C>
1908
1940
|| requires { C{CPP2_FORWARD (x)}; }
1941
+ || specialization_of_template<CPP2_TYPEOF(x), std::variant>
1909
1942
)
1910
1943
{
1911
1944
if constexpr (
@@ -1978,6 +2011,17 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
1978
2011
}
1979
2012
return C{CPP2_FORWARD (x)};
1980
2013
}
2014
+ else if constexpr (specialization_of_template<decltype (x), std::variant>) {
2015
+ constness_like_t <C, decltype (x)>* ptr = nullptr ;
2016
+ type_find_if (CPP2_FORWARD (x), [&]<typename It>(It const &) -> bool {
2017
+ if constexpr (It::index < 20 ) {
2018
+ 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 ; } };
2019
+ }
2020
+ return false ;
2021
+ });
2022
+ if (!ptr) { Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" ); }
2023
+ return cpp2::forward_like<decltype (x)>(*ptr);
2024
+ }
1981
2025
else {
1982
2026
return nonesuch;
1983
2027
}
@@ -1990,111 +2034,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
1990
2034
1991
2035
// Common internal helper
1992
2036
//
1993
- template <std::size_t I, typename ... Ts>
1994
- constexpr auto operator_as ( std::variant<Ts...> && x ) -> decltype(auto ) {
1995
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
1996
- return std::get<I>( x );
1997
- }
1998
- else {
1999
- return nonesuch;
2000
- }
2001
- }
2002
-
2003
- template <std::size_t I, typename ... Ts>
2004
- constexpr auto operator_as ( std::variant<Ts...> & x ) -> decltype(auto ) {
2005
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
2006
- return std::get<I>( x );
2007
- }
2008
- else {
2009
- return nonesuch;
2010
- }
2011
- }
2012
-
2013
- template <std::size_t I, typename ... Ts>
2014
- constexpr auto operator_as ( std::variant<Ts...> const & x ) -> decltype(auto ) {
2015
- if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
2016
- return std::get<I>( x );
2017
- }
2018
- else {
2019
- return nonesuch;
2020
- }
2021
- }
2022
-
2023
-
2024
- template <typename T, typename ... Ts>
2025
- auto as ( std::variant<Ts...> && x ) -> decltype(auto ) {
2026
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 0 >(x)), T >) { if (x.index () == 0 ) return operator_as<0 >(x); }
2027
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 1 >(x)), T >) { if (x.index () == 1 ) return operator_as<1 >(x); }
2028
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 2 >(x)), T >) { if (x.index () == 2 ) return operator_as<2 >(x); }
2029
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 3 >(x)), T >) { if (x.index () == 3 ) return operator_as<3 >(x); }
2030
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 4 >(x)), T >) { if (x.index () == 4 ) return operator_as<4 >(x); }
2031
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 5 >(x)), T >) { if (x.index () == 5 ) return operator_as<5 >(x); }
2032
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 6 >(x)), T >) { if (x.index () == 6 ) return operator_as<6 >(x); }
2033
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 7 >(x)), T >) { if (x.index () == 7 ) return operator_as<7 >(x); }
2034
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 8 >(x)), T >) { if (x.index () == 8 ) return operator_as<8 >(x); }
2035
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 9 >(x)), T >) { if (x.index () == 9 ) return operator_as<9 >(x); }
2036
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<10 >(x)), T >) { if (x.index () == 10 ) return operator_as<10 >(x); }
2037
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<11 >(x)), T >) { if (x.index () == 11 ) return operator_as<11 >(x); }
2038
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<12 >(x)), T >) { if (x.index () == 12 ) return operator_as<12 >(x); }
2039
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<13 >(x)), T >) { if (x.index () == 13 ) return operator_as<13 >(x); }
2040
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<14 >(x)), T >) { if (x.index () == 14 ) return operator_as<14 >(x); }
2041
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<15 >(x)), T >) { if (x.index () == 15 ) return operator_as<15 >(x); }
2042
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<16 >(x)), T >) { if (x.index () == 16 ) return operator_as<16 >(x); }
2043
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<17 >(x)), T >) { if (x.index () == 17 ) return operator_as<17 >(x); }
2044
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<18 >(x)), T >) { if (x.index () == 18 ) return operator_as<18 >(x); }
2045
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<19 >(x)), T >) { if (x.index () == 19 ) return operator_as<19 >(x); }
2046
- Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" );
2047
- }
2048
-
2049
- template <typename T, typename ... Ts>
2050
- auto as ( std::variant<Ts...> & x ) -> decltype(auto ) {
2051
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 0 >(x)), T >) { if (x.index () == 0 ) return operator_as<0 >(x); }
2052
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 1 >(x)), T >) { if (x.index () == 1 ) return operator_as<1 >(x); }
2053
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 2 >(x)), T >) { if (x.index () == 2 ) return operator_as<2 >(x); }
2054
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 3 >(x)), T >) { if (x.index () == 3 ) return operator_as<3 >(x); }
2055
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 4 >(x)), T >) { if (x.index () == 4 ) return operator_as<4 >(x); }
2056
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 5 >(x)), T >) { if (x.index () == 5 ) return operator_as<5 >(x); }
2057
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 6 >(x)), T >) { if (x.index () == 6 ) return operator_as<6 >(x); }
2058
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 7 >(x)), T >) { if (x.index () == 7 ) return operator_as<7 >(x); }
2059
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 8 >(x)), T >) { if (x.index () == 8 ) return operator_as<8 >(x); }
2060
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 9 >(x)), T >) { if (x.index () == 9 ) return operator_as<9 >(x); }
2061
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<10 >(x)), T >) { if (x.index () == 10 ) return operator_as<10 >(x); }
2062
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<11 >(x)), T >) { if (x.index () == 11 ) return operator_as<11 >(x); }
2063
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<12 >(x)), T >) { if (x.index () == 12 ) return operator_as<12 >(x); }
2064
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<13 >(x)), T >) { if (x.index () == 13 ) return operator_as<13 >(x); }
2065
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<14 >(x)), T >) { if (x.index () == 14 ) return operator_as<14 >(x); }
2066
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<15 >(x)), T >) { if (x.index () == 15 ) return operator_as<15 >(x); }
2067
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<16 >(x)), T >) { if (x.index () == 16 ) return operator_as<16 >(x); }
2068
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<17 >(x)), T >) { if (x.index () == 17 ) return operator_as<17 >(x); }
2069
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<18 >(x)), T >) { if (x.index () == 18 ) return operator_as<18 >(x); }
2070
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<19 >(x)), T >) { if (x.index () == 19 ) return operator_as<19 >(x); }
2071
- Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" );
2072
- }
2073
-
2074
- template <typename T, typename ... Ts>
2075
- auto as ( std::variant<Ts...> const & x ) -> decltype(auto ) {
2076
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 0 >(x)), T >) { if (x.index () == 0 ) return operator_as<0 >(x); }
2077
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 1 >(x)), T >) { if (x.index () == 1 ) return operator_as<1 >(x); }
2078
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 2 >(x)), T >) { if (x.index () == 2 ) return operator_as<2 >(x); }
2079
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 3 >(x)), T >) { if (x.index () == 3 ) return operator_as<3 >(x); }
2080
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 4 >(x)), T >) { if (x.index () == 4 ) return operator_as<4 >(x); }
2081
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 5 >(x)), T >) { if (x.index () == 5 ) return operator_as<5 >(x); }
2082
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 6 >(x)), T >) { if (x.index () == 6 ) return operator_as<6 >(x); }
2083
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 7 >(x)), T >) { if (x.index () == 7 ) return operator_as<7 >(x); }
2084
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 8 >(x)), T >) { if (x.index () == 8 ) return operator_as<8 >(x); }
2085
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as< 9 >(x)), T >) { if (x.index () == 9 ) return operator_as<9 >(x); }
2086
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<10 >(x)), T >) { if (x.index () == 10 ) return operator_as<10 >(x); }
2087
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<11 >(x)), T >) { if (x.index () == 11 ) return operator_as<11 >(x); }
2088
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<12 >(x)), T >) { if (x.index () == 12 ) return operator_as<12 >(x); }
2089
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<13 >(x)), T >) { if (x.index () == 13 ) return operator_as<13 >(x); }
2090
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<14 >(x)), T >) { if (x.index () == 14 ) return operator_as<14 >(x); }
2091
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<15 >(x)), T >) { if (x.index () == 15 ) return operator_as<15 >(x); }
2092
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<16 >(x)), T >) { if (x.index () == 16 ) return operator_as<16 >(x); }
2093
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<17 >(x)), T >) { if (x.index () == 17 ) return operator_as<17 >(x); }
2094
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<18 >(x)), T >) { if (x.index () == 18 ) return operator_as<18 >(x); }
2095
- if constexpr (std::is_same_v< CPP2_TYPEOF (operator_as<19 >(x)), T >) { if (x.index () == 19 ) return operator_as<19 >(x); }
2096
- Throw ( std::bad_variant_access (), " 'as' cast failed for 'variant'" );
2097
- }
2098
2037
2099
2038
2100
2039
// -------------------------------------------------------------------------------------------------------------
0 commit comments