Skip to content

Commit 40bd868

Browse files
committed
Merge pull request #104332 from ColinSORourke/FindSeq
Add 'Find Sequence' to `Span`s, and consolidate negative indexing behavior
2 parents ebbd5a7 + 03d32c6 commit 40bd868

File tree

4 files changed

+120
-166
lines changed

4 files changed

+120
-166
lines changed

core/string/ustring.cpp

Lines changed: 75 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,69 +3055,42 @@ String String::substr(int p_from, int p_chars) const {
30553055
}
30563056

30573057
int String::find(const String &p_str, int p_from) const {
3058-
if (p_from < 0) {
3059-
return -1;
3060-
}
3061-
3062-
const int src_len = p_str.length();
3063-
3058+
const int str_len = p_str.length();
30643059
const int len = length();
30653060

3066-
if (src_len == 0 || len == 0) {
3067-
return -1; // won't find anything!
3061+
if (p_from < 0) {
3062+
p_from = len - str_len + p_from + 1;
30683063
}
3069-
3070-
if (src_len == 1) {
3071-
return find_char(p_str[0], p_from); // Optimize with single-char find.
3064+
if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
3065+
return -1; // Still out of bounds
30723066
}
30733067

3074-
const char32_t *src = get_data();
3075-
const char32_t *str = p_str.get_data();
3076-
3077-
for (int i = p_from; i <= (len - src_len); i++) {
3078-
bool found = true;
3079-
for (int j = 0; j < src_len; j++) {
3080-
int read_pos = i + j;
3081-
3082-
if (read_pos >= len) {
3083-
ERR_PRINT("read_pos>=len");
3084-
return -1;
3085-
}
3086-
3087-
if (src[read_pos] != str[j]) {
3088-
found = false;
3089-
break;
3090-
}
3091-
}
3092-
3093-
if (found) {
3094-
return i;
3095-
}
3068+
if (p_str.length() == 1) {
3069+
// Optimize with single-char implementation.
3070+
return span().find(p_str[0], p_from);
30963071
}
30973072

3098-
return -1;
3073+
return span().find_sequence(p_str.span(), p_from);
30993074
}
31003075

31013076
int String::find(const char *p_str, int p_from) const {
3102-
if (p_from < 0 || !p_str) {
3103-
return -1;
3104-
}
3105-
3106-
const int src_len = strlen(p_str);
3107-
3077+
const int str_len = strlen(p_str);
31083078
const int len = length();
31093079

3110-
if (len == 0 || src_len == 0) {
3111-
return -1; // won't find anything!
3080+
if (p_from < 0) {
3081+
p_from = len - str_len + p_from + 1;
3082+
}
3083+
if (p_from < 0 || p_from > len - str_len || str_len == 0) {
3084+
return -1; // Still out of bounds
31123085
}
31133086

3114-
if (src_len == 1) {
3087+
if (str_len == 1) {
31153088
return find_char(*p_str, p_from); // Optimize with single-char find.
31163089
}
31173090

31183091
const char32_t *src = get_data();
31193092

3120-
if (src_len == 1) {
3093+
if (str_len == 1) {
31213094
const char32_t needle = p_str[0];
31223095

31233096
for (int i = p_from; i < len; i++) {
@@ -3127,13 +3100,13 @@ int String::find(const char *p_str, int p_from) const {
31273100
}
31283101

31293102
} else {
3130-
for (int i = p_from; i <= (len - src_len); i++) {
3103+
for (int i = p_from; i <= (len - str_len); i++) {
31313104
bool found = true;
3132-
for (int j = 0; j < src_len; j++) {
3105+
for (int j = 0; j < str_len; j++) {
31333106
int read_pos = i + j;
31343107

31353108
if (read_pos >= len) {
3136-
ERR_PRINT("read_pos>=len");
3109+
ERR_PRINT("read_pos>=length()");
31373110
return -1;
31383111
}
31393112

@@ -3170,7 +3143,7 @@ int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
31703143
return -1;
31713144
}
31723145

3173-
//int src_len=p_str.length();
3146+
//int str_len=p_str.length();
31743147
const String *keys = &p_keys[0];
31753148
int key_count = p_keys.size();
31763149
int len = length();
@@ -3218,24 +3191,24 @@ int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
32183191
}
32193192

32203193
int String::findn(const String &p_str, int p_from) const {
3194+
const int str_len = p_str.length();
3195+
const int len = length();
3196+
32213197
if (p_from < 0) {
3222-
return -1;
3198+
p_from = len - str_len + p_from + 1;
32233199
}
3224-
3225-
int src_len = p_str.length();
3226-
3227-
if (src_len == 0 || length() == 0) {
3228-
return -1; // won't find anything!
3200+
if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
3201+
return -1; // Still out of bounds
32293202
}
32303203

32313204
const char32_t *srcd = get_data();
32323205

3233-
for (int i = p_from; i <= (length() - src_len); i++) {
3206+
for (int i = p_from; i <= (len - str_len); i++) {
32343207
bool found = true;
3235-
for (int j = 0; j < src_len; j++) {
3208+
for (int j = 0; j < str_len; j++) {
32363209
int read_pos = i + j;
32373210

3238-
if (read_pos >= length()) {
3211+
if (read_pos >= len) {
32393212
ERR_PRINT("read_pos>=length()");
32403213
return -1;
32413214
}
@@ -3258,24 +3231,24 @@ int String::findn(const String &p_str, int p_from) const {
32583231
}
32593232

32603233
int String::findn(const char *p_str, int p_from) const {
3234+
const int str_len = strlen(p_str);
3235+
const int len = length();
3236+
32613237
if (p_from < 0) {
3262-
return -1;
3238+
p_from = len - str_len + p_from + 1;
32633239
}
3264-
3265-
int src_len = strlen(p_str);
3266-
3267-
if (src_len == 0 || length() == 0) {
3268-
return -1; // won't find anything!
3240+
if (p_from < 0 || p_from > len - str_len || str_len == 0) {
3241+
return -1; // Still out of bounds
32693242
}
32703243

32713244
const char32_t *srcd = get_data();
32723245

3273-
for (int i = p_from; i <= (length() - src_len); i++) {
3246+
for (int i = p_from; i <= (len - str_len); i++) {
32743247
bool found = true;
3275-
for (int j = 0; j < src_len; j++) {
3248+
for (int j = 0; j < str_len; j++) {
32763249
int read_pos = i + j;
32773250

3278-
if (read_pos >= length()) {
3251+
if (read_pos >= len) {
32793252
ERR_PRINT("read_pos>=length()");
32803253
return -1;
32813254
}
@@ -3298,85 +3271,44 @@ int String::findn(const char *p_str, int p_from) const {
32983271
}
32993272

33003273
int String::rfind(const String &p_str, int p_from) const {
3301-
// establish a limit
3302-
int limit = length() - p_str.length();
3303-
if (limit < 0) {
3304-
return -1;
3305-
}
3274+
const int str_len = p_str.length();
3275+
const int len = length();
33063276

3307-
// establish a starting point
33083277
if (p_from < 0) {
3309-
p_from = limit;
3310-
} else if (p_from > limit) {
3311-
p_from = limit;
3278+
p_from = len - str_len + p_from + 1;
33123279
}
3313-
3314-
int src_len = p_str.length();
3315-
int len = length();
3316-
3317-
if (src_len == 0 || len == 0) {
3318-
return -1; // won't find anything!
3280+
if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
3281+
return -1; // Still out of bounds
33193282
}
33203283

3321-
const char32_t *src = get_data();
3322-
3323-
for (int i = p_from; i >= 0; i--) {
3324-
bool found = true;
3325-
for (int j = 0; j < src_len; j++) {
3326-
int read_pos = i + j;
3327-
3328-
if (read_pos >= len) {
3329-
ERR_PRINT("read_pos>=len");
3330-
return -1;
3331-
}
3332-
3333-
if (src[read_pos] != p_str[j]) {
3334-
found = false;
3335-
break;
3336-
}
3337-
}
3338-
3339-
if (found) {
3340-
return i;
3341-
}
3284+
if (p_str.length() == 1) {
3285+
// Optimize with single-char implementation.
3286+
return span().rfind(p_str[0], p_from);
33423287
}
33433288

3344-
return -1;
3289+
return span().rfind_sequence(p_str.span(), p_from);
33453290
}
33463291

33473292
int String::rfind(const char *p_str, int p_from) const {
3348-
const int source_length = length();
3349-
int substring_length = strlen(p_str);
3350-
3351-
if (source_length == 0 || substring_length == 0) {
3352-
return -1; // won't find anything!
3353-
}
3354-
3355-
// establish a limit
3356-
int limit = length() - substring_length;
3357-
if (limit < 0) {
3358-
return -1;
3359-
}
3293+
const int str_len = strlen(p_str);
3294+
const int len = length();
33603295

3361-
// establish a starting point
3362-
int starting_point;
33633296
if (p_from < 0) {
3364-
starting_point = limit;
3365-
} else if (p_from > limit) {
3366-
starting_point = limit;
3367-
} else {
3368-
starting_point = p_from;
3297+
p_from = len - str_len + p_from + 1;
3298+
}
3299+
if (p_from < 0 || p_from > len - str_len || str_len == 0) {
3300+
return -1; // Still out of bounds
33693301
}
33703302

33713303
const char32_t *source = get_data();
33723304

3373-
for (int i = starting_point; i >= 0; i--) {
3305+
for (int i = p_from; i >= 0; i--) {
33743306
bool found = true;
3375-
for (int j = 0; j < substring_length; j++) {
3307+
for (int j = 0; j < str_len; j++) {
33763308
int read_pos = i + j;
33773309

3378-
if (read_pos >= source_length) {
3379-
ERR_PRINT("read_pos>=source_length");
3310+
if (read_pos >= length()) {
3311+
ERR_PRINT("read_pos>=length()");
33803312
return -1;
33813313
}
33823314

@@ -3406,35 +3338,25 @@ int String::rfind_char(char32_t p_char, int p_from) const {
34063338
}
34073339

34083340
int String::rfindn(const String &p_str, int p_from) const {
3409-
// establish a limit
3410-
int limit = length() - p_str.length();
3411-
if (limit < 0) {
3412-
return -1;
3413-
}
3341+
const int str_len = p_str.length();
3342+
const int len = length();
34143343

3415-
// establish a starting point
34163344
if (p_from < 0) {
3417-
p_from = limit;
3418-
} else if (p_from > limit) {
3419-
p_from = limit;
3345+
p_from = len - str_len + p_from + 1;
34203346
}
3421-
3422-
int src_len = p_str.length();
3423-
int len = length();
3424-
3425-
if (src_len == 0 || len == 0) {
3426-
return -1; // won't find anything!
3347+
if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
3348+
return -1; // Still out of bounds
34273349
}
34283350

34293351
const char32_t *src = get_data();
34303352

34313353
for (int i = p_from; i >= 0; i--) {
34323354
bool found = true;
3433-
for (int j = 0; j < src_len; j++) {
3355+
for (int j = 0; j < str_len; j++) {
34343356
int read_pos = i + j;
34353357

34363358
if (read_pos >= len) {
3437-
ERR_PRINT("read_pos>=len");
3359+
ERR_PRINT("read_pos>=length()");
34383360
return -1;
34393361
}
34403362

@@ -3456,38 +3378,25 @@ int String::rfindn(const String &p_str, int p_from) const {
34563378
}
34573379

34583380
int String::rfindn(const char *p_str, int p_from) const {
3459-
const int source_length = length();
3460-
int substring_length = strlen(p_str);
3461-
3462-
if (source_length == 0 || substring_length == 0) {
3463-
return -1; // won't find anything!
3464-
}
3465-
3466-
// establish a limit
3467-
int limit = length() - substring_length;
3468-
if (limit < 0) {
3469-
return -1;
3470-
}
3381+
const int str_len = strlen(p_str);
3382+
const int len = length();
34713383

3472-
// establish a starting point
3473-
int starting_point;
34743384
if (p_from < 0) {
3475-
starting_point = limit;
3476-
} else if (p_from > limit) {
3477-
starting_point = limit;
3478-
} else {
3479-
starting_point = p_from;
3385+
p_from = len - str_len + p_from + 1;
3386+
}
3387+
if (p_from < 0 || p_from > len - str_len || str_len == 0) {
3388+
return -1; // Still out of bounds
34803389
}
34813390

34823391
const char32_t *source = get_data();
34833392

3484-
for (int i = starting_point; i >= 0; i--) {
3393+
for (int i = p_from; i >= 0; i--) {
34853394
bool found = true;
3486-
for (int j = 0; j < substring_length; j++) {
3395+
for (int j = 0; j < str_len; j++) {
34873396
int read_pos = i + j;
34883397

3489-
if (read_pos >= source_length) {
3490-
ERR_PRINT("read_pos>=source_length");
3398+
if (read_pos >= len) {
3399+
ERR_PRINT("read_pos>=length()");
34913400
return -1;
34923401
}
34933402

0 commit comments

Comments
 (0)