2440 lines
80 KiB
C++
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
|