summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/array.cpp43
-rw-r--r--core/array.h2
-rw-r--r--core/variant_call.cpp4
3 files changed, 49 insertions, 0 deletions
diff --git a/core/array.cpp b/core/array.cpp
index 171c11776c..b7d4ae413a 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -265,6 +265,49 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
return *this;
}
+template <typename Less>
+_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
+
+ int lo = 0;
+ int hi = p_array.size();
+ if (p_before) {
+ while (lo < hi) {
+ const int mid = (lo + hi) / 2;
+ if (p_less(p_array.get(mid), p_value)) {
+ lo = mid + 1;
+ } else {
+ hi = mid;
+ }
+ }
+ } else {
+ while (lo < hi) {
+ const int mid = (lo + hi) / 2;
+ if (p_less(p_value, p_array.get(mid))) {
+ hi = mid;
+ } else {
+ lo = mid + 1;
+ }
+ }
+ }
+ return lo;
+}
+
+int Array::bsearch(const Variant &p_value, bool p_before) {
+
+ return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
+}
+
+int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
+
+ ERR_FAIL_NULL_V(p_obj, 0);
+
+ _ArrayVariantSortCustom less;
+ less.obj = p_obj;
+ less.func = p_function;
+
+ return bisect(_p->array, p_value, p_before, less);
+}
+
Array &Array::invert() {
_p->array.invert();
diff --git a/core/array.h b/core/array.h
index 2c29103108..3d70a31d2f 100644
--- a/core/array.h
+++ b/core/array.h
@@ -70,6 +70,8 @@ public:
Array &sort();
Array &sort_custom(Object *p_obj, const StringName &p_function);
+ int bsearch(const Variant &p_value, bool p_before = true);
+ int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true);
Array &invert();
int find(const Variant &p_value, int p_from = 0) const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 9e6aaeb911..da6e602ccb 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -483,6 +483,8 @@ struct _VariantCall {
VCALL_LOCALMEM1(Array, erase);
VCALL_LOCALMEM0(Array, sort);
VCALL_LOCALMEM2(Array, sort_custom);
+ VCALL_LOCALMEM2R(Array, bsearch);
+ VCALL_LOCALMEM4R(Array, bsearch_custom);
VCALL_LOCALMEM0R(Array, duplicate);
VCALL_LOCALMEM0(Array, invert);
@@ -1625,6 +1627,8 @@ void register_variant_methods() {
ADDFUNC0RNC(ARRAY, NIL, Array, pop_front, varray());
ADDFUNC0NC(ARRAY, NIL, Array, sort, varray());
ADDFUNC2NC(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray());
+ ADDFUNC2R(ARRAY, INT, Array, bsearch, NIL, "value", BOOL, "before", varray(true));
+ ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true));
ADDFUNC0NC(ARRAY, NIL, Array, invert, varray());
ADDFUNC0RNC(ARRAY, ARRAY, Array, duplicate, varray());