Squashed 'external/fmt/' changes from 3b70966df..093b39ca5
093b39ca5 Update docs for meson (#4291) 2c3a5698e Simplify a copying the fill from basic_specs fc1b0f348 Clarify use of FMT_THROW in a comment 1d066890c Resolve C4702 unreachable code warnings dad323751 Fix a bug when copying the fill from basic_specs 880e1494d Improve xchar support for std::bitset formatter e3ddede6c Update version e9ec4fdc8 Bump version feb72126b Readd FMT_NO_UNIQUE_ADDRESS 8d517e54c Update changelog 563fc74ae Update changelog 3e04222d5 Restore ABI compatibility with 11.0.2 853df39d0 Mention compile-time formatting 11742a09c Clarify that format_string should be used instead of fstring da24fac10 Document fstring 5fa4bdd75 Define CMake components to allow docs to be installed separately (#4276) 3c8aad8df Update the release script 0e8aad961 Update version debe784aa Update changelog f6d112567 Update changelog 73d0d3f75 Fix github API call 08f60f1ef Update changelog faf3f8408 Bump version f3a41441d Replace requests with urllib 3f33cb21d Update changelog b07a90386 Update changelog a6fba5177 Update changelog 25e292998 Update changelog 00ab2e98b Update changelog a3ef285ae Always inline const_check to improve debug codegen in clang 28d1abc9d Update changelog 90704b9ef Update changelog 86dae01c2 Fix compatibility with older versions of VS (#4271) d8a79eafd Document formatting of bit-fields and fields of packed structs 7c3d0152e Use the _MSVC_STL_UPDATE macro to detect STL (#4267) 7c50da538 Allow getting size of dynamic format arg store (#4270) 873670ba3 Make parameter basic_memory_buffer<char, SIZE>& buf of to_string const 735d4cc05 Update changelog 141380172 Allow disabling <filesystem> by define FMT_CPP_LIB_FILESYSTEM=0 (#4259) 4302d7429 Update changelog 0f51ea79d Update changelog 9600fee02 Include <filesystem> only if FMT_CPP_LIB_FILESYSTEM is set (#4258) 47a66c5ec Bump msys2/setup-msys2 from 2.24.0 to 2.25.0 (#4250) 385c01dc7 Allow bit_cast to work for 80bit long double (#4246) df249d8ad Remove an old workaround dfad80d1c Remove an old workaround 536cabd56 Export all range join overloads (#4239) b1a054706 Remove more MSVC 2015 workarounds and fix string_view checks bfd95392c Remove MSVC 2015 workaround 9ced61bca Replace std::forward for clang-tidy (#4236) 75e5be6ad Sort specifiers a169d7fa4 Fix chrono formatting syntax doc (#4235) a6c45dfea Fix modular build a35389b3c Corrently handle buffer flush 5a3576acc Implement fmt::join for tuple-like objects (#4230) 542600013 Suppress MSVC warnings "C4127: conditional expression is constant" by used const_check (#4233) 720da57ba Remove reference to unused intrinsic 680db66c3 Explicitly export symbols from detail 56ce41ef6 Remove initializer_list dependency cf50e4d6a Fix const[expr] in context API 6580d7b80 Cleanup the format API 7e73566ce Minor cleanup 8523dba2d Make constexpr precede explicit consistently e3d3b24fc Minor cleanup 1521bba70 Use consistent types for argument count 00649552a Bump github/codeql-action from 3.26.6 to 3.27.0 (#4223) 4b8e2838f More cleanup 7d4662f7a Remove FMT_BUILTIN_CTZ 27110bc47 Minor cleanup 68f315376 Fix narrowing conversion warning in struct fstring (#4210) 168df9a06 Implement fmt::format_to into std::vector<char> (#4211) 4daa3d591 Fix error: cannot use 'try' with exceptions disabled in Win LLVM Clang (#4208) e9eaa27e5 Add std::exception to the docs 2b6a786e3 Use standard context in print a16ff5787 Add support for code units > 0xFFFF in fill 601be1cbe Add support for code units > 0xFFFF in fill 58c185b63 Changing type of data_ to size_t to avoid compilation warnings (#4200) a0a9ba2af Fix hashes cc2ba8f9e Cleanup cifuzz action a18d42b20 Simplify lint (#4197) 4046f9727 Fix -Wmissing-noreturn warning (#4194) 6bdc12a19 detail_exported -> detail 786a4b096 Cleanup fixed_string 2cb3b7c64 Update README.md e9cba6905 Update README.md 02537548f Cleanup an example c68c5fa7c Test FMT_BUILTIN_TYPES 22701d5f6 Address build failures when using Tip-of-Tree clang. (#4187) e62c41ffb Conform `std::iterator_traits<fmt::appender>` to [iterator.traits]/1 (#4185) 18792893d Silencing Wextra-semi warning (#4188) c90bc9186 Bump actions/checkout from 4.1.6 to 4.2.0 (#4182) c95722ad6 Improve naming consistency db06b0df8 Use countl_zero in bigint b9ec48d9c Cleanup bigint 3faf6f181 Add min_of/max_of d64b100a3 Relax constexpr ff9ee0461 Fix handling FMT_BUILTIN_TYPES 1c5883bef Test nondeterministic conversion to format string cacc3108c Don't assume repeated evaluation of string literal produce the same pointer fade652ad Require clang >=15 for _BitInt support (#4176) 96dca569a Module linkage fixes for shared build (#4169) 891c9a73a Cleanup format API 9282222b7 Export more e5b20ff0d Deprecate detail::locale_ref ff9222354 Simplify locale handling 80c4d42c6 Cleanup format.h git-subtree-dir: external/fmt git-subtree-split: 093b39ca5eea129b111060839602bcfaf295125a
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
||||
#define FMT_VERSION 110002
|
||||
#define FMT_VERSION 110101
|
||||
|
||||
// Detect compiler versions.
|
||||
#if defined(__clang__) && !defined(__ibmxl__)
|
||||
@@ -146,6 +146,8 @@
|
||||
// Use the provided definition.
|
||||
#elif defined(__GNUC__) && !defined(__EXCEPTIONS)
|
||||
# define FMT_USE_EXCEPTIONS 0
|
||||
#elif defined(__clang__) && !defined(__cpp_exceptions)
|
||||
# define FMT_USE_EXCEPTIONS 0
|
||||
#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
|
||||
# define FMT_USE_EXCEPTIONS 0
|
||||
#else
|
||||
@@ -159,6 +161,20 @@
|
||||
# define FMT_CATCH(x) if (false)
|
||||
#endif
|
||||
|
||||
#ifdef FMT_NO_UNIQUE_ADDRESS
|
||||
// Use the provided definition.
|
||||
#elif FMT_CPLUSPLUS < 202002L
|
||||
// Not supported.
|
||||
#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
|
||||
# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
|
||||
// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
|
||||
#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
|
||||
# define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
|
||||
#endif
|
||||
#ifndef FMT_NO_UNIQUE_ADDRESS
|
||||
# define FMT_NO_UNIQUE_ADDRESS
|
||||
#endif
|
||||
|
||||
#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
|
||||
# define FMT_FALLTHROUGH [[fallthrough]]
|
||||
#elif defined(__clang__)
|
||||
@@ -332,6 +348,13 @@ struct monostate {
|
||||
# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
|
||||
#endif
|
||||
|
||||
template <typename T> constexpr auto min_of(T a, T b) -> T {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
template <typename T> constexpr auto max_of(T a, T b) -> T {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
// Suppresses "unused variable" warnings with the method described in
|
||||
// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
|
||||
@@ -355,7 +378,9 @@ constexpr auto is_constant_evaluated(bool default_value = false) noexcept
|
||||
}
|
||||
|
||||
// Suppresses "conditional expression is constant" warnings.
|
||||
template <typename T> constexpr auto const_check(T value) -> T { return value; }
|
||||
template <typename T> FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T {
|
||||
return val;
|
||||
}
|
||||
|
||||
FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||
const char* message);
|
||||
@@ -394,7 +419,7 @@ inline auto map(uint128_opt) -> monostate { return {}; }
|
||||
#endif
|
||||
|
||||
#ifndef FMT_USE_BITINT
|
||||
# define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1400)
|
||||
# define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1500)
|
||||
#endif
|
||||
|
||||
#if FMT_USE_BITINT
|
||||
@@ -562,8 +587,8 @@ template <typename Char> class basic_string_view {
|
||||
|
||||
// Lexicographically compare this string reference to other.
|
||||
FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
|
||||
size_t str_size = size_ < other.size_ ? size_ : other.size_;
|
||||
int result = detail::compare(data_, other.data_, str_size);
|
||||
int result =
|
||||
detail::compare(data_, other.data_, min_of(size_, other.size_));
|
||||
if (result != 0) return result;
|
||||
return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
|
||||
}
|
||||
@@ -714,7 +739,7 @@ class basic_specs {
|
||||
max_fill_size = 4
|
||||
};
|
||||
|
||||
unsigned long data_ = 1 << fill_size_shift;
|
||||
size_t data_ = 1 << fill_size_shift;
|
||||
|
||||
// Character (code unit) type is erased to prevent template bloat.
|
||||
char fill_data_[max_fill_size] = {' '};
|
||||
@@ -793,7 +818,8 @@ class basic_specs {
|
||||
template <typename Char> constexpr auto fill_unit() const -> Char {
|
||||
using uchar = unsigned char;
|
||||
return static_cast<Char>(static_cast<uchar>(fill_data_[0]) |
|
||||
(static_cast<uchar>(fill_data_[1]) << 8));
|
||||
(static_cast<uchar>(fill_data_[1]) << 8) |
|
||||
(static_cast<uchar>(fill_data_[2]) << 16));
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void set_fill(char c) {
|
||||
@@ -809,12 +835,19 @@ class basic_specs {
|
||||
unsigned uchar = static_cast<detail::unsigned_char<Char>>(s[0]);
|
||||
fill_data_[0] = static_cast<char>(uchar);
|
||||
fill_data_[1] = static_cast<char>(uchar >> 8);
|
||||
fill_data_[2] = static_cast<char>(uchar >> 16);
|
||||
return;
|
||||
}
|
||||
FMT_ASSERT(size <= max_fill_size, "invalid fill");
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
fill_data_[i & 3] = static_cast<char>(s[i]);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void set_fill(const basic_specs& specs) {
|
||||
set_fill_size(specs.fill_size());
|
||||
for (size_t i = 0; i < max_fill_size; ++i)
|
||||
fill_data_[i] = specs.fill_data_[i];
|
||||
}
|
||||
};
|
||||
|
||||
// Format specifiers for built-in and string types.
|
||||
@@ -842,7 +875,7 @@ template <typename Char = char> class parse_context {
|
||||
using char_type = Char;
|
||||
using iterator = const Char*;
|
||||
|
||||
explicit constexpr parse_context(basic_string_view<Char> fmt,
|
||||
constexpr explicit parse_context(basic_string_view<Char> fmt,
|
||||
int next_arg_id = 0)
|
||||
: fmt_(fmt), next_arg_id_(next_arg_id) {}
|
||||
|
||||
@@ -1012,15 +1045,15 @@ template <typename Char, typename T> struct named_arg : view {
|
||||
static_assert(!is_named_arg<T>::value, "nested named arguments");
|
||||
};
|
||||
|
||||
template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
|
||||
template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
|
||||
template <bool B = false> constexpr auto count() -> int { return B ? 1 : 0; }
|
||||
template <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {
|
||||
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
||||
}
|
||||
|
||||
template <typename... Args> constexpr auto count_named_args() -> size_t {
|
||||
template <typename... Args> constexpr auto count_named_args() -> int {
|
||||
return count<is_named_arg<Args>::value...>();
|
||||
}
|
||||
template <typename... Args> constexpr auto count_static_named_args() -> size_t {
|
||||
template <typename... Args> constexpr auto count_static_named_args() -> int {
|
||||
return count<is_static_named_arg<Args>::value...>();
|
||||
}
|
||||
|
||||
@@ -1180,7 +1213,7 @@ class compile_parse_context : public parse_context<Char> {
|
||||
using base = parse_context<Char>;
|
||||
|
||||
public:
|
||||
explicit FMT_CONSTEXPR compile_parse_context(basic_string_view<Char> fmt,
|
||||
FMT_CONSTEXPR explicit compile_parse_context(basic_string_view<Char> fmt,
|
||||
int num_args, const type* types,
|
||||
int next_arg_id = 0)
|
||||
: base(fmt, next_arg_id), num_args_(num_args), types_(types) {}
|
||||
@@ -1627,16 +1660,16 @@ template <typename... T> struct arg_pack {};
|
||||
template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
|
||||
class format_string_checker {
|
||||
private:
|
||||
type types_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
||||
named_arg_info<Char> named_args_[NUM_NAMED_ARGS > 0 ? NUM_NAMED_ARGS : 1];
|
||||
type types_[max_of(1, NUM_ARGS)];
|
||||
named_arg_info<Char> named_args_[max_of(1, NUM_NAMED_ARGS)];
|
||||
compile_parse_context<Char> context_;
|
||||
|
||||
using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
|
||||
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
||||
parse_func parse_funcs_[max_of(1, NUM_ARGS)];
|
||||
|
||||
public:
|
||||
template <typename... T>
|
||||
explicit FMT_CONSTEXPR format_string_checker(basic_string_view<Char> fmt,
|
||||
FMT_CONSTEXPR explicit format_string_checker(basic_string_view<Char> fmt,
|
||||
arg_pack<T...>)
|
||||
: types_{mapped_type_constant<T, Char>::value...},
|
||||
named_args_{},
|
||||
@@ -1694,7 +1727,7 @@ template <typename T> class buffer {
|
||||
protected:
|
||||
// Don't initialize ptr_ since it is not accessed to save a few cycles.
|
||||
FMT_MSC_WARNING(suppress : 26495)
|
||||
FMT_CONSTEXPR20 buffer(grow_fun grow, size_t sz) noexcept
|
||||
FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept
|
||||
: size_(sz), capacity_(sz), grow_(grow) {}
|
||||
|
||||
constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,
|
||||
@@ -1740,7 +1773,7 @@ template <typename T> class buffer {
|
||||
// the new elements may not be initialized.
|
||||
FMT_CONSTEXPR void try_resize(size_t count) {
|
||||
try_reserve(count);
|
||||
size_ = count <= capacity_ ? count : capacity_;
|
||||
size_ = min_of(count, capacity_);
|
||||
}
|
||||
|
||||
// Tries increasing the buffer capacity to `new_capacity`. It can increase the
|
||||
@@ -1788,9 +1821,9 @@ template <typename T> class buffer {
|
||||
};
|
||||
|
||||
struct buffer_traits {
|
||||
explicit buffer_traits(size_t) {}
|
||||
auto count() const -> size_t { return 0; }
|
||||
auto limit(size_t size) -> size_t { return size; }
|
||||
constexpr explicit buffer_traits(size_t) {}
|
||||
constexpr auto count() const -> size_t { return 0; }
|
||||
constexpr auto limit(size_t size) const -> size_t { return size; }
|
||||
};
|
||||
|
||||
class fixed_buffer_traits {
|
||||
@@ -1799,12 +1832,12 @@ class fixed_buffer_traits {
|
||||
size_t limit_;
|
||||
|
||||
public:
|
||||
explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
|
||||
auto count() const -> size_t { return count_; }
|
||||
auto limit(size_t size) -> size_t {
|
||||
constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
|
||||
constexpr auto count() const -> size_t { return count_; }
|
||||
FMT_CONSTEXPR auto limit(size_t size) -> size_t {
|
||||
size_t n = limit_ > count_ ? limit_ - count_ : 0;
|
||||
count_ += size;
|
||||
return size < n ? size : n;
|
||||
return min_of(size, n);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1962,15 +1995,37 @@ template <typename T = char> class counting_buffer : public buffer<T> {
|
||||
template <typename T>
|
||||
struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
|
||||
|
||||
template <typename OutputIt, typename InputIt, typename = void>
|
||||
struct has_back_insert_iterator_container_append : std::false_type {};
|
||||
template <typename OutputIt, typename InputIt>
|
||||
struct has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt,
|
||||
void_t<decltype(get_container(std::declval<OutputIt>())
|
||||
.append(std::declval<InputIt>(),
|
||||
std::declval<InputIt>()))>> : std::true_type {};
|
||||
|
||||
// An optimized version of std::copy with the output value type (T).
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
|
||||
has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt>::value)>
|
||||
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
-> OutputIt {
|
||||
get_container(out).append(begin, end);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
|
||||
!has_back_insert_iterator_container_append<
|
||||
OutputIt, InputIt>::value)>
|
||||
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||
-> OutputIt {
|
||||
auto& c = get_container(out);
|
||||
c.insert(c.end(), begin, end);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T, typename InputIt, typename OutputIt,
|
||||
FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
|
||||
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
|
||||
@@ -2146,7 +2201,8 @@ template <typename Context> class value {
|
||||
template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
|
||||
value(const T& named_arg) : value(named_arg.value) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(use_formatter<T>::value)>
|
||||
template <typename T,
|
||||
FMT_ENABLE_IF(use_formatter<T>::value || !FMT_BUILTIN_TYPES)>
|
||||
FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
|
||||
|
||||
FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)
|
||||
@@ -2220,9 +2276,12 @@ struct locale_ref {
|
||||
|
||||
public:
|
||||
constexpr locale_ref() : locale_(nullptr) {}
|
||||
template <typename Locale> explicit locale_ref(const Locale& loc);
|
||||
explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||
#endif
|
||||
|
||||
template <typename Locale, FMT_ENABLE_IF(sizeof(Locale::collate) != 0)>
|
||||
locale_ref(const Locale& loc);
|
||||
|
||||
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
template <typename Locale> auto get() const -> Locale;
|
||||
};
|
||||
@@ -2243,16 +2302,15 @@ constexpr auto make_descriptor() -> unsigned long long {
|
||||
: is_unpacked_bit | NUM_ARGS;
|
||||
}
|
||||
|
||||
template <typename Context, size_t NUM_ARGS>
|
||||
template <typename Context, int NUM_ARGS>
|
||||
using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
|
||||
basic_format_arg<Context>>;
|
||||
|
||||
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
|
||||
template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
|
||||
unsigned long long DESC>
|
||||
struct named_arg_store {
|
||||
// args_[0].named_args points to named_args to avoid bloating format_args.
|
||||
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
||||
arg_t<Context, NUM_ARGS> args[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
|
||||
arg_t<Context, NUM_ARGS> args[1 + NUM_ARGS];
|
||||
named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];
|
||||
|
||||
template <typename... T>
|
||||
@@ -2280,13 +2338,13 @@ struct named_arg_store {
|
||||
// An array of references to arguments. It can be implicitly converted to
|
||||
// `basic_format_args` for passing into type-erased formatting functions
|
||||
// such as `vformat`. It is a plain struct to reduce binary size in debug mode.
|
||||
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
|
||||
template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
|
||||
unsigned long long DESC>
|
||||
struct format_arg_store {
|
||||
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
||||
using type =
|
||||
conditional_t<NUM_NAMED_ARGS == 0,
|
||||
arg_t<Context, NUM_ARGS>[NUM_ARGS != 0 ? NUM_ARGS : +1],
|
||||
arg_t<Context, NUM_ARGS>[max_of(1, NUM_ARGS)],
|
||||
named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
|
||||
type args;
|
||||
};
|
||||
@@ -2372,11 +2430,6 @@ template <typename T> class basic_appender {
|
||||
detail::buffer<T>* container;
|
||||
|
||||
public:
|
||||
using iterator_category = int;
|
||||
using value_type = T;
|
||||
using pointer = T*;
|
||||
using reference = T&;
|
||||
using difference_type = decltype(pointer() - pointer());
|
||||
using container_type = detail::buffer<T>;
|
||||
|
||||
FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : container(&buf) {}
|
||||
@@ -2503,7 +2556,7 @@ template <typename Context> class basic_format_args {
|
||||
return static_cast<detail::type>((desc_ >> shift) & mask);
|
||||
}
|
||||
|
||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC>
|
||||
template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC>
|
||||
using store =
|
||||
detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>;
|
||||
|
||||
@@ -2513,14 +2566,14 @@ template <typename Context> class basic_format_args {
|
||||
constexpr basic_format_args() : desc_(0), args_(nullptr) {}
|
||||
|
||||
/// Constructs a `basic_format_args` object from `format_arg_store`.
|
||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
|
||||
template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,
|
||||
FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args)>
|
||||
constexpr FMT_ALWAYS_INLINE basic_format_args(
|
||||
const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
|
||||
: desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
|
||||
values_(s.args) {}
|
||||
|
||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
|
||||
template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,
|
||||
FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>
|
||||
constexpr basic_format_args(const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
|
||||
: desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
|
||||
@@ -2571,10 +2624,11 @@ template <typename Context> class basic_format_args {
|
||||
};
|
||||
|
||||
// A formatting context.
|
||||
class context : private detail::locale_ref {
|
||||
class context {
|
||||
private:
|
||||
appender out_;
|
||||
format_args args_;
|
||||
FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
|
||||
|
||||
public:
|
||||
/// The character type for the output.
|
||||
@@ -2590,24 +2644,26 @@ class context : private detail::locale_ref {
|
||||
/// in the object so make sure they have appropriate lifetimes.
|
||||
FMT_CONSTEXPR context(iterator out, format_args args,
|
||||
detail::locale_ref loc = {})
|
||||
: locale_ref(loc), out_(out), args_(args) {}
|
||||
: out_(out), args_(args), loc_(loc) {}
|
||||
context(context&&) = default;
|
||||
context(const context&) = delete;
|
||||
void operator=(const context&) = delete;
|
||||
|
||||
FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }
|
||||
auto arg(string_view name) -> format_arg { return args_.get(name); }
|
||||
FMT_CONSTEXPR auto arg_id(string_view name) -> int {
|
||||
inline auto arg(string_view name) const -> format_arg {
|
||||
return args_.get(name);
|
||||
}
|
||||
FMT_CONSTEXPR auto arg_id(string_view name) const -> int {
|
||||
return args_.get_id(name);
|
||||
}
|
||||
|
||||
// Returns an iterator to the beginning of the output range.
|
||||
FMT_CONSTEXPR auto out() -> iterator { return out_; }
|
||||
FMT_CONSTEXPR auto out() const -> iterator { return out_; }
|
||||
|
||||
// Advances the begin iterator to `it`.
|
||||
void advance_to(iterator) {}
|
||||
FMT_CONSTEXPR void advance_to(iterator) {}
|
||||
|
||||
FMT_CONSTEXPR auto locale() -> detail::locale_ref { return *this; }
|
||||
FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return loc_; }
|
||||
};
|
||||
|
||||
template <typename Char = char> struct runtime_format_string {
|
||||
@@ -2624,7 +2680,8 @@ template <typename Char = char> struct runtime_format_string {
|
||||
*/
|
||||
inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
|
||||
|
||||
/// A compile-time format string.
|
||||
/// A compile-time format string. Use `format_string` in the public API to
|
||||
/// prevent type deduction.
|
||||
template <typename... T> struct fstring {
|
||||
private:
|
||||
static constexpr int num_static_named_args =
|
||||
@@ -2657,8 +2714,9 @@ template <typename... T> struct fstring {
|
||||
template <typename S,
|
||||
FMT_ENABLE_IF(std::is_convertible<const S&, string_view>::value)>
|
||||
FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) {
|
||||
auto sv = string_view(str);
|
||||
if (FMT_USE_CONSTEVAL)
|
||||
detail::parse_format_string<char>(s, checker(s, arg_pack()));
|
||||
detail::parse_format_string<char>(sv, checker(sv, arg_pack()));
|
||||
#ifdef FMT_ENFORCE_COMPILE_STRING
|
||||
static_assert(
|
||||
FMT_USE_CONSTEVAL && sizeof(s) != 0,
|
||||
@@ -2711,8 +2769,8 @@ struct formatter<T, Char,
|
||||
// Take arguments by lvalue references to avoid some lifetime issues, e.g.
|
||||
// auto args = make_format_args(std::string());
|
||||
template <typename Context = context, typename... T,
|
||||
size_t NUM_ARGS = sizeof...(T),
|
||||
size_t NUM_NAMED_ARGS = detail::count_named_args<T...>(),
|
||||
int NUM_ARGS = sizeof...(T),
|
||||
int NUM_NAMED_ARGS = detail::count_named_args<T...>(),
|
||||
unsigned long long DESC = detail::make_descriptor<Context, T...>()>
|
||||
constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)
|
||||
-> detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC> {
|
||||
@@ -2851,7 +2909,7 @@ FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args);
|
||||
template <typename... T>
|
||||
FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
|
||||
vargs<T...> va = {{args...}};
|
||||
if (!detail::use_utf8)
|
||||
if (detail::const_check(!detail::use_utf8))
|
||||
return detail::vprint_mojibake(stdout, fmt.str, va, false);
|
||||
return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt.str, va)
|
||||
: vprint(fmt.str, va);
|
||||
@@ -2868,7 +2926,8 @@ FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
|
||||
template <typename... T>
|
||||
FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
|
||||
vargs<T...> va = {{args...}};
|
||||
if (!detail::use_utf8) return detail::vprint_mojibake(f, fmt.str, va, false);
|
||||
if (detail::const_check(!detail::use_utf8))
|
||||
return detail::vprint_mojibake(f, fmt.str, va, false);
|
||||
return detail::is_locking<T...>() ? vprint_buffered(f, fmt.str, va)
|
||||
: vprint(f, fmt.str, va);
|
||||
}
|
||||
@@ -2878,8 +2937,9 @@ FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
|
||||
template <typename... T>
|
||||
FMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {
|
||||
vargs<T...> va = {{args...}};
|
||||
return detail::use_utf8 ? vprintln(f, fmt.str, va)
|
||||
: detail::vprint_mojibake(f, fmt.str, va, true);
|
||||
return detail::const_check(detail::use_utf8)
|
||||
? vprintln(f, fmt.str, va)
|
||||
: detail::vprint_mojibake(f, fmt.str, va, true);
|
||||
}
|
||||
|
||||
/// Formats `args` according to specifications in `fmt` and writes the output
|
||||
|
||||
Reference in New Issue
Block a user