template<class T> class StringData
{
public:
    u32 alloc;			// elems allocated (-1 [zero-terminator])
    u32 len;			// length
    u32 refs;			// ref counter
    i16 enc;			// encoding ( only if T == uint8 )
    T data[1];

    static StringData *create( u32 elems )
    {
        StringData *res = (StringData *)calloc( 1, sizeof( StringData ) + elems*sizeof(T) );
//		STATIC_ASSERT( res != 0 );
        res->len = res->alloc = elems;
        return res;
    }

    // reserve space for elems
    StringData *reserve( u32 elems )
    {
        if ( !elems )
            return this;
        if ( !this )
            return create( elems );
        if ( !refs && alloc >= elems )
            return this;		// ok
        // need to reallocate...
        u32 olen = len;
        StringData *res = create( (alloc<<1) > elems ? (alloc<<1) : elems );
        if ( !res )
            return 0;
        memcpy( res->data, data, (len+1) * sizeof(T) );
        res->enc = enc;
        res->len = olen;
        return res;
    }

    StringData *clone()
    {
        StringData *res = 0;
        if ( this )
        {
            res = create( len );
            memcpy( res->data, data, (len+1) * sizeof(T) );
            res->enc = enc;
            release();
        }
        return res;
    }

    void addref()
    {
        if ( this )
        {
            ++refs;
//			STATIC_ASSERT( refs != 0 );
        }
    }

    void release()
    {
        if ( this )
        {
            if ( !refs-- )
            {
                free(this);
            }
        }
    }
};

typedef StringData<u8> AStringData;
typedef StringData<wchar> WStringData;

