mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 08:20:28 +00:00
Copy constructor makes small strings when it can
We create a small string whenever it will fit, instead of only when r is small. This is safe because we always memcpy the whole blob when we call reserve, and optimizes the case when r has been truncated. This also reworks the test to follow the idiom adopted elsewhere re stl, and adds a helper function to tell if a string is small based on data().
This commit is contained in:
parent
d1b6715018
commit
e2f19d5173
3 changed files with 38 additions and 8 deletions
|
@ -42,6 +42,10 @@ void
|
|||
string::init_big(const string& s) noexcept
|
||||
{
|
||||
char* p2;
|
||||
#ifndef NDEBUG
|
||||
if (!s.isbig())
|
||||
__builtin_trap();
|
||||
#endif
|
||||
if (s.size() >= s.capacity() >> 1) {
|
||||
if (!(p2 = (char*)malloc(s.capacity())))
|
||||
__builtin_trap();
|
||||
|
|
|
@ -84,10 +84,12 @@ class string
|
|||
|
||||
string(const string& r) noexcept
|
||||
{
|
||||
if (r.isbig())
|
||||
if (r.size() <= __::sso_max) {
|
||||
__builtin_memcpy(blob, r.data(), __::string_size);
|
||||
set_small_size(r.size());
|
||||
} else {
|
||||
init_big(r);
|
||||
else
|
||||
__builtin_memcpy(blob, r.blob, __::string_size);
|
||||
}
|
||||
}
|
||||
|
||||
string(const char* const p, const size_t n) noexcept
|
||||
|
|
|
@ -23,9 +23,19 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
using String = ctl::string;
|
||||
// #include <string>
|
||||
// using String = std::string;
|
||||
// #define ctl std
|
||||
|
||||
using String = ctl::string;
|
||||
|
||||
#undef ctl
|
||||
|
||||
inline bool
|
||||
issmall(const String& s)
|
||||
{
|
||||
return s.capacity() == sizeof(s) &&
|
||||
s.data() == reinterpret_cast<const char*>(&s);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
|
@ -358,15 +368,14 @@ main()
|
|||
String s;
|
||||
if constexpr (std::is_same_v<ctl::string, decltype(s)>) {
|
||||
// tests the small-string optimization on ctl::string
|
||||
char* d = s.data();
|
||||
for (int i = 0; i < 23; ++i) {
|
||||
s.append("a");
|
||||
if (s.data() != d) {
|
||||
if (!issmall(s)) {
|
||||
return 79 + i;
|
||||
}
|
||||
}
|
||||
s.append("a");
|
||||
if (s.data() == d) {
|
||||
if (issmall(s)) {
|
||||
return 103;
|
||||
}
|
||||
} else {
|
||||
|
@ -380,6 +389,21 @@ main()
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
String s("arst", 4);
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
s.append("a");
|
||||
}
|
||||
s.resize(4);
|
||||
if (s != "arst")
|
||||
return 105;
|
||||
if constexpr (std::is_same_v<ctl::string, decltype(s)>) {
|
||||
String r(s);
|
||||
if (issmall(s) || !issmall(r))
|
||||
return 106;
|
||||
}
|
||||
}
|
||||
|
||||
CheckForMemoryLeaks();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue