v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
iterator.h
Go to the documentation of this file.
1// Copyright 2014 the V8 project 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 V8_BASE_ITERATOR_H_
6#define V8_BASE_ITERATOR_H_
7
8#include <iterator>
9#include <tuple>
10#include <utility>
11
12#include "src/base/logging.h"
13
14namespace v8 {
15namespace base {
16
17template <class Category, class Type, class Diff = std::ptrdiff_t,
18 class Pointer = Type*, class Reference = Type&>
19struct iterator {
20 using iterator_category = Category;
21 using value_type = Type;
22 using difference_type = Diff;
23 using pointer = Pointer;
24 using reference = Reference;
25};
26
27// The intention of the base::iterator_range class is to encapsulate two
28// iterators so that the range defined by the iterators can be used like
29// a regular STL container (actually only a subset of the full container
30// functionality is available usually).
31template <typename ForwardIterator>
33 public:
34 using iterator = ForwardIterator;
35 using const_iterator = ForwardIterator;
36 using pointer = typename std::iterator_traits<iterator>::pointer;
37 using reference = typename std::iterator_traits<iterator>::reference;
38 using value_type = typename std::iterator_traits<iterator>::value_type;
40 typename std::iterator_traits<iterator>::difference_type;
41
43 iterator_range(ForwardIterator begin, ForwardIterator end)
44 : begin_(begin), end_(end) {}
45
46 iterator begin() const { return begin_; }
47 iterator end() const { return end_; }
48 const_iterator cbegin() const { return begin_; }
49 const_iterator cend() const { return end_; }
50 auto rbegin() const { return std::make_reverse_iterator(end_); }
51 auto rend() const { return std::make_reverse_iterator(begin_); }
52
53 bool empty() const { return cbegin() == cend(); }
54
55 // Random Access iterators only.
57 difference_type size() const { return cend() - cbegin(); }
58
59 private:
62};
63
64template <typename ForwardIterator>
65auto make_iterator_range(ForwardIterator begin, ForwardIterator end) {
67}
68
69template <class T>
70struct DerefPtrIterator : base::iterator<std::bidirectional_iterator_tag, T> {
71 T* const* ptr;
72
73 explicit DerefPtrIterator(T* const* ptr) : ptr(ptr) {}
74
75 T& operator*() const { return **ptr; }
77 ++ptr;
78 return *this;
79 }
81 --ptr;
82 return *this;
83 }
84 bool operator!=(const DerefPtrIterator& other) const {
85 return ptr != other.ptr;
86 }
87 bool operator==(const DerefPtrIterator& other) const {
88 return ptr == other.ptr;
89 }
90};
91
92// {Reversed} returns a container adapter usable in a range-based "for"
93// statement for iterating a reversible container in reverse order.
94//
95// Example:
96//
97// std::vector<int> v = ...;
98// for (int i : base::Reversed(v)) {
99// // iterates through v from back to front
100// }
101//
102// The signature avoids binding to temporaries (T&& / const T&) on purpose. The
103// lifetime of a temporary would not extend to a range-based for loop using it.
104template <typename T>
105auto Reversed(T& t) {
106 return make_iterator_range(std::rbegin(t), std::rend(t));
107}
108
109// This overload of `Reversed` is safe even when the argument is a temporary,
110// because we rely on the wrapped iterators instead of the `iterator_range`
111// object itself.
112template <typename T>
114 return make_iterator_range(std::rbegin(t), std::rend(t));
115}
116
117// {IterateWithoutLast} returns a container adapter usable in a range-based
118// "for" statement for iterating all elements without the last in a forward
119// order. It performs a check whether the container is empty.
120//
121// Example:
122//
123// std::vector<int> v = ...;
124// for (int i : base::IterateWithoutLast(v)) {
125// // iterates through v front to --back
126// }
127//
128// The signature avoids binding to temporaries, see the remark in {Reversed}.
129template <typename T>
131 DCHECK_NE(std::begin(t), std::end(t));
132 auto new_end = std::end(t);
133 return make_iterator_range(std::begin(t), --new_end);
134}
135
136template <typename T>
138 iterator_range<T> range_copy = {t.begin(), t.end()};
139 return IterateWithoutLast(range_copy);
140}
141
142// {IterateWithoutFirst} returns a container adapter usable in a range-based
143// "for" statement for iterating all elements without the first in a forward
144// order. It performs a check whether the container is empty.
145template <typename T>
147 DCHECK_NE(std::begin(t), std::end(t));
148 auto new_begin = std::begin(t);
149 return make_iterator_range(++new_begin, std::end(t));
150}
151
152template <typename T>
154 iterator_range<T> range_copy = {t.begin(), t.end()};
155 return IterateWithoutFirst(range_copy);
156}
157
158// TupleIterator is an iterator wrapping around multiple iterators. It is use by
159// the `zip` function below to iterate over multiple containers at once.
160template <class... Iterators>
162 : public base::iterator<
163 std::bidirectional_iterator_tag,
164 std::tuple<typename std::iterator_traits<Iterators>::reference...>> {
165 public:
167 std::tuple<typename std::iterator_traits<Iterators>::reference...>;
168
169 explicit TupleIterator(Iterators... its) : its_(its...) {}
170
172 std::apply([](auto&... iterators) { (++iterators, ...); }, its_);
173 return *this;
174 }
175
176 template <class Other>
177 bool operator!=(const Other& other) const {
178 return not_equal_impl(other, std::index_sequence_for<Iterators...>{});
179 }
180
182 return std::apply(
183 [](auto&... this_iterators) { return value_type{*this_iterators...}; },
184 its_);
185 }
186
187 private:
188 template <class Other, size_t... indices>
189 bool not_equal_impl(const Other& other,
190 std::index_sequence<indices...>) const {
191 return (... || (std::get<indices>(its_) != std::get<indices>(other.its_)));
192 }
193
194 std::tuple<Iterators...> its_;
195};
196
197// `zip` creates an iterator_range from multiple containers. It can be used to
198// iterate over multiple containers at once. For instance:
199//
200// std::vector<int> arr = { 2, 4, 6 };
201// std::set<double> set = { 3.5, 4.5, 5.5 };
202// for (auto [i, d] : base::zip(arr, set)) {
203// std::cout << i << " and " << d << std::endl;
204// }
205//
206// Prints "2 and 3.5", "4 and 4.5" and "6 and 5.5".
207template <class... Containers>
208auto zip(Containers&... containers) {
209 using TupleIt =
211 return base::make_iterator_range(TupleIt(containers.begin()...),
212 TupleIt(containers.end()...));
213}
214
215} // namespace base
216} // namespace v8
217
218#endif // V8_BASE_ITERATOR_H_
TupleIterator(Iterators... its)
Definition iterator.h:169
std::tuple< typename std::iterator_traits< Iterators >::reference... > value_type
Definition iterator.h:166
value_type operator*() const
Definition iterator.h:181
bool not_equal_impl(const Other &other, std::index_sequence< indices... >) const
Definition iterator.h:189
std::tuple< Iterators... > its_
Definition iterator.h:194
bool operator!=(const Other &other) const
Definition iterator.h:177
TupleIterator & operator++()
Definition iterator.h:171
reference operator[](difference_type n)
Definition iterator.h:56
difference_type size() const
Definition iterator.h:57
typename std::iterator_traits< iterator >::pointer pointer
Definition iterator.h:36
iterator end() const
Definition iterator.h:47
typename std::iterator_traits< iterator >::reference reference
Definition iterator.h:37
iterator_range(ForwardIterator begin, ForwardIterator end)
Definition iterator.h:43
const_iterator const begin_
Definition iterator.h:60
const_iterator const end_
Definition iterator.h:61
typename std::iterator_traits< iterator >::difference_type difference_type
Definition iterator.h:39
const_iterator cend() const
Definition iterator.h:49
auto rbegin() const
Definition iterator.h:50
ForwardIterator iterator
Definition iterator.h:34
ForwardIterator const_iterator
Definition iterator.h:35
const_iterator cbegin() const
Definition iterator.h:48
typename std::iterator_traits< iterator >::value_type value_type
Definition iterator.h:38
iterator begin() const
Definition iterator.h:46
int end
int n
Definition mul-fft.cc:296
auto zip(Containers &... containers)
Definition iterator.h:208
auto make_iterator_range(ForwardIterator begin, ForwardIterator end)
Definition iterator.h:65
auto IterateWithoutLast(T &t)
Definition iterator.h:130
auto IterateWithoutFirst(T &t)
Definition iterator.h:146
auto Reversed(T &t)
Definition iterator.h:105
#define DCHECK_NE(v1, v2)
Definition logging.h:486
bool operator==(const DerefPtrIterator &other) const
Definition iterator.h:87
DerefPtrIterator & operator++()
Definition iterator.h:76
DerefPtrIterator & operator--()
Definition iterator.h:80
DerefPtrIterator(T *const *ptr)
Definition iterator.h:73
bool operator!=(const DerefPtrIterator &other) const
Definition iterator.h:84
Reference reference
Definition iterator.h:24
Category iterator_category
Definition iterator.h:20