13 inline bool BindFromPosition(
int position,
int*
value,
16 if (static_cast<size_t>(position) > pack.
size()) {
33 bool Bind(
const UnboundConversion* unbound, BoundConversion* bound);
39 inline bool ArgContext::Bind(
const UnboundConversion* unbound,
40 BoundConversion* bound) {
41 const FormatArgImpl*
arg =
nullptr;
42 int arg_position = unbound->arg_position;
43 if (static_cast<size_t>(arg_position - 1) >=
pack_.size())
return false;
44 arg = &
pack_[arg_position - 1];
46 if (!unbound->flags.basic) {
47 int width = unbound->width.value();
48 bool force_left =
false;
49 if (unbound->width.is_from_arg()) {
50 if (!BindFromPosition(unbound->width.get_from_arg(), &width,
pack_))
57 width = -std::max(width, -std::numeric_limits<int>::max());
61 int precision = unbound->precision.value();
62 if (unbound->precision.is_from_arg()) {
63 if (!BindFromPosition(unbound->precision.get_from_arg(), &precision,
68 bound->set_width(width);
69 bound->set_precision(precision);
70 bound->set_flags(unbound->flags);
72 bound->set_left(
true);
74 bound->set_flags(unbound->flags);
76 bound->set_precision(-1);
79 bound->set_length_mod(unbound->length_mod);
80 bound->set_conv(unbound->conv);
85 template <
typename Converter>
86 class ConverterConsumer {
91 bool Append(string_view s) {
95 bool ConvertOne(
const UnboundConversion& conv, string_view conv_string) {
96 BoundConversion bound;
98 return converter_.ConvertOne(bound, conv_string);
106 template <
typename Converter>
107 bool ConvertAll(
const UntypedFormatSpecImpl
format,
109 if (format.has_parsed_conversion()) {
110 return format.parsed_conversion()->ProcessFormat(
111 ConverterConsumer<Converter>(converter, args));
114 ConverterConsumer<Converter>(converter, args));
118 class DefaultConverter {
120 explicit DefaultConverter(FormatSinkImpl* sink) :
sink_(sink) {}
122 void Append(string_view s)
const {
sink_->Append(s); }
124 bool ConvertOne(
const BoundConversion& bound, string_view )
const {
132 class SummarizingConverter {
134 explicit SummarizingConverter(FormatSinkImpl* sink) :
sink_(sink) {}
136 void Append(string_view s)
const {
sink_->Append(s); }
138 bool ConvertOne(
const BoundConversion& bound, string_view )
const {
139 UntypedFormatSpecImpl spec(
"%d");
141 std::ostringstream ss;
142 ss <<
"{" << Streamable(spec, {*bound.arg()}) <<
":" << bound.flags();
143 if (bound.width() >= 0) ss << bound.width();
144 if (bound.precision() >= 0) ss <<
"." << bound.precision();
145 ss << bound.length_mod() << bound.conv() <<
"}";
151 FormatSinkImpl*
sink_;
159 return ArgContext(pack).Bind(props, bound);
164 typedef SummarizingConverter Converter;
170 if (!ConvertAll(format, args, Converter(&sink))) {
181 using Converter = DefaultConverter;
182 return ConvertAll(format, args, Converter(&sink));
192 size_t orig = out->size();
207 errno = sink.
error();
210 if (sink.
count() > std::numeric_limits<int>::max()) {
214 return static_cast<int>(sink.
count());
225 if (size) output[std::min(total, size - 1)] = 0;
226 return static_cast<int>(total);
absl::Span< const FormatArgImpl > pack_
#define ABSL_PREDICT_FALSE(x)
std::vector< std::string > args_
constexpr size_type size() const noexcept
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
static char * Append(char *out, const AlphaNum &x)