From 077835e4b638af8718ce91e3fb60c646635690ad Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 1 Feb 2017 18:28:57 +0100 Subject: [PATCH] range system fixes, add iterator types to RangeHalf, optimize make_vector(R) --- ostd/range.hh | 42 +++++++++++++++++++++++++++++++++++++++--- ostd/vector.hh | 14 +++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/ostd/range.hh b/ostd/range.hh index bc0dfa0..8530232 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -322,6 +322,34 @@ namespace detail { }; } +namespace detail { + template + struct RangeIteratorTag { + /* better range types all become random access iterators */ + using Type = std::random_access_iterator_tag; + }; + + template<> + struct RangeIteratorTag { + using Type = std::input_iterator_tag; + }; + + template<> + struct RangeIteratorTag { + using Type = std::output_iterator_tag; + }; + + template<> + struct RangeIteratorTag { + using Type = std::forward_iterator_tag; + }; + + template<> + struct RangeIteratorTag { + using Type = std::bidirectional_iterator_tag; + }; +} + template struct RangeHalf { private: @@ -329,6 +357,12 @@ private: public: using Range = T; + using iterator_category = typename detail::RangeIteratorTag::Type; + using value_type = RangeValue; + using difference_type = RangeDifference; + using pointer = RangeValue *; + using reference = RangeReference; + RangeHalf() = delete; RangeHalf(T const &range): p_range(range) {} @@ -387,7 +421,7 @@ public: /* iterator like interface */ RangeReference operator*() const { - return get(); + return p_range.front(); } RangeReference operator[](RangeSize idx) const { @@ -445,7 +479,9 @@ public: }; template -inline RangeDifference operator-(R const &lhs, R const &rhs) { +inline RangeDifference operator-( + RangeHalf const &lhs, RangeHalf const &rhs +) { return rhs.distance(lhs); } @@ -612,7 +648,7 @@ struct InputRange { * this is sometimes convenient as it can be used within expressions */ Reference operator*() const { - return static_cast(this)->front(); + return std::forward(static_cast(this)->front()); } B &operator++() { diff --git a/ostd/vector.hh b/ostd/vector.hh index a1766bf..5c747ac 100644 --- a/ostd/vector.hh +++ b/ostd/vector.hh @@ -7,6 +7,7 @@ #define OSTD_VECTOR_HH #include +#include #include "ostd/range.hh" @@ -28,10 +29,17 @@ struct ranged_traits const> { template inline std::vector make_vector(R range) { - /* TODO: specialize for contiguous ranges and matching value types */ std::vector ret; - for (; !range.empty(); range.pop_front()) { - ret.push_back(range.front()); + using C = RangeCategory; + if constexpr(std::is_convertible_v) { + /* finite random access or contiguous */ + auto h = range.half(); + ret.insert(ret.end(), h, h + range.size()); + } else { + /* infinite random access and below */ + for (; !range.empty(); range.pop_front()) { + ret.push_back(range.front()); + } } return ret; }