0ad/source/i18n/StrImmutable.h

105 lines
1.8 KiB
C++

/*
A reference-counted immutable string; more efficient than std::wstring
when returning strings from functions. (My i18n test program went ~20% faster,
which is not insignificant).
*/
#ifndef I18N_STRIMMUTABLE_H
#define I18N_STRIMMUTABLE_H
#include <wchar.h>
#include <string.h>
typedef unsigned short jschar;
namespace I18n
{
struct strImW_data
{
int refs;
wchar_t* data;
strImW_data() : refs(1) {}
};
class StrImW
{
public:
// I'm lazy (elsewhere), so allow construction from a variety
// of data types:
StrImW(const wchar_t* s)
{
ref = new strImW_data;
size_t len = wcslen(s)+1;
ref->data = new wchar_t[len];
memcpy2((void*)ref->data, s, len*sizeof(wchar_t));
}
StrImW(const char* s)
{
ref = new strImW_data;
size_t len = strlen(s)+1;
ref->data = new wchar_t[len];
for (size_t i=0; i<len; ++i)
ref->data[i] = s[i];
}
// On non-MSVC, or on MSVC with a native wchar_t type, define jschar separately
#if !MSC_VERSION || defined(_NATIVE_WCHAR_T_DEFINED)
StrImW(const jschar* s)
{
ref = new strImW_data;
size_t len = 0;
while (s[len] != '\0') ++len;
++len; // include the \0
ref->data = new wchar_t[len];
for (size_t i=0; i<len; ++i)
ref->data[i] = s[i];
}
#endif
StrImW(const jschar* s, size_t len)
{
ref = new strImW_data;
ref->data = new wchar_t[len+1];
for (size_t i=0; i<len; ++i)
ref->data[i] = s[i];
ref->data[len] = 0;
}
~StrImW()
{
if (--ref->refs == 0)
{
delete[] ref->data;
delete ref;
}
}
// Copy constructor
StrImW(const StrImW& s)
{
ref = s.ref;
++ref->refs;
}
const wchar_t* str() const
{
return ref->data;
}
bool operator== (const StrImW& s)
{
return s.ref==this->ref || wcscmp(s.ref->data, this->ref->data)==0;
}
private:
strImW_data* ref;
};
}
#endif // I18N_STRIMMUTABLE_H