📄 string
字号:
// ---------------------------------------------------------------------------------------------------------------------------------
// _ _
// | | (_)
// ___| |_ _ __ _ _ __ __ _
// / __| __| '__| | '_ \ / _` |
// \__ \ |_| | | | | | | (_| |
// |___/\__|_| |_|_| |_|\__, |
// __/ |
// |___/
//
// Description:
//
// Character string class
//
// Notes:
//
// Best viewed with 8-character tabs and (at least) 132 columns
//
// History:
//
// 04/13/2001 by Paul Nettle: Original creation
//
// Restrictions & freedoms pertaining to usage and redistribution of this software:
//
// This software is 100% free. If you use this software (in part or in whole) you must credit the author. This software may not be
// re-distributed (in part or in whole) in a modified form without clear documentation on how to obtain a copy of the original
// work. You may not use this software to directly or indirectly cause harm to others. This software is provided as-is and without
// warrantee -- Use at your own risk. For more information, visit HTTP://www.FluidStudios.com/
//
// Copyright 2001, Fluid Studios, Inc., all rights reserved.
// ---------------------------------------------------------------------------------------------------------------------------------
#ifndef _FSTL_STRING
#define _FSTL_STRING
// ---------------------------------------------------------------------------------------------------------------------------------
// Module setup (required includes, macros, etc.)
// ---------------------------------------------------------------------------------------------------------------------------------
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include "common"
#include "util"
#include "array"
#include "list"
FSTL_NAMESPACE_BEGIN
// ---------------------------------------------------------------------------------------------------------------------------------
template <class T = char>
class basic_string
{
public:
// Construction/destruction
inline basic_string()
: _length(0), _buffer(static_cast<T *>(0))
{
}
inline basic_string(const basic_string & str)
: _length(0), _buffer(static_cast<T *>(0))
{
*this = str;
}
inline basic_string(const char * str)
: _length(0), _buffer(static_cast<T *>(0))
{
resize(static_cast<const unsigned int>(strlen(str)));
if (_buffer)
{
_buffer[length()] = 0;
fstl::memcpy(_buffer, str, length());
}
}
/*SK:
inline basic_string(const wchar_t * str)
: _length(0), _buffer(static_cast<T *>(0))
{
int len = WideCharToMultiByte(CP_ACP, 0, str, -1, 0, 0, NULL, NULL);
resize(len);
if (_buffer)
{
_buffer[length()] = 0;
WideCharToMultiByte(CP_ACP, 0, str, -1, _buffer, length(), NULL, NULL);
}
}
*/
inline explicit basic_string(const T value)
: _length(0), _buffer(static_cast<T *>(0))
{
resize(1);
buffer()[0] = value;
}
inline explicit basic_string(const int value)
: _length(0), _buffer(static_cast<T *>(0))
{
char s[50];
sprintf(s, "%d", value);
*this = basic_string(s);
}
inline explicit basic_string(const unsigned int value)
: _length(0), _buffer(static_cast<T *>(0))
{
char s[50];
sprintf(s, "%u", value);
*this = basic_string(s);
}
inline explicit basic_string(const long value)
: _length(0), _buffer(static_cast<T *>(0))
{
char s[50];
sprintf(s, "%d", value);
*this = basic_string(s);
}
inline explicit basic_string(const unsigned long value)
: _length(0), _buffer(static_cast<T *>(0))
{
char s[50];
sprintf(s, "%u", value);
*this = basic_string(s);
}
inline explicit basic_string(const float value)
: _length(0), _buffer(static_cast<T *>(0))
{
char s[50];
sprintf(s, "%f", value);
*this = basic_string(s);
}
inline explicit basic_string(const double value)
: _length(0), _buffer(static_cast<T *>(0))
{
char s[50];
sprintf(s, "%f", value);
*this = basic_string(s);
}
inline ~basic_string()
{
erase();
}
// Casting & conversion
inline const T * asArray() const {return buffer();}
inline char asChar() const {return static_cast<char>(asInt());}
inline unsigned char asUChar() const {return static_cast<unsigned char>(asUInt());}
inline short asShort() const {return static_cast<short>(asInt());}
inline unsigned short asUShort() const {return static_cast<unsigned short>(asUInt());}
inline unsigned int asUInt() const {return static_cast<unsigned int>(asInt());}
inline unsigned long asULong() const {return static_cast<unsigned long>(asLong());}
inline float asFloat() const {return static_cast<float>(asDouble());}
inline int asInt() const {return fstl::atoi(buffer());}
inline long asLong() const {return fstl::atol(buffer());}
inline double asDouble() const {return fstl::atof(buffer());}
// Operators
inline basic_string & operator =(const basic_string & rhs)
{
if (this == &rhs) return *this;
resize(rhs.length());
if (!rhs.length()) return *this;
fstl::memcpy(_buffer, rhs._buffer, length());
_buffer[length()] = 0;
return *this;
}
inline void operator +=(const basic_string & rhs)
{
if (!rhs.length()) return;
unsigned int oldLength = length();
unsigned int sLength = rhs.length();
resize(oldLength + sLength);
fstl::memcpy(&_buffer[oldLength], rhs._buffer, sLength);
_buffer[length()] = 0;
}
inline basic_string operator +(const basic_string & rhs) const
{
basic_string result(*this);
result += rhs;
return result;
}
inline basic_string operator - ()
{
if (!_buffer) return *this;
T *p0 = _buffer;
T *p1 = &_buffer[length()-1];
while(p0 < p1)
{
T t = *p0;
*p0 = *p1;
*p1 = t;
p0++;
p1--;
}
return *this;
}
inline operator *=(const int value)
{
*this = *this * value;
}
inline basic_string operator *(const int value) const
{
// Neg numbers are bad
if (value < 0) return *this;
// Something to work with...
basic_string result;
// Make sure we're about to DO something
if (!length() || !value) return result;
result.resize(length() * value);
T *ptr = result._buffer;
for (int i = 0; i < value; i++, ptr += length())
{
fstl::memcpy(ptr, _buffer, length());
}
result._buffer[result.length()] = 0;
return result;
}
inline void operator >>=(const int value)
{
if (value <= 0) return;
resize(length() + value);
fstl::memmove(&_buffer[value], _buffer, (length()-value));
fstl::memset(_buffer, space_char<T>(), value);
_buffer[length()] = 0;
}
inline void operator <<=(const int value)
{
if (value <= 0) return;
if (!_buffer) return;
int count = length() - value;
if (count > 0) fstl::memmove(_buffer, &_buffer[value], count);
resize(count);
}
inline basic_string operator >>(const int value) const
{
basic_string result(*this);
if (value <= 0) return result;
result >>= value;
return result;
}
inline basic_string operator <<(const int value) const
{
basic_string result(*this);
if (value <= 0) return result;
result <<= value;
return result;
}
inline bool operator ==(const basic_string & str) const
{
if (!_buffer || !str._buffer) return _buffer == str._buffer;
return fstl::strcmp(_buffer, str._buffer) == 0;
}
inline bool operator !=(const basic_string & str) const
{
if (!_buffer || !str._buffer) return _buffer != str._buffer;
return fstl::strcmp(_buffer, str._buffer) != 0;
}
inline bool operator <=(const basic_string & str) const
{
if (!_buffer || !str._buffer) return _buffer == str._buffer;
return fstl::strcmp(_buffer, str._buffer) <= 0;
}
inline bool operator >=(const basic_string & str) const
{
if (!_buffer || !str._buffer) return _buffer == str._buffer;
return fstl::strcmp(_buffer, str._buffer) >= 0;
}
inline bool operator <(const basic_string & str) const
{
if (!_buffer || !str._buffer) return _buffer == str._buffer;
return fstl::strcmp(_buffer, str._buffer) < 0;
}
inline bool operator >(const basic_string & str) const
{
if (!_buffer || !str._buffer) return _buffer == str._buffer;
return fstl::strcmp(_buffer, str._buffer) > 0;
}
inline T & operator [](const int index) const
{
return _buffer[index];
}
// Utilitarian (public)
inline basic_string substring(int start, int count = 0x7fffffff) const
{
basic_string result;
if (start < 0)
{
count += start;
start = 0;
}
else if (static_cast<unsigned int>(start) > length()) start = length();
if (!_buffer || !length() || static_cast<unsigned int>(start) >= length()) return result;
if (static_cast<unsigned int>(start + count) > length()+1) count = length() - start;
result.set(&_buffer[start], count);
return result;
}
inline void erase(int start = 0, int count = 0x7fffffff)
{
if (static_cast<unsigned int>(start) >= length()) return;
if (static_cast<unsigned int>(start + count) > length()) count = length() - start;
fstl::memmove(&_buffer[start], &_buffer[start+count], (length() - count - start));
resize(length() - count);
}
inline int find(const basic_string & str, int start = 0) const
{
return find(str._buffer, start);
}
inline int find(const T * str, int start = 0) const
{
if (!_buffer || !str) return -1;
if (start < 0) start = 0;
else if (static_cast<unsigned int>(start) > length()) return -1;
T *ptr = NULL;
ptr = fstl::strstr(&_buffer[start], str);
if (!ptr) return -1;
return static_cast<int>(ptr - _buffer);
}
inline int rfind(const basic_string & str, int start = 0x7fffffff) const
{
if (!_buffer || !str._buffer) return -1;
if (static_cast<unsigned int>(start) > length()) start = length();
// We'll back up by the length of the string since we can't find
// a string in reverse order wihtout at least str's length at the end
// of it...
start -= str.length();
while(start > 0)
{
if (!fstl::strncmp(&_buffer[start], str._buffer, str.length())) return start;
start--;
}
return -1;
}
inline int ncfind(const basic_string & str, int start = 0) const
{
if (!_buffer || !str._buffer) return -1;
if (start < 0) start = 0;
int len = length() - str.length();
if (len < 0) return -1;
if (start > len) return -1;
while(start <= len)
{
if (!fstl::strnicmp(&_buffer[start], str._buffer, str.length())) return start;
start++;
}
return -1;
}
inline int ncrfind(const basic_string & str, int start = 0x7fffffff) const
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -