Skip to content

Instantly share code, notes, and snippets.

@leha-bot
Forked from sftrabbit/delim_istream_iterator.hpp
Last active November 9, 2016 15:50
Show Gist options
  • Save leha-bot/b7dcad3332d10c871d30a9e33a95c3f4 to your computer and use it in GitHub Desktop.
Save leha-bot/b7dcad3332d10c871d30a9e33a95c3f4 to your computer and use it in GitHub Desktop.
Iterate over a delimited input stream
#include <iterator>
#include <istream>
#include <string>
#include <cassert>
#include <cstddef>
/**
* Iterate over each part of a delimited input stream.
* For example, to split a string into a vector:
*
* std::istringstream ss("This;is a;list");
* std::vector<std::string> items(delim_istream_iterator<>(ss,';'),
* delim_istream_iterator<>());
*/
template <class CharT = char,
class Traits = std::char_traits<CharT>,
class Distance = std::ptrdiff_t>
class delim_istream_iterator
: public std::iterator<std::input_iterator_tag,
std::basic_string<CharT, Traits>,
Distance,
const std::basic_string<CharT, Traits>*,
const std::basic_string<CharT, Traits>&>
{
public:
typedef std::basic_istream<CharT, Traits> istream_type;
typedef std::basic_string<CharT, Traits> value_type;
delim_istream_iterator()
: stream(nullptr), value(), ok(false) { }
delim_istream_iterator(istream_type& stream, CharT delimiter)
: stream(&stream), delimiter(delimiter) {
read();
}
delim_istream_iterator(const delim_istream_iterator& other)
: stream(other.stream), value(other.value),
ok(other.ok), delimiter(other.delimiter) { }
const value_type &operator*() const {
assert(ok);
return value;
}
const value_type* operator->() const {
return &(operator*());
}
delim_istream_iterator& operator++() {
assert(ok);
read();
return *this;
}
delim_istream_iterator operator++(int) {
assert(ok);
delim_istream_iterator temp = *this;
read();
return temp;
}
friend bool operator==(const delim_istream_iterator& a,
const delim_istream_iterator& b) {
return (a.ok == b.ok) && (!a.ok || a.stream == b.stream);
}
friend bool operator!=(const delim_istream_iterator& a,
const delim_istream_iterator& b) {
return !operator==(a, b);
}
private:
istream_type* stream;
value_type value;
bool ok;
CharT delimiter;
void read() {
ok = (stream && *stream);
if (ok) {
std::getline(*stream, value, delimiter);
ok = *stream;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment