⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdstring.h

📁 FastDb是高效的内存数据库系统
💻 H
📖 第 1 页 / 共 5 页
字号:
#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 )
 #define Q172398(x) (x).erase()
#else
 #define Q172398(x)
#endif

// =============================================================================
// INLINE FUNCTIONS ON WHICH CSTDSTRING RELIES
//
// Usually for generic text mapping, we rely on preprocessor macro definitions
// to map to string functions.  However the CStdStr<> template cannot use
// macro-based generic text mappings because its character types do not get
// resolved until template processing which comes AFTER macro processing.  In
// other words, UNICODE is of little help to us in the CStdStr template
//
// Therefore, to keep the CStdStr declaration simple, we have these inline
// functions.  The template calls them often.  Since they are inline (and NOT
// exported when this is built as a DLL), they will probably be resolved away
// to nothing.
//
// Without these functions, the CStdStr<> template would probably have to broken
// out into two, almost identical classes.  Either that or it would be a huge,
// convoluted mess, with tons of "if" statements all over the place checking the
// size of template parameter CT.
//
// In several cases, you will see two versions of each function.  One version is
// the more portable, standard way of doing things, while the other is the
// non-standard, but often significantly faster Visual C++ way.
// =============================================================================

// If they defined SS_NO_REFCOUNT, then we must convert all assignments

#ifdef SS_NO_REFCOUNT
 #define SSREF(x) (x).c_str()
#else
 #define SSREF(x) (x)
#endif

// -----------------------------------------------------------------------------
// sslen: strlen/wcslen wrappers
// -----------------------------------------------------------------------------

template<typename CT>
inline int sslen(const CT* pT)
{
  return 0 == pT ? 0 : std::basic_string<CT>::traits_type::length(pT);
  // return 0 == pT ? 0 : std::char_traits<CT>::length(pT);
}

inline SS_NOTHROW int sslen(const std::string& s)
{
  return s.length();
}

inline SS_NOTHROW int sslen(const std::wstring& s)
{
  return s.length();
}

// -----------------------------------------------------------------------------
// sstolower/sstoupper -- convert characters to upper/lower case
// -----------------------------------------------------------------------------
#if !defined(SS_ANSI) || defined(SS_NOLOCALE)
inline char sstoupper(char ch)
{
  return (char)::toupper(ch);
}

inline wchar_t sstoupper(wchar_t ch)
{
  return (wchar_t)::towupper(ch);
}

inline char sstolower(char ch)
{
  return (char)::tolower(ch);
}

inline wchar_t sstolower(wchar_t ch)
{
  return (wchar_t)::tolower(ch);
}

#else

template<typename CT>
inline CT sstolower(const CT& t, const std::locale& lo =std::locale())
{
  return std::tolower<CT>(t, loc);
}

template<typename CT>
inline CT sstoupper(const CT& t, const std::locale& lo =std::locale())
{
  return std::toupper<CT>(t, loc);
}

#endif

// -----------------------------------------------------------------------------
// ssasn: assignment functions -- assign "sSrc" to "sDst"
// -----------------------------------------------------------------------------
typedef std::string::size_type  SS_SIZETYPE; // just for shorthand, really

typedef std::string::pointer  SS_PTRTYPE;

typedef std::wstring::size_type  SW_SIZETYPE;

typedef std::wstring::pointer  SW_PTRTYPE;

inline void ssasn(std::string& sDst, const std::string& sSrc)
{
  if ( sDst.c_str() != sSrc.c_str() )
  {
    sDst.erase();
    sDst.assign(SSREF(sSrc));
  }
}

inline void ssasn(std::string& sDst, PCSTR pA)
{
  // Watch out for NULLs, as always.

  if ( 0 == pA )
  {
    sDst.erase();
  }

  // If pA actually points to part of sDst, we must NOT erase(), but
  // rather take a substring

  else if ( pA >= sDst.c_str() && pA <= sDst.c_str() + sDst.size() )
  {
    sDst =sDst.substr(static_cast<SS_SIZETYPE>(pA-sDst.c_str()));
  }

  // Otherwise (most cases) apply the assignment bug fix, if applicable
  // and do the assignment

  else
  {
    Q172398(sDst);
    sDst.assign(pA);
  }
}

inline void ssasn(std::string& sDst, const std::wstring& sSrc)
{
  int nLen = sSrc.size();
  sDst.resize(nLen+1);
  StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()), sSrc.c_str(), nLen+1);
  sDst.resize(nLen);
}

inline void ssasn(std::string& sDst, PCWSTR pW)
{
  int nLen = sslen(pW);
  sDst.resize(nLen+1);
  StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()), pW, nLen+1);
  sDst.resize(nLen);
}

inline void ssasn(std::string& sDst, const int nNull)
{
  UNUSED(nNull);
  ASSERT(nNull==0);
  sDst.assign("");
}

inline void ssasn(std::wstring& sDst, const std::wstring& sSrc)
{
  if ( sDst.c_str() != sSrc.c_str() )
  {
    sDst.erase();
    sDst.assign(SSREF(sSrc));
  }
}

inline void ssasn(std::wstring& sDst, PCWSTR pW)
{
  // Watch out for NULLs, as always.

  if ( 0 == pW )
  {
    sDst.erase();
  }

  // If pW actually points to part of sDst, we must NOT erase(), but
  // rather take a substring

  else if ( pW >= sDst.c_str() && pW <= sDst.c_str() + sDst.size() )
  {
    sDst = sDst.substr(static_cast<SW_SIZETYPE>(pW-sDst.c_str()));
  }

  // Otherwise (most cases) apply the assignment bug fix, if applicable
  // and do the assignment

  else
  {
    Q172398(sDst);
    sDst.assign(pW);
  }
}

#undef StrSizeType
inline void ssasn(std::wstring& sDst, const std::string& sSrc)
{
  int nLen = sSrc.size();
  sDst.resize(nLen+1);
  StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()), sSrc.c_str(), nLen+1);
  sDst.resize(nLen);
}

inline void ssasn(std::wstring& sDst, PCSTR pA)
{
  int nLen = sslen(pA);
  sDst.resize(nLen+1);
  StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()), pA, nLen+1);
  sDst.resize(nLen);
}

inline void ssasn(std::wstring& sDst, const int nNull)
{
  UNUSED(nNull);
  ASSERT(nNull==0);
  sDst.assign(L"");
}


// -----------------------------------------------------------------------------
// ssadd: string object concatenation -- add second argument to first
// -----------------------------------------------------------------------------
inline void ssadd(std::string& sDst, const std::wstring& sSrc)
{
  int nSrcLen = sSrc.size();
  int nDstLen = sDst.size();
  int nEndLen = nSrcLen + nDstLen;
  sDst.resize(nEndLen + 1);
  StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()+nDstLen), sSrc.c_str(), nSrcLen);
  sDst.resize(nEndLen);
}

inline void ssadd(std::string& sDst, const std::string& sSrc)
{
  if ( &sDst == &sSrc )
    sDst.reserve(2*sDst.size());

  sDst.append(sSrc.c_str());
}

inline void ssadd(std::string& sDst, PCWSTR pW)
{
  int nSrcLen = sslen(pW);
  int nDstLen = sDst.size();
  int nEndLen = nSrcLen + nDstLen;
  sDst.resize(nEndLen + 1);
  StdCodeCvt(const_cast<SS_PTRTYPE>(sDst.data()+nDstLen), pW, nSrcLen+1);
  sDst.resize(nEndLen);
}

inline void ssadd(std::string& sDst, PCSTR pA)
{
  if ( pA )
  {
    // If the string being added is our internal string or a part of our
    // internal string, then we must NOT do any reallocation without
    // first copying that string to another object (since we're using a
    // direct pointer)

    if ( pA >= sDst.c_str() && pA <= sDst.c_str()+sDst.length())
    {
      if ( sDst.capacity() <= sDst.size()+sslen(pA) )
        sDst.append(std::string(pA));
      else
        sDst.append(pA);
    }
    else
    {
      sDst.append(pA);
    }
  }
}

inline void ssadd(std::wstring& sDst, const std::wstring& sSrc)
{
  if ( &sDst == &sSrc )
    sDst.reserve(2*sDst.size());

  sDst.append(sSrc.c_str());
}

inline void ssadd(std::wstring& sDst, const std::string& sSrc)
{
  int nSrcLen = sSrc.size();
  int nDstLen = sDst.size();
  int nEndLen = nSrcLen + nDstLen;
  sDst.resize(nEndLen+1);
  StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()+nDstLen), sSrc.c_str(), nSrcLen+1);
  sDst.resize(nEndLen);
}

inline void ssadd(std::wstring& sDst, PCSTR pA)
{
  int nSrcLen = sslen(pA);
  int nDstLen = sDst.size();
  int nEndLen = nSrcLen + nDstLen;
  sDst.resize(nEndLen + 1);
  StdCodeCvt(const_cast<SW_PTRTYPE>(sDst.data()+nDstLen), pA, nSrcLen+1);
  sDst.resize(nEndLen);
}

inline void ssadd(std::wstring& sDst, PCWSTR pW)
{
  if ( pW )
  {
    // If the string being added is our internal string or a part of our
    // internal string, then we must NOT do any reallocation without
    // first copying that string to another object (since we're using a
    // direct pointer)

    if ( pW >= sDst.c_str() && pW <= sDst.c_str()+sDst.length())
    {
      if ( sDst.capacity() <= sDst.size()+sslen(pW) )
        sDst.append(std::wstring(pW));
      else
        sDst.append(pW);
    }
    else
    {
      sDst.append(pW);
    }
  }
}


// -----------------------------------------------------------------------------
// ssicmp: comparison (case insensitive )
// -----------------------------------------------------------------------------
#ifdef SS_ANSI
 #ifdef SS_NOLOCALE

template<typename CT>
inline int ssicmp(const CT* pA1, const CT* pA2)
{
  CT f;
  CT l;

  do
  {
    f = sstolower(*(pA1++));
    l = sstolower(*(pA2++));
  }
  while ( (f) && (f == l) );

  return (int)(f - l);
}

#else
template<typename CT>
inline int ssicmp(const CT* pA1, const CT* pA2)
{
  std::locale loc;
  const std::ctype<CT>& ct = SS_USE_FACET(loc, std::ctype<CT>);
  CT f;
  CT l;

  do
  {
    f = ct.tolower(*(pA1++));
    l = ct.tolower(*(pA2++));
  }
  while ( (f) && (f == l) );

  return (int)(f - l);
}

#endif
#else
 #ifdef _MBCS
inline long sscmp(PCSTR pA1, PCSTR pA2)
{
  return _mbscmp((PCUSTR)pA1, (PCUSTR)pA2);
}

inline long ssicmp(PCSTR pA1, PCSTR pA2)
{
  return _mbsicmp((PCUSTR)pA1, (PCUSTR)pA2);
}

#else
inline long sscmp(PCSTR pA1, PCSTR pA2)
{
  return strcmp(pA1, pA2);
}

inline long ssicmp(PCSTR pA1, PCSTR pA2)
{
  return _stricmp(pA1, pA2);
}

#endif
inline long sscmp(PCWSTR pW1, PCWSTR pW2)
{
  return wcscmp(pW1, pW2);
}

inline long ssicmp(PCWSTR pW1, PCWSTR pW2)
{
  return _wcsicmp(pW1, pW2);
}

#endif

// -----------------------------------------------------------------------------
// ssupr/sslwr: Uppercase/Lowercase conversion functions
// -----------------------------------------------------------------------------
#ifdef SS_ANSI
 #ifdef SS_NOLOCALE

template<typename CT>
inline void sslwr(CT* pT, size_t nLen)
{
  for ( CT* p = pT; static_cast<size_t>(p - pT) < nLen; ++p)
    *p = (CT)sstolower(*p);
}

template<typename CT>
inline void ssupr(CT* pT, size_t nLen)
{
  for ( CT* p = pT; static_cast<size_t>(p - pT) < nLen; ++p)
    *p = (CT)sstoupper(*p);
}

#else
template<typename CT>
inline void sslwr(CT* pT, size_t nLen)
{
  SS_USE_FACET(std::locale(), std::ctype<CT>).tolower(pT, pT+nLen);
}

template<typename CT>
inline void ssupr(CT* pT, size_t nLen)
{
  SS_USE_FACET(std::locale(), std::ctype<CT>).toupper(pT, pT+nLen);
}

#endif
#else  // #else we must be on Win32
 #ifdef _MBCS
inline void ssupr(PSTR pA, size_t /*nLen*/)
{
  _mbsupr((PUSTR)pA);
}

inline void sslwr(PSTR pA, size_t /*nLen*/)
{
  _mbslwr((PUSTR)pA);
}

#else
inline void ssupr(PSTR pA, size_t /*nLen*/)
{
  _strupr(pA);
}

inline void sslwr(PSTR pA, size_t /*nLen*/)
{
  _strlwr(pA);
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -