// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_BASE_ITERATOR_H_ #define V8_BASE_ITERATOR_H_ #include <iterator> #include <tuple> #include <utility> #include "src/base/logging.h" namespace v8 { namespace base { template <class Category, class Type, class Diff = std::ptrdiff_t, class Pointer = Type*, class Reference = Type&> struct iterator { … }; // The intention of the base::iterator_range class is to encapsulate two // iterators so that the range defined by the iterators can be used like // a regular STL container (actually only a subset of the full container // functionality is available usually). template <typename ForwardIterator> class iterator_range { … }; template <typename ForwardIterator> auto make_iterator_range(ForwardIterator begin, ForwardIterator end) { … } template <class T> struct DerefPtrIterator : base::iterator<std::bidirectional_iterator_tag, T> { … }; // {Reversed} returns a container adapter usable in a range-based "for" // statement for iterating a reversible container in reverse order. // // Example: // // std::vector<int> v = ...; // for (int i : base::Reversed(v)) { // // iterates through v from back to front // } // // The signature avoids binding to temporaries (T&& / const T&) on purpose. The // lifetime of a temporary would not extend to a range-based for loop using it. template <typename T> auto Reversed(T& t) { … } // This overload of `Reversed` is safe even when the argument is a temporary, // because we rely on the wrapped iterators instead of the `iterator_range` // object itself. template <typename T> auto Reversed(const iterator_range<T>& t) { … } // {IterateWithoutLast} returns a container adapter usable in a range-based // "for" statement for iterating all elements without the last in a forward // order. It performs a check whether the container is empty. // // Example: // // std::vector<int> v = ...; // for (int i : base::IterateWithoutLast(v)) { // // iterates through v front to --back // } // // The signature avoids binding to temporaries, see the remark in {Reversed}. template <typename T> auto IterateWithoutLast(T& t) { … } template <typename T> auto IterateWithoutLast(const iterator_range<T>& t) { … } // TupleIterator is an iterator wrapping around multiple iterators. It is use by // the `zip` function below to iterate over multiple containers at once. template <class... Iterators> class TupleIterator : public base::iterator< std::bidirectional_iterator_tag, std::tuple<typename std::iterator_traits<Iterators>::reference...>> { … }; // `zip` creates an iterator_range from multiple containers. It can be used to // iterate over multiple containers at once. For instance: // // std::vector<int> arr = { 2, 4, 6 }; // std::set<double> set = { 3.5, 4.5, 5.5 }; // for (auto [i, d] : base::zip(arr, set)) { // std::cout << i << " and " << d << std::endl; // } // // Prints "2 and 3.5", "4 and 4.5" and "6 and 5.5". template <class... Containers> auto zip(Containers&... containers) { … } } // namespace base } // namespace v8 #endif // V8_BASE_ITERATOR_H_