JD2022-TU1/main/extern/dtest/dtcore/inc/dtstring.h

513 lines
18 KiB
C++

#pragma once
#include "dtcore/inc/dtdefinitions.h"
#include "dtcore/inc/dtvector.h"
#include "dtcore/inc/dtmap.h"
#include "dtcore/inc/dtset.h"
#include "dtcore/inc/dtstrongtype.h"
#include "dtcore/inc/dtchrono.h"
#pragma warning(push)
#include <stdarg.h>
#pragma warning(pop)
namespace dt
{
class WString;
enum class EndOfLineStandards
{
Dos,
Unix
};
class String
{
public:
DT_CORE_DLL_ENTRY String();
DT_CORE_DLL_ENTRY String(char ch);
DT_CORE_DLL_ENTRY String(const String& str);
DT_CORE_DLL_ENTRY String(String&& str);
DT_CORE_DLL_ENTRY String(const char* str);
DT_CORE_DLL_ENTRY String(const char* str, SizeT n);
DT_CORE_DLL_ENTRY String(const WString& str);
DT_CORE_DLL_ENTRY ~String();
// Move assignment operator.
DT_CORE_DLL_ENTRY String& operator=(String&& other);
DT_CORE_DLL_ENTRY String& operator=(const String& str);
DT_CORE_DLL_ENTRY String& operator+=(const String& str);
DT_CORE_DLL_ENTRY String& operator+=(const WString& str);
DT_CORE_DLL_ENTRY String& operator+=(const char* str);
DT_CORE_DLL_ENTRY String& operator+=(const Wchar* str);
DT_CORE_DLL_ENTRY String& operator+=(char c);
DT_CORE_DLL_ENTRY String operator+(const String& str) const;
DT_CORE_DLL_ENTRY const char& operator[](SizeT idx) const;
DT_CORE_DLL_ENTRY char& operator[](SizeT idx);
DT_CORE_DLL_ENTRY bool operator<(const String& str) const { return Compare(str) < 0; }
DT_CORE_DLL_ENTRY bool operator==(const String& str) const;
DT_CORE_DLL_ENTRY bool operator!=(const String& str) const;
DT_CORE_DLL_ENTRY int Compare(const String& str, bool caseSensitive = true) const;
DT_CORE_DLL_ENTRY SizeT Find(const String& str, SizeT start=0, bool caseSensitive = true) const;
DT_CORE_DLL_ENTRY bool Contains(const String& str, SizeT start=0) const;
DT_CORE_DLL_ENTRY bool Matches(const String& expr, bool caseSensitive) const;
DT_CORE_DLL_ENTRY void Split(const String& separator, Vector<String>& out) const;
DT_CORE_DLL_ENTRY SizeT ReverseFind(const String& str, SizeT start = 0, bool caseSensitive = true) const;
DT_CORE_DLL_ENTRY bool StartsWith(const String& str, bool caseSensitive = true) const;
DT_CORE_DLL_ENTRY bool EndsWith(const String& str, bool caseSensitive = true) const;
DT_CORE_DLL_ENTRY void Upper();
DT_CORE_DLL_ENTRY String GetUppered() const;
DT_CORE_DLL_ENTRY void Lower();
DT_CORE_DLL_ENTRY String GetLowered() const;
DT_CORE_DLL_ENTRY String SubStr(SizeT start, SizeT n = -1) const;
DT_CORE_DLL_ENTRY void Trim();
DT_CORE_DLL_ENTRY String GetTrimmed() const;
DT_CORE_DLL_ENTRY void TrimLeft();
DT_CORE_DLL_ENTRY String GetTrimmedLeft() const;
DT_CORE_DLL_ENTRY void PadRight(char c, SizeT n);
DT_CORE_DLL_ENTRY void Repeat(char c, SizeT n);
DT_CORE_DLL_ENTRY static String FromBin(SizeT size, const void* data, int cols = 30);
DT_CORE_DLL_ENTRY void HtmlEscape();
DT_CORE_DLL_ENTRY String GetAsAscii() const;
DT_CORE_DLL_ENTRY bool Replace(const String& str, const String& by, SizeT start = 0);
DT_CORE_DLL_ENTRY String GetReplaced(const String& str, const String& by, SizeT start = 0) const;
DT_CORE_DLL_ENTRY bool ReplaceAll(const String& str, const String& by, SizeT start = 0);
DT_CORE_DLL_ENTRY String GetReplacedAll(const String& str, const String& by, SizeT start = 0) const;
DT_CORE_DLL_ENTRY void Clear();
DT_CORE_DLL_ENTRY void Reserve(SizeT size);
DT_CORE_DLL_ENTRY void Resize(SizeT size);
DT_CORE_DLL_ENTRY SizeT Capacity() const;
DT_CORE_DLL_ENTRY SizeT Size() const;
DT_CORE_DLL_ENTRY void Swap(String& str);
DT_CORE_DLL_ENTRY static SizeT StringLength(const char* str);
DT_CORE_DLL_ENTRY static SizeT StringLengthFromUTF8(const char* str);
DT_CORE_DLL_ENTRY static SizeT StringCompare(const char* str1, const char* str2);
DT_CORE_DLL_ENTRY bool Empty() const;
DT_CORE_DLL_ENTRY bool IsWhiteSpaceOrEmpty() const;
DT_CORE_DLL_ENTRY void StandardizeEndOfLine(EndOfLineStandards standard);
DT_CORE_DLL_ENTRY String GetStandardizedEndOfLine(EndOfLineStandards standard) const;
DT_CORE_DLL_ENTRY const char* CStr() const;
DT_CORE_DLL_ENTRY static const SizeT NPOS;
DT_CORE_DLL_ENTRY static const String& Blank();
private:
enum { FIXED_BUFFER_SIZE=64 };
char m_FixedBuffer[FIXED_BUFFER_SIZE];
char* m_Buffer;
SizeT m_Size;
SizeT m_Capacity;
};
class WString
{
public:
DT_CORE_DLL_ENTRY WString();
DT_CORE_DLL_ENTRY WString(Wchar ch);
DT_CORE_DLL_ENTRY WString(const WString& str);
DT_CORE_DLL_ENTRY WString(const String& str);
DT_CORE_DLL_ENTRY WString(WString&& str);
DT_CORE_DLL_ENTRY WString(const Wchar* str);
DT_CORE_DLL_ENTRY WString(const Wchar* str, SizeT n);
DT_CORE_DLL_ENTRY ~WString();
// Move assignment operator.
DT_CORE_DLL_ENTRY WString& operator=(WString&& other);
DT_CORE_DLL_ENTRY WString& operator=(const WString& str);
DT_CORE_DLL_ENTRY WString& operator+=(const WString& str);
DT_CORE_DLL_ENTRY WString& operator+=(const String& str);
DT_CORE_DLL_ENTRY WString& operator+=(const char* str);
DT_CORE_DLL_ENTRY WString& operator+=(const Wchar* str);
DT_CORE_DLL_ENTRY WString& operator+=(Wchar c);
DT_CORE_DLL_ENTRY WString operator+(const WString& str) const;
DT_CORE_DLL_ENTRY const Wchar& operator[](SizeT idx) const;
DT_CORE_DLL_ENTRY Wchar& operator[](SizeT idx);
DT_CORE_DLL_ENTRY bool operator<(const String& str) const { return Compare(str) < 0; }
DT_CORE_DLL_ENTRY bool operator==(const WString& str) const;
DT_CORE_DLL_ENTRY bool operator!=(const WString& str) const;
DT_CORE_DLL_ENTRY int Compare(const WString& str) const;
DT_CORE_DLL_ENTRY void Clear();
DT_CORE_DLL_ENTRY void Reserve(SizeT size);
DT_CORE_DLL_ENTRY void Resize(SizeT size);
DT_CORE_DLL_ENTRY SizeT Capacity() const;
DT_CORE_DLL_ENTRY SizeT Size() const;
DT_CORE_DLL_ENTRY void Swap(WString& str);
DT_CORE_DLL_ENTRY bool Empty() const;
DT_CORE_DLL_ENTRY bool IsWhiteSpaceOrEmpty() const;
DT_CORE_DLL_ENTRY const Wchar* CStr() const;
DT_CORE_DLL_ENTRY static const WString& Blank();
DT_CORE_DLL_ENTRY static SizeT StringLength(const Wchar* str);
DT_CORE_DLL_ENTRY static SizeT StringLengthToUTF8(const Wchar* str);
private:
enum { FIXED_BUFFER_SIZE = 32 };
Wchar m_FixedBuffer[FIXED_BUFFER_SIZE];
Wchar* m_Buffer;
SizeT m_Size;
SizeT m_Capacity;
};
class IntU8
{
public:
DT_CORE_DLL_ENTRY static String ToString(U8 value, int width = 1);
DT_CORE_DLL_ENTRY static U8 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class IntS8
{
public:
DT_CORE_DLL_ENTRY static String ToString(S8 value, int width = 1);
DT_CORE_DLL_ENTRY static S8 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class IntU16
{
public:
DT_CORE_DLL_ENTRY static String ToString(U16 value, int width = 1);
DT_CORE_DLL_ENTRY static U16 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class IntS16
{
public:
DT_CORE_DLL_ENTRY static String ToString(S16 value, int width = 1);
DT_CORE_DLL_ENTRY static S16 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class IntU32
{
public:
DT_CORE_DLL_ENTRY static String ToString(U32 value, int width = 1);
DT_CORE_DLL_ENTRY static U32 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class IntS32
{
public:
DT_CORE_DLL_ENTRY static String ToString(S32 value, int width = 1);
DT_CORE_DLL_ENTRY static String ToHexString(S32 value);
DT_CORE_DLL_ENTRY static S32 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
using Int = IntS32; // compatibility
class IntU64
{
public:
DT_CORE_DLL_ENTRY static String ToString(U64 value, int width = 1);
DT_CORE_DLL_ENTRY static String ToHexString(U64 value);
DT_CORE_DLL_ENTRY static U64 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class IntS64
{
public:
DT_CORE_DLL_ENTRY static String ToString(S64 value, int width = 1);
DT_CORE_DLL_ENTRY static String ToHexString(S64 value);
DT_CORE_DLL_ENTRY static S64 Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class Float
{
public:
DT_CORE_DLL_ENTRY static String ToString(float value, int decimals = 3);
DT_CORE_DLL_ENTRY static float Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class Double
{
public:
DT_CORE_DLL_ENTRY static String ToString(double value, int decimals = 3);
DT_CORE_DLL_ENTRY static double Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
class Boolean
{
public:
DT_CORE_DLL_ENTRY static String ToString(bool value);
DT_CORE_DLL_ENTRY static bool Parse(const String& value);
DT_CORE_DLL_ENTRY static bool IsValid(const String& value);
};
typedef Vector<String> Strings;
DT_CORE_DLL_ENTRY String PadString(char c, SizeT count, const String& in = String::Blank());
DT_CORE_DLL_ENTRY void CreateTuple(const String& inLeft, const String& inRight, String* out);
DT_CORE_DLL_ENTRY bool ParseTuple(const String& in, String* outLeft, String* outRight);
DT_CORE_DLL_ENTRY String PeriodInMicroSecToString(S64 usecs);
template <class Rep, class Period> String Humanize(std::chrono::duration<Rep, Period> value)
{
return PeriodInMicroSecToString(std::chrono::duration_cast<MicroSeconds>(value).count());
}
DT_CORE_DLL_ENTRY String NumBytesToString(SizeT numBytes);
DT_CORE_DLL_ENTRY void SplitInLines(const String& value,
SizeT firstLineLength,
SizeT remainLength,
Strings& outLines);
struct StringCaseInsensitiveLess
{
bool operator() (const String& lhs, const String& rhs) const
{
return lhs.Compare(rhs, false) < 0;
}
};
struct ConstCharPtrLess
{
bool operator() (const char* lhs, const char* rhs) const
{
return String::StringCompare(lhs, rhs) < 0;
}
};
#if !defined(EAL_USE_STDINT_INT_TYPES)
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, int value);
DT_CORE_DLL_ENTRY extern int& operator>>(const String& buffer, int& value);
#endif // EAL_USE_STDINT_INT_TYPES
DT_CORE_DLL_ENTRY extern bool operator==(const char* lhs, const String& rhs);
DT_CORE_DLL_ENTRY extern bool operator==(const Wchar* lhs, const WString& rhs);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, S8 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, S16 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, S32 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, S64 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, U8 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, U16 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, U32 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, U64 value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, float value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, double value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, const String& value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, const WString& value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, const char* value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, const Wchar* value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, char value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, Wchar value);
DT_CORE_DLL_ENTRY extern String& operator<<(String& buffer, bool value);
DT_CORE_DLL_ENTRY extern WString& operator<<(WString& buffer, const WString& value);
DT_CORE_DLL_ENTRY extern WString& operator<<(WString& buffer, const String& value);
DT_CORE_DLL_ENTRY extern WString& operator<<(WString& buffer, const char* value);
DT_CORE_DLL_ENTRY extern S8& operator>>(const String& buffer, S8& value);
DT_CORE_DLL_ENTRY extern S16& operator>>(const String& buffer, S16& value);
DT_CORE_DLL_ENTRY extern S32& operator>>(const String& buffer, S32& value);
DT_CORE_DLL_ENTRY extern S64& operator>>(const String& buffer, S64& value);
DT_CORE_DLL_ENTRY extern U8& operator>>(const String& buffer, U8& value);
DT_CORE_DLL_ENTRY extern U16& operator>>(const String& buffer, U16& value);
DT_CORE_DLL_ENTRY extern U32& operator>>(const String& buffer, U32& value);
DT_CORE_DLL_ENTRY extern U64& operator>>(const String& buffer, U64& value);
DT_CORE_DLL_ENTRY extern float& operator>>(const String& buffer, float& value);
DT_CORE_DLL_ENTRY extern double& operator>>(const String& buffer, double& value);
DT_CORE_DLL_ENTRY extern String& operator>>(const String& buffer, String& value);
DT_CORE_DLL_ENTRY extern char& operator>>(const String& buffer, char& value);
DT_CORE_DLL_ENTRY extern bool& operator>>(const String& buffer, bool& value);
template <typename T> inline String& operator<<(String& buffer, const T* value)
{
return buffer << IntU64::ToHexString(reinterpret_cast<U64>(value));
}
template <typename T> inline String& operator<<(String& buffer, const Vector<T>& values)
{
bool first = true;
for (auto i = values.Begin(); i != values.End(); ++i)
{
if (!first)
{
buffer << ", ";
}
buffer << *i;
first = false;
}
return buffer;
}
template <typename T> inline const String& operator>>(const String& buffer, Vector<T>& values)
{
Strings parts;
buffer.Split(",", parts);
if (parts.Size() != 1 || !parts.Empty())
{
values.Reserve(parts.Size());
for (String& part : parts)
{
part.Trim();
T v;
part >> v;
values.PushBack(v);
}
}
return buffer;
}
template <typename T, typename U> inline String& operator<<(String& buffer, Map<T, U> values)
{
bool first = true;
for (auto i = values.Begin(); i != values.End(); ++i)
{
if (!first)
{
buffer << ", ";
}
buffer << i->first << ':' << i->second;
first = false;
}
return buffer;
}
template <typename T> inline String& operator<<(String& buffer, Set<T> values)
{
bool first = true;
for (auto i = values.Begin(); i != values.End(); ++i)
{
if (!first)
{
buffer << ", ";
}
buffer << *i;
first = false;
}
return buffer;
}
template <typename T> inline const String& operator>>(const String& buffer, Set<T>& values)
{
Strings parts;
buffer.Split(",", parts);
if (parts.Size() != 1 || !parts.Empty())
{
values.Reserve(parts.Size());
for (String& part : parts)
{
part.Trim();
T v;
part >> v;
values.Insert(v);
}
}
return buffer;
}
template <typename T, typename Param> String& operator<<(String& buffer, StrongType<T, Param> value)
{
buffer << value.UnboxValue();
return buffer;
}
template <typename T, typename Param> StrongType<T, Param>& operator>>(const String& buffer, StrongType<T, Param>& value)
{
buffer >> value.UnboxValue();
return value;
}
template <typename Rep, typename Period> inline
String& operator<<(String& buffer, std::chrono::duration<Rep, Period> value)
{
buffer << value.count();
return buffer;
}
template <typename Rep, typename Period> inline
std::chrono::duration<Rep, Period>& operator>>(const String& buffer, std::chrono::duration<Rep, Period>& value)
{
Rep v;
buffer >> v;
value = std::chrono::duration<Rep, Period>(v);
return value;
}
template <typename String> inline const String& Humanize(const String& value)
{
return value;
}
template <typename T> inline String Humanize(const Vector<T>& values)
{
String buffer;
SizeT counter = 0;
SizeT last = values.Size() - 1;
for (auto i = values.Begin(); i != values.End(); ++i)
{
if (counter != 0)
{
if (counter == last)
{
buffer << " and ";
}
else
{
buffer << ", ";
}
}
buffer << dt::Humanize(*i);
counter++;
}
return buffer;
}
}