8 #ifndef FMTQUILL_ARGS_H_ 9 #define FMTQUILL_ARGS_H_ 11 #ifndef FMTQUILL_MODULE 12 # include <functional> 19 FMTQUILL_BEGIN_NAMESPACE
26 template <
typename T>
auto unwrap(
const T& v) ->
const T& {
return v; }
28 auto unwrap(
const std::reference_wrapper<T>& v) ->
const T& {
29 return static_cast<const T&
>(v);
38 template <
typename =
void>
struct node {
39 virtual ~
node() =
default;
40 std::unique_ptr<node<>> next;
44 template <
typename T>
struct typed_node :
node<> {
47 template <
typename Arg>
48 FMTQUILL_CONSTEXPR typed_node(
const Arg& arg) : value(arg) {}
50 template <
typename Char>
55 std::unique_ptr<node<>> head_;
58 template <
typename T,
typename Arg>
auto push(
const Arg& arg) ->
const T& {
59 auto new_node = std::unique_ptr<typed_node<T>>(
new typed_node<T>(arg));
60 auto&
value = new_node->value;
61 new_node->next = std::move(head_);
62 head_ = std::move(new_node);
76 using char_type =
typename Context::char_type;
78 template <
typename T>
struct need_copy {
79 static constexpr detail::type mapped_type =
84 std::is_same<T, basic_string_view<char_type>>::value ||
85 std::is_same<T, detail::std_string_view<char_type>>::value ||
86 (mapped_type != detail::type::cstring_type &&
87 mapped_type != detail::type::string_type &&
88 mapped_type != detail::type::custom_type))
93 using stored_t = conditional_t<
94 std::is_convertible<T, std::basic_string<char_type>>::value &&
96 std::basic_string<char_type>, T>;
99 std::vector<basic_format_arg<Context>> data_;
100 std::vector<detail::named_arg_info<char_type>> named_info_;
109 return named_info_.empty() ? data_.data() : data_.data() + 1;
112 template <
typename T>
void emplace_arg(
const T& arg) {
113 data_.emplace_back(arg);
116 template <
typename T>
118 if (named_info_.empty())
120 data_.emplace_back(detail::unwrap(arg.value));
121 auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
124 std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
125 guard{&data_, pop_one};
126 named_info_.push_back({arg.name,
static_cast<int>(data_.size() - 2u)});
127 data_[0] = {named_info_.data(), named_info_.size()};
136 !named_info_.empty());
155 if (detail::const_check(need_copy<T>::value))
156 emplace_arg(dynamic_args_.push<stored_t<T>>(arg));
158 emplace_arg(detail::unwrap(arg));
174 template <
typename T>
void push_back(std::reference_wrapper<T> arg) {
177 "objects of built-in types and string views are always copied");
178 emplace_arg(arg.get());
186 template <
typename T>
188 const char_type* arg_name =
189 dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
190 if (detail::const_check(need_copy<T>::value)) {
192 fmtquill::arg(arg_name, dynamic_args_.push<stored_t<T>>(arg.value)));
194 emplace_arg(fmtquill::arg(arg_name, arg.value));
207 void reserve(
size_t new_cap,
size_t new_cap_named) {
208 FMTQUILL_ASSERT(new_cap >= new_cap_named,
209 "set of arguments includes set of named arguments");
210 data_.reserve(new_cap);
211 named_info_.reserve(new_cap_named);
215 size_t size() const noexcept {
return data_.size(); }
218 FMTQUILL_END_NAMESPACE
220 #endif // FMTQUILL_ARGS_H_
constexpr auto data() const noexcept -> const Char *
Returns a pointer to the string data.
Definition: base.h:565
constexpr auto size() const noexcept -> size_t
Returns the string size.
Definition: base.h:568
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
An implementation of std::basic_string_view for pre-C++17.
Definition: base.h:523