Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
iterators.h
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Helper classes to make it easy to implement range-based for loops.
15
16#ifndef UTIL_GRAPH_ITERATORS_H_
17#define UTIL_GRAPH_ITERATORS_H_
18
19#include <iterator>
20#include <vector>
21
22namespace util {
23
24// This is useful for wrapping iterators of a class that support many different
25// iterations. For instance, on a Graph class, one can write:
26//
27// BeginEndWrapper<OutgoingArcIterator> Graph::OutgoingArcs(NodeInde node)
28// const {
29// return BeginEndWrapper(
30// OutgoingArcIterator(*this, node, /*at_end=*/false),
31// OutgoingArcIterator(*this, node, /*at_end=*/true));
32// }
33//
34// And a client will use it like this:
35//
36// for (const ArcIndex arc : graph.OutgoingArcs(node)) { ... }
37template <typename Iterator>
39 public:
40 using const_iterator = Iterator;
41 using value_type = typename std::iterator_traits<Iterator>::value_type;
42
43 BeginEndWrapper(Iterator begin, Iterator end) : begin_(begin), end_(end) {}
44 Iterator begin() const { return begin_; }
45 Iterator end() const { return end_; }
46 size_t size() const { return end_ - begin_; }
47
48 bool empty() const { return begin() == end(); }
49
50 private:
51 const Iterator begin_;
52 const Iterator end_;
53};
54
55// Inline wrapper methods, to make the client code even simpler.
56// The harm of overloading is probably less than the benefit of the nice,
57// compact name, in this special case.
58template <typename Iterator>
59inline BeginEndWrapper<Iterator> BeginEndRange(Iterator begin, Iterator end) {
60 return BeginEndWrapper<Iterator>(begin, end);
61}
62template <typename Iterator>
64 std::pair<Iterator, Iterator> begin_end) {
65 return BeginEndWrapper<Iterator>(begin_end.first, begin_end.second);
66}
67
68// Shortcut for BeginEndRange(multimap::equal_range(key)).
69// TODO(user): go further and expose only the values, not the pairs (key,
70// values) since the caller already knows the key.
71template <typename MultiMap>
73 MultiMap& multi_map, const typename MultiMap::key_type& key) {
74 return BeginEndRange(multi_map.equal_range(key));
75}
76template <typename MultiMap>
78 const MultiMap& multi_map, const typename MultiMap::key_type& key) {
79 return BeginEndRange(multi_map.equal_range(key));
80}
81
82// The Reverse() function allows to reverse the iteration order of a range-based
83// for loop over a container that support STL reverse iterators.
84// The syntax is:
85// for (const type& t : Reverse(container_of_t)) { ... }
86template <typename Container>
88 public:
89 explicit BeginEndReverseIteratorWrapper(const Container& c) : c_(c) {}
90 typename Container::const_reverse_iterator begin() const {
91 return c_.rbegin();
92 }
93 typename Container::const_reverse_iterator end() const { return c_.rend(); }
94
95 private:
96 const Container& c_;
97};
98template <typename Container>
102
103// Simple iterator on an integer range, see IntegerRange below.
104template <typename IntegerType>
106 : public std::iterator<std::input_iterator_tag, IntegerType> {
107 public:
108 explicit IntegerRangeIterator(IntegerType value) : index_(value) {}
110 : index_(other.index_) {}
112 index_ = other.index_;
113 }
114 bool operator!=(const IntegerRangeIterator& other) const {
115 // This may seems weird, but using < instead of != avoid almost-infinite
116 // loop if one use IntegerRange<int>(1, 0) below for instance.
117 return index_ < other.index_;
118 }
119 bool operator==(const IntegerRangeIterator& other) const {
120 return index_ == other.index_;
121 }
122 IntegerType operator*() const { return index_; }
124 ++index_;
125 return *this;
126 }
128 IntegerRangeIterator previous_position(*this);
129 ++index_;
130 return previous_position;
131 }
132
133 private:
134 IntegerType index_;
135};
136
137// Allows to easily construct nice functions for range-based for loop.
138// This can be used like this:
139//
140// for (const int i : IntegerRange<int>(0, 10)) { ... }
141//
142// But it main purpose is to be used as return value for more complex classes:
143//
144// for (const ArcIndex arc : graph.AllOutgoingArcs());
145// for (const NodeIndex node : graph.AllNodes());
146template <typename IntegerType>
147class IntegerRange : public BeginEndWrapper<IntegerRangeIterator<IntegerType>> {
148 public:
149 IntegerRange(IntegerType begin, IntegerType end)
151 IntegerRangeIterator<IntegerType>(begin),
152 IntegerRangeIterator<IntegerType>(end)) {}
153};
154
155// Allow iterating over a vector<T> as a mutable vector<T*>.
156template <class T>
158 explicit MutableVectorIteration(std::vector<T>* v) : v_(v) {}
159 struct Iterator {
160 explicit Iterator(typename std::vector<T>::iterator it) : it_(it) {}
161 T* operator*() { return &*it_; }
163 it_++;
164 return *this;
165 }
166 bool operator!=(const Iterator& other) const { return other.it_ != it_; }
167
168 private:
169 typename std::vector<T>::iterator it_;
170 };
171 Iterator begin() { return Iterator(v_->begin()); }
172 Iterator end() { return Iterator(v_->end()); }
173
174 private:
175 std::vector<T>* const v_;
176};
177} // namespace util
178
179#endif // UTIL_GRAPH_ITERATORS_H_
BeginEndReverseIteratorWrapper(const Container &c)
Definition iterators.h:89
Container::const_reverse_iterator end() const
Definition iterators.h:93
Container::const_reverse_iterator begin() const
Definition iterators.h:90
Iterator end() const
Definition iterators.h:45
Iterator begin() const
Definition iterators.h:44
BeginEndWrapper(Iterator begin, Iterator end)
Definition iterators.h:43
bool empty() const
Definition iterators.h:48
typename std::iterator_traits< Iterator >::value_type value_type
Definition iterators.h:41
Iterator const_iterator
Definition iterators.h:40
size_t size() const
Definition iterators.h:46
Simple iterator on an integer range, see IntegerRange below.
Definition iterators.h:106
IntegerRangeIterator & operator=(const IntegerRangeIterator &other)
Definition iterators.h:111
bool operator==(const IntegerRangeIterator &other) const
Definition iterators.h:119
IntegerRangeIterator & operator++()
Definition iterators.h:123
bool operator!=(const IntegerRangeIterator &other) const
Definition iterators.h:114
IntegerRangeIterator(const IntegerRangeIterator &other)
Definition iterators.h:109
IntegerRangeIterator(IntegerType value)
Definition iterators.h:108
IntegerType operator*() const
Definition iterators.h:122
IntegerRangeIterator operator++(int)
Definition iterators.h:127
IntegerRange(IntegerType begin, IntegerType end)
Definition iterators.h:149
int64_t value
A collections of i/o utilities for the Graph classes in ./graph.h.
BeginEndReverseIteratorWrapper< Container > Reverse(const Container &c)
Definition iterators.h:99
BeginEndWrapper< Iterator > BeginEndRange(Iterator begin, Iterator end)
Definition iterators.h:59
BeginEndWrapper< typename MultiMap::iterator > EqualRange(MultiMap &multi_map, const typename MultiMap::key_type &key)
Definition iterators.h:72
std::optional< int64_t > end
Iterator(typename std::vector< T >::iterator it)
Definition iterators.h:160
bool operator!=(const Iterator &other) const
Definition iterators.h:166
Allow iterating over a vector<T> as a mutable vector<T*>.
Definition iterators.h:157
MutableVectorIteration(std::vector< T > *v)
Definition iterators.h:158