Files
libsst/Lib/Include/ZSTL/ZBasicStringAlgo.hpp
2026-04-03 00:22:39 -05:00

2440 lines
80 KiB
C++

/*
ZStringUtil.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 1/12/2012
Purpose:
Contains additional methods for manipulation and use of ZBasicString<A>.
License:
This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#pragma once
#ifndef _ZBASICSTRINGALGO_HPP
#define _ZBASICSTRINGALGO_HPP
#include <ZSTL/ZSTL.hpp>
#include <ZSTL/ZArrayAlgo.hpp>
#include <string.h> //for strcmp, memset, memmove
#include <stdio.h> //for sprintf
#include <stdarg.h> //for va_start, va_end
namespace ZBasicStringAlgo
{
//Forward Declaration of FindFirst
template <typename A>
size_t FindFirst(const ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end);
template <typename A>
size_t FindFirst(const ZBasicString<A>& _string, const char& _char);
//Forward Declaration of FindSub
template <typename A, typename B>
size_t FindSub(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _substring, size_t _s2, size_t _e2);
//Forward Declaration of TrimLeft
template <typename A>
size_t TrimLeft(ZBasicString<A>& _string, size_t _start, size_t _end);
//Forward Declaration of TrimRight
template <typename A>
size_t TrimRight(ZBasicString<A>& _string, size_t _start, size_t _end);
/*
public ZBasicStringAlgo<A, B>::Append
Appends a range of a string to the provided one.
@param A - allocator type for this string
@param B - the allocator type for the other string
@param _string - the string to append to
@param _other - string to append
@param _start - the starting index of the other string
@param _end - the ending index of the other string (exclusive)
@return (void)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A, typename B>
void Append(ZBasicString<A>& _string, const ZBasicString<B>& _other, size_t _start, size_t _end)
{
if (_start == _end)
return;
const size_t start = _other.BoundsCheck(_start, _other.Length());
const size_t end = _other.BoundsCheck(_end, _other.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Append - Cannot append with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
stringArray.PopBack();
ZArrayAlgo::Append(stringArray, _other.Array(), start, end);
stringArray.PushBack(ZBASICSTRING_NULL_TERMINATOR);
}
/*
public ZBasicStringAlgo<A, B>::Append
Appends a string to the provided one.
@param A - allocator type for this string
@param B - the allocator type for the other string
@param _string - the string to append to
@param _other - string to append
@return (ZBasicString<A>&) - this provided string, after appending
*/
template <typename A, typename B>
void Append(ZBasicString<A>& _string, const ZBasicString<B>& _other)
{
return Append(_string, _other, 0, _other.Length());
}
//Append C-String Implementation
template <typename A>
void Append(ZBasicString<A>& _string, const char *_other)
{ return Append(_string, ZBasicString<A>(_other)); }
//Append C-String Implementation
template <typename A>
void Append(ZBasicString<A>& _string, const char *_other, size_t _start, size_t _end)
{ return Append(_string, ZBasicString<A>(_other), _start, _end); }
/*
public ZBasicStringAlgo<A>::BuildNumeric
Builds a string from an integer or floating point type using the given format string, so
this equivalent to calling snprintf with the provided format string and number.
@param A - the allocator type for the string
@param N - the numeric type to build from (int, double, etc.)
@param _string - the string to build
@param _fmt - the format string to use (any format string valid for _number)
@param _number - the number to use
@param
*/
template <typename A, typename N>
void BuildNumeric(ZBasicString<A>& _string, const char* _fmt, N _number)
{
ZSTL_ASSERT(_fmt != NULL, "BuildNumeric() given null format string!\n");
_string.Clear();
int len = -1;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
len = _snprintf(NULL,0,_fmt,_number);
#pragma warning(pop)
#else
char temp = ' ';
len = snprintf(&temp,0,_fmt,_number);
#endif
ZSTL_ASSERT(len > 0, "BuildNumeric() would've made bad printf!\n");
_string.Resize(len, ZBASICSTRING_NULL_TERMINATOR);
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
// note that ZString has one more in the data array, set to the terminator, so this is okay.
_snprintf(_string.Data(), (_string.Length()) * sizeof(char), _fmt, _number);
#pragma warning(pop)
#else
// for GNU et al, though we need to fake out their null-terminator safety
snprintf(_string.Data(), (_string.Length() + 1) * sizeof(char), _fmt, _number);
#endif
}
/*
public ZBasicStringAlgo<A>::BuildNumeric
Builds a string from a double-precision float. This is equivalent to using
snprintf with a format string of %f.
@param A - the allocator type for the string
@param _string - the string to build
@param _number - the number to use
@return (void)
*/
template <typename A>
void BuildNumeric(ZBasicString<A>& _string, double _number)
{
return BuildNumeric(_string, "%f", _number);
}
/*
public ZBasicStringAlgo<A>::BuildNumeric
Builds a string from an integer. This is equivalent to using
snprintf with a format string of %i.
@param A - the allocator type of the string
@param _string - the string to build
@param _number - the number to use
@return (void)
*/
template <typename A>
void BuildNumeric(ZBasicString<A>& _string, int _number)
{
return BuildNumeric(_string, "%i", _number);
}
/*
public ZBasicStringAlgo<A>::BuildPrintf
Builds a basic string using printf-style formatted output.
@param A - the allocator type of the string
@param _string - the string to build (cleared by this function before building)
@param _fmt - the null-terminated printf format string
@param ... - the variable arguments for the format string
@return (void)
*/
template <typename A>
void BuildPrintf(ZBasicString<A>& _string, const char *_fmt, ...)
{
ZSTL_ASSERT(_fmt != NULL, "BuildPrintf() given null format string!\n");
va_list args;
va_start(args, _fmt);
_string.Clear();
//MSVC's implementation of vsnprintf() family contradicts C standard on return value. It returns -1 if too small, when it should return the number of characters
#if defined(_MSC_VER) || defined(_WIN32) //TODO: Really, we meant MSVCRTxx.dll, i.e. Microsoft VC runtime
_string.Resize(128);
int result;
do
{
result = _vsnprintf_s(_string.Data(), _string.Length()+1, _TRUNCATE, _fmt, args); //NOTE: 2nd param is size of buffer, not number chars. Therefore, we give it +1
//Not enough space? -> Increase string size
if(result < 0)
_string.Resize( _string.Length() * 2);
else //Success, trim extra characters
_string.Resize((size_t)result);
} while (result < 0);
#else //Rest of the world can follow the C standard thankfully (right?)
char temp[1];
int len = vsnprintf(temp, sizeof(temp), _fmt, args); //C standard says 2nd param is sizeof(buffer), not number of chars
//Return is -1 on error, OR number of characters in size
ZSTL_ASSERT(len >= 0, "BuildPrintf() given bad format string!\n");
_string.Resize((size_t)len, ZBASICSTRING_NULL_TERMINATOR);
va_end(args);
va_start(args,_fmt);
len = vsnprintf(_string.Data(), _string.Length()+1, _fmt, args);
#endif
va_end(args);
}
/*
public ZBasicString<>::BuildRepeat
Constructs a ZBasicString<A> by repeating the given null-terminated string the given number of times.
@param A - the allocator type of the string
@param _string - the string to build (cleared by this function before building)
@param _repeatString - the string to repeat
@param _count - the number of times to repeat it
@return (void)
*/
template <typename A>
void BuildRepeat(ZBasicString<A>& _string, const char *_repeatString, size_t _count)
{
size_t i;
size_t len = strlen(_repeatString);
_string.Resize(len * _count); //Resize() includes space for NULL terminator
char* data = _string.Data();
for (i = 0; i < _count; i++)
{
memcpy(data, _repeatString, len);
data += len;
}
*data = '\0';
}
/*
public ZBasicStringAlgo<A>::Contains
Determines if the provided string contains the given character between the given
indices.
@param A - allocator type for this string
@param _string - the string to check
@param _c - the character to look for
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (bool) - true if the string contains this character, false otherwise
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
bool Contains(const ZBasicString<A>& _string, const char _char, size_t _start, size_t _end)
{
if (_start == _end)
return false;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Contains - Cannot check with end < start!");
#endif
return ZArrayAlgo::Contains(_string.Array(), _char, start, end);
}
/*
public ZBasicStringAlgo<A>::Contains
Determines if the provided string contains the given character.
@param A - allocator type for this string
@param _string - the string to check
@param _c - the character to look for
@return (bool) - true if the string contains this character, false otherwise
*/
template <typename A>
bool Contains(const ZBasicString<A>& _string, const char _char)
{
return Contains(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::ContainsSub
Determines if the provided string contains the provided substring in the given ranges.
@param A - allocator type of the string
@param B - allocator type for the substring
@param _string - the string to check
@param _s1 - the starting index in the string
@param _e1 - the ending index in the string (exclusive)
@param _substring - the substring to look for
@param _s2 - the starting index in the substring
@param _e2 - the ending index in the string (exclusive)
@return (bool) - true if the string contains the substring, false otherwise
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
bool ContainsSub(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _substring, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return false;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _substring.BoundsCheck(_s2, _substring.Length());
const size_t e2 = _substring.BoundsCheck(_e2, _substring.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::ContainsSub - Cannot check with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::ContainsSub - Cannot check with end < start!");
#endif
return ZArrayAlgo::ContainsSub(_string.Array(), s1, e1, _substring.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::ContainsSub
Determines if the provided string contains the provided substring.
@param A - allocator type of the string
@param B - allocator type for the substring
@param _string - the string to check
@param _substring - the substring to look for
@return (bool) - true if the string contains the substring, false otherwise
*/
template <typename A, typename B>
bool ContainsSub(const ZBasicString<A>& _string, const ZBasicString<B>& _substring)
{
return ContainsSub(_string, 0, _string.Length(), _substring, 0, _substring.Length());
}
//ContainsSub C-String Implementation
template <typename A>
bool ContainsSub(const ZBasicString<A>& _string, const char* _other)
{ return ContainsSub(_string, ZBasicString<A>(_other)); }
//ContainsSub C-String Implementation
template <typename A>
bool ContainsSub(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _other, size_t _s2, size_t _e2)
{ return ContainsSub(_string, _s1, _e1, ZBasicString<A>(_other), _s2, _e2); }
/*
public ZBasicStringAlgo<A, B>::Copy
Copies the values in the range provided from the given string into the range
provided in another. The maximum number of characters copied is equal to the
minimum of (_e1 - _s1) or (_e2 - _s2).
@param A - allocator type for the destination string
@param B - allocator type for the source string
@param _destination - the destination string
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _source - the source string
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (void)
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
void Copy(ZBasicString<A>& _destination, size_t _s1, size_t _e1, const ZBasicString<B>& _source, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return;
const size_t s1 = _destination.BoundsCheck(_s1, _destination.Length());
const size_t e1 = _destination.BoundsCheck(_e1, _destination.Length() + 1);
const size_t s2 = _source.BoundsCheck(_s2, _source.Length());
const size_t e2 = _source.BoundsCheck(_e2, _source.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::Copy - Cannot copy with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::Copy - Cannot copy with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_destination.Array());
ZArrayAlgo::Copy(stringArray, s1, e1, _source.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::Copy
Copies the characters from a source string into a destination string. The maximum number of
characters copied is equal to the length of the shorter string.
@param A - allocator type for the destination string
@param B - allocator type for the source string
@param _destination - the destination string
@param _source - the source string
@return (void)
*/
template <typename A, typename B>
void Copy(ZBasicString<A>& _destination, const ZBasicString<B>& _source)
{
Copy(_destination, 0, _destination.Length(), _source, 0, _source.Length());
}
//Copy C-String Implementation
template <typename A>
void Copy(ZBasicString<A>& _destination, size_t _s1, size_t _e1, const char* _source, size_t _s2, size_t _e2)
{ Copy(_destination, _s1, _e1, ZBasicString<A>(_source), _s2, _e2); }
//Copy C-String Implementation
template <typename A>
void Copy(ZBasicString<A>& _destination, const char* _source)
{ Copy(_destination, ZBasicString<A>(_source)); }
/*
public ZBasicStringAlgo<A, B>::EndsWith
Determines if the provided range of the given string ends with the values specified in the provided
range of another string.
@param A - allocator type for the string
@param B - allocator type for the other string
@param _string - the string to check
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _other - the string to compare against
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (bool) - true if the string ends with the provided value, false otherwise
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
bool EndsWith(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _other, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return false;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _other.BoundsCheck(_s2, _other.Length());
const size_t e2 = _other.BoundsCheck(_e2, _other.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::EndsWith - Cannot check with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::EndsWith - Cannot check with end < start!");
#endif
return ZArrayAlgo::EndsWith(_string.Array(), s1, e1, _other.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::EndsWith
Determines if the provided string ends with the another string.
@param A - allocator type for the string
@param B - allocator type for the other string
@param _string - the string to check
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _other - the string to compare against
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (bool) - true if the string ends with the provided value, false otherwise
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
bool EndsWith(const ZBasicString<A>& _string, const ZBasicString<B>& _other)
{
return EndsWith(_string, 0, _string.Length(), _other, 0, _other.Length());
}
//EndsWith C-String Implementation
template <typename A>
bool EndsWith(const ZBasicString<A>& _string, const char* _substring)
{ return EndsWith(_string, ZBasicString<A>(_substring)); }
//EndsWith C-String Implementation
template <typename A>
bool EndsWith(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _substring, size_t _s2, size_t _e2)
{ return EndsWith(_string, _s1, _e1, ZBasicString<A>(_substring), _s2, _e2); }
/*
public ZBasicStringAlgo<A, B>::Equal
Determines if the given range of the provided string is equal to the given range
of another string. The maximum number of characters compared is equal to the
minimum of (_e1 - _s1) or (_e2 - _s2).
If provided a range of zero on both strings, the answer is always true.
@param A - allocator type for the string
@param B - allocator type for the other string
@param _string - the string to check
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _other - the string to compare against
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (bool) - true if the string equals the provided value, false otherwise
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
bool Equal(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _other, size_t _s2, size_t _e2)
{
if (_e1 - _s1 == 0 && _e2 - _s2 == 0) {
return true;
}
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(_s1 <= _e1, "ZBasicStringAlgo::Equal - Cannot compare with end < start!");
ZSTL_ASSERT(_s2 <= _e2, "ZBasicStringAlgo::Equal - Cannot compare with end < start!");
#endif
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _other.BoundsCheck(_s2, _other.Length());
const size_t e2 = _other.BoundsCheck(_e2, _other.Length() + 1);
return ZArrayAlgo::Equal(_string.Array(), s1, e1, _other.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::Equal
Determines if the given string is equal to the other string. The maximum number
of characters compared is equal to the length of the shorter string.
@param A - allocator type for the string
@param B - allocator type for the other string
@param _string - the string to check
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _other - the string to compare against
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (bool) - true if the string equals the provided value, false otherwise
*/
template <typename A, typename B>
bool Equal(const ZBasicString<A>& _string, const ZBasicString<B>& _other)
{
return Equal(_string, 0, _string.Length(), _other, 0, _other.Length());
}
//Equal C-String Implementation
template <typename A>
bool Equal(const ZBasicString<A>& _string, const char* _other)
{ return Equal(_string, ZBasicString<A>(_other)); }
//Equal C-String Implementation
template <typename A>
bool Equal(const ZBasicString<A>& _string, size_t _s1, const char* _other, size_t _s2, size_t _count)
{ return Equal(_string, _s1, ZBasicString<A>(_other), _s2, _count); }
/*
public ZBasicStringAlgo<A, B>::EqualIgnoreCase
Determines if the given range of the provided string is equal to the given range
of another string, ignoring the character case. The maximum number of characters
compared is equal to the minimum of (_e1 - _s1) or (_e2 - _s2).
If provided a range of zero on both strings, the answer is always true.
@param A - allocator type for the string
@param B - allocator type for the other string
@param _string - the string to check
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _other - the string to compare against
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (bool) - true if the string equals the provided value ignoring case, false otherwise
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
bool EqualIgnoreCase(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _other, size_t _s2, size_t _e2)
{
if (_e1 - _s1 == 0 && _e2 - _s2 == 0) {
return true;
}
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(_s1 <= _e1, "ZBasicStringAlgo::Equal - Cannot compare with end < start!");
ZSTL_ASSERT(_s2 <= _e2, "ZBasicStringAlgo::Equal - Cannot compare with end < start!");
#endif
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _other.BoundsCheck(_s2, _other.Length());
const size_t e2 = _other.BoundsCheck(_e2, _other.Length() + 1);
size_t i, j;
for (i = s1, j = s2; i < e1 && j < e2; i++, j++)
{
if ( tolower(_string.Data()[i]) != tolower(_other.Data()[j]) )
return false;
}
return true;
}
/*
public ZBasicStringAlgo<A, B>::EqualIgnoreCase
Determines if the given string is equal to the other string ignoring character
case. The maximum number of characters compared is equal to the length of the
shorter string.
@param A - allocator type for the string
@param B - allocator type for the other string
@param _string - the string to check
@param _s1 - the starting index for the destination string
@param _e1 - the ending index for the destination string (exclusive)
@param _other - the string to compare against
@param _s2 - the starting index for the source string
@param _e2 - the ending index for the source string (exclusive)
@return (bool) - true if the string equals the provided value ignoring character case, false otherwise
*/
template <typename A, typename B>
bool EqualIgnoreCase(const ZBasicString<A>& _string, const ZBasicString<B>& _other)
{
return EqualIgnoreCase(_string, 0, _string.Length(), _other, 0, _other.Length());
}
//EqualIgnoreCase C-String Implementation
template <typename A>
bool EqualIgnoreCase(const ZBasicString<A>& _string, const char* _other)
{ return EqualIgnoreCase(_string, ZBasicString<A>(_other)); }
//EqualIgnoreCase C-String Implementation
template <typename A>
bool EqualIgnoreCase(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _other, size_t _s2, size_t _e2)
{ return EqualIgnoreCase(_string, _s1, _e1, ZBasicString<A>(_other), _s2, _e2); }
/*
public ZBasicStringAlgo<A>::Fill
Fills the provided region of the given string with the provided value.
@param A - the allocator type for the string
@param _string - the string to fill
@param _value - the value to fill with
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (void)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
void Fill(ZBasicString<A>& _string, const char& _value, size_t _start, size_t _end)
{
if (_start == _end) {
return;
}
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Fill - Cannot fill with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
ZArrayAlgo::Fill(stringArray, _value, start, end);
}
/*
public ZBasicStringAlgo<A>::Fill
Fills the string full of the provided character value.
@param A - the allocator type for the string
@param _string - the string to fill
@param _value - the value to fill with
@return (void)
*/
template <typename A>
void Fill(ZBasicString<A>& _string, const char& _value)
{
Fill(_string, _value, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::Find
Finds the Nth occurrence of a character in the provided region of the string.
@param A - the allocator type for the string
@param _string - the string to search
@param _value - the value to find
@param _count - the number of occurrences which would be skipped (meaning an index to the (N+1)th occurrence is returned)
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the index of the Nth occurrence (ZBasicString::InvalidPos if not found)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t Find(const ZBasicString<A>& _string, const char& _value, size_t _count, size_t _start, size_t _end)
{
if (_start == _end)
return ZSTL::InvalidPos;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Find - Cannot find with end < start!");
#endif
return ZArrayAlgo::Find(_string.Array(), _value, _count, start, end);
}
/*
public ZBasicStringAlgo<A>::Find
Finds the Nth occurrence of a character in the provided string.
@param A - the allocator type for the string
@param _string - the string to search
@param _value - the value to find
@param _count - the number of occurrences which would be skipped (meaning an index to the (N+1)th occurrence is returned)
@return (size_t) - the index of the Nth occurrence (ZBasicString::InvalidPos if not found)
*/
template <typename A>
size_t Find(const ZBasicString<A>&_string, const char& _value, size_t _count)
{
return Find(_string, _value, _count, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::FindAll
Finds all occurrences of the provided character in the given region in the string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the character to look for
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (ZArray<size_t>) - array of indices to all occurrences of the character
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
ZArray<size_t> FindAll(const ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return ZArray<size_t>();
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::FindAll - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindAll(_string.Array(), _char, start, end);
}
/*
public ZBasicStringAlgo<A>::FindAll
Finds all occurrences of the provided character in the given string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the character to look for
@return (ZArray<size_t>) - array of indices to all occurrences of the character
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
ZArray<size_t> FindAll(const ZBasicString<A>& _string, const char& _char)
{
return FindAll(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::FindAllOf
Finds all occurrences of any of the given characters in the given region.
@param A - the allocator type of the string
@param B - the allocator type of the values string
@param _string - the string to search
@param _s1 - the starting index in the string
@param _e1 - the ending index in the string (exclusive)
@param _values - the values to look for
@param _s2 - the starting index in the values string
@param _e2 - the ending index in the values string (exclusive)
@return (ZArray<size_t>) - array of indices to all occurrences of one of the provided characters
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
ZArray<size_t> FindAllOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _values, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return ZArray<size_t>();
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _string.BoundsCheck(_s2, _values.Length());
const size_t e2 = _string.BoundsCheck(_e2, _values.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::FindAllOf - Cannot find with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::FindAllOf - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindAllOf(_string.Array(), s1, e1, _values.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::FindAllOf
Finds all occurrences of any of the given characters.
@param A - the allocator type of the string
@param B - the allocator type of the values string
@param _string - the string to search
@param _values - the values to look for
@return (ZArray<size_t>) - array of indices to all occurrences of one of the provided characters
*/
template <typename A, typename B>
ZArray<size_t> FindAllOf(const ZBasicString<A>& _string, const ZBasicString<B>& _values)
{
return FindAllOf(_string, 0, _string.Length(), _values, 0, _values.Length());
}
//FindAllOf C-String Implementation
template <typename A>
ZArray<size_t> FindAllOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _values, size_t _s2, size_t _e2)
{
return FindAllOf(_string, _s1, _e1, ZBasicString<A>(_values), _s2, _e2);
}
//FindAllOf C-String Implementation
template <typename A>
ZArray<size_t> FindAllOf(const ZBasicString<A>& _string, const char* _values)
{
return FindAllOf(_string, ZBasicString<A>(_values));
}
/*
public ZBasicStringAlgo<A>::FindFirst
Finds the first occurrence of the provided value in the given region.
@param A - the allocator type for the string
@param _string - the string to search
@param _char - the character to search for
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the first occurrence of the given value (ZSTL::InvalidPos if not found)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t FindFirst(const ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return ZSTL::InvalidPos;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::FindFirst - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindFirst(_string.Array(), _char, start, end);
}
/*
public ZBasicStringAlgo<A>::FindFirst
Finds the first occurrence of the provided value.
@param A - the allocator type for the string
@param _string - the string to search
@param _char - the character to search for
@return (size_t) - the first occurrence of the given value (ZSTL::InvalidPos if not found)
*/
template <typename A>
size_t FindFirst(const ZBasicString<A>& _string, const char& _char)
{
return FindFirst(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::FindFirstOf
Finds the first occurrence of a set of values in the provided region of a string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _s1 - the starting index in the string
@param _e1 - the ending index in the string (exclusive)
@param _delimiters - the delimiters to search for
@param _s2 - the starting index in the delimiters string
@param _e2 - the ending index in the delimiters string (exclusive)
@return (size_t) - the index of the first occurrence of one of the delimiters (ZBasicString::InvalidPos if not found)
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
size_t FindFirstOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _delimiters, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return ZSTL::InvalidPos;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _string.BoundsCheck(_s2, _delimiters.Length());
const size_t e2 = _string.BoundsCheck(_e2, _delimiters.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::FindFirstOf - Cannot find with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::FindFirstOf - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindFirstOf(_string.Array(), s1, e1, _delimiters.Array(), s2, e2);
}
//FindFirstOf C-String Implementation
template <typename A, typename B>
size_t FindFirstOf(const ZBasicString<A>& _string, const ZBasicString<B>& _values, size_t _start, size_t _end)
{ return FindFirstOf(_string, 0, _string.Length(), ZBasicString<A>(_values), _start, _end); }
/*
public ZBasicStringAlgo<A, B>::FindFirstOf
Finds the first occurrence of a set of values in the provided region
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _delimiters - the decimeters to search for
@return (size_t) - the index of the first occurrence of one of the delimiters (ZBasicString::InvalidPos if not found)
*/
template <typename A, typename B>
size_t FindFirstOf(const ZBasicString<A>& _string, const ZBasicString<B>& _delimiters)
{
return FindFirstOf(_string, 0, _string.Length(), _delimiters, 0, _delimiters.Length());
}
//FindFirstOf C-String Implementation
template <typename A>
size_t FindFirstOf(const ZBasicString<A>& _string, const char* _delimiters)
{ return FindFirstOf(_string, ZBasicString<A>(_delimiters)); }
//FindFirstOf C-String Implementation
template <typename A>
size_t FindFirstOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _delimiters, size_t _s2, size_t _e2)
{ return FindFirstOf(_string, _s1, _e1, ZBasicString<A>(_delimiters), _s2, _e2); }
/*
public ZBasicStringAlgo<A>::FindFirstNot
Finds the first occurrence of a value that is not the provided value in the given
region of the string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the character to avoid
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the index of the first value that is not the provided value (ZBasicString::InvalidPos if not found)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t FindFirstNot(const ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return ZSTL::InvalidPos;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::FindFirstNot - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindFirstNot(_string.Array(), _char, start, end);
}
/*
public ZBasicStringAlgo<A>::FindFirstNot
Finds the first occurrence of a value that is not the provided value in the given
region of the string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the character to avoid
@return (size_t) - the index of the first value that is not the provided value (ZBasicString::InvalidPos if not found)
*/
template <typename A>
size_t FindFirstNot(const ZBasicString<A>& _string, const char& _char)
{
return FindFirstNot(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::FindFirstNotOf
Finds the first occurrence of a value that is not one of a set of values
in the provided region of a string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _s1 - the starting index in the string
@param _e1 - the ending index in the string (exclusive)
@param _delimiters - the delimiters to avoid
@param _s2 - the starting index in the delimiters string
@param _e2 - the ending index in the delimiters string (exclusive)
@return (size_t) - the index of the first occurrence of a value that is not one of the delimiters (ZBasicString::InvalidPos if not found)
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
size_t FindFirstNotOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _delimiters, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return ZSTL::InvalidPos;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _string.BoundsCheck(_s2, _delimiters.Length());
const size_t e2 = _string.BoundsCheck(_e2, _delimiters.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::FindFirstNotOf - Cannot find with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::FindFirstNotOf - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindFirstNotOf(_string.Array(), s1, e1, _delimiters.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::FindFirstNotOf
Finds the first occurrence of a value that is not one of a set of values
in the provided region of a string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _delimiters - the delimiters to avoid
@return (size_t) - the index of the first occurrence of a value that is not one of the delimiters (ZBasicString::InvalidPos if not found)
*/
template <typename A, typename B>
size_t FindFirstNotOf(const ZBasicString<A>& _string, const ZBasicString<B>& _delimiters)
{
return FindFirstNotOf(_string, 0, _string.Length(), _delimiters, 0, _delimiters.Length());
}
//FindFirstNotOf C-String Implementation
template <typename A>
size_t FindFirstNotOf(const ZBasicString<A>& _string, const char* _delimiters)
{ return FindFirstNotOf(_string, ZBasicString<A>(_delimiters)); }
//FindFirstNotOf C-String Implementation
template <typename A>
size_t FindFirstNotOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _delimiters, size_t _s2, size_t _e2)
{ return FindFirstNotOf(_string, _s1, _e1, ZBasicString<A>(_delimiters), _s2, _e2); }
/*
public ZBasicStringAlgo<A>::FindLast
Finds the last occurrence of the specified value in the given range of the string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the value to find
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the index of hte last occurence of the specified value (ZBasicString::InvalidPos if not found)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t FindLast(const ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return ZSTL::InvalidPos;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::FindLast - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindLast(_string.Array(), _char, start, end);
}
/*
public ZBasicStringAlgo<A>::FindLast
Finds the last occurrence of the specified value in the string.
@param A - the allocator type for the string
@param _string - the string to search
@param _char - the value to find
@return (size_t) - index of the last occurrence (ZBasicString::InvalidPos if not found)
*/
template <typename A>
size_t FindLast(const ZBasicString<A>& _string, const char& _char)
{
return FindLast(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::FindLastOf
Finds the last occurrence of a set of values in the provided region of a string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _s1 - the starting index in the string
@param _e1 - the ending index in the string (exclusive)
@param _delimiters - the delimiters to search for
@param _s2 - the starting index in the delimiters string
@param _e2 - the ending index in the delimiters string (exclusive)
@return (size_t) - the index of the last occurrence of one of the delimiters (ZBasicString::InvalidPos if not found)
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
size_t FindLastOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _values, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return ZSTL::InvalidPos;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1); // 1 to allow indexing of end
const size_t s2 = _values.BoundsCheck(_s2, _values.Length());
const size_t e2 = _values.BoundsCheck(_e2, _values.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::FindLastOf - Cannot find with e1 < s1!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::FindLasttOf - Cannot find with e2 < s2!");
#endif
return ZArrayAlgo::FindLastOf(_string.Array(), s1, e1, _values.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::FindLastOf
Finds the last occurrence of a set of values in the provided string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _delimiters - the delimiters to search for
@return (size_t) - the index of the last occurrence of one of the delimiters (ZBasicString::InvalidPos if not found)
*/
template <typename A, typename B>
size_t FindLastOf(const ZBasicString<A>& _string, const ZBasicString<B>& _values)
{
return FindLastOf(_string, 0, _string.Length(), _values, 0, _values.Length());
}
//FindLastOf C-String Implementation
template <typename A>
size_t FindLastOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _values, size_t _s2, size_t _e2)
{
return FindLastOf(_string, _s1, _e1, ZBasicString<A>(_values), _s2, _e2);
}
//FindLastOf C-String Implementation
template <typename A>
size_t FindLastOf(const ZBasicString<A>& _string, const char* _values)
{
return FindLastOf(_string, ZBasicString<A>(_values));
}
/*
public ZBasicStringAlgo<A>::FindLastNot
Finds the last occurrence of a value that is not the provided value in the given
region of the string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the character to avoid
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the index of the last value that is not the provided value (ZBasicString::InvalidPos if not found)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t FindLastNot(const ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return ZSTL::InvalidPos;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::FindLastNot - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindLastNot(_string.Array(), _char, start, end);
}
/*
public ZBasicStringAlgo<A>::FindLastNot
Finds the last occurrence of a value that is not the provided value in the given string.
@param A - the allocator type of the string
@param _string - the string to search
@param _char - the character to avoid
@return (size_t) - the index of the last value that is not the provided value (ZBasicString::InvalidPos if not found)
*/
template <typename A>
size_t FindLastNot(const ZBasicString<A>& _string, const char& _char)
{
return FindLastNot(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::FindLastNotOf
Finds the last occurrence of a value that is not one of a set of values
in the provided region of a string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _s1 - the starting index in the string
@param _e1 - the ending index in the string (exclusive)
@param _delimiters - the delimiters to avoid
@param _s2 - the starting index in the delimiters string
@param _e2 - the ending index in the delimiters string (exclusive)
@return (size_t) - the index of the last occurrence of a value that is not one of the delimiters (ZBasicString::InvalidPos if not found)
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
size_t FindLastNotOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _values, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return ZSTL::InvalidPos;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1); // 1 to allow indexing of end
const size_t s2 = _values.BoundsCheck(_s2, _values.Length());
const size_t e2 = _values.BoundsCheck(_e2, _values.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::FindLastNotOf - Cannot find with e1 < s1!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::FindLastNotOf - Cannot find with e2 < s2!");
#endif
return ZArrayAlgo::FindLastNotOf(_string.Array(), s1, e1, _values.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::FindLastNotOf
Finds the last occurrence of a value that is not one of a set of values
in the provided region of a string.
@param A - the allocator type for the string
@param B - the allocator type for the values string
@param _string - the string to search in
@param _delimiters - the delimiters to avoid
@return (size_t) - the index of the last occurrence of a value that is not one of the delimiters (ZBasicString::InvalidPos if not found)
*/
template <typename A, typename B>
size_t FindLastNotOf(const ZBasicString<A>& _string, const ZBasicString<B>& _values)
{
return FindLastNotOf(_string, 0, _string.Length(), _values, 0, _values.Length());
}
//FindLastNotOf C-String Implementation
template <typename A>
size_t FindLastNotOf(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _values, size_t _s2, size_t _e2)
{
return FindLastNotOf(_string, _s1, _e1, ZBasicString<A>(_values), _s2, _e2);
}
//FindLastNotOf C-String Implementation
template <typename A>
size_t FindLastNotOf(const ZBasicString<A>& _string, const char* _values)
{
return FindLastNotOf(_string, ZBasicString<A>(_values));
}
/*
public ZBasicStringAlgo<A, B>::FindSub
Finds the first occurrence of a substring in the provided region in the string.
@param A - the allocator type for the string
@param B - the allocator type for the substring
@param _string - the string to search in
@param _s1 - the starting index
@param _e1 - the ending index (exclusive)
@param _substring - the substring to search for
@param _s2 - the starting index in the substring
@param _e2 - the ending index in the substring
@return (size_t) - the index of the first occurrence of the substring (ZBasicString::InvalidPos if not found)
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
size_t FindSub(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _substring, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return ZSTL::InvalidPos;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _string.BoundsCheck(_s2, _substring.Length());
const size_t e2 = _string.BoundsCheck(_e2, _substring.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::FindSub - Cannot find with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::FindSub - Cannot find with end < start!");
#endif
return ZArrayAlgo::FindSub(_string.Array(), s1, e1, _substring.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::FindSub
Finds the first occurrence of a substring in the provided string.
@param A - the allocator type for the string
@param B - the allocator type for the substring
@param _string - the string to search in
@param _substring - the substring to search for
@return (size_t) - the index of the first occurrence of the substring (ZBasicString::InvalidPos if not found)
*/
template <typename A, typename B>
size_t FindSub(const ZBasicString<A>& _string, const ZBasicString<B>& _substring)
{
return FindSub(_string, 0, _string.Length(), _substring, 0, _substring.Length());
}
//FindSub C-String Implementation
template <typename A>
size_t FindSub(const ZBasicString<A>& _string, const char* _substring)
{ return FindSub(_string, ZBasicString<A>(_substring)); }
//FindSub C-String Implementation
template <typename A>
size_t FindSub(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _substring, size_t _s2, size_t _e2)
{ return FindSub(_string, _s1, _e1, ZBasicString<A>(_substring), _s2, _e2); }
/*
public ZBasicString<A>::IsNumeric
Determines if a range of this string represents a numeric quantity.
@param A - the allocator type for the string
@param _string - the string to check
@param _start - the starting point
@param _end - the ending point (exclusive)
@return (bool) - true if this string is numeric, false otherwise
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
bool IsNumeric(const ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return false;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
bool digitSeen = false;
bool decimalPointSeen = false;
const char* string = _string.Array().Data();
//Ensure we see [-]?[0-9]+[.]?[0-9]*
// * := 0 or more times
// + := 1 or more times
// ? := 0 or 1 times
//May begin with '-' or digit.
if(string[start] != '-')
{
if(!isdigit(string[start]))
return false;
digitSeen = true;
}
/*
Algorithm: Since we know we have either seen a digit or negative sign,
scan for more digits and an optional decimal point, allowing only
a single decimal point. If we terminate the loop before seeing a single
digit, and we didn't see one before checking for the negative sign, then
return false.
*/
for(size_t i = start+ 1; i < end; i++)
{
//Not a digit?
if(!isdigit(string[i]))
{
//Only allow 1 decimal point
if(!decimalPointSeen && string[i] == '.')
{
decimalPointSeen = true;
continue;
}
//Not numeric
return false;
}
else
digitSeen = true;
}
//Must have seen at least one digit for this to be considered numeric.
return digitSeen;
}
/*
public ZBasicStringAlgo<A>::IsNumeric
Determines if this string represents a numeric quantity.
@param A - the allocator type for the string
@param _string - the string to check
@return (bool) - true if this string is numeric, false otherwise
*/
template <typename A>
bool IsNumeric(const ZBasicString<A>& _string)
{
return IsNumeric(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::IsNumeric
Returns the numeric integer value of this string. Empty strings are treated as
zero.
@param A - the allocator type for the string
@param _string - the string to convert to an integer value
@param _start - the starting index for the string
@param _end - the ending index for the string
@return (int) - the integer value of the string
*/
template <typename A>
int NumericInt(const ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end) {
return 0;
}
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
char tmp = _string.Data()[end];
_string.Data()[end] = ZBASICSTRING_NULL_TERMINATOR; //Don't worry, we'll put it back
int val = atoi(_string.Data() + start);
_string.Data()[end] = tmp;
return val;
}
/*
*/
template <typename A>
int NumericInt(const ZBasicString<A>& _string)
{
return NumericInt(_string, 0, _string.Length());
}
/*
*/
template <typename A>
double NumericDouble(const ZBasicString<A>& _string, size_t _start, size_t _end)
{
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
char tmp = _string.Data()[end];
_string.Data()[end] = ZBASICSTRING_NULL_TERMINATOR; //Don't worry, we'll put it back
double val = atof(_string.Data() + start);
_string.Data()[end] = tmp;
return val;
}
/*
*/
template <typename A>
double NumericDouble(const ZBasicString<A>& _string)
{
return NumericDouble(_string, 0, _string.Length());
}
/*
*/
template <typename A>
float NumericFloat(const ZBasicString<A>& _string, size_t _start, size_t _end)
{
return (float)NumericDouble(_string, _start, _end);
}
/*
*/
template <typename A>
float NumericFloat(const ZBasicString<A>& _string)
{
return NumericFloat(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::Remove
Removes the first occurrence of a provided character from the given region in this string.
@param A - the allocator type for the string
@param _string - the string to remove characters from
@param _char - the character to remove
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the index of the first removed character (ZBasicString::InvalidPos if none removed)
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t Remove(ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return ZSTL::InvalidPos;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Remove - Cannot remove with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
return ZArrayAlgo::Remove(stringArray, _char, start, end);
}
/*
public ZBasicStringAlgo<A>::Remove
Removes the first occurrence of a provided character from this string.
@param A - the allocator type for the string
@param _string - the string to remove characters from
@param _char - the character to remove
@return (size_t) the index of the first removed character (ZBasicString::InvalidPos if none removed)
*/
template <typename A>
size_t Remove(ZBasicString<A>& _string, const char& _char)
{
return Remove(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::RemoveAll
Removes all occurrences of a provided character from this string in the given region.
@param A - the allocator type for the string
@param _string - the string to remove characters from
@param _char - the character to remove
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the number of characters removed
@assert - if _end < _start
if _start of _end out of bounds
*/
template <typename A>
size_t RemoveAll(ZBasicString<A>& _string, const char& _char, size_t _start, size_t _end)
{
if (_start == _end)
return 0;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::RemoveAll - Cannot remove with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
return ZArrayAlgo::RemoveAll(stringArray, _char, start, end);
}
/*
public ZBasicStringAlgo<A>::RemoveAll
Removes all occurrences of a provided character from this string.
@param A - the allocator type for the string
@param _string - the string to remove characters from
@param _char - the character to remove
@return (size_t) - the number of characters removed
*/
template <typename A>
size_t RemoveAll(ZBasicString<A>& _string, const char& _char)
{
return RemoveAll(_string, _char, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::RemoveUpTo
Removes up to the provided number of occurrences of a character from the string in
the specified range.
@param A - the allocator type of the string
@param _string - the string to remove elements from
@param _char - the char to look for
@param _count - the maximum number of times to remove the char
@param _start - the index to start at
@param _end - the ending index (exclusive)
@return (size_t) - the number of occurrences removed
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
size_t RemoveUpTo(ZBasicString<A>& _string, const char& _char, size_t _count, size_t _start, size_t _end)
{
if (_start == _end || _count == 0)
return 0;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::RemoveUpTo - Cannot remove with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
return ZArrayAlgo::RemoveUpTo(stringArray, _char, _count, start, end);
}
/*
public ZBasicStringAlgo<A>::RemoveUpTo
Removes up to the provided number of occurrences of a character from the string.
@param A - the allocator type of the string
@param _string - the _string to remove elements from
@param _char - the character to look for
@param _count - the maximum number of times to remove the char
@return (size_t) - the number of occurrences removed
*/
template <typename A>
size_t RemoveUpTo(ZBasicString<A>& _string, const char& _char, size_t _count)
{
return RemoveUpTo(_string, _char, _count, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::Replace
Finds and replaces all occurrences of the provided character with another in the given region.
@param A - the allocator type of the string
@param _string - the string to replace chars in
@param _char - the char to look for
@param _newValue - the char to replace with
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the number of chars replaced
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
size_t Replace(ZBasicString<A>& _string, const char& _char, const char& _newChar, size_t _start, size_t _end)
{
if (_start == _end)
return 0;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Replace - Cannot replace with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
return ZArrayAlgo::Replace(stringArray, _char, _newChar, start, end);
}
/*
public ZBasicStringAlgo<A>::Replace
Finds and replaces all occurrences of the provided character with another.
@param T - the type held by the string
@param A - the allocator type of the string
@param _string - the string to replace chars in
@param _char - the char to look for
@param _newValue - the char to replace with
@return (size_t) - the number of chars replaced
*/
template <typename A>
size_t Replace(ZBasicString<A>& _string, const char& _char, const char& _newChar)
{
return Replace(_string, _char, _newChar, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::Reverse
Reverses an string in place between the given indices.
@param A - the allocator type of the string
@param _string - the string to reverse
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (void)
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
void Reverse(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Reverse - Cannot reverse with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
ZArrayAlgo::Reverse(stringArray, start, end);
}
/*
public ZBasicStringAlgo<A>::Reverse
Reverses an string in place.
@param A - the allocator type of the string
@param _string - the string to reverse
@return (void)
*/
template <typename A>
void Reverse(ZBasicString<A>& _string)
{
Reverse(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::Slice
Removes and returns a given region of a string as a new string.
@param A - the allocator type of the string
@param _string - the string to slice
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (ZBasicString<A>) - the removed region
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
ZBasicString<A> Slice(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return ZBasicString<A>();
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Slice - Cannot slice with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast<ZArray<char, A>&>(_string.Array());
ZArray<char, A> slice = ZArrayAlgo::Slice(stringArray, start, end);
slice.PushBack('\0');
return ZBasicString<A>(slice);
}
/*
public ZBasicStringAlgo<A, B>::Split
Splits the provided range of the given string into a set of strings anywhere a
delimiter occurs up to a maximum number of times. This will omit empty strings,
such as those caused by having two or more delimiters adjacent.
@param A - the allocator type of the string
@param B - the allocator type for the delimiter string
@param _string - the string to split
@param _delimiters - the delimiters to split on
@param _count - the maximum number of times to split
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (ZArray< ZBasicString<A> >) - array of strings
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A, typename B>
ZArray< ZBasicString<A> > Split(const ZBasicString<A>& _string, const ZBasicString<B>& _delimiters, size_t _count, size_t _start, size_t _end)
{
if (_start == _end || _count == 0)
return ZArray< ZBasicString<A> >();
ZArray< ZBasicString<A> > sections(_string.Length() + 1);
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1); // 1 to allow indexing of end
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Split - Cannot split with end < start!");
#endif
size_t previous = start;
for (size_t i = start; i < end ; i++)
{
for (size_t j = 0; j < _delimiters.Length(); j++)
{
if ( _string.Data()[i] == _delimiters.Data()[j] )
{
if (i > previous) //If we have more than just one of the delimiters
{
ZBasicString<A> section = ZBasicString<A>(_string, previous, i);
sections.PushBack( section );
}
if (sections.Size() == _count ) //Break out if we have reached our count limit
{
previous = i + 1;
goto breakOut; // we need to leave at this point
break;
}
previous = i + 1;
break;
}
}
}
breakOut: // breakout from hitting our split count
if (previous != end) //Add the final section if we don't end on a delimiter
sections.PushBack( ZBasicString<A>(_string, previous, end) );
return sections;
}
/*
public ZBasicStringAlgo<A, B>::Split
Splits the given string into a set of strings anywhere a delimiter occurs up
to a maximum number of times. This will omit empty strings, such as those
caused by having two or more delimiters adjacent.
@param A - the allocator type of the string
@param B - the allocator type for the delimiter string
@param _string - the string to split
@param _delimiters - the delimiters to split on
@param _count - the maximum number of times to split
@return (ZArray< ZBasicString<A> >) - array of strings
*/
template <typename A, typename B>
ZArray< ZBasicString<A> > Split(const ZBasicString<A>& _string, const ZBasicString<B>& _delims, size_t _count)
{
return Split(_string, _delims, _count, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A, B>::Split
Splits the given string into a set of strings anywhere a delimiter occurs.
This will omit empty strings, such as those caused by having two or more
delimiters adjacent.
@param A - the allocator type of the string
@param B - the allocator type for the delimiter string
@param _string - the string to split
@param _delimiters - the delimiters to split on
@param _count - the maximum number of times to split
@return (ZArray< ZBasicString<A> >) - array of strings
*/
template <typename A, typename B>
ZArray< ZBasicString<A> > Split(const ZBasicString<A>& _string, const ZBasicString<B>& _delims)
{
return Split(_string, _delims, _string.Length(), 0, _string.Length());
}
//Split C-String Implementation
template <typename A>
ZArray< ZBasicString<A> > Split(const ZBasicString<A>& _string, const char* _delims)
{ return Split(_string, ZBasicString<A>(_delims)); }
//Split C-String Implementation
template <typename A>
ZArray< ZBasicString<A> > Split(const ZBasicString<A>& _string, const char* _delims, size_t _count)
{ return Split(_string, ZBasicString<A>(_delims), _count); }
//Split C-String Implementation
template <typename A>
ZArray< ZBasicString<A> > Split(const ZBasicString<A>& _string, const char* _delims, size_t _count, size_t _start, size_t _end)
{ return Split(_string, ZBasicString<A>(_delims), _count, _start, _end); }
/*
public ZBasicStringAlgo<A, B>::StartsWith
Determines if the provided region of a string starts with the given region of a substring.
@param A - the allocator type for the string
@param B - the allocator type for the substring
@param _string - the string to check
@param _s1 - the starting index for the string
@param _e1 - the ending index for the string (exclusive)
@param _substring - the substring to check
@param _s2 - the starting index for the substring
@param _e2 - the ending index for the substring (exclusive)
@return (bool) - true if the string starts with the given substring, false otherwise
@assert - if _s1 < _e1 or _s2 < _e2
if _s1, _e1, _s2, or _e2 out of bounds
*/
template <typename A, typename B>
bool StartsWith(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const ZBasicString<B>& _substring, size_t _s2, size_t _e2)
{
if (_s1 == _e1 || _s2 == _e2)
return false;
const size_t s1 = _string.BoundsCheck(_s1, _string.Length());
const size_t e1 = _string.BoundsCheck(_e1, _string.Length() + 1);
const size_t s2 = _string.BoundsCheck(_s2, _substring.Length());
const size_t e2 = _string.BoundsCheck(_e2, _substring.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(s1 <= e1, "ZBasicStringAlgo::StartsWith - Cannot check with end < start!");
ZSTL_ASSERT(s2 <= e2, "ZBasicStringAlgo::StartsWith - Cannot check with end < start!");
#endif
// easy check: can substring fit into string?
if (e1 - s1 < e2 - s2)
return false;
return ZArrayAlgo::StartsWith(_string.Array(), s1, e1, _substring.Array(), s2, e2);
}
/*
public ZBasicStringAlgo<A, B>::StartsWith
Determines if the provided string starts with the given substring.
@param A - the allocator type for the string
@param B - the allocator type for the substring
@param _string - the string to check
@param _substring - the substring to check
@return (bool) - true if the string starts with the given substring, false otherwise
*/
template <typename A, typename B>
bool StartsWith(const ZBasicString<A>& _string, const ZBasicString<B>& _substring)
{
return StartsWith(_string, 0, _string.Length(), _substring, 0, _substring.Length());
}
//StartsWith C-String Implementation
template <typename A>
bool StartsWith(const ZBasicString<A>& _string, const char *_substring)
{ return StartsWith(_string, ZBasicString<A>(_substring)); }
//StartsWith C-String Implementation
template <typename A>
bool StartsWith(const ZBasicString<A>& _string, size_t _s1, size_t _e1, const char* _substring, size_t _s2, size_t _e2)
{ return StartsWith(_string, _s1, _e1, ZBasicString<A>(_substring), _s2, _e2); }
/*
public ZBasicStringAlgo<A>::Strip
Removes all whitespace from the provided region of a string.
@param A - the allocator type of the string
@param _string - the string to strip
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the number of whitespace characters removed
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
size_t Strip(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return 0;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::Strip - Cannot strip whitepsace with end < start!");
#endif
ZArray<char, A>& stringArray = const_cast< ZArray<char, A>& >(_string.Array());
size_t removed = 0;
// remove spaces
removed += ZArrayAlgo::RemoveAll(stringArray, ' ', start, end);
// remove tabs (remember that you have to decrement the end counter to stay in bounds)
removed += ZArrayAlgo::RemoveAll(stringArray, '\t', start, end - removed);
return removed;
}
/*
public ZBasicStringAlgo<A>::Strip
Removes all whitespace from the provided string.
@param A - the allocator type of the string
@param _string - the string to strip
@return (size_t) - the number of whitespace characters removed
*/
template <typename A>
size_t Strip(ZBasicString<A>& _string)
{
return Strip(_string, 0, _string.Length());
}
/*
public ZBasicString<A>::Tokenize
Tokenize function, which returns the next token in this string up to
the delimiter, consuming the occurrence of the delimiter in the process.
This may emit empty strings, such as those caused by having two or
more delimiters adjacent.
@param A - the allocator type of the string
@param _delims - the delimiters to look for
@return (ZBasicString<A>) - the token
*/
template <typename A, typename B>
ZBasicString<A> Tokenize(ZBasicString<A>& _string, const ZBasicString<B>& _delims)
{
if (_string.Empty())
return ZBasicString<A>();
if (_delims.Empty())
{
ZBasicString<A> ret = _string;
_string.Clear();
return ret;
}
size_t tokend = ZSTL::InvalidPos;
size_t i, j;
ZBasicString<A> token;
for(i = 0; i < _string.Length(); i++)
{
for (j = 0; j < _delims.Length(); j++)
{
if (_string.At(i) == _delims.At(j))
{
tokend = i;
i = _string.Length() - 1; // forces us to break out of the outer loop
break;
}
}
}
// we found no delimiters :(
if (tokend == ZSTL::InvalidPos)
{
token = _string;
_string.Clear();
return token;
}
// we found a delimiter first
if (tokend == 0)
{
_string.Erase(0);
return ZBasicString<A>();
}
//Grab that token
token = ZBasicString<A>(_string,0,tokend);
//Erase that token from this string
_string.Erase(0, tokend + 1);
//Return the token
return token;
}
//Tokenize C-String Implementation
template <typename A>
ZBasicString<A> Tokenize(ZBasicString<A>& _string, const char *_delims)
{ return Tokenize(_string, ZBasicString<A>(_delims)); }
/*
public ZBasicStringAlgo<A>::ToLower
Changes the provided region of the given string into all lowercase letters.
@param A - the allocator type of the string
@param _string - the string to mutate
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (void)
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
void ToLower(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::ToLower - Cannot lower with end < start!");
#endif
for (size_t i = start; i < end; i++)
_string.Data()[i] = (char)tolower(_string.Data()[i]);
}
/*
public ZBasicStringAlgo<A>::ToLower
Changes the provided string into all lowercase letters.
@param A - the allocator type of the string
@param _string - the string to mutate
@return (void)
*/
template <typename A>
void ToLower(ZBasicString<A>& _string)
{
ToLower(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::ToUpper
Changes the provided region of the given string into all uppercase letters.
@param A - the allocator type of the string
@param _string - the string to mutate
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (void)
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
void ToUpper(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::ToUpper - Cannot upper with end < start!");
#endif
for (size_t i = start; i < end; i++)
_string.Data()[i] = (char)toupper(_string.Data()[i]);
}
/*
public ZBasicStringAlgo<A>::ToUpper
Changes the provided region of the given string into all uppercase letters.
@param A - the allocator type of the string
@param _string - the string to mutate
@return (void)
*/
template <typename A>
void ToUpper(ZBasicString<A>& _string)
{
ToUpper(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::TrimLeft
Trims all the whitespace from the left (front) of the provided region of a string.
@param A - the allocator type for the string
@param _string - the string to trim
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the number of whitespace characters removed
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
size_t TrimLeft(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return 0;
size_t i;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::TrimLeft - Cannot trim with end < start!");
#endif
for (i = start; i < end; i++)
{
if (!isspace(_string.Data()[i]))
break;
}
_string.Erase(start, i);
return (i - start);
}
/*
public ZBasicString<A>::TrimLeft
Removes all whitespace from the left side (front) of this string.
@param A - the allocator type for the string
@param _string - the string to trim whitespace from
@return (size_t) - the number of whitespace characters removed
*/
template <typename A>
size_t TrimLeft(ZBasicString<A>& _string)
{
return TrimLeft(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::TrimLeft
Trims all the whitespace from the right (back) of the provided region of a string.
@param A - the allocator type for the string
@param _string - the string to trim
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the number of whitespace characters removed
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
size_t TrimRight(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return 0;
size_t i;
const size_t start = _string.BoundsCheck(_start, _string.Length());
const size_t end = _string.BoundsCheck(_end, _string.Length() + 1);
#if !ZSTL_DISABLE_RUNTIME_CHECKS
ZSTL_ASSERT(start <= end, "ZBasicStringAlgo::TrimRight - Cannot trim with end < start!");
#endif
//Remove any character that is a space character as determined by isspace
for (i = end; i > start; i--)
{
if (!isspace(_string.Data()[i - 1]))
break;
}
_string.Erase(i, end);
return (end - i);
}
/*
public ZBasicString<A>::TrimRight
Removes all whitespace from the right side (back) of this string.
@param _string - the string to trim whitespace from
@return (size_t) - the number of whitespace characters removed
*/
template <typename A>
size_t TrimRight(ZBasicString<A>& _string)
{
return TrimRight(_string, 0, _string.Length());
}
/*
public ZBasicStringAlgo<A>::Trim
Trims all the whitespace from both the left (front) and right (back) sides of the
given region of a string.
@param A - the allocator type for the string
@param _string - the string to trim
@param _start - the starting index
@param _end - the ending index (exclusive)
@return (size_t) - the number of whitespace characters removed
@assert - if _end < _start
if _start or _end out of bounds
*/
template <typename A>
size_t Trim(ZBasicString<A>& _string, size_t _start, size_t _end)
{
if (_start == _end)
return 0;
size_t removed = TrimRight(_string, _start, _end);
return removed + TrimLeft(_string, _start, _end - removed);
}
/*
public ZBasicString<A>::Trim
Removes all whitespace from both left and right side of this string.
@param A - the allocator type of the string
@param _string - the string to trim whitespace from
@return (size_t) - the number of whitespace characters removed
*/
template <typename A>
size_t Trim(ZBasicString<A>& _string)
{
if (_string.Empty())
return 0;
return TrimLeft(_string) + TrimRight(_string);
}
};
#endif