📄 string_tokeniser.hpp
字号:
/// Returns the length of the delimiter
static ss_size_t get_length_(ss_char_w_t const /* delim */)
{
return 1;
}
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
static const_iterator advance_(const_iterator it, delimiter_type const& delim)
{
return it + get_length_(delim);
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/// @}
/// \name Operations
/// @{
public:
/// Evaluates whether the delimiter and the sequence are not equivalent to the extent of the delimiter
static ss_bool_t not_equal(delimiter_type const& delim, const_iterator &it)
{
return !is_equal_(delim, it);
}
/// Returns the length of the delimiter
static ss_size_t length(delimiter_type const& delim)
{
return get_length_(delim);
}
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
static ss_bool_t test_start_token_advance(const_iterator &it, const_iterator end, delimiter_type const& delim)
{
return is_equal_(delim, it) ? (it = advance_(it, delim), true) : false;
}
static ss_bool_t test_end_token_advance(const_iterator &it, const_iterator end, delimiter_type const& delim)
{
return is_equal_(delim, it) ? (it = advance_(it, delim), true) : false;
}
static const_iterator nonskip_move_to_start(const_iterator it, const_iterator end, delimiter_type const& delim)
{
return it;
}
static ss_bool_t test_end_token(const_iterator it, const_iterator end, delimiter_type const& delim)
{
return is_equal_(delim, it);
}
static const_iterator find_next_start(const_iterator it, const_iterator end, delimiter_type const& delim)
{
return advance_(it, delim);
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/// @}
};
/** \brief A class template that provides string tokenising behaviour
*
* \ingroup group__library__string
*
* This class takes a string, and a delimiter, and fashions a sequence from
* the given string, with each element determined with respect to the
* delimiter
*
* \param S The string type
* \param D The delimiter type (can be a string type or a character type)
* \param B The ignore-blanks type. Defaults to skip_blank_tokens<true>
* \param V The value type (the string type that will be used for the values). Defaults to \c S
* \param T The string type traits type. Defaults to string_tokeniser_type_traits<S, V>
* \param P The tokeniser comparator type. Defaults to string_tokeniser_comparator<D, S, T>
*
* This class template provides tokenising services of a string (of type \c S)
* with a delimiter (of type \c D). The four other template parameters, which are
* defaulted, are used for tailoring the tokenising behaviour for special uses.
*
* The two typical supported tokenising scenarios are:
*
* - tokenising a string with a character (e.g. '\\n')
* - tokenising a string with a string (e.g. "\\r\\n")
*
* More exotic scenarios are supported by customising the comparator and type-traits
* parameters. (See stlsoft::charset_tokeniser.)
*
* <b>1. Tokenising a string with a character.</b>
*
* This uses a specialisation whereby the first template parameter is a string type,
* and the second parameter is a corresponding character type.
*
* The following code shows a specialisation using std::string and char, and
* will output: <b>abc,def,ghi,jkl,</b>
*
\code
stlsoft::string_tokeniser<std::string, char> tokens(":abc::def:ghi:jkl::::::::::", ':');
std::copy(tokens.begin(), tokens.end(), std::ostream_iterator<std::string>(std::cout, ","));
\endcode
*
* The following code shows a specialisation using
* stlsoft::basic_simple_string<wchar_t> and wchar_t, and
* will output: <b>abc-def-ghi-jkl-</b>
*
\code
typedef stlsoft::basic_simple_string<wchar_t> string_t;
string_t s(L"|abc||def|ghi|jkl||||||||||");
stlsoft::string_tokeniser<string_t, wchar_t> tokens(s, L'|');
std::copy(tokens.begin(), tokens.end(), std::ostream_iterator<string_t, wchar_t>(std::wcout, L"-"));
\endcode
*
* Optionally, you can stipulate that the blanks be retained by specifying the third
* template parameter as skip_blank_tokens<false>, as in the following, which will
* output: <b>,abc,,def,ghi,jkl,,,,,,,,,,</b>
*
\code
stlsoft::string_tokeniser< std::string
, char
, stlsoft::skip_blank_tokens<false>
> tokens(":abc::def:ghi:jkl::::::::::", ':');
std::copy(tokens.begin(), tokens.end(), std::ostream_iterator<std::string>(std::cout, ","));
\endcode
*
* \note The tokeniser uses \ref group__concept__shim__string_access "String Access Shims" to elicit the
* string from the given type, so any type that for which shims are defined can be passed to the
* constructor, as in the following, which will output: <b>abc;def;ghi;jkl;</b>
*
\code
#include <stlsoft/string/string_tokeniser.hpp>
#include <winstl/shims/access/string.hpp>
#include <iostream>
#include <iterator>
int main()
{
HWND hwndButton = ::CreateWindowEx(0, "BUTTON", "+abc++def+ghi+jkl++++++++++", 0, 0, 0, 0, 0, NULL, (HMENU)0, NULL, NULL);
stlsoft::string_tokeniser< std::string
, char
, stlsoft::skip_blank_tokens<true>
> tokens(hwndButton, '+');
std::copy(tokens.begin(), tokens.end(), std::ostream_iterator<std::string>(std::cout, ";"));
return 0;
}
\endcode
*
* <b>2. Tokenising a string with a string.</b>
*
* This uses a specialisation whereby the first template parameter is a string type,
* and the second parameter is a corresponding string type.
*
* The following code shows a specialisation using std::string and std::string, and
* will output: <b>abc,def,ghi,jkl,</b>
*
\code
stlsoft::string_tokeniser<std::string, std::string> tokens("\r\nabc\r\n\r\ndef\r\nghi\r\njkl\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", "\r\n");
std::copy(tokens.begin(), tokens.end(), std::ostream_iterator<std::string>(std::cout, ","));
\endcode
*/
template< ss_typename_param_k S
, ss_typename_param_k D
#ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
, ss_typename_param_k B = skip_blank_tokens<true>
, ss_typename_param_k V = S
, ss_typename_param_k T = string_tokeniser_type_traits<S, V>
, ss_typename_param_k P = string_tokeniser_comparator<D, S, T>
#else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
, ss_typename_param_k B
, ss_typename_param_k V
, ss_typename_param_k T
, ss_typename_param_k P
#endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
>
class string_tokeniser
: public stl_collection_tag
{
/// \name Member Types
/// @{
public:
/// The current parameterisation of the type
typedef string_tokeniser<S, D, B, V, T, P> class_type;
/// This tokeniser parameterisation
typedef string_tokeniser<S, D, B, V, T, P> tokeniser_type;
/// The sequence string type
typedef S string_type;
/// The delimiter type
typedef D delimiter_type;
/// The blanks policy type
typedef B blanks_policy_type;
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
typedef B ignore_blanks_type;
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/// The value type
typedef V value_type;
/// The traits type
typedef T traits_type;
/// The tokeniser comparator type
typedef P comparator_type;
/// The character type
typedef ss_typename_type_k traits_type::value_type char_type;
/// The size type
///
/// \note This no longer relies on a size_type member type of the traits type (T). It is defined
/// as size_t
typedef ss_size_t size_type;
/// The difference type
///
/// \note This no longer relies on a difference_type member type of the traits type (T). It is defined
/// as ptrdiff_t
typedef ss_ptrdiff_t difference_type;
/// The non-mutating (const) reference type
typedef const value_type const_reference;
/// The non-mutating (const) iterator type
class const_iterator;
/// @}
/// \name Construction
/// @{
public:
/// Tokenise the given C-string with the given delimiter
///
/// \param psz Pointer to C-string whose contents will be tokenised
/// \param delim The delimiter to perform the tokenisation
///
/// \note The tokeniser class takes a copy of \c psz. It does not alter the contents of \c psz
string_tokeniser(char_type const* psz, delimiter_type const& delim)
: m_str(psz)
, m_delimiter(delim)
{
STLSOFT_MESSAGE_ASSERT("Delimiter of zero-length", 0 != comparator_type::length(m_delimiter));
STLSOFT_ASSERT(is_valid());
}
// Define the string_type overload if there member template ctors are not supported, or
// they are correctly discriminated
#if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED)
/// Tokenise the given string with the given delimiter
///
/// \param str The string whose contents will be tokenised
/// \param delim The delimiter to perform the tokenisation
///
/// \note The tokeniser class takes a copy of \c str. It does not alter the contents of \c str
string_tokeniser(string_type const& str, delimiter_type const& delim)
: m_str(str)
, m_delimiter(delim)
{
STLSOFT_MESSAGE_ASSERT("Delimiter of zero-length", 0 != comparator_type::length(m_delimiter));
STLSOFT_ASSERT(is_valid());
}
#endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */
// Define the template overload if member template ctors are supported
#if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT)
/// Tokenise the given string with the given delimiter
///
/// \param str The string whose contents will be tokenised
/// \param delim The delimiter to perform the tokenisation
///
/// \note The tokeniser class takes a copy of \c str. It does not alter the contents of \c str
template <ss_typename_param_k S1>
string_tokeniser(S1 const& str, delimiter_type const& delim)
: m_str(c_str_data(str), c_str_len(str))
, m_delimiter(delim)
{
STLSOFT_MESSAGE_ASSERT("Delimiter of zero-length", 0 != comparator_type::length(m_delimiter));
STLSOFT_ASSERT(is_valid());
}
#endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
/// Tokenise the specified length of the given string with the given delimiter
///
/// \param psz Pointer to C-string whose contents will be tokenised
/// \param cch The number of characters in \c psz to use
/// \param delim The delimiter to perform the tokenisation
///
/// \note The tokeniser class takes a copy of \c psz. It does not alter the contents of \c psz
string_tokeniser(char_type const* psz, size_type cch, delimiter_type const& delim)
: m_str(psz, cch)
, m_delimiter(delim)
{
STLSOFT_MESSAGE_ASSERT("Delimiter of zero-length", 0 != comparator_type::length(m_delimiter));
STLSOFT_ASSERT(is_valid());
}
#if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED)
/// \brief Tokenise the given range with the given delimiter
///
/// \param from The start of the asymmetric range to tokenise
/// \param to The start of the asymmetric range to tokenise
/// \param delim The delimiter to use
string_tokeniser(char_type const* from, char_type const* to, delimiter_type const& delim)
: m_str(from, to)
, m_delimiter(delim)
{
STLSOFT_MESSAGE_ASSERT("Delimiter of zero-length", 0 != comparator_type::length(m_delimiter));
STLSOFT_ASSERT(is_valid());
}
#endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */
#if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT)
/// Tokenise the given range with the given delimiter
///
/// \param from The start of the asymmetric range to tokenise
/// \param to The start of the asymmetric range to tokenise
/// \param delim The delimiter to use
template <ss_typename_param_k I>
string_tokeniser(I from, I to, delimiter_type const& delim)
: m_str(from, to)
, m_delimiter(delim)
{
STLSOFT_MESSAGE_ASSERT("Delimiter of zero-length", 0 != comparator_type::length(m_delimiter));
STLSOFT_ASSERT(is_valid());
}
#endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
/// @}
/// \name Iteration
/// @{
public:
/// Iterator for string_tokeniser, supporting the Forward Iterator concept
class const_iterator
: public iterator_base< stlsoft_ns_qual_std(forward_iterator_tag)
, value_type
, ss_ptrdiff_t
, void
, value_type
>
{
/// \name Member Types
/// @{
public:
/// The type
typedef const_iterator class_type;
#if ( defined(STLSOFT_COMPILER_IS_DMC) && \
__DMC__ <= 0x0843) || \
defined(STLSOFT_COMPILER_IS_MSVC)
/// The delimiter type
typedef delimiter_type delimiter_type;
/// The value type
typedef value_type value_type;
/// The traits type
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -