I'm working with a low-level API that accepts a char*
and numeric value to represent a string and its length, respectively. My code uses std::basic_string
and calls into these methods with the appropriate translation. Unfortunately, many of these methods accept string lengths of varying size (i.e. max(unsigned char
), max(short
), etc...) and I'm stuck writing code to make sure that my string instances do not exceed the maximum length prescribed by the low-level API.
By default, the maximum length of an std::basic_string
instance is bound by the maximum value of size_t
(either max(unsigned int
) or max(__int64
)). Is there a way to manipulate the traits and allocator implementations of a std::basic_string
implementation so that I may specify my own type to use in place of size_t
? By doing so, I am hoping to leverage any existing bounds checks within the std::basic_string
implementation so I don't have to do so when performing the translation.
My initial investigation suggests that this is not possible without writing my own string class, but I'm hoping that I overlooked something :)
I agree with Evan Teran about his solution. This is just a modification of his solution no more:
Be aware you should not use polymorphism at all with
myalloc
. So this is disastrous:You just use it as if it is a separate type, it is safe in following case:
you can pass a custom allocator to
std::basic_string
which has a max size of whatever you want. This should be sufficient. Perhaps something like this:Then you can probably do this:
EDIT: I've just done a test to make sure this works as expected. The following code tests it.
That last
s += s
will put it over the top and cause astd::bad_alloc
exception, (since my limit is just short of 64k). Unfortunately gcc'sstd::basic_string::max_size()
implementation does not base its result on the allocator you use, so it will still claim to be able to allocate more. (I'm not sure if this is a bug or not...).But this will definitely allow you impose hard limits on the sizes of strings in a simple way. You could even make the max size a template parameter so you only have to write the code for the allocator once.
Can't you create a class with std::string as parent and override c_str()? Or define your own c_str16(), c_str32(), etc and implement translation there?