From cb8e189450144e4b80c19a2e3a75a54bd4599f57 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 16 Apr 2015 23:06:39 +0100 Subject: [PATCH] range-based vector insert + add MoveRange that wraps any InputRange with move semantics --- octa/range.h | 40 ++++++++++++++++++++++++++++++++++++++++ octa/vector.h | 12 ++++++++++++ 2 files changed, 52 insertions(+) diff --git a/octa/range.h b/octa/range.h index f3341ba..0c587d0 100644 --- a/octa/range.h +++ b/octa/range.h @@ -147,6 +147,46 @@ namespace octa { ReverseRange reverse(const T &it) { return ReverseRange(it); } + + template + struct MoveRange { + struct type { + typedef typename RangeTraits::category category; + typedef typename RangeTraits::value value; + typedef typename RangeTraits::pointer pointer; + typedef typename RangeTraits::value &&reference; + }; + + MoveRange(): p_range() {} + MoveRange(const T &range): p_range(range) {} + MoveRange(const MoveRange &it): p_range(it.p_range) {} + MoveRange(MoveRange &&it): p_range(move(it.p_range)) {} + + bool empty () const { return p_range.empty (); } + size_t length() const { return p_range.length(); } + + void pop_first() { p_range.pop_first(); } + void pop_last () { p_range.pop_last (); } + + bool operator==(const MoveRange &v) const { + return p_range == v.p_range; + } + bool operator!=(const MoveRange &v) const { + return p_range != v.p_range; + } + + typename type::reference first() { return move(p_range.first()); } + typename type::reference last () { return move(p_range.last ()); } + + typename type::reference operator[](size_t i) { + return move(p_range[i]); + } + + OCTA_RANGE_ITERATOR(MoveRange) + + private: + T p_range; + }; } #endif \ No newline at end of file diff --git a/octa/vector.h b/octa/vector.h index 534b3c6..8e43444 100644 --- a/octa/vector.h +++ b/octa/vector.h @@ -308,6 +308,18 @@ namespace octa { return &p_buf[idx]; } + template + T *insert(size_t idx, U range) { + size_t len = range.length(); + insert_base(idx, len); + for (size_t i = 0; i < len; ++i) { + p_buf[idx + i].~T(); + new (&p_buf[idx + i]) T(range.first()); + range.pop_first(); + } + return &p_buf[idx]; + } + typename type::range each() { return VectorRange(p_buf, p_buf + p_len); }