8#ifndef GRIDFORMAT_COMMON_ENCODING_ASCII_HPP_
9#define GRIDFORMAT_COMMON_ENCODING_ASCII_HPP_
21#if __has_include(<format>)
25#include <gridformat/common/output_stream.hpp>
26#include <gridformat/common/reserved_string.hpp>
29namespace GridFormat::Encoding::Detail {
32 struct AsciiPrintType : std::type_identity<T> {};
33 template<std::
signed_
integral T>
34 struct AsciiPrintType<T> : std::type_identity<std::intmax_t> {};
35 template<std::
unsigned_
integral T>
36 struct AsciiPrintType<T> : std::type_identity<std::uintmax_t> {};
48 ReservedString<30> delimiter{
""};
49 ReservedString<30> line_prefix{
""};
50 std::size_t entries_per_line = std::numeric_limits<std::size_t>::max();
54 return a.delimiter == b.delimiter
55 && a.line_prefix == b.line_prefix
56 && a.entries_per_line == b.entries_per_line
62template<
typename OStream>
66 Buffer(std::streamsize precision)
67 : _precision{precision} {
71 template<
typename V,
typename D>
72 void push(V&& value, D&& delimiter) {
74 if constexpr (std::floating_point<std::remove_cvref_t<V>>)
75 std::format_to(std::back_inserter(_string_buf),
76 "{:.{}g}{}", std::forward<V>(value), _precision, std::forward<D>(delimiter)
79 std::format_to(std::back_inserter(_string_buf),
80 "{}{}", std::forward<V>(value), std::forward<D>(delimiter)
83 _stream_buf << std::forward<V>(value) << std::forward<D>(delimiter);
87 void prepare_readout() {
91 _string_buf = std::move(_stream_buf).str();
97 return std::span{_string_buf.data(), _string_buf.size()};
105 void _init_stream_buf() {
107 _stream_buf.precision(_precision);
110 std::streamsize _precision;
111 std::string _string_buf;
112 std::ostringstream _stream_buf;
117 : OutputStreamWrapperBase<OStream>(s)
118 , _opts{std::move(opts)}
121 template<
typename T, std::
size_t size>
122 void write(std::span<T, size> data) {
123 std::size_t count_entries = 0;
124 std::size_t count_buffer_lines = 0;
126 using PrintType =
typename Encoding::Detail::AsciiPrintType<T>::type;
127 Buffer buffer(std::numeric_limits<PrintType>::digits10);
128 while (count_entries < data.size()) {
129 buffer.push(count_entries > 0 ?
"\n" :
"", _opts.line_prefix);
132 const auto num_entries = min(_opts.entries_per_line, data.size() - count_entries);
133 for (
const auto& value : data.subspan(count_entries, num_entries))
134 buffer.push(
static_cast<PrintType
>(value), _opts.delimiter);
137 count_entries += num_entries;
138 ++count_buffer_lines;
142 buffer.prepare_readout();
143 this->_write_raw(buffer.data());
145 count_buffer_lines = 0;
150 buffer.prepare_readout();
151 this->_write_raw(buffer.data());
161namespace GridFormat::Encoding {
168 constexpr Ascii() =
default;
170 : _opts{std::move(opts)}
181 return Ascii{std::move(opts)};
192 std::optional<AsciiFormatOptions> _opts = {};
constexpr Ascii ascii
Instance of the ascii encoder.
Definition: ascii.hpp:196