diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2016-09-28 19:03:26 +0100 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2016-09-28 19:06:25 +0100 |
| commit | e701254b02944ecbf228e0c81ef77da86453d260 (patch) | |
| tree | a6378a24bfcd29447b375ecdc428e6a984e21ae7 /src/string.hh | |
| parent | 1b9eb2c6ba6da849480c299d06abb9bdd9f87786 (diff) | |
Fix String::Data::reserve on big endian platforms, and document String::Data
reserve was not ensuring the capacity would be pair, which is needed
on big endian machines, as we use its least significant bit to flag
short string optimizations. On little endian the bit we use is the
8th most significant (the least significant bit of the last byte),
so we were not hitting any problems.
Fixes #828
Diffstat (limited to 'src/string.hh')
| -rw-r--r-- | src/string.hh | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/string.hh b/src/string.hh index be140888..3fa08a83 100644 --- a/src/string.hh +++ b/src/string.hh @@ -130,12 +130,22 @@ public: static const String ms_empty; static constexpr const char* option_type_name = "str"; + // String data storage using small string optimization. + // + // the LSB of the last byte is used to flag if we are using the small buffer + // or an allocated one. On big endian systems that means the allocated + // capacity must be pair, on little endian systems that means the allocated + // capacity cannot use its most significant byte, so we effectively limit + // capacity to 2^24 on 32bit arch, and 2^60 on 64. union Data { using Alloc = Allocator<char, MemoryDomain::String>; struct Long { + static constexpr size_t max_capacity = + (size_t)1 << 8 * (sizeof(size_t) - 1); + char* ptr; size_t size; size_t capacity; |
