Add WTF::move()
[WebKit-https.git] / Source / WTF / wtf / IteratorAdaptors.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef WTF_IteratorAdaptors_h
27 #define WTF_IteratorAdaptors_h
28
29 #include <type_traits>
30
31 namespace WTF {
32
33 template<typename Predicate, typename Iterator>
34 class FilterIterator {
35 public:
36     FilterIterator(Predicate pred, Iterator begin, Iterator end)
37         : m_pred(WTF::move(pred))
38         , m_iter(WTF::move(begin))
39         , m_end(WTF::move(end))
40     {
41         while (m_iter != m_end && !m_pred(*m_iter))
42             ++m_iter;
43     }
44
45     FilterIterator& operator++()
46     {
47         while (m_iter != m_end) {
48             ++m_iter;
49             if (m_iter == m_end || m_pred(*m_iter))
50                 break;
51         }
52         return *this;
53     }
54
55     const typename std::remove_const<decltype(*std::declval<Iterator>())>::type operator*() const
56     {
57         ASSERT(m_iter != m_end);
58         ASSERT(m_pred(*m_iter));
59         return *m_iter;
60     }
61
62     inline bool operator==(FilterIterator& other) const { return m_iter == other.m_iter; }
63     inline bool operator!=(FilterIterator& other) const { return m_iter != other.m_iter; }
64
65 private:
66     const Predicate m_pred;
67     Iterator m_iter;
68     Iterator m_end;
69 };
70
71 template<typename Predicate, typename Iterator>
72 inline FilterIterator<Predicate, Iterator> makeFilterIterator(Predicate&& pred, Iterator&& begin, Iterator&& end)
73 {
74     return FilterIterator<Predicate, Iterator>(std::forward<Predicate>(pred), std::forward<Iterator>(begin), std::forward<Iterator>(end));
75 }
76
77 template<typename Transform, typename Iterator>
78 class TransformIterator {
79 public:
80     TransformIterator(Transform&& transform, Iterator&& iter)
81         : m_transform(WTF::move(transform))
82         , m_iter(WTF::move(iter))
83     {
84     }
85
86     TransformIterator& operator++()
87     {
88         ++m_iter;
89         return *this;
90     }
91
92     const typename std::remove_const<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::type operator*() const
93     {
94         return m_transform(*m_iter);
95     }
96
97     inline bool operator==(TransformIterator& other) const { return m_iter == other.m_iter; }
98     inline bool operator!=(TransformIterator& other) const { return m_iter != other.m_iter; }
99
100 private:
101     const Transform m_transform;
102     Iterator m_iter;
103 };
104
105 template<typename Transform, typename Iterator>
106 inline TransformIterator<Transform, Iterator> makeTransformIterator(Transform&& transform, Iterator&& iter)
107 {
108     return TransformIterator<Transform, Iterator>(WTF::move(transform), WTF::move(iter));
109 }
110
111 } // namespace WTF
112
113 #endif // WTF_IteratorAdaptors_h