From af80bcd2f8e01130357b090126c26717b736665a Mon Sep 17 00:00:00 2001
From: Aaron Franke <arnfranke@yahoo.com>
Date: Thu, 20 Feb 2020 23:19:00 -0500
Subject: [PATCH] Add sort and has methods to PackedArrays

---
 core/variant_call.cpp                         |  36 ++++
 core/vector.h                                 |   4 +
 doc/classes/PackedByteArray.xml               |  16 ++
 doc/classes/PackedColorArray.xml              |  16 ++
 doc/classes/PackedFloat32Array.xml            |  16 ++
 doc/classes/PackedFloat64Array.xml            |  16 ++
 doc/classes/PackedInt32Array.xml              |  16 ++
 doc/classes/PackedInt64Array.xml              |  16 ++
 doc/classes/PackedStringArray.xml             |  16 ++
 doc/classes/PackedVector2Array.xml            |  16 ++
 doc/classes/PackedVector3Array.xml            |  16 ++
 modules/gdnative/gdnative/packed_arrays.cpp   |  94 +++++++++++
 modules/gdnative/gdnative_api.json            | 157 ++++++++++++++++--
 .../gdnative/include/gdnative/packed_arrays.h |  36 ++++
 14 files changed, 460 insertions(+), 11 deletions(-)

diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 308fa3c407ff..0aa1339401e8 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -701,6 +701,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedByteArray, uint8_t, remove);
 	VCALL_PARRMEM1(PackedByteArray, uint8_t, append);
 	VCALL_PARRMEM1(PackedByteArray, uint8_t, append_array);
+	VCALL_PARRMEM1R(PackedByteArray, uint8_t, has);
+	VCALL_PARRMEM0(PackedByteArray, uint8_t, sort);
 	VCALL_PARRMEM0(PackedByteArray, uint8_t, invert);
 	VCALL_PARRMEM2R(PackedByteArray, uint8_t, subarray);
 
@@ -714,6 +716,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedInt32Array, int32_t, remove);
 	VCALL_PARRMEM1(PackedInt32Array, int32_t, append);
 	VCALL_PARRMEM1(PackedInt32Array, int32_t, append_array);
+	VCALL_PARRMEM1R(PackedInt32Array, int32_t, has);
+	VCALL_PARRMEM0(PackedInt32Array, int32_t, sort);
 	VCALL_PARRMEM0(PackedInt32Array, int32_t, invert);
 
 	VCALL_PARRMEM0R(PackedInt64Array, int64_t, size);
@@ -726,6 +730,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedInt64Array, int64_t, remove);
 	VCALL_PARRMEM1(PackedInt64Array, int64_t, append);
 	VCALL_PARRMEM1(PackedInt64Array, int64_t, append_array);
+	VCALL_PARRMEM1R(PackedInt64Array, int64_t, has);
+	VCALL_PARRMEM0(PackedInt64Array, int64_t, sort);
 	VCALL_PARRMEM0(PackedInt64Array, int64_t, invert);
 
 	VCALL_PARRMEM0R(PackedFloat32Array, float, size);
@@ -738,6 +744,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedFloat32Array, float, remove);
 	VCALL_PARRMEM1(PackedFloat32Array, float, append);
 	VCALL_PARRMEM1(PackedFloat32Array, float, append_array);
+	VCALL_PARRMEM1R(PackedFloat32Array, float, has);
+	VCALL_PARRMEM0(PackedFloat32Array, float, sort);
 	VCALL_PARRMEM0(PackedFloat32Array, float, invert);
 
 	VCALL_PARRMEM0R(PackedFloat64Array, double, size);
@@ -750,6 +758,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedFloat64Array, double, remove);
 	VCALL_PARRMEM1(PackedFloat64Array, double, append);
 	VCALL_PARRMEM1(PackedFloat64Array, double, append_array);
+	VCALL_PARRMEM1R(PackedFloat64Array, double, has);
+	VCALL_PARRMEM0(PackedFloat64Array, double, sort);
 	VCALL_PARRMEM0(PackedFloat64Array, double, invert);
 
 	VCALL_PARRMEM0R(PackedStringArray, String, size);
@@ -762,6 +772,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedStringArray, String, remove);
 	VCALL_PARRMEM1(PackedStringArray, String, append);
 	VCALL_PARRMEM1(PackedStringArray, String, append_array);
+	VCALL_PARRMEM1R(PackedStringArray, String, has);
+	VCALL_PARRMEM0(PackedStringArray, String, sort);
 	VCALL_PARRMEM0(PackedStringArray, String, invert);
 
 	VCALL_PARRMEM0R(PackedVector2Array, Vector2, size);
@@ -774,6 +786,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedVector2Array, Vector2, remove);
 	VCALL_PARRMEM1(PackedVector2Array, Vector2, append);
 	VCALL_PARRMEM1(PackedVector2Array, Vector2, append_array);
+	VCALL_PARRMEM1R(PackedVector2Array, Vector2, has);
+	VCALL_PARRMEM0(PackedVector2Array, Vector2, sort);
 	VCALL_PARRMEM0(PackedVector2Array, Vector2, invert);
 
 	VCALL_PARRMEM0R(PackedVector3Array, Vector3, size);
@@ -786,6 +800,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedVector3Array, Vector3, remove);
 	VCALL_PARRMEM1(PackedVector3Array, Vector3, append);
 	VCALL_PARRMEM1(PackedVector3Array, Vector3, append_array);
+	VCALL_PARRMEM1R(PackedVector3Array, Vector3, has);
+	VCALL_PARRMEM0(PackedVector3Array, Vector3, sort);
 	VCALL_PARRMEM0(PackedVector3Array, Vector3, invert);
 
 	VCALL_PARRMEM0R(PackedColorArray, Color, size);
@@ -798,6 +814,8 @@ struct _VariantCall {
 	VCALL_PARRMEM1(PackedColorArray, Color, remove);
 	VCALL_PARRMEM1(PackedColorArray, Color, append);
 	VCALL_PARRMEM1(PackedColorArray, Color, append_array);
+	VCALL_PARRMEM1R(PackedColorArray, Color, has);
+	VCALL_PARRMEM0(PackedColorArray, Color, sort);
 	VCALL_PARRMEM0(PackedColorArray, Color, invert);
 
 #define VCALL_PTR0(m_type, m_method) \
@@ -2085,6 +2103,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_BYTE_ARRAY, INT, PackedByteArray, insert, INT, "idx", INT, "byte", varray());
 	ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_BYTE_ARRAY, BOOL, PackedByteArray, has, INT, "value", varray());
+	ADDFUNC0(PACKED_BYTE_ARRAY, NIL, PackedByteArray, sort, varray());
 	ADDFUNC0(PACKED_BYTE_ARRAY, NIL, PackedByteArray, invert, varray());
 	ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, subarray, INT, "from", INT, "to", varray());
 
@@ -2103,6 +2123,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_INT32_ARRAY, INT, PackedInt32Array, insert, INT, "idx", INT, "integer", varray());
 	ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_INT32_ARRAY, BOOL, PackedInt32Array, has, INT, "value", varray());
+	ADDFUNC0(PACKED_INT32_ARRAY, NIL, PackedInt32Array, sort, varray());
 	ADDFUNC0(PACKED_INT32_ARRAY, NIL, PackedInt32Array, invert, varray());
 
 	ADDFUNC0R(PACKED_INT64_ARRAY, INT, PackedInt64Array, size, varray());
@@ -2114,6 +2136,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_INT64_ARRAY, INT, PackedInt64Array, insert, INT, "idx", INT, "integer", varray());
 	ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_INT64_ARRAY, BOOL, PackedInt64Array, has, INT, "value", varray());
+	ADDFUNC0(PACKED_INT64_ARRAY, NIL, PackedInt64Array, sort, varray());
 	ADDFUNC0(PACKED_INT64_ARRAY, NIL, PackedInt64Array, invert, varray());
 
 	ADDFUNC0R(PACKED_FLOAT32_ARRAY, INT, PackedFloat32Array, size, varray());
@@ -2125,6 +2149,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_FLOAT32_ARRAY, INT, PackedFloat32Array, insert, INT, "idx", FLOAT, "value", varray());
 	ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_FLOAT32_ARRAY, BOOL, PackedFloat32Array, has, FLOAT, "value", varray());
+	ADDFUNC0(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, sort, varray());
 	ADDFUNC0(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, invert, varray());
 
 	ADDFUNC0R(PACKED_FLOAT64_ARRAY, INT, PackedFloat64Array, size, varray());
@@ -2136,6 +2162,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_FLOAT64_ARRAY, INT, PackedFloat64Array, insert, INT, "idx", FLOAT, "value", varray());
 	ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_FLOAT64_ARRAY, BOOL, PackedFloat64Array, has, FLOAT, "value", varray());
+	ADDFUNC0(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, sort, varray());
 	ADDFUNC0(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, invert, varray());
 
 	ADDFUNC0R(PACKED_STRING_ARRAY, INT, PackedStringArray, size, varray());
@@ -2147,6 +2175,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_STRING_ARRAY, INT, PackedStringArray, insert, INT, "idx", STRING, "string", varray());
 	ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_STRING_ARRAY, BOOL, PackedStringArray, has, STRING, "value", varray());
+	ADDFUNC0(PACKED_STRING_ARRAY, NIL, PackedStringArray, sort, varray());
 	ADDFUNC0(PACKED_STRING_ARRAY, NIL, PackedStringArray, invert, varray());
 
 	ADDFUNC0R(PACKED_VECTOR2_ARRAY, INT, PackedVector2Array, size, varray());
@@ -2158,6 +2188,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_VECTOR2_ARRAY, INT, PackedVector2Array, insert, INT, "idx", VECTOR2, "vector2", varray());
 	ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_VECTOR2_ARRAY, BOOL, PackedVector2Array, has, VECTOR2, "value", varray());
+	ADDFUNC0(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, sort, varray());
 	ADDFUNC0(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, invert, varray());
 
 	ADDFUNC0R(PACKED_VECTOR3_ARRAY, INT, PackedVector3Array, size, varray());
@@ -2169,6 +2201,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_VECTOR3_ARRAY, INT, PackedVector3Array, insert, INT, "idx", VECTOR3, "vector3", varray());
 	ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_VECTOR3_ARRAY, BOOL, PackedVector3Array, has, VECTOR3, "value", varray());
+	ADDFUNC0(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, sort, varray());
 	ADDFUNC0(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, invert, varray());
 
 	ADDFUNC0R(PACKED_COLOR_ARRAY, INT, PackedColorArray, size, varray());
@@ -2180,6 +2214,8 @@ void register_variant_methods() {
 	ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, remove, INT, "idx", varray());
 	ADDFUNC2R(PACKED_COLOR_ARRAY, INT, PackedColorArray, insert, INT, "idx", COLOR, "color", varray());
 	ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, resize, INT, "idx", varray());
+	ADDFUNC1R(PACKED_COLOR_ARRAY, BOOL, PackedColorArray, has, COLOR, "value", varray());
+	ADDFUNC0(PACKED_COLOR_ARRAY, NIL, PackedColorArray, sort, varray());
 	ADDFUNC0(PACKED_COLOR_ARRAY, NIL, PackedColorArray, invert, varray());
 
 	//pointerbased
diff --git a/core/vector.h b/core/vector.h
index 4c152fb08420..5fb630c21cf1 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -92,6 +92,10 @@ class Vector {
 
 	void append_array(Vector<T> p_other);
 
+	bool has(const T &p_val) {
+		return find(p_val, 0) != -1;
+	}
+
 	template <class C>
 	void sort_custom() {
 		int len = _cowdata.size();
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index b08357e278e6..08f855888108 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -78,6 +78,15 @@
 				Returns a copy of the array's contents as [String]. Slower than [method get_string_from_ascii] but supports UTF-8 encoded data. Use this function if you are unsure about the source of the data. For user input this function should always be preferred.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="int">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="hex_encode">
 			<return type="String">
 			</return>
@@ -152,6 +161,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 		<method name="subarray">
 			<return type="PackedByteArray">
 			</return>
diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml
index 06228e4dac92..ec087e1b39d5 100644
--- a/doc/classes/PackedColorArray.xml
+++ b/doc/classes/PackedColorArray.xml
@@ -44,6 +44,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="Color">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -107,6 +116,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml
index ee82586cdba9..a6b726944be7 100644
--- a/doc/classes/PackedFloat32Array.xml
+++ b/doc/classes/PackedFloat32Array.xml
@@ -45,6 +45,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="float">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -108,6 +117,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml
index ce2300c65a0a..f867cda3b661 100644
--- a/doc/classes/PackedFloat64Array.xml
+++ b/doc/classes/PackedFloat64Array.xml
@@ -45,6 +45,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="float">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -108,6 +117,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml
index 176c62495655..b796d9cacbd7 100644
--- a/doc/classes/PackedInt32Array.xml
+++ b/doc/classes/PackedInt32Array.xml
@@ -45,6 +45,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="int">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -108,6 +117,13 @@
 				Returns the array size.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml
index d8a807159083..3d0d9a136098 100644
--- a/doc/classes/PackedInt64Array.xml
+++ b/doc/classes/PackedInt64Array.xml
@@ -45,6 +45,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="int">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -108,6 +117,13 @@
 				Returns the array size.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml
index 9526f5899df4..f36af66d6daa 100644
--- a/doc/classes/PackedStringArray.xml
+++ b/doc/classes/PackedStringArray.xml
@@ -44,6 +44,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="String">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -107,6 +116,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml
index 87f202357c76..ecc535e488dc 100644
--- a/doc/classes/PackedVector2Array.xml
+++ b/doc/classes/PackedVector2Array.xml
@@ -44,6 +44,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="Vector2">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -107,6 +116,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml
index 7bfa684ff5e1..f268fbcc830d 100644
--- a/doc/classes/PackedVector3Array.xml
+++ b/doc/classes/PackedVector3Array.xml
@@ -44,6 +44,15 @@
 				Returns [code]true[/code] if the array is empty.
 			</description>
 		</method>
+		<method name="has">
+			<return type="bool">
+			</return>
+			<argument index="0" name="value" type="Vector3">
+			</argument>
+			<description>
+				Returns [code]true[/code] if the array contains [code]value[/code].
+			</description>
+		</method>
 		<method name="insert">
 			<return type="int">
 			</return>
@@ -107,6 +116,13 @@
 				Returns the size of the array.
 			</description>
 		</method>
+		<method name="sort">
+			<return type="void">
+			</return>
+			<description>
+				Sorts the elements of the array in ascending order.
+			</description>
+		</method>
 	</methods>
 	<constants>
 	</constants>
diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp
index fc71d5028930..de93c1d9b3e3 100644
--- a/modules/gdnative/gdnative/packed_arrays.cpp
+++ b/modules/gdnative/gdnative/packed_arrays.cpp
@@ -104,6 +104,16 @@ godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self
 	return (godot_error)self->insert(p_idx, p_data);
 }
 
+godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value) {
+	Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
+	return (godot_bool)self->has(p_value);
+}
+
+void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self) {
+	Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self) {
 	Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
 	self->invert();
@@ -198,6 +208,16 @@ godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_se
 	return (godot_error)self->insert(p_idx, p_data);
 }
 
+godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value) {
+	Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+	return (godot_bool)self->has(p_value);
+}
+
+void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self) {
+	Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self) {
 	Vector<int32_t> *self = (Vector<int32_t> *)p_self;
 	self->invert();
@@ -292,6 +312,16 @@ godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_se
 	return (godot_error)self->insert(p_idx, p_data);
 }
 
+godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value) {
+	Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+	return (godot_bool)self->has(p_value);
+}
+
+void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self) {
+	Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self) {
 	Vector<int64_t> *self = (Vector<int64_t> *)p_self;
 	self->invert();
@@ -386,6 +416,16 @@ godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *
 	return (godot_error)self->insert(p_idx, p_data);
 }
 
+godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value) {
+	Vector<float> *self = (Vector<float> *)p_self;
+	return (godot_bool)self->has(p_value);
+}
+
+void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self) {
+	Vector<float> *self = (Vector<float> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self) {
 	Vector<float> *self = (Vector<float> *)p_self;
 	self->invert();
@@ -480,6 +520,16 @@ godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *
 	return (godot_error)self->insert(p_idx, p_data);
 }
 
+godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value) {
+	Vector<double> *self = (Vector<double> *)p_self;
+	return (godot_bool)self->has(p_value);
+}
+
+void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self) {
+	Vector<double> *self = (Vector<double> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self) {
 	Vector<double> *self = (Vector<double> *)p_self;
 	self->invert();
@@ -576,6 +626,17 @@ godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_
 	return (godot_error)self->insert(p_idx, s);
 }
 
+godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value) {
+	Vector<String> *self = (Vector<String> *)p_self;
+	String &s = *(String *)p_value;
+	return (godot_bool)self->has(s);
+}
+
+void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self) {
+	Vector<String> *self = (Vector<String> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self) {
 	Vector<String> *self = (Vector<String> *)p_self;
 	self->invert();
@@ -678,6 +739,17 @@ godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *
 	return (godot_error)self->insert(p_idx, s);
 }
 
+godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value) {
+	Vector<Vector2> *self = (Vector<Vector2> *)p_self;
+	Vector2 &v = *(Vector2 *)p_value;
+	return (godot_bool)self->has(v);
+}
+
+void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self) {
+	Vector<Vector2> *self = (Vector<Vector2> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self) {
 	Vector<Vector2> *self = (Vector<Vector2> *)p_self;
 	self->invert();
@@ -779,6 +851,17 @@ godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *
 	return (godot_error)self->insert(p_idx, s);
 }
 
+godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value) {
+	Vector<Vector3> *self = (Vector<Vector3> *)p_self;
+	Vector3 &v = *(Vector3 *)p_value;
+	return (godot_bool)self->has(v);
+}
+
+void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self) {
+	Vector<Vector3> *self = (Vector<Vector3> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self) {
 	Vector<Vector3> *self = (Vector<Vector3> *)p_self;
 	self->invert();
@@ -880,6 +963,17 @@ godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_se
 	return (godot_error)self->insert(p_idx, s);
 }
 
+godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value) {
+	Vector<Color> *self = (Vector<Color> *)p_self;
+	Color &c = *(Color *)p_value;
+	return (godot_bool)self->has(c);
+}
+
+void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self) {
+	Vector<Color> *self = (Vector<Color> *)p_self;
+	self->sort();
+}
+
 void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self) {
 	Vector<Color> *self = (Vector<Color> *)p_self;
 	self->invert();
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 1284ebbd6688..eb122089b64e 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -918,42 +918,42 @@
           ["const godot_variant **", "p_arguments"],
           ["godot_int", "p_argcount"]
         ]
-      },  
+      },
       {
         "name": "godot_callable_is_null",
         "return_type": "godot_bool",
         "arguments": [
           ["const godot_callable *", "p_self"]
         ]
-      },  
+      },
       {
         "name": "godot_callable_is_custom",
         "return_type": "godot_bool",
         "arguments": [
           ["const godot_callable *", "p_self"]
         ]
-      },  
+      },
       {
         "name": "godot_callable_is_standard",
         "return_type": "godot_bool",
         "arguments": [
           ["const godot_callable *", "p_self"]
         ]
-      },    
+      },
       {
         "name": "godot_callable_get_object",
         "return_type": "godot_object *",
         "arguments": [
           ["const godot_callable *", "p_self"]
         ]
-      },    
+      },
       {
         "name": "godot_callable_get_object_id",
         "return_type": "uint64_t",
         "arguments": [
           ["const godot_callable *", "p_self"]
         ]
-      },    
+      },
       {
         "name": "godot_callable_get_method",
         "return_type": "godot_string_name",
@@ -1093,14 +1093,14 @@
         "arguments": [
           ["const godot_signal *", "p_self"]
         ]
-      },  
+      },
       {
         "name": "godot_signal_as_string",
         "return_type": "godot_string",
         "arguments": [
           ["const godot_signal *", "p_self"]
         ]
-      },  
+      },
       {
         "name": "godot_signal_operator_equal",
         "return_type": "godot_bool",
@@ -1108,7 +1108,7 @@
           ["const godot_signal *", "p_self"],
           ["const godot_signal *", "p_other"]
         ]
-      },  
+      },
       {
         "name": "godot_signal_operator_less",
         "return_type": "godot_bool",
@@ -1670,6 +1670,21 @@
           ["const uint8_t", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_byte_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_byte_array *", "p_self"],
+          ["const uint8_t", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_byte_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_byte_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_byte_array_invert",
         "return_type": "void",
@@ -1801,6 +1816,21 @@
           ["const int32_t", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_int32_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_int32_array *", "p_self"],
+          ["const int32_t", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_int32_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_int32_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_int32_array_invert",
         "return_type": "void",
@@ -1932,6 +1962,21 @@
           ["const int64_t", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_int64_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_int64_array *", "p_self"],
+          ["const int64_t", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_int64_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_int64_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_int64_array_invert",
         "return_type": "void",
@@ -2063,6 +2108,21 @@
           ["const float", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_float32_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_float32_array *", "p_self"],
+          ["const float", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_float32_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_float32_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_float32_array_invert",
         "return_type": "void",
@@ -2194,6 +2254,21 @@
           ["const double", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_float64_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_float64_array *", "p_self"],
+          ["const double", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_float64_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_float64_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_float64_array_invert",
         "return_type": "void",
@@ -2325,6 +2400,21 @@
           ["const godot_string *", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_string_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_string_array *", "p_self"],
+          ["const godot_string *", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_string_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_string_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_string_array_invert",
         "return_type": "void",
@@ -2456,6 +2546,21 @@
           ["const godot_vector2 *", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_vector2_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_vector2_array *", "p_self"],
+          ["const godot_vector2 *", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_vector2_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_vector2_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_vector2_array_invert",
         "return_type": "void",
@@ -2587,6 +2692,21 @@
           ["const godot_vector3 *", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_vector3_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_vector3_array *", "p_self"],
+          ["const godot_vector3 *", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_vector3_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_vector3_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_vector3_array_invert",
         "return_type": "void",
@@ -2718,6 +2838,21 @@
           ["const godot_color *", "p_data"]
         ]
       },
+      {
+        "name": "godot_packed_color_array_has",
+        "return_type": "godot_bool",
+        "arguments": [
+          ["godot_packed_color_array *", "p_self"],
+          ["const godot_color *", "p_value"]
+        ]
+      },
+      {
+        "name": "godot_packed_color_array_sort",
+        "return_type": "void",
+        "arguments": [
+          ["godot_packed_color_array *", "p_self"]
+        ]
+      },
       {
         "name": "godot_packed_color_array_invert",
         "return_type": "void",
@@ -2748,7 +2883,7 @@
           ["godot_packed_color_array *", "p_self"],
           ["const godot_int", "p_size"]
         ]
-      },    
+      },
       {
         "name": "godot_packed_color_array_ptr",
         "return_type": "const godot_color *",
@@ -5463,7 +5598,7 @@
           ["godot_variant *", "r_dest"],
           ["const godot_packed_int64_array *", "p_pia"]
         ]
-      },    
+      },
       {
         "name": "godot_variant_new_packed_float32_array",
         "return_type": "void",
diff --git a/modules/gdnative/include/gdnative/packed_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h
index 87d467a5b852..6a1727d76ff3 100644
--- a/modules/gdnative/include/gdnative/packed_arrays.h
+++ b/modules/gdnative/include/gdnative/packed_arrays.h
@@ -167,6 +167,10 @@ void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self,
 
 godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
 
+godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value);
+
+void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self);
+
 void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self);
 
 void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data);
@@ -199,6 +203,10 @@ void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_sel
 
 godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data);
 
+godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value);
+
+void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self);
+
 void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self);
 
 void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data);
@@ -231,6 +239,10 @@ void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_sel
 
 godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data);
 
+godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value);
+
+void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self);
+
 void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self);
 
 void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data);
@@ -263,6 +275,10 @@ void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p
 
 godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data);
 
+godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value);
+
+void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self);
+
 void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self);
 
 void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data);
@@ -295,6 +311,10 @@ void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p
 
 godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data);
 
+godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value);
+
+void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self);
+
 void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self);
 
 void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data);
@@ -327,6 +347,10 @@ void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_s
 
 godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
 
+godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value);
+
+void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self);
+
 void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self);
 
 void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data);
@@ -359,6 +383,10 @@ void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p
 
 godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
 
+godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value);
+
+void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self);
+
 void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self);
 
 void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data);
@@ -391,6 +419,10 @@ void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p
 
 godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
 
+godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value);
+
+void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self);
+
 void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self);
 
 void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data);
@@ -423,6 +455,10 @@ void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_sel
 
 godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
 
+godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value);
+
+void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self);
+
 void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self);
 
 void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data);