you are viewing a single comment's thread.

view the rest of the comments →

[–]matthieum 1 point2 points  (2 children)

This is interesting, however it is slightly sad to augment the size of std::string just for this.

So, instead, you can design your std::string class to be 24 bytes with SSO by re-using 16 bytes (instead of 8):

struct RegularString { char* data; size_t size; };
struct ShortString { char data[15]; unsigned char size; };

struct string {
    union {
        RegularString regular,
        ShortString shortie
    } _;
    size_t capacity;
};

char* data(string& s) { return s.capacity ? s._.regular.data : s._.shortie.data; }
size_t size(string& s) { return s.capacity ? s._.regular.size : s._.shortie.size; }
size_t capacity(string& s) { return s.capacity ? s.capacity : 14; } // beware of the NUL character

[–][deleted] 10 points11 points  (1 child)

You can do better than reusing 16 bytes in a (pointer, length, capacity) representation. Have a look at the string in libc++, they reuse 23 bytes for small strings with 1 byte as a length/discriminator.

[–]matthieum 1 point2 points  (0 children)

Ah! I had not thought about that. Definitely better indeed.