Files
Corentin Le Molgat b4b226801b update include guards
2025-11-05 11:54:02 +01:00

89 lines
3.2 KiB
C++

// Copyright 2010-2025 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef ORTOOLS_MATH_OPT_STORAGE_RANGE_H_
#define ORTOOLS_MATH_OPT_STORAGE_RANGE_H_
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>
namespace operations_research::math_opt {
// A range adaptor for a pair of iterators.
//
// This just wraps two iterators into a range-compatible interface. Nothing
// fancy at all.
template <typename IteratorT>
class iterator_range {
public:
using iterator = IteratorT;
using const_iterator = IteratorT;
using value_type = typename std::iterator_traits<IteratorT>::value_type;
iterator_range() : begin_iterator_(), end_iterator_() {}
iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
: begin_iterator_(std::move(begin_iterator)),
end_iterator_(std::move(end_iterator)) {}
IteratorT begin() const { return begin_iterator_; }
IteratorT end() const { return end_iterator_; }
// Returns the size of the wrapped range. Does not participate in overload
// resolution for non-random-access iterators, since in those cases this is a
// slow operation (it must walk the entire range and maintain a count).
//
// Users who need to know the "size" of a non-random-access iterator_range
// should pass the range to `absl::c_distance()` instead.
template <class It = IteratorT>
typename 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 {
return std::distance(begin_iterator_, end_iterator_);
}
// Returns true if this iterator range refers to an empty sequence, and false
// otherwise.
bool empty() const { return begin_iterator_ == end_iterator_; }
private:
IteratorT begin_iterator_, end_iterator_;
};
// Convenience function for iterating over sub-ranges.
//
// This provides a bit of syntactic sugar to make using sub-ranges
// in for loops a bit easier. Analogous to std::make_pair().
template <typename T>
iterator_range<T> make_range(T x, T y) {
return iterator_range<T>(std::move(x), std::move(y));
}
// Converts std::pair<Iter,Iter> to iterator_range<Iter>. E.g.:
// for (const auto& e : make_range(m.equal_range(k))) ...
template <typename T>
iterator_range<T> make_range(std::pair<T, T> p) {
return iterator_range<T>(std::move(p.first), std::move(p.second));
}
template <typename Collection>
auto collection_to_range(Collection& c) {
return make_range(c.begin(), c.end());
}
} // namespace operations_research::math_opt
#endif // ORTOOLS_MATH_OPT_STORAGE_RANGE_H_