Skip to content

Commit a8515ad

Browse files
committed
switch to fmt::dynamic_format_args_store
1 parent 1ceb9d8 commit a8515ad

File tree

1 file changed

+28
-67
lines changed

1 file changed

+28
-67
lines changed

src/serialize_filters.cpp

Lines changed: 28 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ InternalValue Serialize::Filter(const InternalValue& value, RenderContext& conte
156156
return str +"\\u003e";
157157
break;
158158
case '&':
159-
return str +"\\u0026";
159+
return str +"\\u0026";
160160
break;
161161
case '\'':
162162
return str +"\\u0027";
@@ -178,17 +178,25 @@ namespace
178178

179179
using FormatContext = fmt::format_context;
180180
using FormatArgument = fmt::basic_format_arg<FormatContext>;
181+
using FormatDynamicArgsStore = fmt::dynamic_format_arg_store<FormatContext>;
181182

182-
template<typename ResultDecorator>
183183
struct FormatArgumentConverter : visitors::BaseVisitor<FormatArgument>
184184
{
185185
using result_t = FormatArgument;
186186

187187
using BaseVisitor::operator();
188188

189-
FormatArgumentConverter(const RenderContext* context, const ResultDecorator& decorator)
189+
FormatArgumentConverter(const RenderContext* context, FormatDynamicArgsStore& store)
190190
: m_context(context)
191-
, m_decorator(decorator)
191+
, m_store(store)
192+
{
193+
}
194+
195+
FormatArgumentConverter(const RenderContext* context, FormatDynamicArgsStore& store, const std::string& name)
196+
: m_context(context)
197+
, m_store(store)
198+
, m_name(name)
199+
, m_named(true)
192200
{
193201
}
194202

@@ -217,62 +225,21 @@ struct FormatArgumentConverter : visitors::BaseVisitor<FormatArgument>
217225
template<typename T>
218226
result_t make_result(const T& t) const
219227
{
220-
return fmt::detail::make_arg<FormatContext>(m_decorator(t));
228+
if (!m_named)
229+
{
230+
m_store.push_back(t);
231+
}
232+
else
233+
{
234+
m_store.push_back(fmt::arg(m_name.c_str(), t));
235+
}
236+
return fmt::detail::make_arg<FormatContext>(t);
221237
}
222238

223239
const RenderContext* m_context;
224-
const ResultDecorator& m_decorator;
225-
};
226-
227-
template<typename T>
228-
using NamedArgument = fmt::detail::named_arg<char, T>;
229-
230-
using ValueHandle =
231-
nonstd::variant<bool, std::string, int64_t, double, NamedArgument<bool>, NamedArgument<std::string>, NamedArgument<int64_t>, NamedArgument<double>>;
232-
using ValuesBuffer = std::vector<ValueHandle>;
233-
234-
struct CachingIdentity
235-
{
236-
public:
237-
explicit CachingIdentity(ValuesBuffer& values)
238-
: m_values(values)
239-
{
240-
}
241-
242-
template<typename T>
243-
const auto& operator()(const T& t) const
244-
{
245-
m_values.push_back(t);
246-
return nonstd::get<T>(m_values.back());
247-
}
248-
249-
private:
250-
ValuesBuffer& m_values;
251-
};
252-
253-
class NamedArgumentCreator
254-
{
255-
public:
256-
NamedArgumentCreator(const std::string& name, ValuesBuffer& valuesBuffer)
257-
: m_name(name)
258-
, m_valuesBuffer(valuesBuffer)
259-
{
260-
}
261-
262-
template<typename T>
263-
const auto& operator()(const T& t) const
264-
{
265-
m_valuesBuffer.push_back(m_name);
266-
const auto& name = nonstd::get<std::string>(m_valuesBuffer.back());
267-
m_valuesBuffer.push_back(t);
268-
const auto& value = nonstd::get<T>(m_valuesBuffer.back());
269-
m_valuesBuffer.emplace_back(fmt::arg(name.c_str(), value));
270-
return nonstd::get<NamedArgument<T>>(m_valuesBuffer.back());
271-
}
272-
273-
private:
240+
FormatDynamicArgsStore& m_store;
274241
const std::string m_name;
275-
ValuesBuffer& m_valuesBuffer;
242+
bool m_named = false;
276243
};
277244

278245
}
@@ -282,24 +249,18 @@ InternalValue StringFormat::Filter(const InternalValue& baseVal, RenderContext&
282249
// Format library internally likes using non-owning views to complex arguments.
283250
// In order to ensure proper lifetime of values and named args,
284251
// helper buffer is created and passed to visitors.
285-
ValuesBuffer valuesBuffer;
286-
valuesBuffer.reserve(m_params.posParams.size() + 3 * m_params.kwParams.size());
287-
288-
std::vector<FormatArgument> args;
252+
FormatDynamicArgsStore store;
289253
for (auto& arg : m_params.posParams)
290254
{
291-
args.push_back(Apply<FormatArgumentConverter<CachingIdentity>>(arg->Evaluate(context), &context, CachingIdentity{ valuesBuffer }));
255+
Apply<FormatArgumentConverter>(arg->Evaluate(context), &context, store);
292256
}
293257

294258
for (auto& arg : m_params.kwParams)
295259
{
296-
args.push_back(
297-
Apply<FormatArgumentConverter<NamedArgumentCreator>>(arg.second->Evaluate(context), &context, NamedArgumentCreator{ arg.first, valuesBuffer }));
260+
Apply<FormatArgumentConverter>(arg.second->Evaluate(context), &context, store, arg.first);
298261
}
299-
// fmt process arguments until reaching empty argument
300-
args.push_back(FormatArgument{});
301262

302-
return InternalValue(fmt::vformat(AsString(baseVal), fmt::format_args(args.data(), static_cast<unsigned>(args.size() - 1))));
263+
return InternalValue(fmt::vformat(AsString(baseVal), store));
303264
}
304265

305266
class XmlAttrPrinter : public visitors::BaseVisitor<std::string>
@@ -448,7 +409,7 @@ class XmlAttrPrinter : public visitors::BaseVisitor<std::string>
448409
return str +"&gt;";
449410
break;
450411
case '&':
451-
return str +"&amp;";
412+
return str +"&amp;";
452413
break;
453414
case '\'':
454415
return str +"&#39;";

0 commit comments

Comments
 (0)