Skip to content

Commit f0c4322

Browse files
committed
Add static assert in case of ill-formed variant
1 parent 30d151c commit f0c4322

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

include/cpp2util.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,9 @@ inline constexpr auto is_any = std::disjunction_v<std::is_same<T, Ts>...>;
679679
template <typename T, typename... Types>
680680
inline constexpr std::ptrdiff_t count_t = ( std::ptrdiff_t{std::is_same_v<T, Types>} + ... );
681681

682+
template <typename... Types>
683+
inline constexpr bool ill_formed_variant = sizeof...(Types) < 0;
684+
682685
template<typename T, typename... Ts>
683686
constexpr auto is( std::variant<Ts...> const& x ) {
684687
if constexpr (std::is_same_v< T, empty >) {
@@ -689,7 +692,10 @@ constexpr auto is( std::variant<Ts...> const& x ) {
689692
}
690693
} else {
691694
// std::holds_alternative is ill-formed if T does not appear exactly once in Ts
692-
if constexpr (count_t<T, Ts...> == 1) {
695+
if constexpr (count_t<T, Ts...> > 1) {
696+
static_assert(ill_formed_variant<T,Ts...>, "Checking variant is ill-formed - T appears more then once");
697+
}
698+
else if constexpr (count_t<T, Ts...> == 1) {
693699
return std::holds_alternative<T>(x);
694700
}
695701
return false;
@@ -699,7 +705,10 @@ constexpr auto is( std::variant<Ts...> const& x ) {
699705
template<typename T, typename... Ts>
700706
constexpr auto as( std::variant<Ts...> const& x ) {
701707
// std::holds_alternative is ill-formed if T does not appear exactly once in Ts
702-
if constexpr (count_t<T, Ts...> == 1) {
708+
if constexpr (count_t<T, Ts...> > 1) {
709+
static_assert(ill_formed_variant<T,Ts...>, "Casting variant is ill-formed - T appears more then once");
710+
}
711+
else if constexpr (count_t<T, Ts...> == 1) {
703712
if (std::holds_alternative<T>(x))
704713
return std::get<T>(x);
705714
}

0 commit comments

Comments
 (0)