git repos / blockattack-game

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

normal view · raw

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