Skip to content

Commit a2977c2

Browse files
committed
Add static assert in case of ill-formed variant
1 parent 7090820 commit a2977c2

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
@@ -661,6 +661,9 @@ inline constexpr auto is_any = std::disjunction_v<std::is_same<T, Ts>...>;
661661
template <typename T, typename... Types>
662662
inline constexpr std::ptrdiff_t count_t = ( std::ptrdiff_t{std::is_same_v<T, Types>} + ... );
663663

664+
template <typename... Types>
665+
inline constexpr bool ill_formed_variant = sizeof...(Types) < 0;
666+
664667
template<typename T, typename... Ts>
665668
constexpr auto is( std::variant<Ts...> const& x ) {
666669
if constexpr (std::is_same_v< T, empty >) {
@@ -671,7 +674,10 @@ constexpr auto is( std::variant<Ts...> const& x ) {
671674
}
672675
} else {
673676
// std::holds_alternative is ill-formed if T does not appear exactly once in Ts
674-
if constexpr (count_t<T, Ts...> == 1) {
677+
if constexpr (count_t<T, Ts...> > 1) {
678+
static_assert(ill_formed_variant<T,Ts...>, "Checking variant is ill-formed - T appears more then once");
679+
}
680+
else if constexpr (count_t<T, Ts...> == 1) {
675681
return std::holds_alternative<T>(x);
676682
}
677683
return false;
@@ -681,7 +687,10 @@ constexpr auto is( std::variant<Ts...> const& x ) {
681687
template<typename T, typename... Ts>
682688
constexpr auto as( std::variant<Ts...> const& x ) {
683689
// std::holds_alternative is ill-formed if T does not appear exactly once in Ts
684-
if constexpr (count_t<T, Ts...> == 1) {
690+
if constexpr (count_t<T, Ts...> > 1) {
691+
static_assert(ill_formed_variant<T,Ts...>, "Casting variant is ill-formed - T appears more then once");
692+
}
693+
else if constexpr (count_t<T, Ts...> == 1) {
685694
if (std::holds_alternative<T>(x))
686695
return std::get<T>(x);
687696
}

0 commit comments

Comments
 (0)