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.