-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add const char *
overloads to String class
#84379
Conversation
94d4199
to
5247f0b
Compare
I noticed I missed another overload I wanted and took the liberty to add |
Let's add some unit tests for these to ensure correctness, do they work with unicode? If so then ensure it works with non-utf8 input Edit: or rather, you need to rework the tests to test for the |
It currently does break current checks, and unsure what happens with various cases using non-ascii/utf8 input |
5247f0b
to
e89d1ff
Compare
Indeed. I was about to ask about this -- I'm not sure if we want to duplicate the tests like this: CHECK(s.findn("WHA") == 7);
CHECK(s.findn(String("WHA")) == 7); Or maybe add a macro to test both under the same line and keep it DRY. I don't know if there's a cleaner way to do this. There doesn't seem to be. |
e89d1ff
to
764eb07
Compare
764eb07
to
0c2e9b6
Compare
5938333
to
0c2e9b6
Compare
0c2e9b6
to
5c18746
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't directly tested, and there is the possibility of code breaking with non-ascii strings passed as literals, but this applies to the already added methods like , would be good to confirm that it doesn't break things like: find
, so not a new issuestr.findn(U"...")
Otherwise it looks good to me, but TIWAGOS
const char *
overloads to String class
I should clarify I intended to keep this PR unrelated to Having said that, we are indeed missing some tests for |
Agreed, just wanted to make sure the automatic overload resolution works correctly as C++ can be so messy with that some times Tests would be great to ensure it (and future changes) |
5c18746
to
ce145da
Compare
Tests passed for |
9834c09
to
8542abf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realized some missed details
Also needs some fixed for casting
164bf62
to
f70d92b
Compare
Would be nice to do some benchmarking on an optimized build to see if there is actually a significant difference. Performance optimization can have surprising results only reasoned about but not tested. CC @Calinou |
f70d92b
to
6ebdf70
Compare
Here are benchmarks of editor startup + shutdown time (I ran these twice and results were consistent):
The difference is small, but it's an improvement either way. As for binary size: Editor
Release export template
I think the improvement is worth the added code complexity, as getting binary size down is important. |
6ebdf70
to
8e2356c
Compare
Rebased to incorporate test changes from #89194. |
tests/core/string/test_string.h
Outdated
MULTICHECK_STRING_EQ(s, find, "tty", 3); | ||
MULTICHECK_STRING_INT_EQ(s, find, "Wo", 9, 13); | ||
MULTICHECK_STRING_EQ(s, find, "Revenge of the Monster Truck", -1); | ||
MULTICHECK_STRING_EQ(s, rfind, "man", 15); | ||
} | ||
|
||
TEST_CASE("[String] Find no case") { | ||
String s = "Pretty Whale Whale"; | ||
CHECK(s.findn("WHA") == 7); | ||
CHECK(s.findn("WHA", 9) == 13); | ||
CHECK(s.findn("Revenge of the Monster SawFish") == -1); | ||
CHECK(s.rfindn("WHA") == 13); | ||
MULTICHECK_STRING_EQ(s, findn, "WHA", 7); | ||
MULTICHECK_STRING_INT_EQ(s, findn, "WHA", 9, 13); | ||
MULTICHECK_STRING_EQ(s, findn, "Revenge of the Monster SawFish", -1); | ||
MULTICHECK_STRING_EQ(s, rfindn, "WHA", 13); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about some more tests for finds. I would also suggest separating find
and rfind
test to separate test cases (also findn
and rfindn
).
These tests are still in the old format.
CHECK(s.find("") == 0);
CHECK(s.find("", 9) == 9);
CHECK(s.find("Pretty Woman Woman") == 0);
CHECK(s.find("WOMAN") == -1);
CHECK(s.rfind("") == 18); // fails (returns -1)
CHECK(s.rfind("", 15) == 15); // fails (returns -1)
CHECK(s.rfind("foo") == -1);
CHECK(s.rfind("Pretty Woman Woman") == 0);
CHECK(s.rfind("man", 13) == 9);
CHECK(s.rfind("WOMAN") == -1);
CHECK(s.findn("") == 0); // fails (returns -1)
CHECK(s.findn("", 3) == 3); // fails (returns -1)
CHECK(s.findn("wha") == 7);
CHECK(s.findn("Wha") == 7);
CHECK(s.rfindn("") == 15); // fails (returns -1)
CHECK(s.rfindn("", 13) == 13); // fails (returns -1)
CHECK(s.rfindn("wha") == 13);
CHECK(s.rfindn("Wha") == 13);
There are some some inconsistencies how things work in master and thus some of these tests fail. Finding with "" seems to be a somewhat undefined case. The basic find
returns 0
when ""
is searched, which to me seems to be the correct answer. There is a ""
at every index. But all other functions (rfind
, findn
, rfindn
) return -1
when ""
is searched. In my opinion that is wrong, when ""
is searched, I would expect the first index checked to be returned.
However, in GDScript both find
and rfind
return -1
when "" is searched. Although I personally would prefer not returning -1
, consistency is more important. If it is decided that ""
is never found (-1), current C++ find
implementation should be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The basic
find
returns0
when""
is searched, which to me seems to be the correct answer. There is a""
at every index. But all other functions (rfind
,findn
,rfindn
) return-1
when""
is searched.
That's a bug in the overload String::find(const char *p_str, int p_from)
. It's documented it should return -1
, and the same applies to rfind
, findn
, and rfindn
. The way I see it, ""
is by definition an empty string and therefore searching for it implies nothing will be found and therefore the function should return -1
.
I've patched this bug in this PR -- find("")
now returns -1
to match the behavior of the rest. Thanks for pointing that out.
separate test cases
That's a style code change better suited for a different PR. I consider that change to be out of the scope of this PR.
8e2356c
to
72f0d38
Compare
Seems good to me. Could you rebase to make sure it still passes CI? |
Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
72f0d38
to
d4154db
Compare
CI checks passed after rebasing. |
Thanks! |
The added function overloads, namely:
help avoid creating a ton of
String
objects and the underlying dynamic memory allocations they require by using the C-strings directly when possible.I personally find that this patch makes the Editor feel snappier, but I have not run any benchmarks yet.
Edit: Added the following overloads:
Edit: In #84379 (comment) @miv391 pointed out that finding an empty string (
""
) throughString::find(const char *p_str, int p_from)
returns0
which is inconsistent when doing the same throughGDScript
. I've updated this PR to also fix that pre existing bug since it should return-1
.