1// Copyright 2014 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 CompositionUnderlineRangeFilter_h
6#define CompositionUnderlineRangeFilter_h
7
8#include "core/editing/CompositionUnderline.h"
9#include "wtf/NotFound.h"
10#include "wtf/Vector.h"
11
12namespace blink {
13
14// A visitor class to yield elements of a sorted (by startOffset) list of
15// underlines, visiting only elements that intersect with specified *inclusive*
16// range [indexLo, indexHi].
17class CompositionUnderlineRangeFilter {
18    WTF_MAKE_NONCOPYABLE(CompositionUnderlineRangeFilter);
19public:
20    class ConstIterator {
21    public:
22        ConstIterator(): m_filter(nullptr), m_index(0) { }
23        const CompositionUnderline& operator*()
24        {
25            ASSERT(m_index != kNotFound);
26            return m_filter->m_underlines[m_index];
27        }
28        ConstIterator& operator++()
29        {
30            if (m_index != kNotFound)
31                m_index = m_filter->seekValidIndex(m_index + 1);
32            return *this;
33        }
34        const CompositionUnderline* operator->()
35        {
36            ASSERT(m_index != kNotFound);
37            return &m_filter->m_underlines[m_index];
38        }
39        bool operator==(const ConstIterator& other)
40        {
41            return other.m_index == m_index && other.m_filter == m_filter;
42        }
43        bool operator!=(const ConstIterator& other) { return !operator==(other); }
44
45    private:
46        friend class CompositionUnderlineRangeFilter;
47
48        ConstIterator(CompositionUnderlineRangeFilter* filter, size_t index)
49            : m_filter(filter)
50            , m_index(index) { }
51        CompositionUnderlineRangeFilter* m_filter;
52        size_t m_index;
53    };
54
55    CompositionUnderlineRangeFilter(const Vector<CompositionUnderline>& underlines, size_t indexLo, size_t indexHi);
56
57    ConstIterator begin() { return ConstIterator(this, seekValidIndex(0)); }
58    const ConstIterator& end() { return m_theEnd; }
59
60private:
61    friend class ConstIterator;
62
63    // Returns |index| if |m_underlines[index]| intersects with range
64    // [m_indexLo, m_indexHi]. Otherwise returns the index of the next
65    // intersecting interval, or END if there are none left.
66    size_t seekValidIndex(size_t index);
67
68    // Assume that elements of |m_underlines| are sorted by |.startOffset|.
69    const Vector<CompositionUnderline>& m_underlines;
70    // The "query range" is the inclusive range [m_indexLo, m_indexHi].
71    const size_t m_indexLo;
72    const size_t m_indexHi;
73    const ConstIterator m_theEnd;
74};
75
76} // namespace blink
77
78#endif
79