1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_
6 #define COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_
14 // Usage note: First check whether std::unique() would suffice.
16 // ConsecutiveRangeVisitor is a visitor to read equal consecutive items
17 // ("ranges") between two iterators. The base value of InputIterator must
18 // implement the == operator.
20 // Example: "AAAAABZZZZOO" consists of ranges ["AAAAA", "B", "ZZZZ", "OO"]. The
21 // visitor provides accessors to iterate through the ranges, and to access each
22 // range's value and repeat, i.e., [('A', 5), ('B', 1), ('Z', 4), ('O', 2)].
23 template <class InputIterator>
24 class ConsecutiveRangeVisitor {
26 ConsecutiveRangeVisitor(InputIterator begin, InputIterator end)
27 : head_(begin), end_(end) {
31 ConsecutiveRangeVisitor(const ConsecutiveRangeVisitor&) = delete;
32 ConsecutiveRangeVisitor& operator=(const ConsecutiveRangeVisitor&) = delete;
34 // Returns whether there are more ranges to traverse.
35 bool has_more() const { return tail_ != end_; }
37 // Returns an iterator to an element in the current range.
38 InputIterator cur() const { return tail_; }
40 // Returns the number of repeated elements in the current range.
41 size_t repeat() const { return std::distance(tail_, head_); }
43 // Advances to the next range.
47 while (++head_ != end_ && *head_ == *tail_) {}
51 InputIterator tail_; // The trailing pionter of a range (inclusive).
52 InputIterator head_; // The leading pointer of a range (exclusive).
53 InputIterator end_; // Store the end pointer so we know when to stop.
56 } // namespace courgette
58 #endif // COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_