diff --git a/core/io/ip_address.h b/core/io/ip_address.h index d296e50f7f9..114038d902b 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -94,3 +94,7 @@ public: IPAddress(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6 = false); IPAddress() { clear(); } }; + +// Zero-constructing IPAddress initializes field, valid, and wildcard to 0 (and thus empty). +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/core/object/object_id.h b/core/object/object_id.h index 76aec0f7290..2fc66beb387 100644 --- a/core/object/object_id.h +++ b/core/object/object_id.h @@ -58,3 +58,6 @@ public: _ALWAYS_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; } _ALWAYS_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; } }; + +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index be1633622ce..77b6472dd43 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -276,3 +276,7 @@ struct VariantInternalAccessor &> { static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } }; + +// Zero-constructing Ref initializes reference to nullptr (and thus empty). +template +struct is_zero_constructible> : std::true_type {}; diff --git a/core/string/node_path.h b/core/string/node_path.h index 0fe83a95fc3..2dce2d1c403 100644 --- a/core/string/node_path.h +++ b/core/string/node_path.h @@ -95,3 +95,7 @@ public: NodePath() {} ~NodePath(); }; + +// Zero-constructing NodePath initializes data to nullptr (and thus empty). +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/core/string/string_name.h b/core/string/string_name.h index 1ac1582e09a..2be64de8c8a 100644 --- a/core/string/string_name.h +++ b/core/string/string_name.h @@ -219,6 +219,10 @@ public: #endif }; +// Zero-constructing StringName initializes _data to nullptr (and thus empty). +template <> +struct is_zero_constructible : std::true_type {}; + bool operator==(const String &p_name, const StringName &p_string_name); bool operator!=(const String &p_name, const StringName &p_string_name); bool operator==(const char *p_name, const StringName &p_string_name); diff --git a/core/templates/pair.h b/core/templates/pair.h index 2b8929f8b07..a39ed4aa7a1 100644 --- a/core/templates/pair.h +++ b/core/templates/pair.h @@ -77,6 +77,10 @@ struct PairHash { } }; +// Pair is zero-constructible if and only if both constrained types are zero-constructible. +template +struct is_zero_constructible> : std::conjunction, is_zero_constructible> {}; + template struct KeyValue { const K key; @@ -109,3 +113,7 @@ struct KeyValueSort { return A.key < B.key; } }; + +// KeyValue is zero-constructible if and only if both constrained types are zero-constructible. +template +struct is_zero_constructible> : std::conjunction, is_zero_constructible> {}; diff --git a/core/templates/rid.h b/core/templates/rid.h index a63749b2993..a8b86c1e535 100644 --- a/core/templates/rid.h +++ b/core/templates/rid.h @@ -71,3 +71,6 @@ public: _ALWAYS_INLINE_ RID() {} }; + +template <> +struct is_zero_constructible : std::true_type {}; diff --git a/core/templates/span.h b/core/templates/span.h index 4995279c073..5498a88eaba 100644 --- a/core/templates/span.h +++ b/core/templates/span.h @@ -113,3 +113,7 @@ constexpr uint64_t Span::count(const T &p_val) const { } return amount; } + +// Zero-constructing Span initializes _ptr and _len to 0 (and thus empty). +template +struct is_zero_constructible> : std::true_type {}; diff --git a/core/templates/tuple.h b/core/templates/tuple.h index 2dc81f9678e..4492fab7fdb 100644 --- a/core/templates/tuple.h +++ b/core/templates/tuple.h @@ -85,6 +85,10 @@ struct Tuple : Tuple { value(std::forward(f)) {} }; +// Tuple is zero-constructible if and only if all constrained types are zero-constructible. +template +struct is_zero_constructible> : std::conjunction...> {}; + template struct TupleGet; diff --git a/core/variant/callable.h b/core/variant/callable.h index 9c51e82fe8e..89299c568b5 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -135,6 +135,10 @@ public: ~Callable(); }; +// Zero-constructing Callable initializes method and object to 0 (and thus empty). +template <> +struct is_zero_constructible : std::true_type {}; + class CallableCustom { friend class Callable; SafeRefCount ref_count; @@ -200,6 +204,10 @@ public: Signal() {} }; +// Zero-constructing Signal initializes name and object to 0 (and thus empty). +template <> +struct is_zero_constructible : std::true_type {}; + struct CallableComparator { const Callable &func; diff --git a/core/variant/type_info.h b/core/variant/type_info.h index ad18801b79d..48277b18779 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -268,6 +268,9 @@ public: _FORCE_INLINE_ BitField operator^(const BitField &p_b) const { return BitField(value ^ p_b.value); } }; +template +struct is_zero_constructible> : std::true_type {}; + #define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \ template <> \ struct GetTypeInfo { \