1 // Copyright 2015 The Chromium Authors. All rights reserved.
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_
12 #include "base/macros.h"
16 // Usage note: First check whether std::unique() would suffice.
18 // ConsecutiveRangeVisitor is a visitor to read equal consecutive items
19 // ("ranges") between two iterators. The base value of InputIterator must
20 // implement the == operator.
22 // Example: "AAAAABZZZZOO" consists of ranges ["AAAAA", "B", "ZZZZ", "OO"]. The
23 // visitor provides accessors to iterate through the ranges, and to access each
24 // range's value and repeat, i.e., [('A', 5), ('B', 1), ('Z', 4), ('O', 2)].
25 template <class InputIterator>
26 class ConsecutiveRangeVisitor {
28 ConsecutiveRangeVisitor(InputIterator begin, InputIterator end)
29 : head_(begin), end_(end) {
33 // Returns whether there are more ranges to traverse.
34 bool has_more() const { return tail_ != end_; }
36 // Returns an iterator to an element in the current range.
37 InputIterator cur() const { return tail_; }
39 // Returns the number of repeated elements in the current range.
40 size_t repeat() const { return std::distance(tail_, head_); }
42 // Advances to the next range.
46 while (++head_ != end_ && *head_ == *tail_) {}
50 InputIterator tail_; // The trailing pionter of a range (inclusive).
51 InputIterator head_; // The leading pointer of a range (exclusive).
52 InputIterator end_; // Store the end pointer so we know when to stop.
54 DISALLOW_COPY_AND_ASSIGN(ConsecutiveRangeVisitor);
57 } // namespace courgette
59 #endif // COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_