From c6cefb1b79d207af1bc78ce20c01b5788e806252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 10 Jan 2022 13:56:55 +0100 Subject: `Array`: Relax `slice` bound checks to properly handle negative indices The same is done for `Vector` (and thus `Packed*Array`). `begin` and `end` can now take any value and will be clamped to `[-size(), size()]`. Negative values are a shorthand for indexing the array from the last element upward. `end` is given a default `INT_MAX` value (which will be clamped to `size()`) so that the `end` parameter can be omitted to go from `begin` to the max size of the array. This makes `slice` works similarly to numpy's and JavaScript's. --- core/templates/vector.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'core/templates') diff --git a/core/templates/vector.h b/core/templates/vector.h index 4ada3b597a..d1408125c8 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -43,6 +43,7 @@ #include "core/templates/search_array.h" #include "core/templates/sort_array.h" +#include #include template @@ -145,25 +146,29 @@ public: return ret; } - Vector slice(int p_begin, int p_end) const { + Vector slice(int p_begin, int p_end = INT_MAX) const { Vector result; - if (p_end < 0) { - p_end += size() + 1; - } + const int s = size(); - ERR_FAIL_INDEX_V(p_begin, size(), result); - ERR_FAIL_INDEX_V(p_end, size() + 1, result); + int begin = CLAMP(p_begin, -s, s); + if (begin < 0) { + begin += s; + } + int end = CLAMP(p_end, -s, s); + if (end < 0) { + end += s; + } - ERR_FAIL_COND_V(p_begin > p_end, result); + ERR_FAIL_COND_V(begin > end, result); - int result_size = p_end - p_begin; + int result_size = end - begin; result.resize(result_size); const T *const r = ptr(); T *const w = result.ptrw(); for (int i = 0; i < result_size; ++i) { - w[i] = r[p_begin + i]; + w[i] = r[begin + i]; } return result; -- cgit v1.2.3