📄 simple_string.hpp
字号:
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::string_buffer const* basic_simple_string<C, T, A>::string_buffer_from_member_pointer_(ss_typename_type_k basic_simple_string<C, T, A>::member_const_pointer m)
{
STLSOFT_MESSAGE_ASSERT("Attempt to convert a null string_buffer in basic_simple_string", NULL != m);
#ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
return m;
#else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
return reinterpret_cast<string_buffer const*>(ptr_byte_offset(m, -static_cast<ss_ptrdiff_t>(STLSOFT_RAW_OFFSETOF(string_buffer, contents))));
#endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::member_pointer_from_string_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::string_buffer *b)
{
#ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
return b;
#else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
return b->contents;
#endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::alloc_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type const* s
, ss_typename_type_k basic_simple_string<C, T, A>::size_type capacity
, ss_typename_type_k basic_simple_string<C, T, A>::size_type length)
{
// Pre-conditions
STLSOFT_ASSERT(length <= capacity);
STLSOFT_ASSERT(length >= traits_type::length_max_null(s, length));
const ss_size_t members = (STLSOFT_RAW_OFFSETOF(string_buffer, contents) + (sizeof(char_type) - 1)) / sizeof(char_type);
capacity += 1; // For null terminator
capacity += members; // Include the internal members.
capacity = (alloc_quantum + capacity) & ~alloc_quantum; // Round up to (alloc_quantum + 1)
byte_ator_type byte_ator;
ss_byte_t *raw_buffer = byte_ator.allocate(capacity * sizeof(char_type), NULL);
string_buffer *buffer = sap_cast<string_buffer*>(raw_buffer);
if(NULL != buffer)
{
if(NULL == s)
{
STLSOFT_ASSERT(0 == length);
buffer->contents[0] = traits_type::to_char_type(0);
}
else
{
traits_type::copy(buffer->contents, s, length);
buffer->contents[length] = traits_type::to_char_type(0);
}
buffer->length = length;
buffer->capacity = capacity - members;
return member_pointer_from_string_buffer_(buffer);
}
return NULL;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::alloc_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type const* s
, ss_typename_type_k basic_simple_string<C, T, A>::size_type cch)
{
size_type length = traits_type::length_max_null(s, cch);
size_type capacity = cch;
if(cch < length)
{
length = cch;
}
return alloc_buffer_(s, capacity, length);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::alloc_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type const* s)
{
member_pointer res;
if(NULL == s)
{
res = NULL;
}
else
{
size_type len = traits_type::length(s);
res = alloc_buffer_(s, len, len);
}
return res;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::copy_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::member_pointer m)
{
if(NULL != m)
{
byte_ator_type byte_ator;
string_buffer *buffer = string_buffer_from_member_pointer_(m);
ss_size_t cb = buffer->capacity * sizeof(char_type) + STLSOFT_RAW_OFFSETOF(string_buffer, contents);
ss_byte_t *raw_buffer = byte_ator.allocate(cb, NULL);
string_buffer *new_buffer = sap_cast<string_buffer*>(raw_buffer);
if(NULL != new_buffer)
{
memcpy(new_buffer, buffer, cb);
return member_pointer_from_string_buffer_(new_buffer);
}
}
return NULL;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ void basic_simple_string<C, T, A>::destroy_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::string_buffer *buffer)
{
byte_ator_type byte_ator;
byte_ator.deallocate(sap_cast<ss_byte_t*>(buffer), 0);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ void basic_simple_string<C, T, A>::destroy_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type *s)
{
destroy_buffer_(string_buffer_from_member_pointer_(s));
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_typename_type_k basic_simple_string<C, T, A>::pointer basic_simple_string<C, T, A>::begin_()
{
return char_pointer_from_member_pointer_(m_buffer);
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_typename_type_k basic_simple_string<C, T, A>::pointer basic_simple_string<C, T, A>::end_()
{
return begin_() + length();
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline ss_bool_t basic_simple_string<C, T, A>::is_valid() const
{
if(NULL != m_buffer)
{
string_buffer const* buffer = string_buffer_from_member_pointer_(m_buffer);
if(buffer->capacity < 1)
{
#if defined(STLSOFT_UNITTEST) || \
defined(STLSOFT_PRINT_CONTRACT_VIOLATION_DETAILS)
printf("%08x: capacity (%u) < 1\n", static_cast<unsigned>(reinterpret_cast<ss_size_t>(this)), static_cast<unsigned>(buffer->capacity));
#endif /* STLSOFT_UNITTEST */
return false;
}
else if(buffer->capacity < buffer->length)
{
#if defined(STLSOFT_UNITTEST) || \
defined(STLSOFT_PRINT_CONTRACT_VIOLATION_DETAILS)
printf("%08x: capacity (%u) < length (%u, %08x)\n", static_cast<unsigned>(reinterpret_cast<ss_size_t>(this)), static_cast<unsigned>(buffer->capacity), static_cast<unsigned>(buffer->length), static_cast<unsigned>(buffer->length));
#endif /* STLSOFT_UNITTEST */
return false;
}
else
{
size_type len = traits_type::length(buffer->contents);
if(buffer->length < len)
{
#if defined(STLSOFT_UNITTEST) || \
defined(STLSOFT_PRINT_CONTRACT_VIOLATION_DETAILS)
printf("%08x: length (%u) < length() (%u, %08x)\n", static_cast<unsigned>(reinterpret_cast<ss_size_t>(this)), static_cast<unsigned>(buffer->length), static_cast<unsigned>(len), static_cast<unsigned>(len));
#endif /* STLSOFT_UNITTEST */
return false;
}
}
}
return true;
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::char_type const* basic_simple_string<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;
}
// Construction
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string()
: m_buffer(NULL)
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string(class_type const& rhs)
: m_buffer(copy_buffer_(rhs.m_buffer))
{
STLSOFT_ASSERT(rhs.is_valid());
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string( ss_typename_type_k basic_simple_string<C, T, A>::class_type const& rhs
, ss_typename_type_k basic_simple_string<C, T, A>::size_type pos)
: m_buffer(alloc_buffer_(&rhs[pos]))
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string( ss_typename_type_k basic_simple_string<C, T, A>::class_type const& rhs
, ss_typename_type_k basic_simple_string<C, T, A>::size_type pos
, ss_typename_type_k basic_simple_string<C, T, A>::size_type cch)
: m_buffer(alloc_buffer_(&rhs[pos], cch, minimum(cch, rhs.length() - pos)))
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string(ss_typename_type_k basic_simple_string<C, T, A>::char_type const* s) // No, not explicit. Sigh
: m_buffer(alloc_buffer_(s))
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string( ss_typename_type_k basic_simple_string<C, T, A>::char_type const* s
, ss_typename_type_k basic_simple_string<C, T, A>::size_type cch)
: m_buffer(alloc_buffer_(s, cch))
{
STLSOFT_ASSERT(is_valid());
}
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string( ss_typename_type_k basic_simple_string<C, T, A>::size_type cch
, ss_typename_type_k basic_simple_string<C, T, A>::char_type ch)
: m_buffer(NULL)
{
STLSOFT_ASSERT(is_valid());
assign(cch, ch);
}
#if !defined(STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
template< ss_typename_param_k C
, ss_typename_param_k T
, ss_typename_param_k A
>
inline basic_simple_string<C, T, A>::basic_simple_string( ss_typename_type_k basic_simple_string<C, T, A>::char_type const* first
, ss_typename_type_k basic_simple_string<C, T, A>::char_type const* last)
: m_buffer(alloc_buffer_(first, last - first))
{
STLSOFT_ASSER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -