Enable dev build with the latest repo
[platform/framework/web/chromium-efl.git] / courgette / consecutive_range_visitor.h
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.
4
5 #ifndef COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_
6 #define COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_
7
8 #include <stddef.h>
9
10 #include <iterator>
11
12 #include "base/macros.h"
13
14 namespace courgette {
15
16 // Usage note: First check whether std::unique() would suffice.
17 //
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.
21 //
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 {
27  public:
28   ConsecutiveRangeVisitor(InputIterator begin, InputIterator end)
29       : head_(begin), end_(end) {
30     advance();
31   }
32
33   // Returns whether there are more ranges to traverse.
34   bool has_more() const { return tail_ != end_; }
35
36   // Returns an iterator to an element in the current range.
37   InputIterator cur() const { return tail_; }
38
39   // Returns the number of repeated elements in the current range.
40   size_t repeat() const { return std::distance(tail_, head_); }
41
42   // Advances to the next range.
43   void advance() {
44     tail_ = head_;
45     if (head_ != end_)
46       while (++head_ != end_ && *head_ == *tail_) {}
47   }
48
49  private:
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.
53
54   DISALLOW_COPY_AND_ASSIGN(ConsecutiveRangeVisitor);
55 };
56
57 }  // namespace courgette
58
59 #endif  // COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_