Browse Source

Merge pull request #1717 from tomfull123/typed-array-range-based-loop-support

Add support for range based loops for Array
David Snopek 4 months ago
parent
commit
da064d84d2
3 changed files with 105 additions and 0 deletions
  1. 46 0
      binding_generator.py
  2. 51 0
      include/godot_cpp/variant/variant.hpp
  3. 8 0
      src/variant/packed_arrays.cpp

+ 46 - 0
binding_generator.py

@@ -642,6 +642,11 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
     result.append("")
     result.append(f"\t{class_name}(const Variant *p_variant);")
 
+    if class_name == "Array":
+        result.append("")
+        result.append("\tconst Variant *ptr() const;")
+        result.append("\tVariant *ptrw();")
+
     result.append("")
     result.append("public:")
 
@@ -907,6 +912,47 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
         result.append("\tVariant &operator[](int64_t p_index);")
         result.append("\tvoid set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);")
         result.append("\tvoid _ref(const Array &p_from) const;")
+        result.append("""
+	struct Iterator {
+		_FORCE_INLINE_ Variant &operator*() const;
+		_FORCE_INLINE_ Variant *operator->() const;
+		_FORCE_INLINE_ Iterator &operator++();
+		_FORCE_INLINE_ Iterator &operator--();
+
+		_FORCE_INLINE_ bool operator==(const Iterator &b) const { return elem_ptr == b.elem_ptr; }
+		_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return elem_ptr != b.elem_ptr; }
+
+		Iterator(Variant *p_ptr) { elem_ptr = p_ptr; }
+		Iterator() {}
+		Iterator(const Iterator &p_it) { elem_ptr = p_it.elem_ptr; }
+
+	private:
+		Variant *elem_ptr = nullptr;
+	};
+
+	struct ConstIterator {
+		_FORCE_INLINE_ const Variant &operator*() const;
+		_FORCE_INLINE_ const Variant *operator->() const;
+		_FORCE_INLINE_ ConstIterator &operator++();
+		_FORCE_INLINE_ ConstIterator &operator--();
+
+		_FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; }
+		_FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; }
+
+		ConstIterator(const Variant *p_ptr) { elem_ptr = p_ptr; }
+		ConstIterator() {}
+		ConstIterator(const ConstIterator &p_it) { elem_ptr = p_it.elem_ptr; }
+
+	private:
+		const Variant *elem_ptr = nullptr;
+	};
+
+	_FORCE_INLINE_ Iterator begin();
+	_FORCE_INLINE_ Iterator end();
+
+	_FORCE_INLINE_ ConstIterator begin() const;
+	_FORCE_INLINE_ ConstIterator end() const;
+	""")
 
     if class_name == "Dictionary":
         result.append("\tconst Variant &operator[](const Variant &p_key) const;")

+ 51 - 0
include/godot_cpp/variant/variant.hpp

@@ -32,6 +32,7 @@
 
 #include <godot_cpp/core/defs.hpp>
 
+#include <godot_cpp/variant/array.hpp>
 #include <godot_cpp/variant/builtin_types.hpp>
 #include <godot_cpp/variant/variant_size.hpp>
 
@@ -357,6 +358,56 @@ String vformat(const String &p_text, const VarArgs... p_args) {
 	return p_text % args_array;
 }
 
+Variant &Array::Iterator::operator*() const {
+	return *elem_ptr;
+}
+
+Variant *Array::Iterator::operator->() const {
+	return elem_ptr;
+}
+
+Array::Iterator &Array::Iterator::operator++() {
+	elem_ptr++;
+	return *this;
+}
+
+Array::Iterator &Array::Iterator::operator--() {
+	elem_ptr--;
+	return *this;
+}
+
+const Variant &Array::ConstIterator::operator*() const {
+	return *elem_ptr;
+}
+
+const Variant *Array::ConstIterator::operator->() const {
+	return elem_ptr;
+}
+
+Array::ConstIterator &Array::ConstIterator::operator++() {
+	elem_ptr++;
+	return *this;
+}
+
+Array::ConstIterator &Array::ConstIterator::operator--() {
+	elem_ptr--;
+	return *this;
+}
+
+Array::Iterator Array::begin() {
+	return Array::Iterator(ptrw());
+}
+Array::Iterator Array::end() {
+	return Array::Iterator(ptrw() + size());
+}
+
+Array::ConstIterator Array::begin() const {
+	return Array::ConstIterator(ptr());
+}
+Array::ConstIterator Array::end() const {
+	return Array::ConstIterator(ptr() + size());
+}
+
 #include <godot_cpp/variant/builtin_vararg_methods.hpp>
 
 #ifdef REAL_T_IS_DOUBLE

+ 8 - 0
src/variant/packed_arrays.cpp

@@ -236,6 +236,14 @@ void Array::_ref(const Array &p_from) const {
 	internal::gdextension_interface_array_ref((GDExtensionTypePtr *)this, (GDExtensionConstTypePtr *)&p_from);
 }
 
+const Variant *Array::ptr() const {
+	return (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, 0);
+}
+
+Variant *Array::ptrw() {
+	return (Variant *)internal::gdextension_interface_array_operator_index((GDExtensionTypePtr *)this, 0);
+}
+
 const Variant &Dictionary::operator[](const Variant &p_key) const {
 	const Variant *var = (const Variant *)internal::gdextension_interface_dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
 	return *var;