Skip to content

Commit 4755e81

Browse files
committed
Move is() and as() for variant to separate functions
1 parent aa1a4ba commit 4755e81

File tree

1 file changed

+54
-44
lines changed

1 file changed

+54
-44
lines changed

include/cpp2util.h

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,26 +1761,6 @@ constexpr auto is( X const& x ) -> auto {
17611761
{
17621762
return Dynamic_cast<C const*>(&x) != nullptr;
17631763
}
1764-
else if constexpr (
1765-
specialization_of_template<X, std::variant>
1766-
)
1767-
{
1768-
if (x.valueless_by_exception()) {
1769-
return std::is_same_v<C, empty>;
1770-
}
1771-
if constexpr (
1772-
std::is_same_v<C, empty>
1773-
)
1774-
{
1775-
if constexpr (requires { {variant_contains_type<std::monostate>(std::declval<X>())} -> std::same_as<std::true_type>; }) {
1776-
return std::get_if<std::monostate>(&x) != nullptr;
1777-
}
1778-
}
1779-
return type_find_if(x, [&]<typename It>(It const&) -> bool {
1780-
if (x.index() == It::index) { return std::is_same_v<C, std::variant_alternative_t<It::index, X>>;}
1781-
return false;
1782-
}) != std::variant_npos;
1783-
}
17841764
else if constexpr (
17851765
(
17861766
std::is_same_v<X, std::nullptr_t>
@@ -1831,18 +1811,6 @@ inline constexpr auto is( auto const& x, auto&& value ) -> bool
18311811
else if constexpr (requires{ bool{x == value}; }) {
18321812
return x == value;
18331813
}
1834-
else if constexpr (specialization_of_template<decltype(x), std::variant> ) {
1835-
return type_find_if(x, [&]<typename It>(It const&) -> bool {
1836-
if (x.index() == It::index) {
1837-
if constexpr (valid_predicate<decltype(value), decltype(std::get<It::index>(x))>) {
1838-
return value(std::get<It::index>(x));
1839-
} else if constexpr ( requires { bool{std::get<It::index>(x) == value}; } ) {
1840-
return std::get<It::index>(x) == value;
1841-
}
1842-
}
1843-
return false;
1844-
}) != std::variant_npos;
1845-
}
18461814
return false;
18471815
}
18481816

@@ -1947,7 +1915,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
19471915
|| std::is_base_of_v<C, CPP2_TYPEOF(x)>
19481916
|| std::is_base_of_v<CPP2_TYPEOF(x), C>
19491917
|| requires { C{CPP2_FORWARD(x)}; }
1950-
|| specialization_of_template<CPP2_TYPEOF(x), std::variant>
19511918
)
19521919
{
19531920
if constexpr (
@@ -2020,15 +1987,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
20201987
}
20211988
return C{CPP2_FORWARD(x)};
20221989
}
2023-
else if constexpr (specialization_of_template<decltype(x), std::variant>) {
2024-
constness_like_t<C, decltype(x)>* ptr = nullptr;
2025-
type_find_if(CPP2_FORWARD(x), [&]<typename It>(It const&) -> bool {
2026-
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; } };
2027-
return false;
2028-
});
2029-
if (!ptr) { Throw( std::bad_variant_access(), "'as' cast failed for 'variant'"); }
2030-
return cpp2::forward_like<decltype(x)>(*ptr);
2031-
}
20321990
else {
20331991
return nonesuch;
20341992
}
@@ -2039,9 +1997,61 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
20391997
// std::variant is and as
20401998
//
20411999

2042-
// Common internal helper
2043-
//
2000+
template< typename C, specialization_of_template<std::variant> X >
2001+
constexpr auto is( X const& x ) -> auto
2002+
{
2003+
if constexpr (
2004+
std::is_same_v<C, X>
2005+
|| std::is_base_of_v<C, X>
2006+
)
2007+
{
2008+
return std::true_type{};
2009+
}
2010+
else {
2011+
if (x.valueless_by_exception()) {
2012+
return std::is_same_v<C, empty>;
2013+
}
2014+
if constexpr (
2015+
std::is_same_v<C, empty>
2016+
)
2017+
{
2018+
if constexpr (requires { {variant_contains_type<std::monostate>(std::declval<X>())} -> std::same_as<std::true_type>; }) {
2019+
return std::get_if<std::monostate>(&x) != nullptr;
2020+
}
2021+
}
2022+
return type_find_if(x, [&]<typename It>(It const&) -> bool {
2023+
if (x.index() == It::index) { return std::is_same_v<C, std::variant_alternative_t<It::index, X>>;}
2024+
return false;
2025+
}) != std::variant_npos;
2026+
}
2027+
}
2028+
2029+
2030+
inline constexpr auto is( specialization_of_template<std::variant> auto const& x, auto&& value ) -> bool
2031+
{
2032+
return type_find_if(x, [&]<typename It>(It const&) -> bool {
2033+
if (x.index() == It::index) {
2034+
if constexpr (valid_predicate<decltype(value), decltype(std::get<It::index>(x))>) {
2035+
return value(std::get<It::index>(x));
2036+
} else if constexpr ( requires { bool{std::get<It::index>(x) == value}; } ) {
2037+
return std::get<It::index>(x) == value;
2038+
}
2039+
}
2040+
return false;
2041+
}) != std::variant_npos;
2042+
}
20442043

2044+
template< typename C >
2045+
auto as(specialization_of_template<std::variant> auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
2046+
{
2047+
constness_like_t<C, decltype(x)>* ptr = nullptr;
2048+
type_find_if(CPP2_FORWARD(x), [&]<typename It>(It const&) -> bool {
2049+
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; } };
2050+
return false;
2051+
});
2052+
if (!ptr) { Throw( std::bad_variant_access(), "'as' cast failed for 'variant'"); }
2053+
return cpp2::forward_like<decltype(x)>(*ptr);
2054+
}
20452055

20462056
//-------------------------------------------------------------------------------------------------------------
20472057
// std::any is and as

0 commit comments

Comments
 (0)