summaryrefslogtreecommitdiff
path: root/src/common.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common.hpp')
-rw-r--r--src/common.hpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/common.hpp b/src/common.hpp
index d3aca257..1971faa9 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -348,4 +348,52 @@ auto end (reversion_wrapper<T> w) { return w.iterable.rend(); }
template <typename T>
reversion_wrapper<T> reverse (T&& iterable) { return { iterable }; }
+
+template<typename T>
+struct RunIterable {
+ const ::std::vector<T>& list;
+ unsigned int ofs;
+ ::std::pair<size_t,size_t> cur;
+ RunIterable(const ::std::vector<T>& list):
+ list(list), ofs(0)
+ {
+ advance();
+ }
+ void advance() {
+ if( ofs < list.size() )
+ {
+ auto start = ofs;
+ while(ofs < list.size() && list[ofs] == list[start])
+ ofs ++;
+ cur = ::std::make_pair(start, ofs-1);
+ }
+ else
+ {
+ ofs = list.size()+1;
+ }
+ }
+ RunIterable<T> begin() { return *this; }
+ RunIterable<T> end() { auto rv = *this; rv.ofs = list.size()+1; return rv; }
+ bool operator==(const RunIterable<T>& x) {
+ return x.ofs == ofs;
+ }
+ bool operator!=(const RunIterable<T>& x) {
+ return !(*this == x);
+ }
+ void operator++() {
+ advance();
+ }
+ const ::std::pair<size_t,size_t>& operator*() const {
+ return this->cur;
+ }
+ const ::std::pair<size_t,size_t>* operator->() const {
+ return &this->cur;
+ }
+};
+template<typename T>
+RunIterable<T> runs(const ::std::vector<T>& x) {
+ return RunIterable<T>(x);
+}
+
+
#endif