#include #include #include namespace pit{ template class passthrough{ T underlying; public: passthrough(T underlying): underlying(underlying){} passthrough(passthrough& from): underlying(from.underlying){} passthrough operator+(std::size_t amount){ return passthrough(this->underlying+amount); } void operator+=(std::size_t amount){ this->underlying += amount; } passthrough operator-(std::size_t amount){ return passthrough(this->underlying-amount); } void operator-=(std::size_t amount){ this->underlying -= amount; } T const& operator*(){ return this->underlying; } bool operator==(passthrough const& rhs){ return this->underlying == rhs.underlying; } }; template class range{ private: T beginning; T ending; public: range(T begin, T end):beginning(begin), ending(end){} passthrough begin(){ return passthrough(this->beginning); } passthrough end(){ return passthrough(this->ending); } }; template class repeat{ T val; public: // noops repeat operator+(std::size_t ){} repeat operator-(std::size_t ){} void operator+=(std::size_t ){} void operator-=(std::size_t ){} // always return false on equality to ensure it repeats forever bool operator==(repeat const& rhs){return false;} // if T isn't copyable then make the template arg a reference T operator*(){ return this->val; } // convenience for for loops and what not repeat begin(){ return *this; } repeat end(){ return *this; } repeat rbegin(){ return *this; } repeat rend(){ return *this; } }; // Allocator could be generic on just * with + and += using a stack buf and the istream getline method but lazy template, class Allocator = std::allocator> class basic_stream_split { bool ended; std::basic_istream& stream; CharT delim; public: // there's no reason to specify the ending argument unless you want to manually construct the .end state of this iterator basic_stream_split(std::basic_istream& stream, CharT delim, bool ending=false): stream(stream), ended(ending), delim(delim){} bool operator==(basic_stream_split const& rhs){ return this->ended == rhs; } std::basic_string operator*(){ std::basic_string s; std::getline(this->stream, s, this->delim); return s; } // can't do -, or -= there's no reasonable way to undo istream reads // can't do + without storing a line void operator+=(std::size_t rhs){ std::basic_string s; for(size_t i =0;istream, s, this->delim); return *this; } }; using stream_split = basic_stream_split; using wstream_split = basic_stream_split; template, class Allocator = std::allocator> basic_stream_split split_stream(std::basic_istream& stream){ } }