//////////////////////////////////////////////////////////////////// // Strings.h // // Copyright 2007 cDc@seacave // Distributed under the Boost Software License, Version 1.0 // (See http://www.boost.org/LICENSE_1_0.txt) #ifndef __SEACAVE_STRING_H__ #define __SEACAVE_STRING_H__ // I N C L U D E S ///////////////////////////////////////////////// #include "Streams.h" // D E F I N E S /////////////////////////////////////////////////// namespace SEACAVE { // S T R U C T S /////////////////////////////////////////////////// /// String class: enhanced std::string class GENERAL_API String : public std::string { public: typedef std::string Base; public: inline String() {} inline String(LPCTSTR sz) : Base(sz) {} inline String(const Base& str) : Base(str) {} inline String(size_t n, value_type v) : Base(n, v) {} inline String(LPCTSTR sz, size_t count) : Base(sz, count) {} inline String(LPCTSTR sz, size_t offset, size_t count) : Base(sz, offset, count) {} #ifdef _SUPPORT_CPP11 inline String(Base&& rhs) : Base(std::forward(rhs)) {} inline String(String&& rhs) : Base(std::forward(rhs)) {} inline String(const String& rhs) : Base(rhs) {} inline String& operator=(Base&& rhs) { Base::operator=(std::forward(rhs)); return *this; } inline String& operator=(String&& rhs) { Base::operator=(std::forward(rhs)); return *this; } inline String& operator=(TCHAR rhs) { Base::operator=(rhs); return *this; } inline String& operator=(LPCTSTR rhs) { Base::operator=(rhs); return *this; } inline String& operator=(const String& rhs) { Base::operator=(rhs); return *this; } #endif inline String& operator+=(TCHAR rhs) { *this = (*this) + rhs; return *this; } inline String& operator+=(LPCTSTR rhs) { *this = (*this) + rhs; return *this; } inline String& operator+=(const Base& rhs) { *this = (*this) + rhs; return *this; } inline String& operator+=(const String& rhs) { *this = (*this) + rhs; return *this; } inline void Release() { return clear(); } inline bool IsEmpty() const { return empty(); } inline operator LPCTSTR() const { return c_str(); } String& Format(LPCTSTR szFormat, ...) { va_list args; va_start(args, szFormat); TCHAR szBuffer[2048]; const size_t len((size_t)_vsntprintf(szBuffer, 2048, szFormat, args)); if (len > 2048) { *this = FormatStringSafe(szFormat, args); va_end(args); } else { va_end(args); this->assign(szBuffer, len); } return *this; } String& FormatSafe(LPCTSTR szFormat, ...) { va_list args; va_start(args, szFormat); const size_t len((size_t)_vsctprintf(szFormat, args)); ASSERT(len != (size_t)-1); TCHAR* szBuffer(new TCHAR[len]); _vsntprintf(szBuffer, len, szFormat, args); va_end(args); this->assign(szBuffer, len); delete[] szBuffer; return *this; } static String FormatString(LPCTSTR szFormat, ...) { va_list args; va_start(args, szFormat); TCHAR szBuffer[2048]; const size_t len((size_t)_vsntprintf(szBuffer, 2048, szFormat, args)); if (len > 2048) { const String str(FormatStringSafe(szFormat, args)); va_end(args); return str; } va_end(args); return String(szBuffer, len); } static inline String FormatStringSafe(LPCTSTR szFormat, va_list args) { const size_t len((size_t)_vsctprintf(szFormat, args)); ASSERT(len != (size_t)-1); TCHAR* szBuffer(new TCHAR[len]); _vsntprintf(szBuffer, len, szFormat, args); String str(szBuffer, len); delete[] szBuffer; return str; } inline void ToUpper(String& out) const { out.resize(size()); std::transform(begin(), end(), out.begin(), [](TCHAR c) { return (TCHAR)std::toupper(c); }); } inline String ToUpper() const { String str; ToUpper(str); return str; } inline void ToLower(String& out) const { out.resize(size()); std::transform(begin(), end(), out.begin(), [](TCHAR c) { return (TCHAR)std::tolower(c); }); } inline String ToLower() const { String str; ToLower(str); return str; } inline void Save(OSTREAM& oStream) const { const WORD nSize = (WORD)size(); oStream.write(&nSize, sizeof(WORD)); oStream.write(c_str(), nSize); } inline void Load(ISTREAM& oStream) { WORD nSize; oStream.read(&nSize, sizeof(WORD)); if (nSize == 0) { clear(); return; } char* pBuffer = new char[nSize]; oStream.read(pBuffer, nSize); assign(pBuffer, nSize); delete[] pBuffer; } template static String ToString(const T& val) { std::ostringstream os; os << val; return os.str(); } template static String ToStringHex(const T& val) { std::ostringstream os; os << std::hex << val; return os.str(); } template static void FromString(const String& str, T& val) { std::istringstream is(str); is >> val; } template static T FromString(const String& str, const T& def) { T val(def); FromString(str, val); return val; } template static T FromString(const String& str) { T val; FromString(str, val); return val; } template inline void From(T& val) const { FromString(*this, val); } template inline T From(const T& def) const { T val(def); From(val); return val; } template inline T From() const { T val; From(val); return val; } static int CompareAlphabetically(const void* elem, const void* key) { return _tcscmp(((const String*)elem)->c_str(), ((const String*)key)->c_str()); } static int CompareAlphabeticallyInv(const void* elem, const void* key) { return _tcscmp(((const String*)key)->c_str(), ((const String*)elem)->c_str()); } #ifdef _USE_BOOST protected: // implement BOOST serialization friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int /*version*/) { ar & boost::serialization::base_object(*this); } #endif }; /*----------------------------------------------------------------*/ inline String operator+(const String& lhs, TCHAR rhs) { return std::operator+(lhs, rhs); } inline String operator+(const String& lhs, LPCTSTR rhs) { return std::operator+(lhs, rhs); } inline String operator+(const String& lhs, const std::string& rhs) { return std::operator+(lhs, rhs); } inline String operator+(TCHAR lhs, const String& rhs) { return std::operator+(lhs, rhs); } inline String operator+(LPCTSTR lhs, const String& rhs) { return std::operator+(lhs, rhs); } inline String operator+(const std::string& lhs, const String& rhs) { return std::operator+(lhs, rhs); } inline String operator+(const String& lhs, const String& rhs) { return std::operator+(lhs, rhs); } #ifdef _SUPPORT_CPP11 inline String operator+(String&& lhs, TCHAR rhs) { return std::operator+(std::forward(lhs), rhs); } inline String operator+(String&& lhs, LPCTSTR rhs) { return std::operator+(std::forward(lhs), rhs); } inline String operator+(String&& lhs, const std::string& rhs) { return std::operator+(std::forward(lhs), rhs); } inline String operator+(TCHAR lhs, String&& rhs) { return std::operator+(lhs, std::forward(rhs)); } inline String operator+(LPCTSTR lhs, String&& rhs) { return std::operator+(lhs, std::forward(rhs)); } inline String operator+(const std::string& lhs, String&& rhs) { return std::operator+(lhs, std::forward(rhs)); } inline String operator+(const String& lhs, String&& rhs) { return std::operator+(lhs, std::forward(rhs)); } inline String operator+(String&& lhs, const String& rhs) { return std::operator+(std::forward(lhs), rhs); } inline String operator+(String&& lhs, String&& rhs) { return std::operator+(std::forward(lhs), std::forward(rhs)); } #endif /*----------------------------------------------------------------*/ } // namespace SEACAVE namespace std { //namespace tr1 { // Specializations for unordered containers template <> struct hash : public hash{}; //} // namespace tr1 template <> struct equal_to : public equal_to{}; } // namespace std #endif // __SEACAVE_STRING_H__