17
17
#include " format.h" // std_string_view
18
18
19
19
FMT_BEGIN_NAMESPACE
20
-
21
20
namespace detail {
22
21
23
22
template <typename T> struct is_reference_wrapper : std::false_type {};
@@ -72,19 +71,13 @@ class dynamic_arg_list {
72
71
* It can be implicitly converted into `fmt::basic_format_args` for passing
73
72
* into type-erased formatting functions such as `fmt::vformat`.
74
73
*/
75
- template <typename Context>
76
- class dynamic_format_arg_store
77
- #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
78
- // Workaround a GCC template argument substitution bug.
79
- : public basic_format_args<Context>
80
- #endif
81
- {
74
+ template <typename Context> class dynamic_format_arg_store {
82
75
private:
83
76
using char_type = typename Context::char_type;
84
77
85
78
template <typename T> struct need_copy {
86
79
static constexpr detail::type mapped_type =
87
- detail::mapped_type_constant<T, Context >::value;
80
+ detail::mapped_type_constant<T, char_type >::value;
88
81
89
82
enum {
90
83
value = !(detail::is_reference_wrapper<T>::value ||
@@ -97,7 +90,7 @@ class dynamic_format_arg_store
97
90
};
98
91
99
92
template <typename T>
100
- using stored_type = conditional_t <
93
+ using stored_t = conditional_t <
101
94
std::is_convertible<T, std::basic_string<char_type>>::value &&
102
95
!detail::is_reference_wrapper<T>::value,
103
96
std::basic_string<char_type>, T>;
@@ -112,41 +105,37 @@ class dynamic_format_arg_store
112
105
113
106
friend class basic_format_args <Context>;
114
107
115
- auto get_types () const -> unsigned long long {
116
- return detail::is_unpacked_bit | data_.size () |
117
- (named_info_.empty ()
118
- ? 0ULL
119
- : static_cast <unsigned long long >(detail::has_named_args_bit));
120
- }
121
-
122
108
auto data () const -> const basic_format_arg<Context>* {
123
109
return named_info_.empty () ? data_.data () : data_.data () + 1 ;
124
110
}
125
111
126
112
template <typename T> void emplace_arg (const T& arg) {
127
- data_.emplace_back (detail::make_arg<Context>( arg) );
113
+ data_.emplace_back (arg);
128
114
}
129
115
130
116
template <typename T>
131
117
void emplace_arg (const detail::named_arg<char_type, T>& arg) {
132
- if (named_info_.empty ()) {
133
- constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr };
134
- data_.insert (data_.begin (), {zero_ptr, 0 });
135
- }
136
- data_.emplace_back (detail::make_arg<Context>(detail::unwrap (arg.value )));
118
+ if (named_info_.empty ())
119
+ data_.insert (data_.begin (), basic_format_arg<Context>(nullptr , 0 ));
120
+ data_.emplace_back (detail::unwrap (arg.value ));
137
121
auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
138
122
data->pop_back ();
139
123
};
140
124
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype (pop_one)>
141
125
guard{&data_, pop_one};
142
126
named_info_.push_back ({arg.name , static_cast <int >(data_.size () - 2u )});
143
- data_[0 ]. value_ . named_args = {named_info_.data (), named_info_.size ()};
127
+ data_[0 ] = {named_info_.data (), named_info_.size ()};
144
128
guard.release ();
145
129
}
146
130
147
131
public:
148
132
constexpr dynamic_format_arg_store () = default;
149
133
134
+ operator basic_format_args<Context>() const {
135
+ return basic_format_args<Context>(data (), static_cast <int >(data_.size ()),
136
+ !named_info_.empty ());
137
+ }
138
+
150
139
/* *
151
140
* Adds an argument into the dynamic store for later passing to a formatting
152
141
* function.
@@ -164,7 +153,7 @@ class dynamic_format_arg_store
164
153
*/
165
154
template <typename T> void push_back (const T& arg) {
166
155
if (detail::const_check (need_copy<T>::value))
167
- emplace_arg (dynamic_args_.push <stored_type <T>>(arg));
156
+ emplace_arg (dynamic_args_.push <stored_t <T>>(arg));
168
157
else
169
158
emplace_arg (detail::unwrap (arg));
170
159
}
@@ -200,7 +189,7 @@ class dynamic_format_arg_store
200
189
dynamic_args_.push <std::basic_string<char_type>>(arg.name ).c_str ();
201
190
if (detail::const_check (need_copy<T>::value)) {
202
191
emplace_arg (
203
- fmt::arg (arg_name, dynamic_args_.push <stored_type <T>>(arg.value )));
192
+ fmt::arg (arg_name, dynamic_args_.push <stored_t <T>>(arg.value )));
204
193
} else {
205
194
emplace_arg (fmt::arg (arg_name, arg.value ));
206
195
}
@@ -210,17 +199,20 @@ class dynamic_format_arg_store
210
199
void clear () {
211
200
data_.clear ();
212
201
named_info_.clear ();
213
- dynamic_args_ = detail::dynamic_arg_list () ;
202
+ dynamic_args_ = {} ;
214
203
}
215
204
216
205
// / Reserves space to store at least `new_cap` arguments including
217
206
// / `new_cap_named` named arguments.
218
207
void reserve (size_t new_cap, size_t new_cap_named) {
219
208
FMT_ASSERT (new_cap >= new_cap_named,
220
- " Set of arguments includes set of named arguments" );
209
+ " set of arguments includes set of named arguments" );
221
210
data_.reserve (new_cap);
222
211
named_info_.reserve (new_cap_named);
223
212
}
213
+
214
+ // / Returns the number of elements in the store.
215
+ size_t size () const noexcept { return data_.size (); }
224
216
};
225
217
226
218
FMT_END_NAMESPACE
0 commit comments