mirror of
https://github.com/fmtlib/fmt.git
synced 2024-10-02 21:12:05 +00:00
Type erase output iterators
This commit is contained in:
parent
18024853b6
commit
9d3cd0afb2
@ -725,6 +725,41 @@ class container_buffer : public buffer<typename Container::value_type> {
|
|||||||
: buffer<typename Container::value_type>(c.size()), container_(c) {}
|
: buffer<typename Container::value_type>(c.size()), container_(c) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A buffer that writes to an output iterator when flushed.
|
||||||
|
template <typename OutputIt, typename T>
|
||||||
|
class iterator_buffer : public buffer<T> {
|
||||||
|
private:
|
||||||
|
enum { buffer_size = 256 };
|
||||||
|
|
||||||
|
OutputIt out_;
|
||||||
|
T data_[buffer_size];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void grow(size_t) final {
|
||||||
|
if (this->size() == buffer_size) flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit iterator_buffer(OutputIt out)
|
||||||
|
: buffer<T>(data_, 0, buffer_size), out_(out) {}
|
||||||
|
~iterator_buffer() { flush(); }
|
||||||
|
|
||||||
|
OutputIt out() { return out_; }
|
||||||
|
void flush();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class iterator_buffer<T*, T> : public buffer<T> {
|
||||||
|
protected:
|
||||||
|
void grow(size_t) final {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit iterator_buffer(T* out) : buffer<T>(out, 0, ~size_t()) {}
|
||||||
|
|
||||||
|
T* out() { return &*this->end(); }
|
||||||
|
void flush() {}
|
||||||
|
};
|
||||||
|
|
||||||
// An output iterator that appends to the buffer.
|
// An output iterator that appends to the buffer.
|
||||||
// It is used to reduce symbol sizes for the common case.
|
// It is used to reduce symbol sizes for the common case.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1229,6 +1264,9 @@ struct is_contiguous_back_insert_iterator : std::false_type {};
|
|||||||
template <typename Container>
|
template <typename Container>
|
||||||
struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>>
|
struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>>
|
||||||
: is_contiguous<Container> {};
|
: is_contiguous<Container> {};
|
||||||
|
template <typename Char>
|
||||||
|
struct is_contiguous_back_insert_iterator<buffer_appender<Char>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
// A type-erased reference to an std::locale to avoid heavy <locale> include.
|
// A type-erased reference to an std::locale to avoid heavy <locale> include.
|
||||||
class locale_ref {
|
class locale_ref {
|
||||||
|
@ -581,6 +581,12 @@ void buffer<T>::append(const U* begin, const U* end) {
|
|||||||
begin += count;
|
begin += count;
|
||||||
} while (begin != end);
|
} while (begin != end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt, typename T>
|
||||||
|
void iterator_buffer<OutputIt, T>::flush() {
|
||||||
|
out_ = std::copy(data_, data_ + this->size(), out_);
|
||||||
|
this->clear();
|
||||||
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// The number of characters to store in the basic_memory_buffer object itself
|
// The number of characters to store in the basic_memory_buffer object itself
|
||||||
@ -3560,9 +3566,12 @@ template <typename OutputIt, typename S, typename... Args,
|
|||||||
detail::is_string<S>::value)>
|
detail::is_string<S>::value)>
|
||||||
inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) {
|
inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) {
|
||||||
detail::check_format_string<Args...>(format_str);
|
detail::check_format_string<Args...>(format_str);
|
||||||
using context = format_context_t<OutputIt, char_t<S>>;
|
using Char = char_t<S>;
|
||||||
return vformat_to(out, to_string_view(format_str),
|
detail::iterator_buffer<OutputIt, Char> buf(out);
|
||||||
make_format_args<context>(args...));
|
detail::vformat_to(buf, to_string_view(format_str),
|
||||||
|
make_format_args<buffer_context<Char>>(args...));
|
||||||
|
buf.flush();
|
||||||
|
return buf.out();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt> struct format_to_n_result {
|
template <typename OutputIt> struct format_to_n_result {
|
||||||
|
Loading…
Reference in New Issue
Block a user