#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 #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& 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 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 String Humanize(std::chrono::duration value) { return PeriodInMicroSecToString(std::chrono::duration_cast(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 inline String& operator<<(String& buffer, const T* value) { return buffer << IntU64::ToHexString(reinterpret_cast(value)); } template inline String& operator<<(String& buffer, const Vector& values) { bool first = true; for (auto i = values.Begin(); i != values.End(); ++i) { if (!first) { buffer << ", "; } buffer << *i; first = false; } return buffer; } template inline const String& operator>>(const String& buffer, Vector& 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 inline String& operator<<(String& buffer, Map 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 inline String& operator<<(String& buffer, Set values) { bool first = true; for (auto i = values.Begin(); i != values.End(); ++i) { if (!first) { buffer << ", "; } buffer << *i; first = false; } return buffer; } template inline const String& operator>>(const String& buffer, Set& 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 String& operator<<(String& buffer, StrongType value) { buffer << value.UnboxValue(); return buffer; } template StrongType& operator>>(const String& buffer, StrongType& value) { buffer >> value.UnboxValue(); return value; } template inline String& operator<<(String& buffer, std::chrono::duration value) { buffer << value.count(); return buffer; } template inline std::chrono::duration& operator>>(const String& buffer, std::chrono::duration& value) { Rep v; buffer >> v; value = std::chrono::duration(v); return value; } template inline const String& Humanize(const String& value) { return value; } template inline String Humanize(const Vector& 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; } }