If null-terminated strings are already a thing in your language and you can just pass an inlined string to whatever function without any bit manipulation I fail to see the downside.
> I fail to see how that is better. Null-terminated strings are a terrible idea in the first place.
TLDR: you get extra bytes in your small strings
Long version: Copying from FBString code:
struct MediumLarge {
Char* data_;
size_t size_;
size_t capacity_;
};
// sizeof(MediumLarge) == 24
struct FBString {
union {
// For accessing the last byte.
uint8_t bytes_[sizeof(MediumLarge)];
Char small_[sizeof(MediumLarge) / sizeof(Char)];
MediumLarge ml_;
};
};
Then `bytes_[23]` is set to `24 - size of small string` for a small string. You also "steal" a couple of bits from `capacity_` as a tag to see if a string is small or large.
This has two advantages:
- You get to reuse seven of the eight bytes of `capacity_` in your small string (i.e. your max small string size is 23, not 16 as it would be with a simpler scheme).
- You get a null terminator "for free" (though, of course, you still have size and capacity). This is on top of size/capacity.
This could be reduced to 16 bytes by making `size_` and `capacity_` uint32_t instead of size_t.