Skip to content

Commit 735ccf6

Browse files
committed
Move is() and as() for variant to separate functions
1 parent 091695d commit 735ccf6

File tree

1 file changed

+54
-44
lines changed

1 file changed

+54
-44
lines changed

include/cpp2util.h

+54-44
Original file line numberDiff line numberDiff line change
@@ -1746,26 +1746,6 @@ constexpr auto is( X const& x ) -> auto {
17461746
{
17471747
return Dynamic_cast<C const*>(&x) != nullptr;
17481748
}
1749-
else if constexpr (
1750-
specialization_of_template<X, std::variant>
1751-
)
1752-
{
1753-
if (x.valueless_by_exception()) {
1754-
return std::is_same_v<C, empty>;
1755-
}
1756-
if constexpr (
1757-
std::is_same_v<C, empty>
1758-
)
1759-
{
1760-
if constexpr (requires { {variant_contains_type<std::monostate>(std::declval<X>())} -> std::same_as<std::true_type>; }) {
1761-
return std::get_if<std::monostate>(&x) != nullptr;
1762-
}
1763-
}
1764-
return type_find_if(x, [&]<typename It>(It const&) -> bool {
1765-
if (x.index() == It::index) { return std::is_same_v<C, std::variant_alternative_t<It::index, X>>;}
1766-
return false;
1767-
}) != std::variant_npos;
1768-
}
17691749
else if constexpr (
17701750
(
17711751
std::is_same_v<X, std::nullptr_t>
@@ -1816,18 +1796,6 @@ inline constexpr auto is( auto const& x, auto&& value ) -> bool
18161796
else if constexpr (requires{ bool{x == value}; }) {
18171797
return x == value;
18181798
}
1819-
else if constexpr (specialization_of_template<decltype(x), std::variant> ) {
1820-
return type_find_if(x, [&]<typename It>(It const&) -> bool {
1821-
if (x.index() == It::index) {
1822-
if constexpr (valid_predicate<decltype(value), decltype(std::get<It::index>(x))>) {
1823-
return value(std::get<It::index>(x));
1824-
} else if constexpr ( requires { bool{std::get<It::index>(x) == value}; } ) {
1825-
return std::get<It::index>(x) == value;
1826-
}
1827-
}
1828-
return false;
1829-
}) != std::variant_npos;
1830-
}
18311799
return false;
18321800
}
18331801

@@ -1932,7 +1900,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
19321900
|| std::is_base_of_v<C, CPP2_TYPEOF(x)>
19331901
|| std::is_base_of_v<CPP2_TYPEOF(x), C>
19341902
|| requires { C{CPP2_FORWARD(x)}; }
1935-
|| specialization_of_template<CPP2_TYPEOF(x), std::variant>
19361903
)
19371904
{
19381905
if constexpr (
@@ -2005,15 +1972,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
20051972
}
20061973
return C{CPP2_FORWARD(x)};
20071974
}
2008-
else if constexpr (specialization_of_template<decltype(x), std::variant>) {
2009-
constness_like_t<C, decltype(x)>* ptr = nullptr;
2010-
type_find_if(CPP2_FORWARD(x), [&]<typename It>(It const&) -> bool {
2011-
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; } };
2012-
return false;
2013-
});
2014-
if (!ptr) { Throw( std::bad_variant_access(), "'as' cast failed for 'variant'"); }
2015-
return cpp2::forward_like<decltype(x)>(*ptr);
2016-
}
20171975
else {
20181976
return nonesuch;
20191977
}
@@ -2024,9 +1982,61 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
20241982
// std::variant is and as
20251983
//
20261984

2027-
// Common internal helper
2028-
//
1985+
template< typename C, specialization_of_template<std::variant> X >
1986+
constexpr auto is( X const& x ) -> auto
1987+
{
1988+
if constexpr (
1989+
std::is_same_v<C, X>
1990+
|| std::is_base_of_v<C, X>
1991+
)
1992+
{
1993+
return std::true_type{};
1994+
}
1995+
else {
1996+
if (x.valueless_by_exception()) {
1997+
return std::is_same_v<C, empty>;
1998+
}
1999+
if constexpr (
2000+
std::is_same_v<C, empty>
2001+
)
2002+
{
2003+
if constexpr (requires { {variant_contains_type<std::monostate>(std::declval<X>())} -> std::same_as<std::true_type>; }) {
2004+
return std::get_if<std::monostate>(&x) != nullptr;
2005+
}
2006+
}
2007+
return type_find_if(x, [&]<typename It>(It const&) -> bool {
2008+
if (x.index() == It::index) { return std::is_same_v<C, std::variant_alternative_t<It::index, X>>;}
2009+
return false;
2010+
}) != std::variant_npos;
2011+
}
2012+
}
2013+
2014+
2015+
inline constexpr auto is( specialization_of_template<std::variant> auto const& x, auto&& value ) -> bool
2016+
{
2017+
return type_find_if(x, [&]<typename It>(It const&) -> bool {
2018+
if (x.index() == It::index) {
2019+
if constexpr (valid_predicate<decltype(value), decltype(std::get<It::index>(x))>) {
2020+
return value(std::get<It::index>(x));
2021+
} else if constexpr ( requires { bool{std::get<It::index>(x) == value}; } ) {
2022+
return std::get<It::index>(x) == value;
2023+
}
2024+
}
2025+
return false;
2026+
}) != std::variant_npos;
2027+
}
20292028

2029+
template< typename C >
2030+
auto as(specialization_of_template<std::variant> auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
2031+
{
2032+
constness_like_t<C, decltype(x)>* ptr = nullptr;
2033+
type_find_if(CPP2_FORWARD(x), [&]<typename It>(It const&) -> bool {
2034+
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; } };
2035+
return false;
2036+
});
2037+
if (!ptr) { Throw( std::bad_variant_access(), "'as' cast failed for 'variant'"); }
2038+
return cpp2::forward_like<decltype(x)>(*ptr);
2039+
}
20302040

20312041
//-------------------------------------------------------------------------------------------------------------
20322042
// std::any is and as

0 commit comments

Comments
 (0)