Fix FullScreen crash in Webapp
[platform/framework/web/chromium-efl.git] / courgette / consecutive_range_visitor.h
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.
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 namespace courgette {
13
14 // Usage note: First check whether std::unique() would suffice.
15 //
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.
19 //
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 {
25  public:
26   ConsecutiveRangeVisitor(InputIterator begin, InputIterator end)
27       : head_(begin), end_(end) {
28     advance();
29   }
30
31   ConsecutiveRangeVisitor(const ConsecutiveRangeVisitor&) = delete;
32   ConsecutiveRangeVisitor& operator=(const ConsecutiveRangeVisitor&) = delete;
33
34   // Returns whether there are more ranges to traverse.
35   bool has_more() const { return tail_ != end_; }
36
37   // Returns an iterator to an element in the current range.
38   InputIterator cur() const { return tail_; }
39
40   // Returns the number of repeated elements in the current range.
41   size_t repeat() const { return std::distance(tail_, head_); }
42
43   // Advances to the next range.
44   void advance() {
45     tail_ = head_;
46     if (head_ != end_)
47       while (++head_ != end_ && *head_ == *tail_) {}
48   }
49
50  private:
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.
54 };
55
56 }  // namespace courgette
57
58 #endif  // COURGETTE_CONSECUTIVE_RANGE_VISITOR_H_