45 template <
typename T>
struct typed_node :
node<> {
48 template <
typename Arg>
49 FMT_CONSTEXPR typed_node(
const Arg& arg) :
value(arg) {}
51 template <
typename Char>
53 :
value(arg.data(), arg.size()) {}
56 std::unique_ptr<node<>> head_;
59 template <
typename T,
typename Arg>
auto push(
const Arg& arg) ->
const T& {
60 auto new_node = std::unique_ptr<typed_node<T>>(
new typed_node<T>(arg));
61 auto&
value = new_node->value;
62 new_node->next = std::move(head_);
63 head_ = std::move(new_node);
76class dynamic_format_arg_store
77#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
83 using char_type =
typename Context::char_type;
85 template <
typename T>
struct need_copy {
86 static constexpr detail::type mapped_type =
87 detail::mapped_type_constant<T, Context>::value;
91 std::is_same<T, basic_string_view<char_type>>::value ||
92 std::is_same<T, detail::std_string_view<char_type>>::value ||
93 (mapped_type != detail::type::cstring_type &&
94 mapped_type != detail::type::string_type &&
95 mapped_type != detail::type::custom_type))
100 using stored_type = conditional_t<
101 std::is_convertible<T, std::basic_string<char_type>>::value &&
103 std::basic_string<char_type>, T>;
106 std::vector<basic_format_arg<Context>> data_;
107 std::vector<detail::named_arg_info<char_type>> named_info_;
115 auto get_types()
const ->
unsigned long long {
116 return detail::is_unpacked_bit | data_.size() |
119 :
static_cast<unsigned long long>(detail::has_named_args_bit));
123 return named_info_.empty() ? data_.data() : data_.data() + 1;
126 template <
typename T>
void emplace_arg(
const T& arg) {
127 data_.emplace_back(detail::make_arg<Context>(arg));
130 template <
typename T>
132 if (named_info_.empty()) {
134 data_.insert(data_.begin(), {zero_ptr, 0});
136 data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
137 auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
140 std::unique_ptr<std::vector<basic_format_arg<Context>>,
decltype(pop_one)>
141 guard{&data_, pop_one};
142 named_info_.push_back({arg.name,
static_cast<int>(data_.size() - 2u)});
143 data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
148 constexpr dynamic_format_arg_store() =
default;
166 if (detail::const_check(need_copy<T>::value))
167 emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
169 emplace_arg(detail::unwrap(arg));
185 template <
typename T>
void push_back(std::reference_wrapper<T> arg) {
188 "objects of built-in types and string views are always copied");
189 emplace_arg(arg.get());
197 template <
typename T>
199 const char_type* arg_name =
200 dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
201 if (detail::const_check(need_copy<T>::value)) {
203 fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
205 emplace_arg(fmt::arg(arg_name, arg.value));
218 void reserve(
size_t new_cap,
size_t new_cap_named) {
219 FMT_ASSERT(new_cap >= new_cap_named,
220 "Set of arguments includes set of named arguments");
221 data_.reserve(new_cap);
222 named_info_.reserve(new_cap_named);