Core: Expand `is_zero_constructible` coverage
@@ -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<IPAddress> : std::true_type {};
@@ -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; }
+struct is_zero_constructible<ObjectID> : std::true_type {};
@@ -276,3 +276,7 @@ struct VariantInternalAccessor<const Ref<T> &> {
static _FORCE_INLINE_ Ref<T> get(const Variant *v) { return Ref<T>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const Ref<T> &p_ref) { VariantInternal::object_assign(v, p_ref); }
+// Zero-constructing Ref initializes reference to nullptr (and thus empty).
+template <typename T>
+struct is_zero_constructible<Ref<T>> : std::true_type {};
@@ -95,3 +95,7 @@ public:
NodePath() {}
~NodePath();
+// Zero-constructing NodePath initializes data to nullptr (and thus empty).
+struct is_zero_constructible<NodePath> : std::true_type {};
@@ -219,6 +219,10 @@ public:
#endif
+// Zero-constructing StringName initializes _data to nullptr (and thus empty).
+struct is_zero_constructible<StringName> : 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);
@@ -77,6 +77,10 @@ struct PairHash {
}
+// Pair is zero-constructible if and only if both constrained types are zero-constructible.
+template <typename F, typename S>
+struct is_zero_constructible<Pair<F, S>> : std::conjunction<is_zero_constructible<F>, is_zero_constructible<S>> {};
template <typename K, typename V>
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 <typename K, typename V>
+struct is_zero_constructible<KeyValue<K, V>> : std::conjunction<is_zero_constructible<K>, is_zero_constructible<V>> {};
@@ -71,3 +71,6 @@ public:
_ALWAYS_INLINE_ RID() {}
+struct is_zero_constructible<RID> : std::true_type {};
@@ -113,3 +113,7 @@ constexpr uint64_t Span<T>::count(const T &p_val) const {
return amount;
+// Zero-constructing Span initializes _ptr and _len to 0 (and thus empty).
+struct is_zero_constructible<Span<T>> : std::true_type {};
@@ -85,6 +85,10 @@ struct Tuple<T, Rest...> : Tuple<Rest...> {
value(std::forward<F>(f)) {}
+// Tuple is zero-constructible if and only if all constrained types are zero-constructible.
+template <typename... Types>
+struct is_zero_constructible<Tuple<Types...>> : std::conjunction<is_zero_constructible<Types>...> {};
template <size_t I, typename Tuple>
struct TupleGet;
@@ -135,6 +135,10 @@ public:
~Callable();
+// Zero-constructing Callable initializes method and object to 0 (and thus empty).
+struct is_zero_constructible<Callable> : 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).
+struct is_zero_constructible<Signal> : std::true_type {};
struct CallableComparator {
const Callable &func;
@@ -268,6 +268,9 @@ public:
_FORCE_INLINE_ BitField<T> operator^(const BitField<T> &p_b) const { return BitField<T>(value ^ p_b.value); }
+struct is_zero_constructible<BitField<T>> : std::true_type {};
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
template <> \
struct GetTypeInfo<m_impl> { \