Skip to content

Instantly share code, notes, and snippets.

@sftrabbit
Last active January 9, 2019 13:08
Show Gist options
  • Save sftrabbit/4335b21717fff8f8932a to your computer and use it in GitHub Desktop.
Save sftrabbit/4335b21717fff8f8932a 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) { }
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;
}
}
};
@leha-bot
Copy link

leha-bot commented Nov 9, 2016

There are a bug at line 47: returning address of temporary local variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment