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#pragma once
27
28#include <type_traits>
29
30namespace WTF {
31
32template<typename Predicate, typename Iterator>
33class FilterIterator {
34public:
35 FilterIterator(Predicate pred, Iterator begin, Iterator end)
36 : m_pred(WTFMove(pred))
37 , m_iter(WTFMove(begin))
38 , m_end(WTFMove(end))
39 {
40 while (m_iter != m_end && !m_pred(*m_iter))
41 ++m_iter;
42 }
43
44 FilterIterator& operator++()
45 {
46 while (m_iter != m_end) {
47 ++m_iter;
48 if (m_iter == m_end || m_pred(*m_iter))
49 break;
50 }
51 return *this;
52 }
53
54 const typename std::remove_const<decltype(*std::declval<Iterator>())>::type operator*() const
55 {
56 ASSERT(m_iter != m_end);
57 ASSERT(m_pred(*m_iter));
58 return *m_iter;
59 }
60
61 inline bool operator==(FilterIterator& other) const { return m_iter == other.m_iter; }
62 inline bool operator!=(FilterIterator& other) const { return m_iter != other.m_iter; }
63
64private:
65 const Predicate m_pred;
66 Iterator m_iter;
67 Iterator m_end;
68};
69
70template<typename Predicate, typename Iterator>
71inline FilterIterator<Predicate, Iterator> makeFilterIterator(Predicate&& pred, Iterator&& begin, Iterator&& end)
72{
73 return FilterIterator<Predicate, Iterator>(std::forward<Predicate>(pred), std::forward<Iterator>(begin), std::forward<Iterator>(end));
74}
75
76template<typename Transform, typename Iterator>
77class TransformIterator {
78public:
79 TransformIterator(Transform&& transform, Iterator&& iter)
80 : m_transform(WTFMove(transform))
81 , m_iter(WTFMove(iter))
82 {
83 }
84
85 TransformIterator& operator++()
86 {
87 ++m_iter;
88 return *this;
89 }
90
91 const typename std::remove_const<decltype(std::declval<Transform>()(*std::declval<Iterator>()))>::type operator*() const
92 {
93 return m_transform(*m_iter);
94 }
95
96 inline bool operator==(TransformIterator& other) const { return m_iter == other.m_iter; }
97 inline bool operator!=(TransformIterator& other) const { return m_iter != other.m_iter; }
98
99private:
100 const Transform m_transform;
101 Iterator m_iter;
102};
103
104template<typename Transform, typename Iterator>
105inline TransformIterator<Transform, Iterator> makeTransformIterator(Transform&& transform, Iterator&& iter)
106{
107 return TransformIterator<Transform, Iterator>(WTFMove(transform), WTFMove(iter));
108}
109
110} // namespace WTF
111