BasicString
BasicString
is a template class implementing a reference counted C++ string type.
The API is similar to the API exposed by std::basic_string
, and it’s used throughout
the Harlinn.Common.Core library
as a container for sequences of the char
or wchar_t
character types.
The internal representation of the string data is:
template< typename T >
struct Data
{
using CharType = T;
size_t referenceCount_ = 1;
size_t size_ = 0;
CharType buffer_[1024];
size_t AddRef( ) noexcept
{
return InterlockedIncrementSizeT( &referenceCount_ );
}
size_t DecRef( ) noexcept
{
return InterlockedDecrementSizeT( &referenceCount_ );
}
};
The above specifies the layout of the string data, which is basically
Member | Size |
---|---|
Reference count | 8 bytes |
Number of characters | 8 bytes |
The first character | sizeof(CharType) |
The second character | sizeof(CharType) |
. | . |
. | . |
The size_ th character |
sizeof(CharType) |
Terminating zero | sizeof(CharType) |
The buffer size doesn’t really mean anything, it could be set to 1
and it would change nothing.
Setting it to something quite a bit larger is just convenient for debugging purposes, and nothing else.
The BasicString
template has a single
data member, Data* data_
, so the the size of a BasicString
object is just the size of this pointer.
A BasicString
of length 0
does have a data object, so initializing a container with a large number of empty BasicString
objects is cheap, and so is copying the contents of the BasicString
object, as no allocation will occur, since all that is needed is incrementing the reference count.
BasicString( const BasicString& other ) noexcept
: data_( other.data_ )
{
if ( data_ )
{
data_->AddRef( );
}
}
BasicString
can be move constructed:
BasicString( BasicString&& other ) noexcept
: data_( other.data_ )
{
other.data_ = nullptr;
}
and move assigned:
BasicString& operator = ( BasicString&& other ) noexcept
{
std::swap( other.data_, data_ );
return *this;
}
BasicString
objects are not thread safe,
but BasicString
objects on different threads can
share the same reference counted Data
object.