string: allow cstring tokenisers

This commit is contained in:
Danny Robson 2016-03-18 11:08:12 +11:00
parent 6a1ea8ff29
commit eacd2f6072
3 changed files with 77 additions and 31 deletions

View File

@ -31,37 +31,42 @@ strbegins (const char *restrict str,
///////////////////////////////////////////////////////////////////////////////
tokeniser::tokeniser (const string_type &_value,
value_type _separator):
m_value (_value),
template <typename Iterator>
tokeniser<Iterator>::tokeniser (Iterator _first,
Iterator _last,
value_type _separator):
m_range (_first, _last),
m_separator (_separator)
{ }
//-----------------------------------------------------------------------------
tokeniser::iterator
tokeniser::cbegin (void) const
///////////////////////////////////////////////////////////////////////////////
template <typename Iterator>
typename tokeniser<Iterator>::iterator
tokeniser<Iterator>::cbegin (void) const
{
return iterator (
{m_value.cbegin (), m_value.cend ()},
m_range,
m_separator
);
}
//-----------------------------------------------------------------------------
tokeniser::iterator
tokeniser::cend (void) const
template <typename Iterator>
typename tokeniser<Iterator>::iterator
tokeniser<Iterator>::cend (void) const
{
return iterator (
{m_value.cend (), m_value.cend ()},
{m_range.cend (), m_range.cend ()},
m_separator
);
}
///////////////////////////////////////////////////////////////////////////////
tokeniser::iterator::iterator (range_type _range, value_type _separator):
template <typename Iterator>
tokeniser<Iterator>::iterator::iterator (range_type _range, value_type _separator):
m_separator (_separator),
m_range (_range.cbegin (),
std::find (_range.cbegin (),
@ -72,8 +77,9 @@ tokeniser::iterator::iterator (range_type _range, value_type _separator):
//-----------------------------------------------------------------------------
tokeniser::iterator
tokeniser::iterator::operator++ (int)
template <typename Iterator>
typename tokeniser<Iterator>::iterator
tokeniser<Iterator>::iterator::operator++ (int)
{
iterator res(*this);
++*this;
@ -82,8 +88,9 @@ tokeniser::iterator::operator++ (int)
//-----------------------------------------------------------------------------
tokeniser::iterator&
tokeniser::iterator::operator++ (void)
template <typename Iterator>
typename tokeniser<Iterator>::iterator&
tokeniser<Iterator>::iterator::operator++ (void)&
{
auto newend = m_range.cend ();
if (newend != m_end) {
@ -101,16 +108,48 @@ tokeniser::iterator::operator++ (void)
//-----------------------------------------------------------------------------
tokeniser::iterator::range_type
tokeniser::iterator::operator* (void) const
template <typename Iterator>
typename tokeniser<Iterator>::range_type
tokeniser<Iterator>::iterator::operator* (void) const
{
return m_range;
}
//-----------------------------------------------------------------------------
template <typename Iterator>
bool
tokeniser::iterator::operator== (const iterator &rhs) const
tokeniser<Iterator>::iterator::operator== (const iterator &rhs) const
{
return m_range == rhs.m_range && m_separator == rhs.m_separator;
}
//-----------------------------------------------------------------------------
template <typename Iterator>
bool
tokeniser<Iterator>::iterator::operator!= (const iterator &rhs) const
{
return !(*this == rhs);
}
///////////////////////////////////////////////////////////////////////////////
tokeniser<std::string::const_iterator>
util::make_tokeniser (const std::string &value, std::string::value_type separator)
{
return tokeniser<std::string::const_iterator> (value.cbegin (), value.cend (), separator);
}
//-----------------------------------------------------------------------------
tokeniser<const char*>
util::make_tokeniser (const char *str, char separator)
{
return tokeniser<const char*> (str, str + strlen (str), separator);
}
///////////////////////////////////////////////////////////////////////////////
template struct util::tokeniser<std::string::const_iterator>;
template struct util::tokeniser<const char*>;

View File

@ -26,31 +26,32 @@ strbegins(const char *restrict str,
namespace util {
template <typename Iterator>
struct tokeniser {
public:
using string_type = std::string;
using value_type = string_type::value_type;
using value_type = typename std::iterator_traits<Iterator>::value_type;
using range_type = view<Iterator>;
tokeniser (const std::string &value, char separator);
tokeniser (std::string &&value, char separator) = delete;
tokeniser (Iterator first, Iterator last, value_type separator);
struct iterator {
public:
using range_type = util::view<string_type::const_iterator>;
iterator (range_type range, char separator);
iterator operator++ (int);
iterator& operator++ (void);
iterator& operator++ (void)&;
range_type operator* (void) const;
bool operator== (const iterator&) const;
bool operator!= (const iterator&) const;
private:
const value_type m_separator;
iterator (range_type range, value_type separator);
const value_type m_separator;
range_type m_range;
string_type::const_iterator m_end;
Iterator m_end;
friend tokeniser;
};
iterator cbegin (void) const;
@ -60,9 +61,15 @@ namespace util {
iterator end (void) const;
private:
const string_type &m_value;
const range_type m_range;
const value_type m_separator;
};
tokeniser<std::string::const_iterator> make_tokeniser (const std::string&, std::string::value_type);
tokeniser<std::string::const_iterator> make_tokeniser (std::string&&, std::string::value_type) = delete;
tokeniser<const char*> make_tokeniser (const char*, char);
}
#endif // __UTIL_STRING_HPP

View File

@ -18,7 +18,7 @@ main (int, char**)
};
std::string str (std::cbegin (csv), std::cbegin (csv) + elems (csv));
auto tok = util::tokeniser (str, ',');
auto tok = util::make_tokeniser (str, ',');
auto t_cursor = tok.cbegin ();
auto v_cursor = std::cbegin (values);