From c4e0cd31f905ffed8072c663fbb2e0ac8a8669b3 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 30 Jan 2018 11:31:40 +1100 Subject: [PATCH] string: move tokeniser into the header This allows more varied template parameters to be used. --- string.cpp | 143 ------------------------------------------------ string.hpp | 99 +++++++++++++++++++++------------ term.cpp | 2 +- test/string.cpp | 7 ++- 4 files changed, 69 insertions(+), 182 deletions(-) diff --git a/string.cpp b/string.cpp index 753d10db..214dc4d4 100644 --- a/string.cpp +++ b/string.cpp @@ -51,146 +51,3 @@ strbegins (const char *restrict str, const char *restrict prefix) { return 0 == strncmp (prefix, str, strlen (prefix)); } - - -/////////////////////////////////////////////////////////////////////////////// -template -tokeniser::tokeniser (Iterator _first, - Iterator _last, - value_type _separator): - m_range (_first, _last), - m_separator (_separator) -{ } - - -/////////////////////////////////////////////////////////////////////////////// -template -typename tokeniser::iterator -tokeniser::cbegin (void) const -{ - return iterator ( - m_range, - m_separator - ); -} - - -//----------------------------------------------------------------------------- -template -typename tokeniser::iterator -tokeniser::cend (void) const -{ - return iterator ( - {m_range.cend (), m_range.cend ()}, - m_separator - ); -} - - -//----------------------------------------------------------------------------- -template -typename tokeniser::iterator -tokeniser::begin (void) const -{ - return cbegin (); -} - - -//----------------------------------------------------------------------------- -template -typename tokeniser::iterator -tokeniser::end (void) const -{ - return cend (); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -tokeniser::iterator::iterator (range_type _range, value_type _separator): - m_separator (_separator), - m_range (_range.cbegin (), - std::find (_range.cbegin (), - _range.cend (), - _separator)), - m_end (_range.cend ()) -{ } - - -//----------------------------------------------------------------------------- -template -typename tokeniser::iterator -tokeniser::iterator::operator++ (int) -{ - iterator res(*this); - ++*this; - return res; -} - - -//----------------------------------------------------------------------------- -template -typename tokeniser::iterator& -tokeniser::iterator::operator++ (void)& -{ - auto newend = m_range.cend (); - if (newend != m_end) { - CHECK_EQ (*m_range.cend (), m_separator); - newend++; - } - - m_range = { - newend, - std::find (newend, m_end, m_separator) - }; - - return *this; -} - - -//----------------------------------------------------------------------------- -template -typename tokeniser::range_type -tokeniser::iterator::operator* (void) const -{ - return m_range; -} - - -//----------------------------------------------------------------------------- -template -bool -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 5fc4cb6c..edc7c66d 100644 --- a/string.hpp +++ b/string.hpp @@ -14,9 +14,10 @@ * Copyright 2011-2016 Danny Robson */ -#ifndef __UTIL_STRING_HPP -#define __UTIL_STRING_HPP +#ifndef CRUFT_UTIL_STRING_HPP +#define CRUFT_UTIL_STRING_HPP +#include "debug.hpp" #include "view.hpp" @@ -38,15 +39,14 @@ namespace util { using value_type = typename std::iterator_traits::value_type; using range_type = view; - tokeniser (Iterator first, Iterator last, value_type separator); + tokeniser (util::view _range, value_type _separator): + m_range (_range), + m_separator (_separator) + { ; } - template - tokeniser (ContainerT &container, typename ContainerT::value_type _separator): - tokeniser ( - std::begin (container), - std::end (container), - _separator - ) + tokeniser (const char *_range, char _separator): + m_range (_range), + m_separator (_separator) { ; } struct iterator : public std::iterator< @@ -55,16 +55,54 @@ namespace util { std::size_t > { public: - iterator operator++ (int); - iterator& operator++ (void)&; + iterator operator++ (int) + { + iterator res(*this); + ++*this; + return res; + } - range_type operator* (void) const; + iterator& operator++ (void)& + { + auto newend = m_range.cend (); + if (newend != m_end) { + CHECK_EQ (*m_range.cend (), m_separator); + newend++; + } - bool operator== (const iterator&) const; - bool operator!= (const iterator&) const; + m_range = { + newend, + std::find (newend, m_end, m_separator) + }; + + return *this; + } + + range_type operator* (void) const + { + return m_range; + } + + bool operator== (const iterator &rhs) const + { + return m_range == rhs.m_range && m_separator == rhs.m_separator; + } + + bool operator!= (const iterator &rhs) const + { + return !(*this == rhs); + } private: - iterator (range_type range, value_type separator); + iterator (range_type _range, value_type _separator): + m_separator (_separator), + m_range (_range.cbegin (), + std::find (_range.cbegin (), + _range.cend (), + _separator) + ), + m_end (_range.cend ()) + { ; } const value_type m_separator; range_type m_range; @@ -73,11 +111,11 @@ namespace util { friend tokeniser; }; - iterator cbegin (void) const; - iterator begin (void) const; + iterator cbegin (void) const { return { m_range, m_separator }; } + iterator begin (void) const { return { m_range, m_separator }; } - iterator cend (void) const; - iterator end (void) const; + iterator cend (void) const { return { { m_range.cend (), m_range.cend () }, m_separator }; } + iterator end (void) const { return { { m_range.cend (), m_range.cend () }, m_separator }; } private: const range_type m_range; @@ -85,6 +123,11 @@ namespace util { }; + template + tokeniser (ContainerT&, typename ContainerT::value_type) -> tokeniser; + + tokeniser (const char*,char) -> tokeniser; + /////////////////////////////////////////////////////////////////////////// template auto @@ -92,22 +135,6 @@ namespace util { { return tokeniser { std::begin (data), std::end (data), 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/term.cpp b/term.cpp index cbc87074..bbbfa05d 100644 --- a/term.cpp +++ b/term.cpp @@ -71,7 +71,7 @@ find_terminfo_path [[gnu::unused]] (const std::string &key) // check colon seperated list in TERMINFO_DIRS if (const char *dirs = getenv ("TERMINFO_DIRS")) { - auto tok = util::make_tokeniser (dirs, ':'); + auto tok = util::tokeniser (dirs, ':'); for (auto i: tok) { try { diff --git a/test/string.cpp b/test/string.cpp index cce00832..3f090678 100644 --- a/test/string.cpp +++ b/test/string.cpp @@ -29,8 +29,11 @@ main (int, char**) { "", "trailing empty" } }; - for (const auto &[tok, expected]: util::zip (util::make_tokeniser (csv, ','), TESTS)) + for (const auto tok: util::tokeniser (csv.c_str (), ',')) + std::cout << '"' << tok << "\"\n"; + + for (const auto &[tok, expected]: util::zip (util::tokeniser (csv.c_str (), ','), TESTS)) tap.expect_eq (tok, expected.value, "%s", expected.message); return tap.status (); -} +} \ No newline at end of file