65 explicit StaticString(
const char* pSrc) : m_Length(0), m_Hash(0), m_AllowHashes(false) {
74 StaticString(
const char* pSrc,
size_t len) : m_Length(0), m_Hash(0), m_AllowHashes(false) {
80 assign(str.cstr(), str.length());
87 template <
unsigned int N2>
89 :
StaticString(static_cast<const char*>(src), src.length()) {}
91 operator const char*()
const {
95 template <
unsigned int N2>
106 template <
typename T>
119 void assign(
const char* str,
size_t len = 0) {
126 len = min(N - 1, StringLength(str));
128 len = min(len, N - 1);
131 MemoryCopy(m_pData, str, len);
140 void assign(
const String& str) {
141 assign(str.cstr(), str.length());
144 template <
unsigned int N2>
146 assign(other, other.length());
160 if (StringLength(pStr) != length()) {
164 return StringCompareN(m_pData, pStr, length()) == 0;
167 template <
unsigned int N2>
169 if (other.length() != length()) {
171 }
else if ((m_AllowHashes && other.m_AllowHashes) && (m_Hash != other.hash())) {
175 return StringCompareN(m_pData, other.m_pData, length()) == 0;
178 int last(
const char search)
const {
179 for (
int i = length(); i >= 0; i--)
180 if (m_pData[i] == search)
185 int first(
const char search)
const {
186 for (
size_t i = 0; i < length(); i++)
187 if (m_pData[i] == search)
194 m_pData[--m_Length] =
'\0';
199 bool contains(
const char* other)
const {
200 return contains(m_pData, other, length(), StringLength(other));
203 template <
unsigned int N2>
205 return contains(m_pData, other.m_pData, length(), other.length());
208 int intValue(
int nBase = 0)
const {
210 int ret = StringToUnsignedLong(m_pData, &pEnd, nBase);
217 uintptr_t uintptrValue(
int nBase = 0)
const {
219 uintptr_t ret = StringToUnsignedLong(m_pData, &pEnd, nBase);
226 void truncate(
size_t len) {
252 for (i = n; m_pData[i] !=
'\0'; i++)
253 m_pData[i - n] = m_pData[i];
254 m_pData[i - n] =
'\0';
262 template <
typename T>
268 void append(
char Char,
size_t nLen = 0,
char c =
'0') {
269 char Characters[] = {Char,
'\0'};
270 append(Characters, nLen, c);
273 void append(
short nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
276 unsigned short magnitude =
static_cast<unsigned short>(-(nInt + 1));
277 append(++magnitude, nRadix, nLen, c);
280 append(
static_cast<unsigned short>(nInt), nRadix, nLen, c);
283 void append(
int nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
286 unsigned int magnitude =
static_cast<unsigned int>(-(nInt + 1));
287 append(++magnitude, nRadix, nLen, c);
290 append(
static_cast<unsigned int>(nInt), nRadix, nLen, c);
293 void append(
long nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
296 unsigned long magnitude =
static_cast<unsigned long>(-(nInt + 1));
297 append(++magnitude, nRadix, nLen, c);
300 append(
static_cast<unsigned long>(nInt), nRadix, nLen, c);
303 void append(
long long nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
306 unsigned long long magnitude =
static_cast<unsigned long long>(-(nInt + 1));
307 append(++magnitude, nRadix, nLen, c);
310 append(
static_cast<unsigned long long>(nInt), nRadix, nLen, c);
313 void append(
unsigned char nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
314 appendInteger<sizeof(char)>(nInt, nRadix, nLen, c);
317 void append(
unsigned short nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
318 appendInteger<sizeof(short)>(nInt, nRadix, nLen, c);
321 void append(
unsigned int nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
322 appendInteger<sizeof(int)>(nInt, nRadix, nLen, c);
325 void append(
unsigned long nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
326 appendInteger<sizeof(long)>(nInt, nRadix, nLen, c);
329 void append(
unsigned long long nInt,
size_t nRadix = 10,
size_t nLen = 0,
char c =
'0') {
330 appendInteger<sizeof(long long)>(nInt, nRadix, nLen, c);
333 template <
unsigned int size,
typename T>
334 void appendInteger(T nInt,
size_t nRadix,
size_t nLen,
char c) {
335 if (!canAppend() || (nRadix < 2) || (nRadix > 36)) {
340 char pStr[size * 8 + 1];
343 size_t tmp = nInt % nRadix;
346 pStr[index++] =
'0' + tmp;
348 pStr[index++] =
'a' + (tmp - 10);
351 for (
size_t i = 0; i < (index / 2); i++) {
353 pStr[i] = pStr[index - i - 1];
354 pStr[index - i - 1] = tmp;
359 append(pStr, nLen, c);
362 void append(
const char* str,
size_t nLen = 0,
char c =
' ') {
363 if (!str || !canAppend()) {
367 const size_t available = (N - 1) - m_Length;
368 size_t stringLength = nLen ? BoundedStringLength(str, nLen) : StringLength(str);
369 size_t padding = nLen > stringLength ? nLen - stringLength : 0;
370 padding = min(padding, available);
373 ByteSet(m_pData + m_Length, c, padding);
377 const size_t remaining = (N - 1) - m_Length;
378 const size_t copyLength = min(stringLength, remaining);
379 MemoryCopy(m_pData + m_Length, str, copyLength);
380 m_Length += copyLength;
381 m_pData[m_Length] = 0;
388 void append(
const String& str) {
389 append(str.cstr(), str.length());
392 void appendBytes(
const char* bytes,
size_t numBytes) {
398 for (
size_t i = 0; i < numBytes; ++i) {
400 if ((c < -1) || (c >= 0x20 && c != 0x7f)) {
406 append(
static_cast<unsigned int>(
static_cast<unsigned char>(c)), 16, 2);
411 template <
unsigned int N2>
418 const size_t available = (N - 1) - m_Length;
419 const size_t stringLength = nLen ? min(nLen, str.length()) : str.length();
420 size_t padding = nLen > stringLength ? nLen - stringLength : 0;
421 padding = min(padding, available);
423 ByteSet(m_pData + m_Length, c, padding);
427 const size_t remaining = (N - 1) - m_Length;
428 const size_t copyLength = min(stringLength, remaining);
429 MemoryCopy(m_pData + m_Length,
static_cast<const char*
>(str), copyLength);
430 m_Length += copyLength;
431 m_pData[m_Length] = 0;
438 void pad(
size_t nLen,
char c =
' ') {
445 if (nLen > length()) {
446 const size_t newLength = min(nLen,
static_cast<size_t>(N - 1));
447 ByteSet(m_pData + m_Length, c, newLength - m_Length);
448 m_Length = newLength;
449 m_pData[m_Length] =
'\0';
455 size_t length()
const {
459 uint64_t hash()
const {
471 m_AllowHashes =
true;
479 m_AllowHashes =
false;
483 static bool contains(
const char* a,
const char* b,
size_t alen,
size_t blen) {
484 return StringContainsN(a, alen, b, blen) == 1;
490 STATICSTRING_ASSERT(StringLength(m_pData) == m_Length);
492 m_Hash = spookyHash(m_pData, m_Length);
498 m_pData[N - 1] =
'\0';
503 bool canAppend()
const {
504 return m_Length < (N - 1);