consider using size_t instead of int for length
Currently str uses (signed) int for all lengths/sizes/capacity. when handling large strings (~2g and up, which is fairly realistic these days on 64 bit machines) signedness issues occur and memory corruption happens in various places.
The type was designed to be compact. We currently don't even use 32-bits for size but 21-bits which is even lower, so your statement seems to be coming from a strictly theoretical position rather than actual need, since you didn't realize it was already capped to 21-bits.
The current packing made sense on 32-bits targets but effectively we have 4 bytes of unused padding on 64-bits targets. There is a todo to actually update to 32-bit storage for size, but I suppose we could use 53 bits just as well..