From eacd2f6072d1716490891e616e89116e17df5696 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 18 Mar 2016 11:08:12 +1100 Subject: [PATCH] string: allow cstring tokenisers --- string.cpp | 75 +++++++++++++++++++++++++++++++++++++------------ string.hpp | 31 ++++++++++++-------- test/string.cpp | 2 +- 3 files changed, 77 insertions(+), 31 deletions(-) diff --git a/string.cpp b/string.cpp index 4a467573..7a6c0d18 100644 --- a/string.cpp +++ b/string.cpp @@ -31,37 +31,42 @@ strbegins (const char *restrict str, /////////////////////////////////////////////////////////////////////////////// -tokeniser::tokeniser (const string_type &_value, - value_type _separator): - m_value (_value), +template +tokeniser::tokeniser (Iterator _first, + Iterator _last, + value_type _separator): + m_range (_first, _last), m_separator (_separator) { } -//----------------------------------------------------------------------------- -tokeniser::iterator -tokeniser::cbegin (void) const +/////////////////////////////////////////////////////////////////////////////// +template +typename tokeniser::iterator +tokeniser::cbegin (void) const { return iterator ( - {m_value.cbegin (), m_value.cend ()}, + m_range, m_separator ); } //----------------------------------------------------------------------------- -tokeniser::iterator -tokeniser::cend (void) const +template +typename tokeniser::iterator +tokeniser::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 +tokeniser::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 tokeniser::iterator +tokeniser::iterator::operator++ (int) { iterator res(*this); ++*this; @@ -82,8 +88,9 @@ tokeniser::iterator::operator++ (int) //----------------------------------------------------------------------------- -tokeniser::iterator& -tokeniser::iterator::operator++ (void) +template +typename tokeniser::iterator& +tokeniser::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 tokeniser::range_type +tokeniser::iterator::operator* (void) const { return m_range; } //----------------------------------------------------------------------------- +template bool -tokeniser::iterator::operator== (const iterator &rhs) const +tokeniser::iterator::operator== (const iterator &rhs) const { return m_range == rhs.m_range && m_separator == rhs.m_separator; } + + +//----------------------------------------------------------------------------- +template +bool +tokeniser::iterator::operator!= (const iterator &rhs) const +{ + return !(*this == rhs); +} + + +/////////////////////////////////////////////////////////////////////////////// +tokeniser +util::make_tokeniser (const std::string &value, std::string::value_type separator) +{ + return tokeniser (value.cbegin (), value.cend (), separator); +} + + +//----------------------------------------------------------------------------- +tokeniser +util::make_tokeniser (const char *str, char separator) +{ + return tokeniser (str, str + strlen (str), separator); +} + + +/////////////////////////////////////////////////////////////////////////////// +template struct util::tokeniser; +template struct util::tokeniser; diff --git a/string.hpp b/string.hpp index 99a4b5e5..539bc9fd 100644 --- a/string.hpp +++ b/string.hpp @@ -26,31 +26,32 @@ strbegins(const char *restrict str, namespace util { + template struct tokeniser { public: - using string_type = std::string; - using value_type = string_type::value_type; + using value_type = typename std::iterator_traits::value_type; + using range_type = view; - 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; - - 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 make_tokeniser (const std::string&, std::string::value_type); + tokeniser make_tokeniser (std::string&&, std::string::value_type) = delete; + tokeniser make_tokeniser (const char*, char); + } #endif // __UTIL_STRING_HPP diff --git a/test/string.cpp b/test/string.cpp index 29cff4f2..0edd34d3 100644 --- a/test/string.cpp +++ b/test/string.cpp @@ -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);