git repos / blockattack-game

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

normal view · raw

f8deb5b9 Poul Sander 2022-01-15 13:55 1
// Formatting library for C++ - experimental format string compilation
f8deb5b9 Poul Sander 2022-01-15 13:55 2
//
f8deb5b9 Poul Sander 2022-01-15 13:55 3
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
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_COMPILE_H_
f8deb5b9 Poul Sander 2022-01-15 13:55 9
#define FMT_COMPILE_H_
f8deb5b9 Poul Sander 2022-01-15 13:55 10
f8deb5b9 Poul Sander 2022-01-15 13:55 11
#include "format.h"
f8deb5b9 Poul Sander 2022-01-15 13:55 12
f8deb5b9 Poul Sander 2022-01-15 13:55 13
FMT_BEGIN_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 14
namespace detail {
f8deb5b9 Poul Sander 2022-01-15 13:55 15
f8deb5b9 Poul Sander 2022-01-15 13:55 16
// An output iterator that counts the number of objects written to it and
f8deb5b9 Poul Sander 2022-01-15 13:55 17
// discards them.
f8deb5b9 Poul Sander 2022-01-15 13:55 18
class counting_iterator {
f8deb5b9 Poul Sander 2022-01-15 13:55 19
 private:
f8deb5b9 Poul Sander 2022-01-15 13:55 20
  size_t count_;
f8deb5b9 Poul Sander 2022-01-15 13:55 21
f8deb5b9 Poul Sander 2022-01-15 13:55 22
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 23
  using iterator_category = std::output_iterator_tag;
f8deb5b9 Poul Sander 2022-01-15 13:55 24
  using difference_type = std::ptrdiff_t;
f8deb5b9 Poul Sander 2022-01-15 13:55 25
  using pointer = void;
f8deb5b9 Poul Sander 2022-01-15 13:55 26
  using reference = void;
f8deb5b9 Poul Sander 2022-01-15 13:55 27
  using _Unchecked_type = counting_iterator;  // Mark iterator as checked.
f8deb5b9 Poul Sander 2022-01-15 13:55 28
f8deb5b9 Poul Sander 2022-01-15 13:55 29
  struct value_type {
f8deb5b9 Poul Sander 2022-01-15 13:55 30
    template <typename T> void operator=(const T&) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 31
  };
f8deb5b9 Poul Sander 2022-01-15 13:55 32
f8deb5b9 Poul Sander 2022-01-15 13:55 33
  counting_iterator() : count_(0) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 34
f8deb5b9 Poul Sander 2022-01-15 13:55 35
  size_t count() const { return count_; }
f8deb5b9 Poul Sander 2022-01-15 13:55 36
f8deb5b9 Poul Sander 2022-01-15 13:55 37
  counting_iterator& operator++() {
f8deb5b9 Poul Sander 2022-01-15 13:55 38
    ++count_;
f8deb5b9 Poul Sander 2022-01-15 13:55 39
    return *this;
f8deb5b9 Poul Sander 2022-01-15 13:55 40
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 41
  counting_iterator operator++(int) {
f8deb5b9 Poul Sander 2022-01-15 13:55 42
    auto it = *this;
f8deb5b9 Poul Sander 2022-01-15 13:55 43
    ++*this;
f8deb5b9 Poul Sander 2022-01-15 13:55 44
    return it;
f8deb5b9 Poul Sander 2022-01-15 13:55 45
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 46
f8deb5b9 Poul Sander 2022-01-15 13:55 47
  friend counting_iterator operator+(counting_iterator it, difference_type n) {
f8deb5b9 Poul Sander 2022-01-15 13:55 48
    it.count_ += static_cast<size_t>(n);
f8deb5b9 Poul Sander 2022-01-15 13:55 49
    return it;
f8deb5b9 Poul Sander 2022-01-15 13:55 50
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 51
f8deb5b9 Poul Sander 2022-01-15 13:55 52
  value_type operator*() const { return {}; }
f8deb5b9 Poul Sander 2022-01-15 13:55 53
};
f8deb5b9 Poul Sander 2022-01-15 13:55 54
f8deb5b9 Poul Sander 2022-01-15 13:55 55
template <typename Char, typename InputIt>
f8deb5b9 Poul Sander 2022-01-15 13:55 56
inline counting_iterator copy_str(InputIt begin, InputIt end,
f8deb5b9 Poul Sander 2022-01-15 13:55 57
                                  counting_iterator it) {
f8deb5b9 Poul Sander 2022-01-15 13:55 58
  return it + (end - begin);
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
template <typename OutputIt> class truncating_iterator_base {
f8deb5b9 Poul Sander 2022-01-15 13:55 62
 protected:
f8deb5b9 Poul Sander 2022-01-15 13:55 63
  OutputIt out_;
f8deb5b9 Poul Sander 2022-01-15 13:55 64
  size_t limit_;
f8deb5b9 Poul Sander 2022-01-15 13:55 65
  size_t count_ = 0;
f8deb5b9 Poul Sander 2022-01-15 13:55 66
f8deb5b9 Poul Sander 2022-01-15 13:55 67
  truncating_iterator_base() : out_(), limit_(0) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 68
f8deb5b9 Poul Sander 2022-01-15 13:55 69
  truncating_iterator_base(OutputIt out, size_t limit)
f8deb5b9 Poul Sander 2022-01-15 13:55 70
      : out_(out), limit_(limit) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 71
f8deb5b9 Poul Sander 2022-01-15 13:55 72
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 73
  using iterator_category = std::output_iterator_tag;
f8deb5b9 Poul Sander 2022-01-15 13:55 74
  using value_type = typename std::iterator_traits<OutputIt>::value_type;
f8deb5b9 Poul Sander 2022-01-15 13:55 75
  using difference_type = std::ptrdiff_t;
f8deb5b9 Poul Sander 2022-01-15 13:55 76
  using pointer = void;
f8deb5b9 Poul Sander 2022-01-15 13:55 77
  using reference = void;
f8deb5b9 Poul Sander 2022-01-15 13:55 78
  using _Unchecked_type =
f8deb5b9 Poul Sander 2022-01-15 13:55 79
      truncating_iterator_base;  // Mark iterator as checked.
f8deb5b9 Poul Sander 2022-01-15 13:55 80
f8deb5b9 Poul Sander 2022-01-15 13:55 81
  OutputIt base() const { return out_; }
f8deb5b9 Poul Sander 2022-01-15 13:55 82
  size_t count() const { return count_; }
f8deb5b9 Poul Sander 2022-01-15 13:55 83
};
f8deb5b9 Poul Sander 2022-01-15 13:55 84
f8deb5b9 Poul Sander 2022-01-15 13:55 85
// An output iterator that truncates the output and counts the number of objects
f8deb5b9 Poul Sander 2022-01-15 13:55 86
// written to it.
f8deb5b9 Poul Sander 2022-01-15 13:55 87
template <typename OutputIt,
f8deb5b9 Poul Sander 2022-01-15 13:55 88
          typename Enable = typename std::is_void<
f8deb5b9 Poul Sander 2022-01-15 13:55 89
              typename std::iterator_traits<OutputIt>::value_type>::type>
f8deb5b9 Poul Sander 2022-01-15 13:55 90
class truncating_iterator;
f8deb5b9 Poul Sander 2022-01-15 13:55 91
f8deb5b9 Poul Sander 2022-01-15 13:55 92
template <typename OutputIt>
f8deb5b9 Poul Sander 2022-01-15 13:55 93
class truncating_iterator<OutputIt, std::false_type>
f8deb5b9 Poul Sander 2022-01-15 13:55 94
    : public truncating_iterator_base<OutputIt> {
f8deb5b9 Poul Sander 2022-01-15 13:55 95
  mutable typename truncating_iterator_base<OutputIt>::value_type blackhole_;
f8deb5b9 Poul Sander 2022-01-15 13:55 96
f8deb5b9 Poul Sander 2022-01-15 13:55 97
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 98
  using value_type = typename truncating_iterator_base<OutputIt>::value_type;
f8deb5b9 Poul Sander 2022-01-15 13:55 99
f8deb5b9 Poul Sander 2022-01-15 13:55 100
  truncating_iterator() = default;
f8deb5b9 Poul Sander 2022-01-15 13:55 101
f8deb5b9 Poul Sander 2022-01-15 13:55 102
  truncating_iterator(OutputIt out, size_t limit)
f8deb5b9 Poul Sander 2022-01-15 13:55 103
      : truncating_iterator_base<OutputIt>(out, limit) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 104
f8deb5b9 Poul Sander 2022-01-15 13:55 105
  truncating_iterator& operator++() {
f8deb5b9 Poul Sander 2022-01-15 13:55 106
    if (this->count_++ < this->limit_) ++this->out_;
f8deb5b9 Poul Sander 2022-01-15 13:55 107
    return *this;
f8deb5b9 Poul Sander 2022-01-15 13:55 108
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 109
f8deb5b9 Poul Sander 2022-01-15 13:55 110
  truncating_iterator operator++(int) {
f8deb5b9 Poul Sander 2022-01-15 13:55 111
    auto it = *this;
f8deb5b9 Poul Sander 2022-01-15 13:55 112
    ++*this;
f8deb5b9 Poul Sander 2022-01-15 13:55 113
    return it;
f8deb5b9 Poul Sander 2022-01-15 13:55 114
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 115
f8deb5b9 Poul Sander 2022-01-15 13:55 116
  value_type& operator*() const {
f8deb5b9 Poul Sander 2022-01-15 13:55 117
    return this->count_ < this->limit_ ? *this->out_ : blackhole_;
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
f8deb5b9 Poul Sander 2022-01-15 13:55 121
template <typename OutputIt>
f8deb5b9 Poul Sander 2022-01-15 13:55 122
class truncating_iterator<OutputIt, std::true_type>
f8deb5b9 Poul Sander 2022-01-15 13:55 123
    : public truncating_iterator_base<OutputIt> {
f8deb5b9 Poul Sander 2022-01-15 13:55 124
 public:
f8deb5b9 Poul Sander 2022-01-15 13:55 125
  truncating_iterator() = default;
f8deb5b9 Poul Sander 2022-01-15 13:55 126
f8deb5b9 Poul Sander 2022-01-15 13:55 127
  truncating_iterator(OutputIt out, size_t limit)
f8deb5b9 Poul Sander 2022-01-15 13:55 128
      : truncating_iterator_base<OutputIt>(out, limit) {}
f8deb5b9 Poul Sander 2022-01-15 13:55 129
f8deb5b9 Poul Sander 2022-01-15 13:55 130
  template <typename T> truncating_iterator& operator=(T val) {
f8deb5b9 Poul Sander 2022-01-15 13:55 131
    if (this->count_++ < this->limit_) *this->out_++ = val;
f8deb5b9 Poul Sander 2022-01-15 13:55 132
    return *this;
f8deb5b9 Poul Sander 2022-01-15 13:55 133
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 134
f8deb5b9 Poul Sander 2022-01-15 13:55 135
  truncating_iterator& operator++() { return *this; }
f8deb5b9 Poul Sander 2022-01-15 13:55 136
  truncating_iterator& operator++(int) { return *this; }
f8deb5b9 Poul Sander 2022-01-15 13:55 137
  truncating_iterator& operator*() { return *this; }
f8deb5b9 Poul Sander 2022-01-15 13:55 138
};
f8deb5b9 Poul Sander 2022-01-15 13:55 139
f8deb5b9 Poul Sander 2022-01-15 13:55 140
// A compile-time string which is compiled into fast formatting code.
f8deb5b9 Poul Sander 2022-01-15 13:55 141
class compiled_string {};
f8deb5b9 Poul Sander 2022-01-15 13:55 142
f8deb5b9 Poul Sander 2022-01-15 13:55 143
template <typename S>
f8deb5b9 Poul Sander 2022-01-15 13:55 144
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
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
  \rst
f8deb5b9 Poul Sander 2022-01-15 13:55 148
  Converts a string literal *s* into a format string that will be parsed at
f8deb5b9 Poul Sander 2022-01-15 13:55 149
  compile time and converted into efficient formatting code. Requires C++17
f8deb5b9 Poul Sander 2022-01-15 13:55 150
  ``constexpr if`` compiler support.
f8deb5b9 Poul Sander 2022-01-15 13:55 151
f8deb5b9 Poul Sander 2022-01-15 13:55 152
  **Example**::
f8deb5b9 Poul Sander 2022-01-15 13:55 153
f8deb5b9 Poul Sander 2022-01-15 13:55 154
    // Converts 42 into std::string using the most efficient method and no
f8deb5b9 Poul Sander 2022-01-15 13:55 155
    // runtime format string processing.
f8deb5b9 Poul Sander 2022-01-15 13:55 156
    std::string s = fmt::format(FMT_COMPILE("{}"), 42);
f8deb5b9 Poul Sander 2022-01-15 13:55 157
  \endrst
f8deb5b9 Poul Sander 2022-01-15 13:55 158
 */
f8deb5b9 Poul Sander 2022-01-15 13:55 159
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
f8deb5b9 Poul Sander 2022-01-15 13:55 160
#  define FMT_COMPILE(s) \
f8deb5b9 Poul Sander 2022-01-15 13:55 161
    FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit)
f8deb5b9 Poul Sander 2022-01-15 13:55 162
#else
f8deb5b9 Poul Sander 2022-01-15 13:55 163
#  define FMT_COMPILE(s) FMT_STRING(s)
f8deb5b9 Poul Sander 2022-01-15 13:55 164
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 165
f8deb5b9 Poul Sander 2022-01-15 13:55 166
#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
f8deb5b9 Poul Sander 2022-01-15 13:55 167
template <typename Char, size_t N,
f8deb5b9 Poul Sander 2022-01-15 13:55 168
          fmt::detail_exported::fixed_string<Char, N> Str>
f8deb5b9 Poul Sander 2022-01-15 13:55 169
struct udl_compiled_string : compiled_string {
f8deb5b9 Poul Sander 2022-01-15 13:55 170
  using char_type = Char;
f8deb5b9 Poul Sander 2022-01-15 13:55 171
  constexpr operator basic_string_view<char_type>() const {
f8deb5b9 Poul Sander 2022-01-15 13:55 172
    return {Str.data, N - 1};
f8deb5b9 Poul Sander 2022-01-15 13:55 173
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 174
};
f8deb5b9 Poul Sander 2022-01-15 13:55 175
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 176
f8deb5b9 Poul Sander 2022-01-15 13:55 177
template <typename T, typename... Tail>
f8deb5b9 Poul Sander 2022-01-15 13:55 178
const T& first(const T& value, const Tail&...) {
f8deb5b9 Poul Sander 2022-01-15 13:55 179
  return value;
f8deb5b9 Poul Sander 2022-01-15 13:55 180
}
f8deb5b9 Poul Sander 2022-01-15 13:55 181
f8deb5b9 Poul Sander 2022-01-15 13:55 182
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
f8deb5b9 Poul Sander 2022-01-15 13:55 183
template <typename... Args> struct type_list {};
f8deb5b9 Poul Sander 2022-01-15 13:55 184
f8deb5b9 Poul Sander 2022-01-15 13:55 185
// Returns a reference to the argument at index N from [first, rest...].
f8deb5b9 Poul Sander 2022-01-15 13:55 186
template <int N, typename T, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 187
constexpr const auto& get([[maybe_unused]] const T& first,
f8deb5b9 Poul Sander 2022-01-15 13:55 188
                          [[maybe_unused]] const Args&... rest) {
f8deb5b9 Poul Sander 2022-01-15 13:55 189
  static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
f8deb5b9 Poul Sander 2022-01-15 13:55 190
  if constexpr (N == 0)
f8deb5b9 Poul Sander 2022-01-15 13:55 191
    return first;
f8deb5b9 Poul Sander 2022-01-15 13:55 192
  else
f8deb5b9 Poul Sander 2022-01-15 13:55 193
    return detail::get<N - 1>(rest...);
f8deb5b9 Poul Sander 2022-01-15 13:55 194
}
f8deb5b9 Poul Sander 2022-01-15 13:55 195
f8deb5b9 Poul Sander 2022-01-15 13:55 196
template <typename Char, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 197
constexpr int get_arg_index_by_name(basic_string_view<Char> name,
f8deb5b9 Poul Sander 2022-01-15 13:55 198
                                    type_list<Args...>) {
f8deb5b9 Poul Sander 2022-01-15 13:55 199
  return get_arg_index_by_name<Args...>(name);
f8deb5b9 Poul Sander 2022-01-15 13:55 200
}
f8deb5b9 Poul Sander 2022-01-15 13:55 201
f8deb5b9 Poul Sander 2022-01-15 13:55 202
template <int N, typename> struct get_type_impl;
f8deb5b9 Poul Sander 2022-01-15 13:55 203
f8deb5b9 Poul Sander 2022-01-15 13:55 204
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
f8deb5b9 Poul Sander 2022-01-15 13:55 205
  using type =
f8deb5b9 Poul Sander 2022-01-15 13:55 206
      remove_cvref_t<decltype(detail::get<N>(std::declval<Args>()...))>;
f8deb5b9 Poul Sander 2022-01-15 13:55 207
};
f8deb5b9 Poul Sander 2022-01-15 13:55 208
f8deb5b9 Poul Sander 2022-01-15 13:55 209
template <int N, typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 210
using get_type = typename get_type_impl<N, T>::type;
f8deb5b9 Poul Sander 2022-01-15 13:55 211
f8deb5b9 Poul Sander 2022-01-15 13:55 212
template <typename T> struct is_compiled_format : std::false_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 213
f8deb5b9 Poul Sander 2022-01-15 13:55 214
template <typename Char> struct text {
f8deb5b9 Poul Sander 2022-01-15 13:55 215
  basic_string_view<Char> data;
f8deb5b9 Poul Sander 2022-01-15 13:55 216
  using char_type = Char;
f8deb5b9 Poul Sander 2022-01-15 13:55 217
f8deb5b9 Poul Sander 2022-01-15 13:55 218
  template <typename OutputIt, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 219
  constexpr OutputIt format(OutputIt out, const Args&...) const {
f8deb5b9 Poul Sander 2022-01-15 13:55 220
    return write<Char>(out, data);
f8deb5b9 Poul Sander 2022-01-15 13:55 221
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 222
};
f8deb5b9 Poul Sander 2022-01-15 13:55 223
f8deb5b9 Poul Sander 2022-01-15 13:55 224
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 225
struct is_compiled_format<text<Char>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 226
f8deb5b9 Poul Sander 2022-01-15 13:55 227
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 228
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
f8deb5b9 Poul Sander 2022-01-15 13:55 229
                               size_t size) {
f8deb5b9 Poul Sander 2022-01-15 13:55 230
  return {{&s[pos], size}};
f8deb5b9 Poul Sander 2022-01-15 13:55 231
}
f8deb5b9 Poul Sander 2022-01-15 13:55 232
f8deb5b9 Poul Sander 2022-01-15 13:55 233
template <typename Char> struct code_unit {
f8deb5b9 Poul Sander 2022-01-15 13:55 234
  Char value;
f8deb5b9 Poul Sander 2022-01-15 13:55 235
  using char_type = Char;
f8deb5b9 Poul Sander 2022-01-15 13:55 236
f8deb5b9 Poul Sander 2022-01-15 13:55 237
  template <typename OutputIt, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 238
  constexpr OutputIt format(OutputIt out, const Args&...) const {
f8deb5b9 Poul Sander 2022-01-15 13:55 239
    return write<Char>(out, value);
f8deb5b9 Poul Sander 2022-01-15 13:55 240
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 241
};
f8deb5b9 Poul Sander 2022-01-15 13:55 242
f8deb5b9 Poul Sander 2022-01-15 13:55 243
// This ensures that the argument type is convertible to `const T&`.
f8deb5b9 Poul Sander 2022-01-15 13:55 244
template <typename T, int N, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 245
constexpr const T& get_arg_checked(const Args&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 246
  const auto& arg = detail::get<N>(args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 247
  if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 248
    return arg.value;
f8deb5b9 Poul Sander 2022-01-15 13:55 249
  } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 250
    return arg;
f8deb5b9 Poul Sander 2022-01-15 13:55 251
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 252
}
f8deb5b9 Poul Sander 2022-01-15 13:55 253
f8deb5b9 Poul Sander 2022-01-15 13:55 254
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 255
struct is_compiled_format<code_unit<Char>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 256
f8deb5b9 Poul Sander 2022-01-15 13:55 257
// A replacement field that refers to argument N.
f8deb5b9 Poul Sander 2022-01-15 13:55 258
template <typename Char, typename T, int N> struct field {
f8deb5b9 Poul Sander 2022-01-15 13:55 259
  using char_type = Char;
f8deb5b9 Poul Sander 2022-01-15 13:55 260
f8deb5b9 Poul Sander 2022-01-15 13:55 261
  template <typename OutputIt, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 262
  constexpr OutputIt format(OutputIt out, const Args&... args) const {
f8deb5b9 Poul Sander 2022-01-15 13:55 263
    return write<Char>(out, get_arg_checked<T, N>(args...));
f8deb5b9 Poul Sander 2022-01-15 13:55 264
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 265
};
f8deb5b9 Poul Sander 2022-01-15 13:55 266
f8deb5b9 Poul Sander 2022-01-15 13:55 267
template <typename Char, typename T, int N>
f8deb5b9 Poul Sander 2022-01-15 13:55 268
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 269
f8deb5b9 Poul Sander 2022-01-15 13:55 270
// A replacement field that refers to argument with name.
f8deb5b9 Poul Sander 2022-01-15 13:55 271
template <typename Char> struct runtime_named_field {
f8deb5b9 Poul Sander 2022-01-15 13:55 272
  using char_type = Char;
f8deb5b9 Poul Sander 2022-01-15 13:55 273
  basic_string_view<Char> name;
f8deb5b9 Poul Sander 2022-01-15 13:55 274
f8deb5b9 Poul Sander 2022-01-15 13:55 275
  template <typename OutputIt, typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 276
  constexpr static bool try_format_argument(
f8deb5b9 Poul Sander 2022-01-15 13:55 277
      OutputIt& out,
f8deb5b9 Poul Sander 2022-01-15 13:55 278
      // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9
f8deb5b9 Poul Sander 2022-01-15 13:55 279
      [[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) {
f8deb5b9 Poul Sander 2022-01-15 13:55 280
    if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) {
f8deb5b9 Poul Sander 2022-01-15 13:55 281
      if (arg_name == arg.name) {
f8deb5b9 Poul Sander 2022-01-15 13:55 282
        out = write<Char>(out, arg.value);
f8deb5b9 Poul Sander 2022-01-15 13:55 283
        return true;
f8deb5b9 Poul Sander 2022-01-15 13:55 284
      }
f8deb5b9 Poul Sander 2022-01-15 13:55 285
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 286
    return false;
f8deb5b9 Poul Sander 2022-01-15 13:55 287
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 288
f8deb5b9 Poul Sander 2022-01-15 13:55 289
  template <typename OutputIt, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 290
  constexpr OutputIt format(OutputIt out, const Args&... args) const {
f8deb5b9 Poul Sander 2022-01-15 13:55 291
    bool found = (try_format_argument(out, name, args) || ...);
f8deb5b9 Poul Sander 2022-01-15 13:55 292
    if (!found) {
f8deb5b9 Poul Sander 2022-01-15 13:55 293
      FMT_THROW(format_error("argument with specified name is not found"));
f8deb5b9 Poul Sander 2022-01-15 13:55 294
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 295
    return out;
f8deb5b9 Poul Sander 2022-01-15 13:55 296
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 297
};
f8deb5b9 Poul Sander 2022-01-15 13:55 298
f8deb5b9 Poul Sander 2022-01-15 13:55 299
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 300
struct is_compiled_format<runtime_named_field<Char>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 301
f8deb5b9 Poul Sander 2022-01-15 13:55 302
// A replacement field that refers to argument N and has format specifiers.
f8deb5b9 Poul Sander 2022-01-15 13:55 303
template <typename Char, typename T, int N> struct spec_field {
f8deb5b9 Poul Sander 2022-01-15 13:55 304
  using char_type = Char;
f8deb5b9 Poul Sander 2022-01-15 13:55 305
  formatter<T, Char> fmt;
f8deb5b9 Poul Sander 2022-01-15 13:55 306
f8deb5b9 Poul Sander 2022-01-15 13:55 307
  template <typename OutputIt, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 308
  constexpr FMT_INLINE OutputIt format(OutputIt out,
f8deb5b9 Poul Sander 2022-01-15 13:55 309
                                       const Args&... args) const {
f8deb5b9 Poul Sander 2022-01-15 13:55 310
    const auto& vargs =
f8deb5b9 Poul Sander 2022-01-15 13:55 311
        fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 312
    basic_format_context<OutputIt, Char> ctx(out, vargs);
f8deb5b9 Poul Sander 2022-01-15 13:55 313
    return fmt.format(get_arg_checked<T, N>(args...), ctx);
f8deb5b9 Poul Sander 2022-01-15 13:55 314
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 315
};
f8deb5b9 Poul Sander 2022-01-15 13:55 316
f8deb5b9 Poul Sander 2022-01-15 13:55 317
template <typename Char, typename T, int N>
f8deb5b9 Poul Sander 2022-01-15 13:55 318
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 319
f8deb5b9 Poul Sander 2022-01-15 13:55 320
template <typename L, typename R> struct concat {
f8deb5b9 Poul Sander 2022-01-15 13:55 321
  L lhs;
f8deb5b9 Poul Sander 2022-01-15 13:55 322
  R rhs;
f8deb5b9 Poul Sander 2022-01-15 13:55 323
  using char_type = typename L::char_type;
f8deb5b9 Poul Sander 2022-01-15 13:55 324
f8deb5b9 Poul Sander 2022-01-15 13:55 325
  template <typename OutputIt, typename... Args>
f8deb5b9 Poul Sander 2022-01-15 13:55 326
  constexpr OutputIt format(OutputIt out, const Args&... args) const {
f8deb5b9 Poul Sander 2022-01-15 13:55 327
    out = lhs.format(out, args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 328
    return rhs.format(out, args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 329
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 330
};
f8deb5b9 Poul Sander 2022-01-15 13:55 331
f8deb5b9 Poul Sander 2022-01-15 13:55 332
template <typename L, typename R>
f8deb5b9 Poul Sander 2022-01-15 13:55 333
struct is_compiled_format<concat<L, R>> : std::true_type {};
f8deb5b9 Poul Sander 2022-01-15 13:55 334
f8deb5b9 Poul Sander 2022-01-15 13:55 335
template <typename L, typename R>
f8deb5b9 Poul Sander 2022-01-15 13:55 336
constexpr concat<L, R> make_concat(L lhs, R rhs) {
f8deb5b9 Poul Sander 2022-01-15 13:55 337
  return {lhs, rhs};
f8deb5b9 Poul Sander 2022-01-15 13:55 338
}
f8deb5b9 Poul Sander 2022-01-15 13:55 339
f8deb5b9 Poul Sander 2022-01-15 13:55 340
struct unknown_format {};
f8deb5b9 Poul Sander 2022-01-15 13:55 341
f8deb5b9 Poul Sander 2022-01-15 13:55 342
template <typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 343
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
f8deb5b9 Poul Sander 2022-01-15 13:55 344
  for (size_t size = str.size(); pos != size; ++pos) {
f8deb5b9 Poul Sander 2022-01-15 13:55 345
    if (str[pos] == '{' || str[pos] == '}') break;
f8deb5b9 Poul Sander 2022-01-15 13:55 346
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 347
  return pos;
f8deb5b9 Poul Sander 2022-01-15 13:55 348
}
f8deb5b9 Poul Sander 2022-01-15 13:55 349
f8deb5b9 Poul Sander 2022-01-15 13:55 350
template <typename Args, size_t POS, int ID, typename S>
f8deb5b9 Poul Sander 2022-01-15 13:55 351
constexpr auto compile_format_string(S format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 352
f8deb5b9 Poul Sander 2022-01-15 13:55 353
template <typename Args, size_t POS, int ID, typename T, typename S>
f8deb5b9 Poul Sander 2022-01-15 13:55 354
constexpr auto parse_tail(T head, S format_str) {
f8deb5b9 Poul Sander 2022-01-15 13:55 355
  if constexpr (POS !=
f8deb5b9 Poul Sander 2022-01-15 13:55 356
                basic_string_view<typename S::char_type>(format_str).size()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 357
    constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 358
    if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
f8deb5b9 Poul Sander 2022-01-15 13:55 359
                               unknown_format>())
f8deb5b9 Poul Sander 2022-01-15 13:55 360
      return tail;
f8deb5b9 Poul Sander 2022-01-15 13:55 361
    else
f8deb5b9 Poul Sander 2022-01-15 13:55 362
      return make_concat(head, tail);
f8deb5b9 Poul Sander 2022-01-15 13:55 363
  } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 364
    return head;
f8deb5b9 Poul Sander 2022-01-15 13:55 365
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 366
}
f8deb5b9 Poul Sander 2022-01-15 13:55 367
f8deb5b9 Poul Sander 2022-01-15 13:55 368
template <typename T, typename Char> struct parse_specs_result {
f8deb5b9 Poul Sander 2022-01-15 13:55 369
  formatter<T, Char> fmt;
f8deb5b9 Poul Sander 2022-01-15 13:55 370
  size_t end;
f8deb5b9 Poul Sander 2022-01-15 13:55 371
  int next_arg_id;
f8deb5b9 Poul Sander 2022-01-15 13:55 372
};
f8deb5b9 Poul Sander 2022-01-15 13:55 373
f8deb5b9 Poul Sander 2022-01-15 13:55 374
constexpr int manual_indexing_id = -1;
f8deb5b9 Poul Sander 2022-01-15 13:55 375
f8deb5b9 Poul Sander 2022-01-15 13:55 376
template <typename T, typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 377
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
f8deb5b9 Poul Sander 2022-01-15 13:55 378
                                                  size_t pos, int next_arg_id) {
f8deb5b9 Poul Sander 2022-01-15 13:55 379
  str.remove_prefix(pos);
f8deb5b9 Poul Sander 2022-01-15 13:55 380
  auto ctx = basic_format_parse_context<Char>(str, {}, next_arg_id);
f8deb5b9 Poul Sander 2022-01-15 13:55 381
  auto f = formatter<T, Char>();
f8deb5b9 Poul Sander 2022-01-15 13:55 382
  auto end = f.parse(ctx);
f8deb5b9 Poul Sander 2022-01-15 13:55 383
  return {f, pos + fmt::detail::to_unsigned(end - str.data()) + 1,
f8deb5b9 Poul Sander 2022-01-15 13:55 384
          next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};
f8deb5b9 Poul Sander 2022-01-15 13:55 385
}
f8deb5b9 Poul Sander 2022-01-15 13:55 386
f8deb5b9 Poul Sander 2022-01-15 13:55 387
template <typename Char> struct arg_id_handler {
f8deb5b9 Poul Sander 2022-01-15 13:55 388
  arg_ref<Char> arg_id;
f8deb5b9 Poul Sander 2022-01-15 13:55 389
f8deb5b9 Poul Sander 2022-01-15 13:55 390
  constexpr int operator()() {
f8deb5b9 Poul Sander 2022-01-15 13:55 391
    FMT_ASSERT(false, "handler cannot be used with automatic indexing");
f8deb5b9 Poul Sander 2022-01-15 13:55 392
    return 0;
f8deb5b9 Poul Sander 2022-01-15 13:55 393
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 394
  constexpr int operator()(int id) {
f8deb5b9 Poul Sander 2022-01-15 13:55 395
    arg_id = arg_ref<Char>(id);
f8deb5b9 Poul Sander 2022-01-15 13:55 396
    return 0;
f8deb5b9 Poul Sander 2022-01-15 13:55 397
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 398
  constexpr int operator()(basic_string_view<Char> id) {
f8deb5b9 Poul Sander 2022-01-15 13:55 399
    arg_id = arg_ref<Char>(id);
f8deb5b9 Poul Sander 2022-01-15 13:55 400
    return 0;
f8deb5b9 Poul Sander 2022-01-15 13:55 401
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 402
f8deb5b9 Poul Sander 2022-01-15 13:55 403
  constexpr void on_error(const char* message) {
f8deb5b9 Poul Sander 2022-01-15 13:55 404
    FMT_THROW(format_error(message));
f8deb5b9 Poul Sander 2022-01-15 13:55 405
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 406
};
f8deb5b9 Poul Sander 2022-01-15 13:55 407
f8deb5b9 Poul Sander 2022-01-15 13:55 408
template <typename Char> struct parse_arg_id_result {
f8deb5b9 Poul Sander 2022-01-15 13:55 409
  arg_ref<Char> arg_id;
f8deb5b9 Poul Sander 2022-01-15 13:55 410
  const Char* arg_id_end;
f8deb5b9 Poul Sander 2022-01-15 13:55 411
};
f8deb5b9 Poul Sander 2022-01-15 13:55 412
f8deb5b9 Poul Sander 2022-01-15 13:55 413
template <int ID, typename Char>
f8deb5b9 Poul Sander 2022-01-15 13:55 414
constexpr auto parse_arg_id(const Char* begin, const Char* end) {
f8deb5b9 Poul Sander 2022-01-15 13:55 415
  auto handler = arg_id_handler<Char>{arg_ref<Char>{}};
f8deb5b9 Poul Sander 2022-01-15 13:55 416
  auto arg_id_end = parse_arg_id(begin, end, handler);
f8deb5b9 Poul Sander 2022-01-15 13:55 417
  return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
f8deb5b9 Poul Sander 2022-01-15 13:55 418
}
f8deb5b9 Poul Sander 2022-01-15 13:55 419
f8deb5b9 Poul Sander 2022-01-15 13:55 420
template <typename T, typename Enable = void> struct field_type {
f8deb5b9 Poul Sander 2022-01-15 13:55 421
  using type = remove_cvref_t<T>;
f8deb5b9 Poul Sander 2022-01-15 13:55 422
};
f8deb5b9 Poul Sander 2022-01-15 13:55 423
f8deb5b9 Poul Sander 2022-01-15 13:55 424
template <typename T>
f8deb5b9 Poul Sander 2022-01-15 13:55 425
struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> {
f8deb5b9 Poul Sander 2022-01-15 13:55 426
  using type = remove_cvref_t<decltype(T::value)>;
f8deb5b9 Poul Sander 2022-01-15 13:55 427
};
f8deb5b9 Poul Sander 2022-01-15 13:55 428
f8deb5b9 Poul Sander 2022-01-15 13:55 429
template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,
f8deb5b9 Poul Sander 2022-01-15 13:55 430
          typename S>
f8deb5b9 Poul Sander 2022-01-15 13:55 431
constexpr auto parse_replacement_field_then_tail(S format_str) {
f8deb5b9 Poul Sander 2022-01-15 13:55 432
  using char_type = typename S::char_type;
f8deb5b9 Poul Sander 2022-01-15 13:55 433
  constexpr auto str = basic_string_view<char_type>(format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 434
  constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
f8deb5b9 Poul Sander 2022-01-15 13:55 435
  if constexpr (c == '}') {
f8deb5b9 Poul Sander 2022-01-15 13:55 436
    return parse_tail<Args, END_POS + 1, NEXT_ID>(
f8deb5b9 Poul Sander 2022-01-15 13:55 437
        field<char_type, typename field_type<T>::type, ARG_INDEX>(),
f8deb5b9 Poul Sander 2022-01-15 13:55 438
        format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 439
  } else if constexpr (c == ':') {
f8deb5b9 Poul Sander 2022-01-15 13:55 440
    constexpr auto result = parse_specs<typename field_type<T>::type>(
f8deb5b9 Poul Sander 2022-01-15 13:55 441
        str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);
f8deb5b9 Poul Sander 2022-01-15 13:55 442
    return parse_tail<Args, result.end, result.next_arg_id>(
f8deb5b9 Poul Sander 2022-01-15 13:55 443
        spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
f8deb5b9 Poul Sander 2022-01-15 13:55 444
            result.fmt},
f8deb5b9 Poul Sander 2022-01-15 13:55 445
        format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 446
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 447
}
f8deb5b9 Poul Sander 2022-01-15 13:55 448
f8deb5b9 Poul Sander 2022-01-15 13:55 449
// Compiles a non-empty format string and returns the compiled representation
f8deb5b9 Poul Sander 2022-01-15 13:55 450
// or unknown_format() on unrecognized input.
f8deb5b9 Poul Sander 2022-01-15 13:55 451
template <typename Args, size_t POS, int ID, typename S>
f8deb5b9 Poul Sander 2022-01-15 13:55 452
constexpr auto compile_format_string(S format_str) {
f8deb5b9 Poul Sander 2022-01-15 13:55 453
  using char_type = typename S::char_type;
f8deb5b9 Poul Sander 2022-01-15 13:55 454
  constexpr auto str = basic_string_view<char_type>(format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 455
  if constexpr (str[POS] == '{') {
f8deb5b9 Poul Sander 2022-01-15 13:55 456
    if constexpr (POS + 1 == str.size())
f8deb5b9 Poul Sander 2022-01-15 13:55 457
      FMT_THROW(format_error("unmatched '{' in format string"));
f8deb5b9 Poul Sander 2022-01-15 13:55 458
    if constexpr (str[POS + 1] == '{') {
f8deb5b9 Poul Sander 2022-01-15 13:55 459
      return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 460
    } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
f8deb5b9 Poul Sander 2022-01-15 13:55 461
      static_assert(ID != manual_indexing_id,
f8deb5b9 Poul Sander 2022-01-15 13:55 462
                    "cannot switch from manual to automatic argument indexing");
f8deb5b9 Poul Sander 2022-01-15 13:55 463
      constexpr auto next_id =
f8deb5b9 Poul Sander 2022-01-15 13:55 464
          ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
f8deb5b9 Poul Sander 2022-01-15 13:55 465
      return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 466
                                               POS + 1, ID, next_id>(
f8deb5b9 Poul Sander 2022-01-15 13:55 467
          format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 468
    } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 469
      constexpr auto arg_id_result =
f8deb5b9 Poul Sander 2022-01-15 13:55 470
          parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());
f8deb5b9 Poul Sander 2022-01-15 13:55 471
      constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data();
f8deb5b9 Poul Sander 2022-01-15 13:55 472
      constexpr char_type c =
f8deb5b9 Poul Sander 2022-01-15 13:55 473
          arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
f8deb5b9 Poul Sander 2022-01-15 13:55 474
      static_assert(c == '}' || c == ':', "missing '}' in format string");
f8deb5b9 Poul Sander 2022-01-15 13:55 475
      if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index) {
f8deb5b9 Poul Sander 2022-01-15 13:55 476
        static_assert(
f8deb5b9 Poul Sander 2022-01-15 13:55 477
            ID == manual_indexing_id || ID == 0,
f8deb5b9 Poul Sander 2022-01-15 13:55 478
            "cannot switch from automatic to manual argument indexing");
f8deb5b9 Poul Sander 2022-01-15 13:55 479
        constexpr auto arg_index = arg_id_result.arg_id.val.index;
f8deb5b9 Poul Sander 2022-01-15 13:55 480
        return parse_replacement_field_then_tail<get_type<arg_index, Args>,
f8deb5b9 Poul Sander 2022-01-15 13:55 481
                                                 Args, arg_id_end_pos,
f8deb5b9 Poul Sander 2022-01-15 13:55 482
                                                 arg_index, manual_indexing_id>(
f8deb5b9 Poul Sander 2022-01-15 13:55 483
            format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 484
      } else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
f8deb5b9 Poul Sander 2022-01-15 13:55 485
        constexpr auto arg_index =
f8deb5b9 Poul Sander 2022-01-15 13:55 486
            get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
f8deb5b9 Poul Sander 2022-01-15 13:55 487
        if constexpr (arg_index != invalid_arg_index) {
f8deb5b9 Poul Sander 2022-01-15 13:55 488
          constexpr auto next_id =
f8deb5b9 Poul Sander 2022-01-15 13:55 489
              ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
f8deb5b9 Poul Sander 2022-01-15 13:55 490
          return parse_replacement_field_then_tail<
f8deb5b9 Poul Sander 2022-01-15 13:55 491
              decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
f8deb5b9 Poul Sander 2022-01-15 13:55 492
              arg_index, next_id>(format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 493
        } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 494
          if constexpr (c == '}') {
f8deb5b9 Poul Sander 2022-01-15 13:55 495
            return parse_tail<Args, arg_id_end_pos + 1, ID>(
f8deb5b9 Poul Sander 2022-01-15 13:55 496
                runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
f8deb5b9 Poul Sander 2022-01-15 13:55 497
                format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 498
          } else if constexpr (c == ':') {
f8deb5b9 Poul Sander 2022-01-15 13:55 499
            return unknown_format();  // no type info for specs parsing
f8deb5b9 Poul Sander 2022-01-15 13:55 500
          }
f8deb5b9 Poul Sander 2022-01-15 13:55 501
        }
f8deb5b9 Poul Sander 2022-01-15 13:55 502
      }
f8deb5b9 Poul Sander 2022-01-15 13:55 503
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 504
  } else if constexpr (str[POS] == '}') {
f8deb5b9 Poul Sander 2022-01-15 13:55 505
    if constexpr (POS + 1 == str.size())
f8deb5b9 Poul Sander 2022-01-15 13:55 506
      FMT_THROW(format_error("unmatched '}' in format string"));
f8deb5b9 Poul Sander 2022-01-15 13:55 507
    return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 508
  } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 509
    constexpr auto end = parse_text(str, POS + 1);
f8deb5b9 Poul Sander 2022-01-15 13:55 510
    if constexpr (end - POS > 1) {
f8deb5b9 Poul Sander 2022-01-15 13:55 511
      return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
f8deb5b9 Poul Sander 2022-01-15 13:55 512
                                       format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 513
    } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 514
      return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
f8deb5b9 Poul Sander 2022-01-15 13:55 515
                                       format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 516
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 517
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 518
}
f8deb5b9 Poul Sander 2022-01-15 13:55 519
f8deb5b9 Poul Sander 2022-01-15 13:55 520
template <typename... Args, typename S,
f8deb5b9 Poul Sander 2022-01-15 13:55 521
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 522
constexpr auto compile(S format_str) {
f8deb5b9 Poul Sander 2022-01-15 13:55 523
  constexpr auto str = basic_string_view<typename S::char_type>(format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 524
  if constexpr (str.size() == 0) {
f8deb5b9 Poul Sander 2022-01-15 13:55 525
    return detail::make_text(str, 0, 0);
f8deb5b9 Poul Sander 2022-01-15 13:55 526
  } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 527
    constexpr auto result =
f8deb5b9 Poul Sander 2022-01-15 13:55 528
        detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
f8deb5b9 Poul Sander 2022-01-15 13:55 529
            format_str);
f8deb5b9 Poul Sander 2022-01-15 13:55 530
    return result;
f8deb5b9 Poul Sander 2022-01-15 13:55 531
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 532
}
f8deb5b9 Poul Sander 2022-01-15 13:55 533
#endif  // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
f8deb5b9 Poul Sander 2022-01-15 13:55 534
}  // namespace detail
f8deb5b9 Poul Sander 2022-01-15 13:55 535
f8deb5b9 Poul Sander 2022-01-15 13:55 536
FMT_MODULE_EXPORT_BEGIN
f8deb5b9 Poul Sander 2022-01-15 13:55 537
f8deb5b9 Poul Sander 2022-01-15 13:55 538
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
f8deb5b9 Poul Sander 2022-01-15 13:55 539
f8deb5b9 Poul Sander 2022-01-15 13:55 540
template <typename CompiledFormat, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 541
          typename Char = typename CompiledFormat::char_type,
f8deb5b9 Poul Sander 2022-01-15 13:55 542
          FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 543
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
f8deb5b9 Poul Sander 2022-01-15 13:55 544
                                          const Args&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 545
  auto s = std::basic_string<Char>();
f8deb5b9 Poul Sander 2022-01-15 13:55 546
  cf.format(std::back_inserter(s), args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 547
  return s;
f8deb5b9 Poul Sander 2022-01-15 13:55 548
}
f8deb5b9 Poul Sander 2022-01-15 13:55 549
f8deb5b9 Poul Sander 2022-01-15 13:55 550
template <typename OutputIt, typename CompiledFormat, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 551
          FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 552
constexpr FMT_INLINE OutputIt format_to(OutputIt out, const CompiledFormat& cf,
f8deb5b9 Poul Sander 2022-01-15 13:55 553
                                        const Args&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 554
  return cf.format(out, args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 555
}
f8deb5b9 Poul Sander 2022-01-15 13:55 556
f8deb5b9 Poul Sander 2022-01-15 13:55 557
template <typename S, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 558
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 559
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
f8deb5b9 Poul Sander 2022-01-15 13:55 560
                                                           Args&&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 561
  if constexpr (std::is_same<typename S::char_type, char>::value) {
f8deb5b9 Poul Sander 2022-01-15 13:55 562
    constexpr auto str = basic_string_view<typename S::char_type>(S());
f8deb5b9 Poul Sander 2022-01-15 13:55 563
    if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') {
f8deb5b9 Poul Sander 2022-01-15 13:55 564
      const auto& first = detail::first(args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 565
      if constexpr (detail::is_named_arg<
f8deb5b9 Poul Sander 2022-01-15 13:55 566
                        remove_cvref_t<decltype(first)>>::value) {
f8deb5b9 Poul Sander 2022-01-15 13:55 567
        return fmt::to_string(first.value);
f8deb5b9 Poul Sander 2022-01-15 13:55 568
      } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 569
        return fmt::to_string(first);
f8deb5b9 Poul Sander 2022-01-15 13:55 570
      }
f8deb5b9 Poul Sander 2022-01-15 13:55 571
    }
f8deb5b9 Poul Sander 2022-01-15 13:55 572
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 573
  constexpr auto compiled = detail::compile<Args...>(S());
f8deb5b9 Poul Sander 2022-01-15 13:55 574
  if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
f8deb5b9 Poul Sander 2022-01-15 13:55 575
                             detail::unknown_format>()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 576
    return format(static_cast<basic_string_view<typename S::char_type>>(S()),
f8deb5b9 Poul Sander 2022-01-15 13:55 577
                  std::forward<Args>(args)...);
f8deb5b9 Poul Sander 2022-01-15 13:55 578
  } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 579
    return format(compiled, std::forward<Args>(args)...);
f8deb5b9 Poul Sander 2022-01-15 13:55 580
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 581
}
f8deb5b9 Poul Sander 2022-01-15 13:55 582
f8deb5b9 Poul Sander 2022-01-15 13:55 583
template <typename OutputIt, typename S, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 584
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 585
FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 586
  constexpr auto compiled = detail::compile<Args...>(S());
f8deb5b9 Poul Sander 2022-01-15 13:55 587
  if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
f8deb5b9 Poul Sander 2022-01-15 13:55 588
                             detail::unknown_format>()) {
f8deb5b9 Poul Sander 2022-01-15 13:55 589
    return format_to(out,
f8deb5b9 Poul Sander 2022-01-15 13:55 590
                     static_cast<basic_string_view<typename S::char_type>>(S()),
f8deb5b9 Poul Sander 2022-01-15 13:55 591
                     std::forward<Args>(args)...);
f8deb5b9 Poul Sander 2022-01-15 13:55 592
  } else {
f8deb5b9 Poul Sander 2022-01-15 13:55 593
    return format_to(out, compiled, std::forward<Args>(args)...);
f8deb5b9 Poul Sander 2022-01-15 13:55 594
  }
f8deb5b9 Poul Sander 2022-01-15 13:55 595
}
f8deb5b9 Poul Sander 2022-01-15 13:55 596
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 597
f8deb5b9 Poul Sander 2022-01-15 13:55 598
template <typename OutputIt, typename S, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 599
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 600
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
f8deb5b9 Poul Sander 2022-01-15 13:55 601
                                         const S& format_str, Args&&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 602
  auto it = format_to(detail::truncating_iterator<OutputIt>(out, n), format_str,
f8deb5b9 Poul Sander 2022-01-15 13:55 603
                      std::forward<Args>(args)...);
f8deb5b9 Poul Sander 2022-01-15 13:55 604
  return {it.base(), it.count()};
f8deb5b9 Poul Sander 2022-01-15 13:55 605
}
f8deb5b9 Poul Sander 2022-01-15 13:55 606
f8deb5b9 Poul Sander 2022-01-15 13:55 607
template <typename S, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 608
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 609
size_t formatted_size(const S& format_str, const Args&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 610
  return format_to(detail::counting_iterator(), format_str, args...).count();
f8deb5b9 Poul Sander 2022-01-15 13:55 611
}
f8deb5b9 Poul Sander 2022-01-15 13:55 612
f8deb5b9 Poul Sander 2022-01-15 13:55 613
template <typename S, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 614
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 615
void print(std::FILE* f, const S& format_str, const Args&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 616
  memory_buffer buffer;
f8deb5b9 Poul Sander 2022-01-15 13:55 617
  format_to(std::back_inserter(buffer), format_str, args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 618
  detail::print(f, {buffer.data(), buffer.size()});
f8deb5b9 Poul Sander 2022-01-15 13:55 619
}
f8deb5b9 Poul Sander 2022-01-15 13:55 620
f8deb5b9 Poul Sander 2022-01-15 13:55 621
template <typename S, typename... Args,
f8deb5b9 Poul Sander 2022-01-15 13:55 622
          FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
f8deb5b9 Poul Sander 2022-01-15 13:55 623
void print(const S& format_str, const Args&... args) {
f8deb5b9 Poul Sander 2022-01-15 13:55 624
  print(stdout, format_str, args...);
f8deb5b9 Poul Sander 2022-01-15 13:55 625
}
f8deb5b9 Poul Sander 2022-01-15 13:55 626
f8deb5b9 Poul Sander 2022-01-15 13:55 627
#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
f8deb5b9 Poul Sander 2022-01-15 13:55 628
inline namespace literals {
f8deb5b9 Poul Sander 2022-01-15 13:55 629
template <detail_exported::fixed_string Str>
f8deb5b9 Poul Sander 2022-01-15 13:55 630
constexpr detail::udl_compiled_string<
f8deb5b9 Poul Sander 2022-01-15 13:55 631
    remove_cvref_t<decltype(Str.data[0])>,
f8deb5b9 Poul Sander 2022-01-15 13:55 632
    sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str>
f8deb5b9 Poul Sander 2022-01-15 13:55 633
operator""_cf() {
f8deb5b9 Poul Sander 2022-01-15 13:55 634
  return {};
f8deb5b9 Poul Sander 2022-01-15 13:55 635
}
f8deb5b9 Poul Sander 2022-01-15 13:55 636
}  // namespace literals
f8deb5b9 Poul Sander 2022-01-15 13:55 637
#endif
f8deb5b9 Poul Sander 2022-01-15 13:55 638
f8deb5b9 Poul Sander 2022-01-15 13:55 639
FMT_MODULE_EXPORT_END
f8deb5b9 Poul Sander 2022-01-15 13:55 640
FMT_END_NAMESPACE
f8deb5b9 Poul Sander 2022-01-15 13:55 641
f8deb5b9 Poul Sander 2022-01-15 13:55 642
#endif  // FMT_COMPILE_H_
1970-01-01 00:00 643