📄 static_string.hpp
字号:
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator >=(basic_static_string<C, CCH, T> const &lhs, ss_typename_type_k basic_static_string<C, CCH, T>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator >=(basic_static_string<C, CCH, T> const &lhs, C const *rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
return lhs.compare(rhs) >= 0;
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator >=(ss_typename_type_k basic_static_string<C, CCH, T>::char_type const *lhs, basic_static_string<C, CCH, T> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator >=(C const *lhs, basic_static_string<C, CCH, T> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
return rhs.compare(lhs) <= 0;
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* swapping
*/
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline void swap(basic_static_string<C, CCH, T> &lhs, basic_static_string<C, CCH, T> &rhs)
{
lhs.swap(rhs);
}
/* /////////////////////////////////////////////////////////////////////////
* Shims
*/
#ifndef STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED
/* c_str_ptr_null */
/// \brief Returns the corresponding C-string pointer of \c s, or a null pointer
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline C const *c_str_ptr_null(basic_static_string<C, CCH, T> const &s)
{
return (s.length() == 0) ? 0 : s.c_str();
}
/* c_str_ptr */
/// \brief Returns the corresponding C-string pointer of \c s
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline C const *c_str_ptr(basic_static_string<C, CCH, T> const &s)
{
return s.c_str();
}
/* c_str_data */
/// \brief Returns the corresponding C-string pointer of \c s
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline C const *c_str_data(basic_static_string<C, CCH, T> const &s)
{
return s.data();
}
/* c_str_ptr_len */
/// \brief Returns the length (in characters) of \c s, <b><i>not</i></b> including the null-terminating character
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline ss_size_t c_str_len(basic_static_string<C, CCH, T> const &s)
{
return s.length();
}
/* c_str_ptr_size */
#if 0
/// \brief Returns the size (in bytes) of the contents of \c s, <b><i>not</i></b> including the null-terminating character
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline ss_size_t c_str_size(basic_static_string<C, CCH, T> const &s)
{
return c_str_len(s) * sizeof(C);
}
#endif /* 0 */
#endif /* !STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED */
template< ss_typename_param_k S
, ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline S &operator <<(S & s, basic_static_string<C, CCH, T> const &str)
{
s << str.c_str();
return s;
}
/* /////////////////////////////////////////////////////////////////////////
* Unit-testing
*/
#ifdef STLSOFT_UNITTEST
# include "./unittest/static_string_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* /////////////////////////////////////////////////////////////////////////
* Implementation
*/
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline ss_typename_type_k basic_static_string<C, CCH, T>::size_type basic_static_string<C, CCH, T>::length_() const
{
if(m_length == static_cast<ss_size_t>(-1))
{
ss_size_t &_m_length = const_cast<class_type *>(this)->m_length;
_m_length = traits_type::length(m_buffer);
}
return m_length;
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline ss_bool_t basic_static_string<C, CCH, T>::is_valid() const
{
char_type const *b = &m_buffer[0];
char_type const *const e = &m_buffer[STLSOFT_NUM_ELEMENTS(m_buffer) - 1];
for(; b != e && '\0' != *b; ++b)
{}
if(b == e)
{
#ifdef STLSOFT_UNITTEST
printf("%08x: string contents have been overwritten! Contents=[%*s]\n", static_cast<unsigned>(reinterpret_cast<size_t>(this)), static_cast<int>(max_size()), &m_buffer[0]);
#endif /* STLSOFT_UNITTEST */
return false;
}
else if(m_length != static_cast<ss_size_t>(-1) &&
m_length > max_size())
{
#ifdef STLSOFT_UNITTEST
printf("%08x: length (%ld) greater than maximum allowed (%ld)\n", static_cast<unsigned>(reinterpret_cast<size_t>(this)), static_cast<long>(m_length), static_cast<long>(max_size()));
#endif /* STLSOFT_UNITTEST */
return false;
}
else if(m_length != static_cast<ss_size_t>(-1) &&
'\0' != m_buffer[m_length])
{
#ifdef STLSOFT_UNITTEST
printf("%08x: string not nul-terminated at index (%ld); maximum allowed (%ld)\n", static_cast<unsigned>(reinterpret_cast<size_t>(this)), static_cast<long>(m_length), static_cast<long>(max_size()));
#endif /* STLSOFT_UNITTEST */
return false;
}
return true;
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string()
: m_length(static_cast<ss_size_t>(-1))
{
m_buffer[0] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(class_type const &rhs)
: m_length(rhs.length())
{
traits_type::copy(m_buffer, rhs.m_buffer, rhs.length());
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
#ifdef _DEBUG
//printf("*this(%s, %d)\n", &m_buffer[0], m_length);
#endif /* _DEBUG */
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(class_type const &rhs, size_type pos)
: m_length(rhs.length() - pos)
{
traits_type::copy(m_buffer, rhs.m_buffer + pos, m_length);
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(class_type const &rhs, size_type pos, size_type n)
: m_length(n)
{
STLSOFT_MESSAGE_ASSERT("incident string too large for static_string construction", !(max_size() < n));
//printf("ctor(%s, %d, %d = %.*s)\n", rhs.c_str(), pos, n, n, rhs.c_str() + pos);
traits_type::copy(m_buffer, rhs.m_buffer + pos, n);
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(char_type const *s)
: m_length((NULL != s) ? traits_type::length(s) : 0)
{
STLSOFT_MESSAGE_ASSERT("incident string too large for static_string construction", !(max_size() < m_length));
//printf("Length: %u\n", m_length);
traits_type::copy(m_buffer, s, m_length);
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(char_type const *s, size_type n)
: m_length(n)
{
STLSOFT_MESSAGE_ASSERT("incident string too large for static_string construction", !(max_size() < n));
traits_type::copy(m_buffer, s, n);
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(size_type n, char_type c)
: m_length(n)
{
traits_type::assign(m_buffer, n, c);
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
#if !defined(STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::basic_static_string(char_type const *f, char_type const *t)
: m_length(t - f)
{
STLSOFT_MESSAGE_ASSERT("incident string too large for static_string construction", !(max_size() < m_length));
traits_type::copy(m_buffer, f, m_length);
m_buffer[m_length] = '\0';
m_buffer[max_size()] = '\0';
STLSOFT_ASSERT(is_valid());
}
#endif /* STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline basic_static_string<C, CCH, T>::~basic_static_string() stlsoft_throw_0()
{
STLSOFT_ASSERT(is_valid());
}
// Assignment
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline ss_typename_type_k basic_static_string<C, CCH, T>::class_type &basic_static_string<C, CCH, T>::assign(const ss_typename_type_k basic_static_string<C, CCH, T>::char_type *s)
{
STLSOFT_ASSERT(is_valid());
#if 0
m_length = static_cast<ss_size_t>(-1);
traits_type::copy(m_buffer, s, CCH);
m_buffer[max_size()] = '\0';
#else /* ? 0 */
class_type t(s);
t.swap(*this);
#endif /* 0 */
STLSOFT_ASSERT(is_valid());
return *this;
}
template< ss_typename_param_k C
, ss_size_t CCH
, ss_typename_param_k T
>
inline ss_typename_type_k basic_static_string<C, CCH, T>::class_type &basic_static_string<C, CCH, T>::assign(const ss_typename_type_k basic_static_string<C, CCH, T>::char_type *s, ss_typename_type_k basic_static_string<C, CCH, T>::size_type n)
{
STLSOFT_MESSAGE_ASSERT("incident string too large for static_string assignment", !(max_size() < n));
STLSOFT_ASSERT(is_valid());
#if 0
traits_type::copy(m_buffer, s, n);
m_length = n;
m_buffer[m_length] = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -