From 133a41850f1bc3020c6054c6e727b97e8b7aa336 Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 4 Jul 2015 21:09:07 +0100 Subject: [PATCH] add AppenderRange + make format() take rvalue reference as first argument + rvalue-ref push for vector --- octa/format.hh | 8 +++---- octa/range.hh | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ octa/vector.hh | 7 ++++++ 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/octa/format.hh b/octa/format.hh index d9db9d6..4c6346e 100644 --- a/octa/format.hh +++ b/octa/format.hh @@ -894,26 +894,26 @@ namespace detail { } /* namespace detail */ template -static inline octa::Ptrdiff format(R writer, octa::Size &fmtn, +static inline octa::Ptrdiff format(R &&writer, octa::Size &fmtn, const char *fmt, const A &...args) { return octa::detail::format_impl(writer, fmtn, false, fmt, args...); } template -octa::Ptrdiff format(R writer, octa::Size &fmtn, +octa::Ptrdiff format(R &&writer, octa::Size &fmtn, const octa::AnyString &fmt, const A &...args) { return format(writer, fmtn, fmt.data(), args...); } template -octa::Ptrdiff format(R writer, const char *fmt, const A &...args) { +octa::Ptrdiff format(R &&writer, const char *fmt, const A &...args) { octa::Size fmtn = 0; return format(writer, fmtn, fmt, args...); } template -octa::Ptrdiff format(R writer, const octa::AnyString &fmt, +octa::Ptrdiff format(R &&writer, const octa::AnyString &fmt, const A &...args) { octa::Size fmtn = 0; return format(writer, fmtn, fmt.data(), args...); diff --git a/octa/range.hh b/octa/range.hh index 315babc..b8d36d6 100644 --- a/octa/range.hh +++ b/octa/range.hh @@ -1117,6 +1117,67 @@ ChunksRange chunks(const T &it, RangeSize chs) { return ChunksRange(it, chs); } +template +struct AppenderRange: OutputRange, typename T::Value> { + AppenderRange(): p_data() {} + AppenderRange(const T &v): p_data(v) {} + AppenderRange(T &&v): p_data(octa::move(v)) {} + AppenderRange(const AppenderRange &v): p_data(v.p_data) {} + AppenderRange(AppenderRange &&v): p_data(octa::move(v.p_data)) {} + + AppenderRange &operator=(const AppenderRange &v) { + p_data = v.p_data; + return *this; + } + + AppenderRange &operator=(AppenderRange &&v) { + p_data = octa::move(v.p_data); + return *this; + } + + AppenderRange &operator=(const T &v) { + p_data = v; + return *this; + } + + AppenderRange &operator=(T &&v) { + p_data = octa::move(v); + return *this; + } + + void clear() { p_data.clear(); } + + void reserve(typename T::Size cap) { p_data.reserve(cap); } + void resize(typename T::Size len) { p_data.resize(len); } + + typename T::Size size() const { return p_data.size(); } + typename T::Size capacity() const { return p_data.capacity(); } + + bool put(const typename T::Value &v) { + p_data.push(v); + return true; + } + + bool put(typename T::Value &&v) { + p_data.push(octa::move(v)); + return true; + } + + T &get() { return p_data; } +private: + T p_data; +}; + +template +AppenderRange appender() { + return AppenderRange(); +} + +template +AppenderRange appender(T &&v) { + return AppenderRange(octa::forward(v)); +} + // range of template using RangeOf = decltype(octa::iter(octa::declval())); diff --git a/octa/vector.hh b/octa/vector.hh index f2b0b9b..02eb16d 100644 --- a/octa/vector.hh +++ b/octa/vector.hh @@ -295,6 +295,13 @@ public: return p_buf.first()[p_len++]; } + T &push(T &&v) { + if (p_len == p_cap) reserve(p_len + 1); + octa::allocator_construct(p_buf.second(), + &p_buf.first()[p_len], octa::move(v)); + return p_buf.first()[p_len++]; + } + T &push() { if (p_len == p_cap) reserve(p_len + 1); octa::allocator_construct(p_buf.second(), &p_buf.first()[p_len]);