OR-Tools  9.6
range.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 #ifndef OR_TOOLS_MATH_OPT_STORAGE_RANGE_H_
15 #define OR_TOOLS_MATH_OPT_STORAGE_RANGE_H_
16 
17 #include <cstddef>
18 #include <iterator>
19 #include <type_traits>
20 #include <utility>
21 
23 
24 // A range adaptor for a pair of iterators.
25 //
26 // This just wraps two iterators into a range-compatible interface. Nothing
27 // fancy at all.
28 template <typename IteratorT>
30  public:
31  using iterator = IteratorT;
32  using const_iterator = IteratorT;
33  using value_type = typename std::iterator_traits<IteratorT>::value_type;
34 
35  iterator_range() : begin_iterator_(), end_iterator_() {}
36  iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
37  : begin_iterator_(std::move(begin_iterator)),
38  end_iterator_(std::move(end_iterator)) {}
39 
40  IteratorT begin() const { return begin_iterator_; }
41  IteratorT end() const { return end_iterator_; }
42 
43  // Returns the size of the wrapped range. Does not participate in overload
44  // resolution for non-random-access iterators, since in those cases this is a
45  // slow operation (it must walk the entire range and maintain a count).
46  //
47  // Users who need to know the "size" of a non-random-access iterator_range
48  // should pass the range to `absl::c_distance()` instead.
49  template <class It = IteratorT>
50  typename std::enable_if<std::is_base_of<std::random_access_iterator_tag,
51  typename std::iterator_traits<
52  It>::iterator_category>::value,
53  size_t>::type
54  size() const {
55  return std::distance(begin_iterator_, end_iterator_);
56  }
57  // Returns true if this iterator range refers to an empty sequence, and false
58  // otherwise.
59  bool empty() const { return begin_iterator_ == end_iterator_; }
60 
61  private:
62  IteratorT begin_iterator_, end_iterator_;
63 };
64 
65 // Convenience function for iterating over sub-ranges.
66 //
67 // This provides a bit of syntactic sugar to make using sub-ranges
68 // in for loops a bit easier. Analogous to std::make_pair().
69 template <typename T>
71  return iterator_range<T>(std::move(x), std::move(y));
72 }
73 
74 // Converts std::pair<Iter,Iter> to iterator_range<Iter>. E.g.:
75 // for (const auto& e : make_range(m.equal_range(k))) ...
76 template <typename T>
77 iterator_range<T> make_range(std::pair<T, T> p) {
78  return iterator_range<T>(std::move(p.first), std::move(p.second));
79 }
80 
81 template <typename Collection>
82 auto collection_to_range(Collection& c) {
83  return make_range(c.begin(), c.end());
84 }
85 
86 } // namespace operations_research::math_opt
87 
88 #endif // OR_TOOLS_MATH_OPT_STORAGE_RANGE_H_
std::enable_if< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< It >::iterator_category >::value, size_t >::type size() const
Definition: range.h:54
typename std::iterator_traits< IteratorT >::value_type value_type
Definition: range.h:33
iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
Definition: range.h:36
int64_t value
auto collection_to_range(Collection &c)
Definition: range.h:82
iterator_range< T > make_range(T x, T y)
Definition: range.h:70
double distance