git repos / blockattack-game

blame: source/misc/embedded_libs/fmt-11.0.2/include/fmt/args.h

normal view · raw

47fd5c32 Poul Sander 2024-10-05 08:44 1
// Formatting library for C++ - dynamic argument lists
f8deb5b9 Poul Sander 2022-01-15 13:55 2
//
f8deb5b9 Poul Sander 2022-01-15 13:55 3
// Copyright (c) 2012 - present, Victor Zverovich
f8deb5b9 Poul Sander 2022-01-15 13:55 4
// All rights reserved.
f8deb5b9 Poul Sander 2022-01-15 13:55 5
//
f8deb5b9 Poul Sander 2022-01-15 13:55 6
// For the license information refer to format.h.
f8deb5b9 Poul Sander 2022-01-15 13:55 7
f8deb5b9 Poul Sander 2022-01-15 13:55 8
#ifndef FMT_ARGS_H_
f8deb5b9 Poul Sander 2022-01-15 13:55 9
#define FMT_ARGS_H_
f8deb5b9 Poul Sander 2022-01-15 13:55 10
47fd5c32 Poul Sander 2024-10-05 08:44 11
#ifndef FMT_MODULE
47fd5c32 Poul Sander 2024-10-05 08:44 12
#  include <functional>  // std::reference_wrapper
47fd5c32 Poul Sander 2024-10-05 08:44 13
#  include <memory>      // std::unique_ptr
47fd5c32 Poul Sander 2024-10-05 08:44 14
#  include <vector>
47fd5c32 Poul Sander 2024-10-05 08:44 15
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 16
47fd5c32 Poul Sander 2024-10-05 08:44 17
#include "format.h"  // std_string_view
f8deb5b9 Poul Sander 2022-01-15 13:55 18
f8deb5b9 Poul Sander 2022-01-15 13:55 19
FMT_BEGIN_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 20
f8deb5b9 Poul Sander 2022-01-15 13:55 21
namespace detail {
f8deb5b9 Poul Sander 2022-01-15 13:55 22
f8deb5b9 Poul Sander 2022-01-15 13:55 23
template <typename T> struct is_reference_wrapper : std::false_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 24
template <typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 25
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 26
47fd5c32 Poul Sander 2024-10-05 08:44 27
template <typename T> auto unwrap(const T& v) -> const T& { return v; }
47fd5c32 Poul Sander 2024-10-05 08:44 28
template <typename T>
47fd5c32 Poul Sander 2024-10-05 08:44 29
auto unwrap(const std::reference_wrapper<T>& v) -> const T& {
f8deb5b9 Poul Sander 2022-01-15 13:55 30
  return static_cast<const T&>(v);
f8deb5b9 Poul Sander 2022-01-15 13:55 31
}
f8deb5b9 Poul Sander 2022-01-15 13:55 32
47fd5c32 Poul Sander 2024-10-05 08:44 33
// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC
47fd5c32 Poul Sander 2024-10-05 08:44 34
// 2022 (v17.10.0).
47fd5c32 Poul Sander 2024-10-05 08:44 35
//
47fd5c32 Poul Sander 2024-10-05 08:44 36
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
47fd5c32 Poul Sander 2024-10-05 08:44 37
// templates it doesn't complain about inability to deduce single translation
47fd5c32 Poul Sander 2024-10-05 08:44 38
// unit for placing vtable. So node is made a fake template.
47fd5c32 Poul Sander 2024-10-05 08:44 39
template <typename = void> struct node {
47fd5c32 Poul Sander 2024-10-05 08:44 40
  virtual ~node() = default;
47fd5c32 Poul Sander 2024-10-05 08:44 41
  std::unique_ptr<node<>> next;
47fd5c32 Poul Sander 2024-10-05 08:44 42
};
f8deb5b9 Poul Sander 2022-01-15 13:55 43
47fd5c32 Poul Sander 2024-10-05 08:44 44
class dynamic_arg_list {
f8deb5b9 Poul Sander 2022-01-15 13:55 45
  template <typename T> struct typed_node : node<> {
f8deb5b9 Poul Sander 2022-01-15 13:55 46
    T value;
f8deb5b9 Poul Sander 2022-01-15 13:55 47
f8deb5b9 Poul Sander 2022-01-15 13:55 48
    template <typename Arg>
f8deb5b9 Poul Sander 2022-01-15 13:55 49
    FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 50
f8deb5b9 Poul Sander 2022-01-15 13:55 51
    template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 52
    FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg)
f8deb5b9 Poul Sander 2022-01-15 13:55 53
        : value(arg.data(), arg.size()) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 54
  };
f8deb5b9 Poul Sander 2022-01-15 13:55 55
f8deb5b9 Poul Sander 2022-01-15 13:55 56
  std::unique_ptr<node<>> head_;
f8deb5b9 Poul Sander 2022-01-15 13:55 57
f8deb5b9 Poul Sander 2022-01-15 13:55 58
 public:
47fd5c32 Poul Sander 2024-10-05 08:44 59
  template <typename T, typename Arg> auto push(const Arg& arg) -> const T& {
f8deb5b9 Poul Sander 2022-01-15 13:55 60
    auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
f8deb5b9 Poul Sander 2022-01-15 13:55 61
    auto& value = new_node->value;
f8deb5b9 Poul Sander 2022-01-15 13:55 62
    new_node->next = std::move(head_);
f8deb5b9 Poul Sander 2022-01-15 13:55 63
    head_ = std::move(new_node);
f8deb5b9 Poul Sander 2022-01-15 13:55 64
    return value;
f8deb5b9 Poul Sander 2022-01-15 13:55 65
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 66
};
f8deb5b9 Poul Sander 2022-01-15 13:55 67
}  // namespace detail
f8deb5b9 Poul Sander 2022-01-15 13:55 68
f8deb5b9 Poul Sander 2022-01-15 13:55 69
/**
47fd5c32 Poul Sander 2024-10-05 08:44 70
 * A dynamic list of formatting arguments with storage.
47fd5c32 Poul Sander 2024-10-05 08:44 71
 *
47fd5c32 Poul Sander 2024-10-05 08:44 72
 * It can be implicitly converted into `fmt::basic_format_args` for passing
47fd5c32 Poul Sander 2024-10-05 08:44 73
 * into type-erased formatting functions such as `fmt::vformat`.
f8deb5b9 Poul Sander 2022-01-15 13:55 74
 */
f8deb5b9 Poul Sander 2022-01-15 13:55 75
template <typename Context>
f8deb5b9 Poul Sander 2022-01-15 13:55 76
class dynamic_format_arg_store
f8deb5b9 Poul Sander 2022-01-15 13:55 77
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
f8deb5b9 Poul Sander 2022-01-15 13:55 78
    // Workaround a GCC template argument substitution bug.
f8deb5b9 Poul Sander 2022-01-15 13:55 79
    : public basic_format_args<Context>
f8deb5b9 Poul Sander 2022-01-15 13:55 80
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 81
{
f8deb5b9 Poul Sander 2022-01-15 13:55 82
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 83
  using char_type = typename Context::char_type;
f8deb5b9 Poul Sander 2022-01-15 13:55 84
f8deb5b9 Poul Sander 2022-01-15 13:55 85
  template <typename T> struct need_copy {
f8deb5b9 Poul Sander 2022-01-15 13:55 86
    static constexpr detail::type mapped_type =
f8deb5b9 Poul Sander 2022-01-15 13:55 87
        detail::mapped_type_constant<T, Context>::value;
f8deb5b9 Poul Sander 2022-01-15 13:55 88
f8deb5b9 Poul Sander 2022-01-15 13:55 89
    enum {
f8deb5b9 Poul Sander 2022-01-15 13:55 90
      value = !(detail::is_reference_wrapper<T>::value ||
f8deb5b9 Poul Sander 2022-01-15 13:55 91
                std::is_same<T, basic_string_view<char_type>>::value ||
f8deb5b9 Poul Sander 2022-01-15 13:55 92
                std::is_same<T, detail::std_string_view<char_type>>::value ||
f8deb5b9 Poul Sander 2022-01-15 13:55 93
                (mapped_type != detail::type::cstring_type &&
f8deb5b9 Poul Sander 2022-01-15 13:55 94
                 mapped_type != detail::type::string_type &&
f8deb5b9 Poul Sander 2022-01-15 13:55 95
                 mapped_type != detail::type::custom_type))
f8deb5b9 Poul Sander 2022-01-15 13:55 96
    };
f8deb5b9 Poul Sander 2022-01-15 13:55 97
  };
f8deb5b9 Poul Sander 2022-01-15 13:55 98
f8deb5b9 Poul Sander 2022-01-15 13:55 99
  template <typename T>
47fd5c32 Poul Sander 2024-10-05 08:44 100
  using stored_type = conditional_t<
47fd5c32 Poul Sander 2024-10-05 08:44 101
      std::is_convertible<T, std::basic_string<char_type>>::value &&
47fd5c32 Poul Sander 2024-10-05 08:44 102
          !detail::is_reference_wrapper<T>::value,
47fd5c32 Poul Sander 2024-10-05 08:44 103
      std::basic_string<char_type>, T>;
f8deb5b9 Poul Sander 2022-01-15 13:55 104
f8deb5b9 Poul Sander 2022-01-15 13:55 105
  // Storage of basic_format_arg must be contiguous.
f8deb5b9 Poul Sander 2022-01-15 13:55 106
  std::vector<basic_format_arg<Context>> data_;
f8deb5b9 Poul Sander 2022-01-15 13:55 107
  std::vector<detail::named_arg_info<char_type>> named_info_;
f8deb5b9 Poul Sander 2022-01-15 13:55 108
f8deb5b9 Poul Sander 2022-01-15 13:55 109
  // Storage of arguments not fitting into basic_format_arg must grow
f8deb5b9 Poul Sander 2022-01-15 13:55 110
  // without relocation because items in data_ refer to it.
f8deb5b9 Poul Sander 2022-01-15 13:55 111
  detail::dynamic_arg_list dynamic_args_;
f8deb5b9 Poul Sander 2022-01-15 13:55 112
f8deb5b9 Poul Sander 2022-01-15 13:55 113
  friend class basic_format_args<Context>;
f8deb5b9 Poul Sander 2022-01-15 13:55 114
47fd5c32 Poul Sander 2024-10-05 08:44 115
  auto get_types() const -> unsigned long long {
f8deb5b9 Poul Sander 2022-01-15 13:55 116
    return detail::is_unpacked_bit | data_.size() |
f8deb5b9 Poul Sander 2022-01-15 13:55 117
           (named_info_.empty()
f8deb5b9 Poul Sander 2022-01-15 13:55 118
                ? 0ULL
f8deb5b9 Poul Sander 2022-01-15 13:55 119
                : static_cast<unsigned long long>(detail::has_named_args_bit));
f8deb5b9 Poul Sander 2022-01-15 13:55 120
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 121
47fd5c32 Poul Sander 2024-10-05 08:44 122
  auto data() const -> const basic_format_arg<Context>* {
f8deb5b9 Poul Sander 2022-01-15 13:55 123
    return named_info_.empty() ? data_.data() : data_.data() + 1;
f8deb5b9 Poul Sander 2022-01-15 13:55 124
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 125
f8deb5b9 Poul Sander 2022-01-15 13:55 126
  template <typename T> void emplace_arg(const T& arg) {
f8deb5b9 Poul Sander 2022-01-15 13:55 127
    data_.emplace_back(detail::make_arg<Context>(arg));
f8deb5b9 Poul Sander 2022-01-15 13:55 128
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 129
f8deb5b9 Poul Sander 2022-01-15 13:55 130
  template <typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 131
  void emplace_arg(const detail::named_arg<char_type, T>& arg) {
f8deb5b9 Poul Sander 2022-01-15 13:55 132
    if (named_info_.empty()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 133
      constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr};
f8deb5b9 Poul Sander 2022-01-15 13:55 134
      data_.insert(data_.begin(), {zero_ptr, 0});
f8deb5b9 Poul Sander 2022-01-15 13:55 135
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 136
    data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
f8deb5b9 Poul Sander 2022-01-15 13:55 137
    auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
f8deb5b9 Poul Sander 2022-01-15 13:55 138
      data->pop_back();
f8deb5b9 Poul Sander 2022-01-15 13:55 139
    };
f8deb5b9 Poul Sander 2022-01-15 13:55 140
    std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
f8deb5b9 Poul Sander 2022-01-15 13:55 141
        guard{&data_, pop_one};
f8deb5b9 Poul Sander 2022-01-15 13:55 142
    named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
f8deb5b9 Poul Sander 2022-01-15 13:55 143
    data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
f8deb5b9 Poul Sander 2022-01-15 13:55 144
    guard.release();
f8deb5b9 Poul Sander 2022-01-15 13:55 145
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 146
f8deb5b9 Poul Sander 2022-01-15 13:55 147
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 148
  constexpr dynamic_format_arg_store() = default;
f8deb5b9 Poul Sander 2022-01-15 13:55 149
f8deb5b9 Poul Sander 2022-01-15 13:55 150
  /**
47fd5c32 Poul Sander 2024-10-05 08:44 151
   * Adds an argument into the dynamic store for later passing to a formatting
47fd5c32 Poul Sander 2024-10-05 08:44 152
   * function.
47fd5c32 Poul Sander 2024-10-05 08:44 153
   *
47fd5c32 Poul Sander 2024-10-05 08:44 154
   * Note that custom types and string types (but not string views) are copied
47fd5c32 Poul Sander 2024-10-05 08:44 155
   * into the store dynamically allocating memory if necessary.
47fd5c32 Poul Sander 2024-10-05 08:44 156
   *
47fd5c32 Poul Sander 2024-10-05 08:44 157
   * **Example**:
47fd5c32 Poul Sander 2024-10-05 08:44 158
   *
47fd5c32 Poul Sander 2024-10-05 08:44 159
   *     fmt::dynamic_format_arg_store<fmt::format_context> store;
47fd5c32 Poul Sander 2024-10-05 08:44 160
   *     store.push_back(42);
47fd5c32 Poul Sander 2024-10-05 08:44 161
   *     store.push_back("abc");
47fd5c32 Poul Sander 2024-10-05 08:44 162
   *     store.push_back(1.5f);
47fd5c32 Poul Sander 2024-10-05 08:44 163
   *     std::string result = fmt::vformat("{} and {} and {}", store);
47fd5c32 Poul Sander 2024-10-05 08:44 164
   */
f8deb5b9 Poul Sander 2022-01-15 13:55 165
  template <typename T> void push_back(const T& arg) {
f8deb5b9 Poul Sander 2022-01-15 13:55 166
    if (detail::const_check(need_copy<T>::value))
f8deb5b9 Poul Sander 2022-01-15 13:55 167
      emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
f8deb5b9 Poul Sander 2022-01-15 13:55 168
    else
f8deb5b9 Poul Sander 2022-01-15 13:55 169
      emplace_arg(detail::unwrap(arg));
f8deb5b9 Poul Sander 2022-01-15 13:55 170
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 171
f8deb5b9 Poul Sander 2022-01-15 13:55 172
  /**
47fd5c32 Poul Sander 2024-10-05 08:44 173
   * Adds a reference to the argument into the dynamic store for later passing
47fd5c32 Poul Sander 2024-10-05 08:44 174
   * to a formatting function.
47fd5c32 Poul Sander 2024-10-05 08:44 175
   *
47fd5c32 Poul Sander 2024-10-05 08:44 176
   * **Example**:
47fd5c32 Poul Sander 2024-10-05 08:44 177
   *
47fd5c32 Poul Sander 2024-10-05 08:44 178
   *     fmt::dynamic_format_arg_store<fmt::format_context> store;
47fd5c32 Poul Sander 2024-10-05 08:44 179
   *     char band[] = "Rolling Stones";
47fd5c32 Poul Sander 2024-10-05 08:44 180
   *     store.push_back(std::cref(band));
47fd5c32 Poul Sander 2024-10-05 08:44 181
   *     band[9] = 'c'; // Changing str affects the output.
47fd5c32 Poul Sander 2024-10-05 08:44 182
   *     std::string result = fmt::vformat("{}", store);
47fd5c32 Poul Sander 2024-10-05 08:44 183
   *     // result == "Rolling Scones"
47fd5c32 Poul Sander 2024-10-05 08:44 184
   */
f8deb5b9 Poul Sander 2022-01-15 13:55 185
  template <typename T> void push_back(std::reference_wrapper<T> arg) {
f8deb5b9 Poul Sander 2022-01-15 13:55 186
    static_assert(
f8deb5b9 Poul Sander 2022-01-15 13:55 187
        need_copy<T>::value,
f8deb5b9 Poul Sander 2022-01-15 13:55 188
        "objects of built-in types and string views are always copied");
f8deb5b9 Poul Sander 2022-01-15 13:55 189
    emplace_arg(arg.get());
f8deb5b9 Poul Sander 2022-01-15 13:55 190
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 191
f8deb5b9 Poul Sander 2022-01-15 13:55 192
  /**
47fd5c32 Poul Sander 2024-10-05 08:44 193
   * Adds named argument into the dynamic store for later passing to a
47fd5c32 Poul Sander 2024-10-05 08:44 194
   * formatting function. `std::reference_wrapper` is supported to avoid
47fd5c32 Poul Sander 2024-10-05 08:44 195
   * copying of the argument. The name is always copied into the store.
47fd5c32 Poul Sander 2024-10-05 08:44 196
   */
f8deb5b9 Poul Sander 2022-01-15 13:55 197
  template <typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 198
  void push_back(const detail::named_arg<char_type, T>& arg) {
f8deb5b9 Poul Sander 2022-01-15 13:55 199
    const char_type* arg_name =
f8deb5b9 Poul Sander 2022-01-15 13:55 200
        dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
f8deb5b9 Poul Sander 2022-01-15 13:55 201
    if (detail::const_check(need_copy<T>::value)) {
f8deb5b9 Poul Sander 2022-01-15 13:55 202
      emplace_arg(
f8deb5b9 Poul Sander 2022-01-15 13:55 203
          fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
f8deb5b9 Poul Sander 2022-01-15 13:55 204
    } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 205
      emplace_arg(fmt::arg(arg_name, arg.value));
f8deb5b9 Poul Sander 2022-01-15 13:55 206
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 207
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 208
47fd5c32 Poul Sander 2024-10-05 08:44 209
  /// Erase all elements from the store.
f8deb5b9 Poul Sander 2022-01-15 13:55 210
  void clear() {
f8deb5b9 Poul Sander 2022-01-15 13:55 211
    data_.clear();
f8deb5b9 Poul Sander 2022-01-15 13:55 212
    named_info_.clear();
f8deb5b9 Poul Sander 2022-01-15 13:55 213
    dynamic_args_ = detail::dynamic_arg_list();
f8deb5b9 Poul Sander 2022-01-15 13:55 214
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 215
47fd5c32 Poul Sander 2024-10-05 08:44 216
  /// Reserves space to store at least `new_cap` arguments including
47fd5c32 Poul Sander 2024-10-05 08:44 217
  /// `new_cap_named` named arguments.
f8deb5b9 Poul Sander 2022-01-15 13:55 218
  void reserve(size_t new_cap, size_t new_cap_named) {
f8deb5b9 Poul Sander 2022-01-15 13:55 219
    FMT_ASSERT(new_cap >= new_cap_named,
f8deb5b9 Poul Sander 2022-01-15 13:55 220
               "Set of arguments includes set of named arguments");
f8deb5b9 Poul Sander 2022-01-15 13:55 221
    data_.reserve(new_cap);
f8deb5b9 Poul Sander 2022-01-15 13:55 222
    named_info_.reserve(new_cap_named);
f8deb5b9 Poul Sander 2022-01-15 13:55 223
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 224
};
f8deb5b9 Poul Sander 2022-01-15 13:55 225
f8deb5b9 Poul Sander 2022-01-15 13:55 226
FMT_END_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 227
f8deb5b9 Poul Sander 2022-01-15 13:55 228
#endif  // FMT_ARGS_H_
1970-01-01 00:00 229