Skip to content

Commit 330e225

Browse files
committed
Move is() and as() for variant to separate functions
1 parent f95546d commit 330e225

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
@@ -1784,26 +1784,6 @@ constexpr auto is( X const& x ) -> auto {
17841784
{
17851785
return Dynamic_cast<C const*>(&x) != nullptr;
17861786
}
1787-
else if constexpr (
1788-
specialization_of_template<X, std::variant>
1789-
)
1790-
{
1791-
if (x.valueless_by_exception()) {
1792-
return std::is_same_v<C, empty>;
1793-
}
1794-
if constexpr (
1795-
std::is_same_v<C, empty>
1796-
)
1797-
{
1798-
if constexpr (requires { {variant_contains_type<std::monostate>(std::declval<X>())} -> std::same_as<std::true_type>; }) {
1799-
return std::get_if<std::monostate>(&x) != nullptr;
1800-
}
1801-
}
1802-
return type_find_if(x, [&]<typename It>(It const&) -> bool {
1803-
if (x.index() == It::index) { return std::is_same_v<C, std::variant_alternative_t<It::index, X>>;}
1804-
return false;
1805-
}) != std::variant_npos;
1806-
}
18071787
else if constexpr (
18081788
(
18091789
std::is_same_v<X, std::nullptr_t>
@@ -1854,18 +1834,6 @@ inline constexpr auto is( auto const& x, auto&& value ) -> bool
18541834
else if constexpr (requires{ bool{x == value}; }) {
18551835
return x == value;
18561836
}
1857-
else if constexpr (specialization_of_template<decltype(x), std::variant> ) {
1858-
return type_find_if(x, [&]<typename It>(It const&) -> bool {
1859-
if (x.index() == It::index) {
1860-
if constexpr (valid_predicate<decltype(value), decltype(std::get<It::index>(x))>) {
1861-
return value(std::get<It::index>(x));
1862-
} else if constexpr ( requires { bool{std::get<It::index>(x) == value}; } ) {
1863-
return std::get<It::index>(x) == value;
1864-
}
1865-
}
1866-
return false;
1867-
}) != std::variant_npos;
1868-
}
18691837
return false;
18701838
}
18711839

@@ -1970,7 +1938,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
19701938
|| std::is_base_of_v<C, CPP2_TYPEOF(x)>
19711939
|| std::is_base_of_v<CPP2_TYPEOF(x), C>
19721940
|| requires { C{CPP2_FORWARD(x)}; }
1973-
|| specialization_of_template<CPP2_TYPEOF(x), std::variant>
19741941
)
19751942
{
19761943
if constexpr (
@@ -2043,15 +2010,6 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
20432010
}
20442011
return C{CPP2_FORWARD(x)};
20452012
}
2046-
else if constexpr (specialization_of_template<decltype(x), std::variant>) {
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-
}
20552013
else {
20562014
return nonesuch;
20572015
}
@@ -2062,9 +2020,61 @@ auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
20622020
// std::variant is and as
20632021
//
20642022

2065-
// Common internal helper
2066-
//
2023+
template< typename C, specialization_of_template<std::variant> X >
2024+
constexpr auto is( X const& x ) -> auto
2025+
{
2026+
if constexpr (
2027+
std::is_same_v<C, X>
2028+
|| std::is_base_of_v<C, X>
2029+
)
2030+
{
2031+
return std::true_type{};
2032+
}
2033+
else {
2034+
if (x.valueless_by_exception()) {
2035+
return std::is_same_v<C, empty>;
2036+
}
2037+
if constexpr (
2038+
std::is_same_v<C, empty>
2039+
)
2040+
{
2041+
if constexpr (requires { {variant_contains_type<std::monostate>(std::declval<X>())} -> std::same_as<std::true_type>; }) {
2042+
return std::get_if<std::monostate>(&x) != nullptr;
2043+
}
2044+
}
2045+
return type_find_if(x, [&]<typename It>(It const&) -> bool {
2046+
if (x.index() == It::index) { return std::is_same_v<C, std::variant_alternative_t<It::index, X>>;}
2047+
return false;
2048+
}) != std::variant_npos;
2049+
}
2050+
}
2051+
2052+
2053+
inline constexpr auto is( specialization_of_template<std::variant> auto const& x, auto&& value ) -> bool
2054+
{
2055+
return type_find_if(x, [&]<typename It>(It const&) -> bool {
2056+
if (x.index() == It::index) {
2057+
if constexpr (valid_predicate<decltype(value), decltype(std::get<It::index>(x))>) {
2058+
return value(std::get<It::index>(x));
2059+
} else if constexpr ( requires { bool{std::get<It::index>(x) == value}; } ) {
2060+
return std::get<It::index>(x) == value;
2061+
}
2062+
}
2063+
return false;
2064+
}) != std::variant_npos;
2065+
}
20672066

2067+
template< typename C >
2068+
auto as(specialization_of_template<std::variant> auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
2069+
{
2070+
constness_like_t<C, decltype(x)>* ptr = nullptr;
2071+
type_find_if(CPP2_FORWARD(x), [&]<typename It>(It const&) -> bool {
2072+
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; } };
2073+
return false;
2074+
});
2075+
if (!ptr) { Throw( std::bad_variant_access(), "'as' cast failed for 'variant'"); }
2076+
return cpp2::forward_like<decltype(x)>(*ptr);
2077+
}
20682078

20692079
//-------------------------------------------------------------------------------------------------------------
20702080
// std::any is and as

0 commit comments

Comments
 (0)