From 8645d8c7fc82913977189197eeedab71ff03cd8e Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Mon, 2 Jan 2017 09:38:46 +0100 Subject: [PATCH] Make osrm::util::range a model of SinglePassRangeConcept References: - http://www.boost.org/doc/libs/1_63_0/libs/range/doc/html/range/concepts/single_pass_range.html --- include/util/integer_range.hpp | 74 +++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/include/util/integer_range.hpp b/include/util/integer_range.hpp index 29d428f80..befaa3275 100644 --- a/include/util/integer_range.hpp +++ b/include/util/integer_range.hpp @@ -2,6 +2,7 @@ #define INTEGER_RANGE_HPP #include +#include #include @@ -12,6 +13,50 @@ namespace osrm namespace util { +// Ported from Boost.Range 1.56 due to required fix +// https://github.com/boostorg/range/commit/9e6bdc13ba94af4e150afae547557a2fbbfe3bf0 +// Can be removed after dropping support of Boost < 1.56 +template +class integer_iterator : public boost::iterator_facade, + Integer, + boost::random_access_traversal_tag, + Integer> +{ + typedef boost::iterator_facade, + Integer, + boost::random_access_traversal_tag, + Integer> + base_t; + + public: + typedef typename base_t::value_type value_type; + typedef typename base_t::difference_type difference_type; + typedef typename base_t::reference reference; + typedef std::random_access_iterator_tag iterator_category; + + integer_iterator() : m_value() {} + explicit integer_iterator(value_type x) : m_value(x) {} + + private: + void increment() { ++m_value; } + void decrement() { --m_value; } + void advance(difference_type offset) { m_value += offset; } + bool equal(const integer_iterator &other) const { return m_value == other.m_value; } + reference dereference() const { return m_value; } + + difference_type distance_to(const integer_iterator &other) const + { + return std::is_signed::value + ? (other.m_value - m_value) + : (other.m_value >= m_value) + ? static_cast(other.m_value - m_value) + : -static_cast(m_value - other.m_value); + } + + friend class ::boost::iterator_core_access; + value_type m_value; +}; + // Warning: do not try to replace this with Boost's irange, as it is broken on Boost 1.55: // auto r = boost::irange(0, 15); // std::cout << r.size() << std::endl; @@ -19,28 +64,21 @@ namespace util template class range { - private: - const Integer last; - Integer iter; - public: - range(Integer start, Integer end) noexcept : last(end), iter(start) - { - BOOST_ASSERT_MSG(start <= end, "backwards counting ranges not suppoted"); - static_assert(std::is_integral::value, "range type must be integral"); - } + typedef integer_iterator const_iterator; + typedef integer_iterator iterator; - // Iterable functions - const range &begin() const noexcept { return *this; } - const range &end() const noexcept { return *this; } - Integer front() const noexcept { return iter; } - Integer back() const noexcept { return last - 1; } + range(Integer begin, Integer end) : iter(begin), last(end) {} + + iterator begin() const noexcept { return iter; } + iterator end() const noexcept { return last; } + Integer front() const noexcept { return *iter; } + Integer back() const noexcept { return *last - 1; } std::size_t size() const noexcept { return static_cast(last - iter); } - // Iterator functions - bool operator!=(const range &) const noexcept { return iter < last; } - void operator++() noexcept { ++iter; } - Integer operator*() const noexcept { return iter; } + private: + iterator iter; + iterator last; }; // convenience function to construct an integer range with type deduction