summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-06-02 18:11:48 +0430
committerAndreas Kling <kling@serenityos.org>2021-06-02 18:02:47 +0200
commitea7ba34a31b3ef9f3ef49bb77068ffdb0167497c (patch)
tree335dbadb86c57bab43efc37cbddc7fe59163544c /AK
parent87ff76bd57046ef9fb287c68b740fee6c601621a (diff)
downloadserenity-ea7ba34a31b3ef9f3ef49bb77068ffdb0167497c.zip
AK+LibWasm+LibJS: Disallow Variant.has() on types that aren't contained
Checking for this (and get()'ing it) is always invalid, so let's just disallow it. This also finds two bugs where the code is checking for types that can never actually be in the variant (which was actually a refactor artifact).
Diffstat (limited to 'AK')
-rw-r--r--AK/Variant.h26
1 files changed, 13 insertions, 13 deletions
diff --git a/AK/Variant.h b/AK/Variant.h
index 3475143793..af6b649105 100644
--- a/AK/Variant.h
+++ b/AK/Variant.h
@@ -201,6 +201,12 @@ private:
static constexpr IndexType index_of() { return Detail::index_of<T, IndexType, Ts...>(); }
public:
+ template<typename T>
+ static constexpr bool can_contain()
+ {
+ return index_of<T>() != invalid_index;
+ }
+
template<typename... NewTs>
friend struct Variant;
@@ -246,7 +252,7 @@ public:
using Detail::MergeAndDeduplicatePacks<Detail::VariantConstructors<Ts, Variant<Ts...>>...>::MergeAndDeduplicatePacks;
template<typename T, typename StrippedT = RemoveCV<RemoveReference<T>>>
- void set(T&& t) requires(index_of<StrippedT>() != invalid_index)
+ void set(T&& t) requires(can_contain<StrippedT>())
{
constexpr auto new_index = index_of<StrippedT>();
Helper::delete_(m_index, m_data);
@@ -255,7 +261,7 @@ public:
}
template<typename T, typename StrippedT = RemoveCV<RemoveReference<T>>>
- void set(T&& t, Detail::VariantNoClearTag) requires(index_of<StrippedT>() != invalid_index)
+ void set(T&& t, Detail::VariantNoClearTag) requires(can_contain<StrippedT>())
{
constexpr auto new_index = index_of<StrippedT>();
new (m_data) StrippedT(forward<T>(t));
@@ -263,7 +269,7 @@ public:
}
template<typename T>
- T* get_pointer()
+ T* get_pointer() requires(can_contain<T>())
{
if (index_of<T>() == m_index)
return bit_cast<T*>(&m_data);
@@ -271,14 +277,14 @@ public:
}
template<typename T>
- T& get()
+ T& get() requires(can_contain<T>())
{
VERIFY(has<T>());
return *bit_cast<T*>(&m_data);
}
template<typename T>
- const T* get_pointer() const
+ const T* get_pointer() const requires(can_contain<T>())
{
if (index_of<T>() == m_index)
return bit_cast<const T*>(&m_data);
@@ -286,14 +292,14 @@ public:
}
template<typename T>
- const T& get() const
+ const T& get() const requires(can_contain<T>())
{
VERIFY(has<T>());
return *bit_cast<const T*>(&m_data);
}
template<typename T>
- [[nodiscard]] bool has() const
+ [[nodiscard]] bool has() const requires(can_contain<T>())
{
return index_of<T>() == m_index;
}
@@ -336,12 +342,6 @@ public:
return instance;
}
- template<typename T>
- static constexpr bool can_contain()
- {
- return index_of<T>() != invalid_index;
- }
-
private:
static constexpr auto data_size = integer_sequence_generate_array<size_t>(0, IntegerSequence<size_t, sizeof(Ts)...>()).max();
static constexpr auto data_alignment = integer_sequence_generate_array<size_t>(0, IntegerSequence<size_t, alignof(Ts)...>()).max();