📄 string_view.hpp
字号:
/// \name Members
/// @{
private:
size_type m_length; // The number of elements in the view
char_type const *m_base; // Pointer to the first element in the view, or NULL for a null view
char_type *m_cstr; // Pointer to a nul-terminated copy of the view, at the time of the c_str() call. Will be NULL before c_str() is called
/// @}
};
/* /////////////////////////////////////////////////////////////////////////
* Typedefs
*/
#ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
typedef basic_string_view<ss_char_a_t> string_view;
typedef basic_string_view<ss_char_w_t> wstring_view;
#else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
typedef basic_string_view<ss_char_a_t
, stlsoft_char_traits<ss_char_a_t>
, allocator_selector<ss_char_a_t>::allocator_type
> string_view;
typedef basic_string_view<ss_char_w_t
, stlsoft_char_traits<ss_char_w_t>
, allocator_selector<ss_char_w_t>::allocator_type
> wstring_view;
#endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
/* /////////////////////////////////////////////////////////////////////////
* Operators
*/
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
// operator ==
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t operator ==(basic_string_view<C, T, A> const &lhs, basic_string_view<C, T, A> const &rhs)
{
return lhs.equal(rhs);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator ==(basic_string_view<C, T, A> const &lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator ==(basic_string_view<C, T, A> const &lhs, C const *rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
return lhs.equal(rhs, rhs_len);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator ==(ss_typename_type_k basic_string_view<C, T, A>::char_type const *lhs, basic_string_view<C, T, A> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator ==(C *lhs, basic_string_view<C, T, A> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
size_type lhs_len = (NULL == lhs) ? 0 : traits_type::length(lhs);
return rhs.equal(lhs, lhs_len);
}
// operator !=
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t operator !=(basic_string_view<C, T, A> const &lhs, basic_string_view<C, T, A> const &rhs)
{
return !lhs.equal(rhs);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator !=(basic_string_view<C, T, A> const &lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator !=(basic_string_view<C, T, A> const &lhs, C const *rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
return !lhs.equal(rhs, rhs_len);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator !=(ss_typename_type_k basic_string_view<C, T, A>::char_type const *lhs, basic_string_view<C, T, A> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator !=(C const *lhs, basic_string_view<C, T, A> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
size_type lhs_len = (NULL == lhs) ? 0 : traits_type::length(lhs);
return !rhs.equal(lhs, lhs_len);
}
// operator <
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t operator <(basic_string_view<C, T, A> const &lhs, basic_string_view<C, T, A> const &rhs)
{
return lhs.compare(rhs) < 0;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator <(basic_string_view<C, T, A> const &lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator <(basic_string_view<C, T, A> 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_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator <(ss_typename_type_k basic_string_view<C, T, A>::char_type const *lhs, basic_string_view<C, T, A> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator <(C const *lhs, basic_string_view<C, T, A> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
return rhs.compare(lhs) > 0;
}
// operator <=
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t operator <=(basic_string_view<C, T, A> const &lhs, basic_string_view<C, T, A> const &rhs)
{
return lhs.compare(rhs) <= 0;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator <=(basic_string_view<C, T, A> const &lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator <=(basic_string_view<C, T, A> 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_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator <=(ss_typename_type_k basic_string_view<C, T, A>::char_type const *lhs, basic_string_view<C, T, A> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator <=(C const *lhs, basic_string_view<C, T, A> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
return rhs.compare(lhs) >= 0;
}
// operator >
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t operator >(basic_string_view<C, T, A> const &lhs, basic_string_view<C, T, A> const &rhs)
{
return lhs.compare(rhs) > 0;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator >(basic_string_view<C, T, A> const &lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator >(basic_string_view<C, T, A> 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_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator >(ss_typename_type_k basic_string_view<C, T, A>::char_type const *lhs, basic_string_view<C, T, A> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator >(C const *lhs, basic_string_view<C, T, A> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
return rhs.compare(lhs) < 0;
}
// operator >=
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t operator >=(basic_string_view<C, T, A> const &lhs, basic_string_view<C, T, A> const &rhs)
{
return lhs.compare(rhs) >= 0;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator >=(basic_string_view<C, T, A> const &lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const *rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator >=(basic_string_view<C, T, A> 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_typename_param_k T
, ss_typename_param_k A
>
#ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
inline ss_bool_t operator >=(ss_typename_type_k basic_string_view<C, T, A>::char_type const *lhs, basic_string_view<C, T, A> const &rhs)
#else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
inline ss_bool_t operator >=(C const *lhs, basic_string_view<C, T, A> const &rhs)
#endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
{
return rhs.compare(lhs) <= 0;
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* IOStream compatibility
*/
template< ss_typename_param_k S
, ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline S &operator <<(S & s, basic_string_view<C, T, A> const &str)
{
s.write(str.data(), static_cast<ss_streamoff_t>(str.length()));
return s;
}
/* /////////////////////////////////////////////////////////////////////////
* Unit-testing
*/
#ifdef STLSOFT_UNITTEST
# include "./unittest/string_view_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* /////////////////////////////////////////////////////////////////////////
* Implementation
*/
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
// Implementation
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_string_view<C, T, A>::char_type const *basic_string_view<C, T, A>::empty_string_()
{
// This character array is initialised to 0, which conveniently happens to
// be the empty string, by the module/application load, so it is
// guaranteed to be valid, and there are no threading/race conditions
static char_type s_empty[1];
STLSOFT_ASSERT(s_empty[0] == '\0'); // Paranoid check
return s_empty;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_sint_t basic_string_view<C, T, A>::compare_( ss_typename_type_k basic_string_view<C, T, A>::value_type const *lhs
, ss_typename_type_k basic_string_view<C, T, A>::size_type lhs_len
, ss_typename_type_k basic_string_view<C, T, A>::value_type const *rhs
, ss_typename_type_k basic_string_view<C, T, A>::size_type rhs_len)
{
size_type cmp_len = (lhs_len < rhs_len) ? lhs_len : rhs_len;
ss_int_t result = traits_type::compare(lhs, rhs, cmp_len);
if(0 == result)
{
result = static_cast<ss_int_t>(lhs_len) - static_cast<ss_int_t>(rhs_len);
}
return result;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ void basic_string_view<C, T, A>::close_() stlsoft_throw_0()
{
STLSOFT_ASSERT(NULL != m_cstr);
allocator_type &ator = *this;
ator.deallocate(m_cstr, 1 + m_length);
#if defined(STLSOFT_COMPILER_IS_BORLAND)
STLSOFT_SUPPRESS_UNUSED(ator);
#endif /* compiler */
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ void basic_string_view<C, T, A>::close_set_null_() stlsoft_throw_0()
{
if(NULL != m_cstr)
{
close_();
m_cstr = NULL;
}
}
/// Invariant
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t basic_string_view<C, T, A>::is_valid() const
{
// NOTE: Must not call any methods or ctors in this function!!
if( 0 == m_length &&
NULL != m_cstr)
{
return false; // If the slice is empty, there should be no m_cstr
}
if( 0 != m_length &&
NULL == m_base)
{
return false; // If the slice is non-empty, m_base should not be NULL
}
return true;
}
// Construction
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_string_view<C, T, A>::basic_string_view()
: m_length(0)
, m_base(NULL)
, m_cstr(NULL)
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_string_view<C, T, A>::basic_string_view(basic_string_view<C, T, A> const &rhs)
: m_length(rhs.m_length)
, m_base(rhs.m_base)
, m_cstr(NULL)
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_string_view<C, T, A>::basic_string_view(basic_string_view<C, T, A> const &rhs, ss_typename_type_k basic_string_view<C, T, A>::size_type pos)
: m_length(rhs.m_length - pos)
, m_base(&rhs[pos]) // Use this so we get the debug-time invariant checking on the validity of pos
, m_cstr(NULL)
{
STLSOFT_ASSERT(pos <= rhs.m_length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -