You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.9 KiB
239 lines
7.9 KiB
//////////////////////////////////////////////////////////////////// |
|
// 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<Base>(rhs)) {} |
|
inline String(String&& rhs) : Base(std::forward<Base>(rhs)) {} |
|
inline String(const String& rhs) : Base(rhs) {} |
|
|
|
inline String& operator=(Base&& rhs) { Base::operator=(std::forward<Base>(rhs)); return *this; } |
|
inline String& operator=(String&& rhs) { Base::operator=(std::forward<Base>(rhs)); return *this; } |
|
#endif |
|
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; } |
|
|
|
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 <class T> |
|
static String ToString(const T& val) { |
|
std::ostringstream os; |
|
os << val; |
|
return os.str(); |
|
} |
|
template <class T> |
|
static String ToStringHex(const T& val) { |
|
std::ostringstream os; |
|
os << std::hex << val; |
|
return os.str(); |
|
} |
|
|
|
template <class T> |
|
static void FromString(const String& str, T& val) { |
|
std::istringstream is(str); |
|
is >> val; |
|
} |
|
template <class T> |
|
static T FromString(const String& str, const T& def) { |
|
T val(def); |
|
FromString(str, val); |
|
return val; |
|
} |
|
template <class T> |
|
static T FromString(const String& str) { |
|
T val; |
|
FromString(str, val); |
|
return val; |
|
} |
|
template <class T> |
|
inline void From(T& val) const { |
|
FromString(*this, val); |
|
} |
|
template <class T> |
|
inline T From(const T& def) const { |
|
T val(def); |
|
From(val); |
|
return val; |
|
} |
|
template <class T> |
|
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<class Archive> |
|
void serialize(Archive& ar, const unsigned int /*version*/) { |
|
ar & boost::serialization::base_object<Base>(*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<String::Base>(lhs), rhs); } |
|
inline String operator+(String&& lhs, LPCTSTR rhs) { return std::operator+(std::forward<String::Base>(lhs), rhs); } |
|
inline String operator+(String&& lhs, const std::string& rhs) { return std::operator+(std::forward<String::Base>(lhs), rhs); } |
|
inline String operator+(TCHAR lhs, String&& rhs) { return std::operator+(lhs, std::forward<String::Base>(rhs)); } |
|
inline String operator+(LPCTSTR lhs, String&& rhs) { return std::operator+(lhs, std::forward<String::Base>(rhs)); } |
|
inline String operator+(const std::string& lhs, String&& rhs) { return std::operator+(lhs, std::forward<String::Base>(rhs)); } |
|
inline String operator+(const String& lhs, String&& rhs) { return std::operator+(lhs, std::forward<String::Base>(rhs)); } |
|
inline String operator+(String&& lhs, const String& rhs) { return std::operator+(std::forward<String::Base>(lhs), rhs); } |
|
inline String operator+(String&& lhs, String&& rhs) { return std::operator+(std::forward<String::Base>(lhs), std::forward<String::Base>(rhs)); } |
|
#endif |
|
/*----------------------------------------------------------------*/ |
|
|
|
} // namespace SEACAVE |
|
|
|
|
|
namespace std { |
|
//namespace tr1 { |
|
// Specializations for unordered containers |
|
template <> struct hash<SEACAVE::String> : public hash<string>{}; |
|
//} // namespace tr1 |
|
template <> struct equal_to<SEACAVE::String> : public equal_to<string>{}; |
|
} // namespace std |
|
|
|
#endif // __SEACAVE_STRING_H__
|
|
|