mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 14:12:51 +00:00
Merge pull request #76735 from AThousandShips/natural_cmp
Add `naturalcasecmp_to` function to `String`
This commit is contained in:
commit
5ade250c7d
@ -812,15 +812,15 @@ signed char String::nocasecmp_to(const String &p_str) const {
|
||||
const char32_t *this_str = get_data();
|
||||
|
||||
while (true) {
|
||||
if (*that_str == 0 && *this_str == 0) {
|
||||
return 0; //we're equal
|
||||
} else if (*this_str == 0) {
|
||||
return -1; //if this is empty, and the other one is not, then we're less.. I think?
|
||||
} else if (*that_str == 0) {
|
||||
return 1; //otherwise the other one is smaller..
|
||||
} else if (_find_upper(*this_str) < _find_upper(*that_str)) { //more than
|
||||
if (*that_str == 0 && *this_str == 0) { // If both strings are at the end, they are equal.
|
||||
return 0;
|
||||
} else if (*this_str == 0) { // If at the end of this, and not of other, we are less.
|
||||
return -1;
|
||||
} else if (_find_upper(*this_str) > _find_upper(*that_str)) { //less than
|
||||
} else if (*that_str == 0) { // If at end of other, and not of this, we are greater.
|
||||
return 1;
|
||||
} else if (_find_upper(*this_str) < _find_upper(*that_str)) { // If current character in this is less, we are less.
|
||||
return -1;
|
||||
} else if (_find_upper(*this_str) > _find_upper(*that_str)) { // If current character in this is greater, we are greater.
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -844,15 +844,15 @@ signed char String::casecmp_to(const String &p_str) const {
|
||||
const char32_t *this_str = get_data();
|
||||
|
||||
while (true) {
|
||||
if (*that_str == 0 && *this_str == 0) {
|
||||
return 0; //we're equal
|
||||
} else if (*this_str == 0) {
|
||||
return -1; //if this is empty, and the other one is not, then we're less.. I think?
|
||||
} else if (*that_str == 0) {
|
||||
return 1; //otherwise the other one is smaller..
|
||||
} else if (*this_str < *that_str) { //more than
|
||||
if (*that_str == 0 && *this_str == 0) { // If both strings are at the end, they are equal.
|
||||
return 0;
|
||||
} else if (*this_str == 0) { // If at the end of this, and not of other, we are less.
|
||||
return -1;
|
||||
} else if (*this_str > *that_str) { //less than
|
||||
} else if (*that_str == 0) { // If at end of other, and not of this, we are greater.
|
||||
return 1;
|
||||
} else if (*this_str < *that_str) { // If current character in this is less, we are less.
|
||||
return -1;
|
||||
} else if (*this_str > *that_str) { // If current character in this is greater, we are greater.
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -861,6 +861,100 @@ signed char String::casecmp_to(const String &p_str) const {
|
||||
}
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ signed char natural_cmp_common(const char32_t *&r_this_str, const char32_t *&r_that_str) {
|
||||
// Keep ptrs to start of numerical sequences.
|
||||
const char32_t *this_substr = r_this_str;
|
||||
const char32_t *that_substr = r_that_str;
|
||||
|
||||
// Compare lengths of both numerical sequences, ignoring leading zeros.
|
||||
while (is_digit(*r_this_str)) {
|
||||
r_this_str++;
|
||||
}
|
||||
while (is_digit(*r_that_str)) {
|
||||
r_that_str++;
|
||||
}
|
||||
while (*this_substr == '0') {
|
||||
this_substr++;
|
||||
}
|
||||
while (*that_substr == '0') {
|
||||
that_substr++;
|
||||
}
|
||||
int this_len = r_this_str - this_substr;
|
||||
int that_len = r_that_str - that_substr;
|
||||
|
||||
if (this_len < that_len) {
|
||||
return -1;
|
||||
} else if (this_len > that_len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If lengths equal, compare lexicographically.
|
||||
while (this_substr != r_this_str && that_substr != r_that_str) {
|
||||
if (*this_substr < *that_substr) {
|
||||
return -1;
|
||||
} else if (*this_substr > *that_substr) {
|
||||
return 1;
|
||||
}
|
||||
this_substr++;
|
||||
that_substr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
signed char String::naturalcasecmp_to(const String &p_str) const {
|
||||
const char32_t *this_str = get_data();
|
||||
const char32_t *that_str = p_str.get_data();
|
||||
|
||||
if (this_str && that_str) {
|
||||
while (*this_str == '.' || *that_str == '.') {
|
||||
if (*this_str++ != '.') {
|
||||
return 1;
|
||||
}
|
||||
if (*that_str++ != '.') {
|
||||
return -1;
|
||||
}
|
||||
if (!*that_str) {
|
||||
return 1;
|
||||
}
|
||||
if (!*this_str) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (*this_str) {
|
||||
if (!*that_str) {
|
||||
return 1;
|
||||
} else if (is_digit(*this_str)) {
|
||||
if (!is_digit(*that_str)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
signed char ret = natural_cmp_common(this_str, that_str);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
} else if (is_digit(*that_str)) {
|
||||
return 1;
|
||||
} else {
|
||||
if (*this_str < *that_str) { // If current character in this is less, we are less.
|
||||
return -1;
|
||||
} else if (*this_str > *that_str) { // If current character in this is greater, we are greater.
|
||||
return 1;
|
||||
}
|
||||
|
||||
this_str++;
|
||||
that_str++;
|
||||
}
|
||||
}
|
||||
if (*that_str) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
signed char String::naturalnocasecmp_to(const String &p_str) const {
|
||||
const char32_t *this_str = get_data();
|
||||
const char32_t *that_str = p_str.get_data();
|
||||
@ -889,48 +983,16 @@ signed char String::naturalnocasecmp_to(const String &p_str) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Keep ptrs to start of numerical sequences
|
||||
const char32_t *this_substr = this_str;
|
||||
const char32_t *that_substr = that_str;
|
||||
|
||||
// Compare lengths of both numerical sequences, ignoring leading zeros
|
||||
while (is_digit(*this_str)) {
|
||||
this_str++;
|
||||
}
|
||||
while (is_digit(*that_str)) {
|
||||
that_str++;
|
||||
}
|
||||
while (*this_substr == '0') {
|
||||
this_substr++;
|
||||
}
|
||||
while (*that_substr == '0') {
|
||||
that_substr++;
|
||||
}
|
||||
int this_len = this_str - this_substr;
|
||||
int that_len = that_str - that_substr;
|
||||
|
||||
if (this_len < that_len) {
|
||||
return -1;
|
||||
} else if (this_len > that_len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If lengths equal, compare lexicographically
|
||||
while (this_substr != this_str && that_substr != that_str) {
|
||||
if (*this_substr < *that_substr) {
|
||||
return -1;
|
||||
} else if (*this_substr > *that_substr) {
|
||||
return 1;
|
||||
}
|
||||
this_substr++;
|
||||
that_substr++;
|
||||
signed char ret = natural_cmp_common(this_str, that_str);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
} else if (is_digit(*that_str)) {
|
||||
return 1;
|
||||
} else {
|
||||
if (_find_upper(*this_str) < _find_upper(*that_str)) { //more than
|
||||
if (_find_upper(*this_str) < _find_upper(*that_str)) { // If current character in this is less, we are less.
|
||||
return -1;
|
||||
} else if (_find_upper(*this_str) > _find_upper(*that_str)) { //less than
|
||||
} else if (_find_upper(*this_str) > _find_upper(*that_str)) { // If current character in this is greater, we are greater.
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -262,6 +262,7 @@ public:
|
||||
|
||||
signed char casecmp_to(const String &p_str) const;
|
||||
signed char nocasecmp_to(const String &p_str) const;
|
||||
signed char naturalcasecmp_to(const String &p_str) const;
|
||||
signed char naturalnocasecmp_to(const String &p_str) const;
|
||||
|
||||
const char32_t *get_data() const;
|
||||
|
@ -1633,6 +1633,7 @@ static void _register_variant_builtin_methods() {
|
||||
|
||||
bind_string_method(casecmp_to, sarray("to"), varray());
|
||||
bind_string_method(nocasecmp_to, sarray("to"), varray());
|
||||
bind_string_method(naturalcasecmp_to, sarray("to"), varray());
|
||||
bind_string_method(naturalnocasecmp_to, sarray("to"), varray());
|
||||
bind_string_method(length, sarray(), varray());
|
||||
bind_string_method(substr, sarray("from", "len"), varray(-1));
|
||||
|
@ -111,7 +111,7 @@
|
||||
<description>
|
||||
Performs a case-sensitive comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" and "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order.
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method nocasecmp_to] and [method naturalnocasecmp_to].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method nocasecmp_to], [method naturalcasecmp_to], and [method naturalnocasecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="chr" qualifiers="static">
|
||||
@ -578,6 +578,16 @@
|
||||
Returns the [url=https://en.wikipedia.org/wiki/MD5]MD5 hash[/url] of the string as another [String].
|
||||
</description>
|
||||
</method>
|
||||
<method name="naturalcasecmp_to" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="to" type="String" />
|
||||
<description>
|
||||
Performs a [b]case-sensitive[/b], [i]natural order[/i] comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" or "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order.
|
||||
When used for sorting, natural order comparison orders sequences of numbers by the combined value of each digit as is often expected, instead of the single digit's value. A sorted sequence of numbered strings will be [code]["1", "2", "3", ...][/code], not [code]["1", "10", "2", "3", ...][/code].
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method naturalnocasecmp_to], [method nocasecmp_to], and [method casecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="naturalnocasecmp_to" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="to" type="String" />
|
||||
@ -585,7 +595,7 @@
|
||||
Performs a [b]case-insensitive[/b], [i]natural order[/i] comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" or "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order. Internally, lowercase characters are converted to uppercase for the comparison.
|
||||
When used for sorting, natural order comparison orders sequences of numbers by the combined value of each digit as is often expected, instead of the single digit's value. A sorted sequence of numbered strings will be [code]["1", "2", "3", ...][/code], not [code]["1", "10", "2", "3", ...][/code].
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method nocasecmp_to] and [method casecmp_to].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method naturalcasecmp_to], [method nocasecmp_to], and [method casecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="nocasecmp_to" qualifiers="const">
|
||||
@ -594,7 +604,7 @@
|
||||
<description>
|
||||
Performs a [b]case-insensitive[/b] comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" or "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order. Internally, lowercase characters are converted to uppercase for the comparison.
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method casecmp_to] and [method naturalnocasecmp_to].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method casecmp_to], [method naturalcasecmp_to], and [method naturalnocasecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="num" qualifiers="static">
|
||||
|
@ -105,7 +105,7 @@
|
||||
<description>
|
||||
Performs a case-sensitive comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" and "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order.
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method nocasecmp_to] and [method naturalnocasecmp_to].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method nocasecmp_to], [method naturalcasecmp_to], and [method naturalnocasecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="contains" qualifiers="const">
|
||||
@ -553,6 +553,16 @@
|
||||
Returns the [url=https://en.wikipedia.org/wiki/MD5]MD5 hash[/url] of the string as another [String].
|
||||
</description>
|
||||
</method>
|
||||
<method name="naturalcasecmp_to" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="to" type="String" />
|
||||
<description>
|
||||
Performs a [b]case-sensitive[/b], [i]natural order[/i] comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" or "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order.
|
||||
When used for sorting, natural order comparison orders sequences of numbers by the combined value of each digit as is often expected, instead of the single digit's value. A sorted sequence of numbered strings will be [code]["1", "2", "3", ...][/code], not [code]["1", "10", "2", "3", ...][/code].
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method naturalnocasecmp_to], [method nocasecmp_to], and [method casecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="naturalnocasecmp_to" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="to" type="String" />
|
||||
@ -560,7 +570,7 @@
|
||||
Performs a [b]case-insensitive[/b], [i]natural order[/i] comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" or "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order. Internally, lowercase characters are converted to uppercase for the comparison.
|
||||
When used for sorting, natural order comparison orders sequences of numbers by the combined value of each digit as is often expected, instead of the single digit's value. A sorted sequence of numbered strings will be [code]["1", "2", "3", ...][/code], not [code]["1", "10", "2", "3", ...][/code].
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method nocasecmp_to] and [method casecmp_to].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method naturalcasecmp_to], [method nocasecmp_to], and [method casecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="nocasecmp_to" qualifiers="const">
|
||||
@ -569,7 +579,7 @@
|
||||
<description>
|
||||
Performs a [b]case-insensitive[/b] comparison to another string. Returns [code]-1[/code] if less than, [code]1[/code] if greater than, or [code]0[/code] if equal. "Less than" or "greater than" are determined by the [url=https://en.wikipedia.org/wiki/List_of_Unicode_characters]Unicode code points[/url] of each string, which roughly matches the alphabetical order. Internally, lowercase characters are converted to uppercase for the comparison.
|
||||
With different string lengths, returns [code]1[/code] if this string is longer than the [param to] string, or [code]-1[/code] if shorter. Note that the length of empty strings is [i]always[/i] [code]0[/code].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method casecmp_to] and [method naturalnocasecmp_to].
|
||||
To get a [bool] result from a string comparison, use the [code]==[/code] operator instead. See also [method casecmp_to], [method naturalcasecmp_to], and [method naturalnocasecmp_to].
|
||||
</description>
|
||||
</method>
|
||||
<method name="pad_decimals" qualifiers="const">
|
||||
|
Loading…
Reference in New Issue
Block a user