diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/array.cpp | 43 | ||||
-rw-r--r-- | core/array.h | 2 | ||||
-rw-r--r-- | core/variant_call.cpp | 4 |
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()); |