mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-09 21:00:06 +00:00
Cleanup base API
This commit is contained in:
parent
d980dd7171
commit
4fa533c70e
@ -112,13 +112,6 @@ class dynamic_format_arg_store
|
|||||||
|
|
||||||
friend class basic_format_args<Context>;
|
friend class basic_format_args<Context>;
|
||||||
|
|
||||||
auto get_types() const -> unsigned long long {
|
|
||||||
return detail::is_unpacked_bit | data_.size() |
|
|
||||||
(named_info_.empty()
|
|
||||||
? 0ULL
|
|
||||||
: static_cast<unsigned long long>(detail::has_named_args_bit));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data() const -> const basic_format_arg<Context>* {
|
auto data() const -> const basic_format_arg<Context>* {
|
||||||
return named_info_.empty() ? data_.data() : data_.data() + 1;
|
return named_info_.empty() ? data_.data() : data_.data() + 1;
|
||||||
}
|
}
|
||||||
@ -140,13 +133,18 @@ class dynamic_format_arg_store
|
|||||||
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
|
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
|
||||||
guard{&data_, pop_one};
|
guard{&data_, pop_one};
|
||||||
named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
|
named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
|
||||||
data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
|
data_[0] = {named_info_.data(), named_info_.size()};
|
||||||
guard.release();
|
guard.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr dynamic_format_arg_store() = default;
|
constexpr dynamic_format_arg_store() = default;
|
||||||
|
|
||||||
|
operator basic_format_args<Context>() const {
|
||||||
|
return basic_format_args<Context>(data(), static_cast<int>(data_.size()),
|
||||||
|
!named_info_.empty());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an argument into the dynamic store for later passing to a formatting
|
* Adds an argument into the dynamic store for later passing to a formatting
|
||||||
* function.
|
* function.
|
||||||
@ -217,7 +215,7 @@ class dynamic_format_arg_store
|
|||||||
/// `new_cap_named` named arguments.
|
/// `new_cap_named` named arguments.
|
||||||
void reserve(size_t new_cap, size_t new_cap_named) {
|
void reserve(size_t new_cap, size_t new_cap_named) {
|
||||||
FMT_ASSERT(new_cap >= new_cap_named,
|
FMT_ASSERT(new_cap >= new_cap_named,
|
||||||
"Set of arguments includes set of named arguments");
|
"set of arguments includes set of named arguments");
|
||||||
data_.reserve(new_cap);
|
data_.reserve(new_cap);
|
||||||
named_info_.reserve(new_cap_named);
|
named_info_.reserve(new_cap_named);
|
||||||
}
|
}
|
||||||
|
@ -216,20 +216,6 @@
|
|||||||
# define FMT_DEPRECATED /* deprecated */
|
# define FMT_DEPRECATED /* deprecated */
|
||||||
#endif
|
#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
|
|
||||||
|
|
||||||
#ifdef FMT_ALWAYS_INLINE
|
#ifdef FMT_ALWAYS_INLINE
|
||||||
// Use the provided definition.
|
// Use the provided definition.
|
||||||
#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
|
#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
|
||||||
@ -652,7 +638,6 @@ using buffered_context =
|
|||||||
|
|
||||||
template <typename Context> class basic_format_arg;
|
template <typename Context> class basic_format_arg;
|
||||||
template <typename Context> class basic_format_args;
|
template <typename Context> class basic_format_args;
|
||||||
template <typename Context> class dynamic_format_arg_store;
|
|
||||||
|
|
||||||
// A separate type would result in shorter symbols but break ABI compatibility
|
// A separate type would result in shorter symbols but break ABI compatibility
|
||||||
// between clang and gcc on ARM (#1919).
|
// between clang and gcc on ARM (#1919).
|
||||||
@ -790,18 +775,22 @@ enum {
|
|||||||
|
|
||||||
struct view {};
|
struct view {};
|
||||||
|
|
||||||
template <typename Char, typename T> struct named_arg : view {
|
template <typename Char, typename T> struct named_arg;
|
||||||
const Char* name;
|
|
||||||
const T& value;
|
|
||||||
named_arg(const Char* n, const T& v) : name(n), value(v) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct is_named_arg : std::false_type {};
|
template <typename T> struct is_named_arg : std::false_type {};
|
||||||
template <typename T> struct is_static_named_arg : std::false_type {};
|
template <typename T> struct is_static_named_arg : std::false_type {};
|
||||||
|
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
struct is_named_arg<named_arg<Char, T>> : std::true_type {};
|
struct is_named_arg<named_arg<Char, T>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename Char, typename T> struct named_arg : view {
|
||||||
|
const Char* name;
|
||||||
|
const T& value;
|
||||||
|
|
||||||
|
named_arg(const Char* n, const T& v) : name(n), value(v) {}
|
||||||
|
|
||||||
|
static_assert(!is_named_arg<T>::value, "nested named arguments");
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
auto unwrap_named_arg(const named_arg<Char, T>& arg) -> const T& {
|
auto unwrap_named_arg(const named_arg<Char, T>& arg) -> const T& {
|
||||||
return arg.value;
|
return arg.value;
|
||||||
@ -2407,7 +2396,7 @@ FMT_CONSTEXPR auto make_arg(T& val) -> value<Context> {
|
|||||||
enum {
|
enum {
|
||||||
formattable_char = !std::is_same<arg_type, unformattable_char>::value
|
formattable_char = !std::is_same<arg_type, unformattable_char>::value
|
||||||
};
|
};
|
||||||
static_assert(formattable_char, "Mixing character types is disallowed.");
|
static_assert(formattable_char, "mixing character types is disallowed");
|
||||||
|
|
||||||
// Formatting of arbitrary pointers is disallowed. If you want to format a
|
// Formatting of arbitrary pointers is disallowed. If you want to format a
|
||||||
// pointer cast it to `void*` or `const void*`. In particular, this forbids
|
// pointer cast it to `void*` or `const void*`. In particular, this forbids
|
||||||
@ -2416,7 +2405,7 @@ FMT_CONSTEXPR auto make_arg(T& val) -> value<Context> {
|
|||||||
formattable_pointer = !std::is_same<arg_type, unformattable_pointer>::value
|
formattable_pointer = !std::is_same<arg_type, unformattable_pointer>::value
|
||||||
};
|
};
|
||||||
static_assert(formattable_pointer,
|
static_assert(formattable_pointer,
|
||||||
"Formatting of non-void pointers is disallowed.");
|
"formatting of non-void pointers is disallowed");
|
||||||
|
|
||||||
enum { formattable = !std::is_same<arg_type, unformattable>::value };
|
enum { formattable = !std::is_same<arg_type, unformattable>::value };
|
||||||
#if defined(__cpp_if_constexpr)
|
#if defined(__cpp_if_constexpr)
|
||||||
@ -2426,7 +2415,7 @@ FMT_CONSTEXPR auto make_arg(T& val) -> value<Context> {
|
|||||||
#endif
|
#endif
|
||||||
static_assert(
|
static_assert(
|
||||||
formattable,
|
formattable,
|
||||||
"Cannot format an argument. To make type T formattable provide a "
|
"cannot format an argument; to make type T formattable provide a "
|
||||||
"formatter<T> specialization: https://fmt.dev/latest/api.html#udt");
|
"formatter<T> specialization: https://fmt.dev/latest/api.html#udt");
|
||||||
return {arg_mapper<char_type>::map(val)};
|
return {arg_mapper<char_type>::map(val)};
|
||||||
}
|
}
|
||||||
@ -2562,22 +2551,12 @@ template <typename Context> class basic_format_arg {
|
|||||||
detail::value<Context> value_;
|
detail::value<Context> value_;
|
||||||
detail::type type_;
|
detail::type type_;
|
||||||
|
|
||||||
template <typename ContextType, typename T>
|
template <typename Ctx, typename T>
|
||||||
friend FMT_CONSTEXPR auto detail::make_arg(T& value)
|
friend FMT_CONSTEXPR auto detail::make_arg(T& value) -> basic_format_arg<Ctx>;
|
||||||
-> basic_format_arg<ContextType>;
|
|
||||||
|
|
||||||
friend class basic_format_args<Context>;
|
friend class basic_format_args<Context>;
|
||||||
friend class dynamic_format_arg_store<Context>;
|
|
||||||
friend class loc_value;
|
|
||||||
|
|
||||||
using char_type = typename Context::char_type;
|
using char_type = typename Context::char_type;
|
||||||
|
|
||||||
template <typename, size_t, size_t, unsigned long long>
|
|
||||||
friend struct detail::format_arg_store;
|
|
||||||
|
|
||||||
basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
|
|
||||||
: value_(args, size) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class handle {
|
class handle {
|
||||||
private:
|
private:
|
||||||
@ -2592,15 +2571,14 @@ template <typename Context> class basic_format_arg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr basic_format_arg() : type_(detail::type::none_type) {}
|
constexpr basic_format_arg() : type_(detail::type::none_type) {}
|
||||||
|
basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
|
||||||
|
: value_(args, size) {}
|
||||||
|
|
||||||
constexpr explicit operator bool() const noexcept {
|
constexpr explicit operator bool() const noexcept {
|
||||||
return type_ != detail::type::none_type;
|
return type_ != detail::type::none_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto type() const -> detail::type { return type_; }
|
auto type() const -> detail::type { return type_; }
|
||||||
|
|
||||||
auto is_integral() const -> bool { return detail::is_integral_type(type_); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visits an argument dispatching to the appropriate visit method based on
|
* Visits an argument dispatching to the appropriate visit method based on
|
||||||
* the argument type. For example, if the argument type is `double` then
|
* the argument type. For example, if the argument type is `double` then
|
||||||
@ -2714,18 +2692,16 @@ template <typename Context> class basic_format_args {
|
|||||||
store)
|
store)
|
||||||
: desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {}
|
: desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {}
|
||||||
|
|
||||||
/// Constructs a `basic_format_args` object from `dynamic_format_arg_store`.
|
|
||||||
constexpr basic_format_args(const dynamic_format_arg_store<Context>& store)
|
|
||||||
: desc_(store.get_types()), args_(store.data()) {}
|
|
||||||
|
|
||||||
/// Constructs a `basic_format_args` object from a dynamic list of arguments.
|
/// Constructs a `basic_format_args` object from a dynamic list of arguments.
|
||||||
constexpr basic_format_args(const format_arg* args, int count)
|
constexpr basic_format_args(const format_arg* args, int count,
|
||||||
: desc_(detail::is_unpacked_bit | detail::to_unsigned(count)),
|
bool has_named = false)
|
||||||
|
: desc_(detail::is_unpacked_bit | detail::to_unsigned(count) |
|
||||||
|
(has_named ? +detail::has_named_args_bit : 0ULL)),
|
||||||
args_(args) {}
|
args_(args) {}
|
||||||
|
|
||||||
/// Returns the argument with the specified id.
|
/// Returns the argument with the specified id.
|
||||||
FMT_CONSTEXPR auto get(int id) const -> format_arg {
|
FMT_CONSTEXPR auto get(int id) const -> format_arg {
|
||||||
format_arg arg;
|
auto arg = format_arg();
|
||||||
if (!is_packed()) {
|
if (!is_packed()) {
|
||||||
if (id < max_size()) arg = args_[id];
|
if (id < max_size()) arg = args_[id];
|
||||||
return arg;
|
return arg;
|
||||||
@ -2761,11 +2737,10 @@ template <typename Context> class basic_format_args {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A formatting context.
|
// A formatting context.
|
||||||
class context {
|
class context : private detail::locale_ref {
|
||||||
private:
|
private:
|
||||||
appender out_;
|
appender out_;
|
||||||
format_args args_;
|
format_args args_;
|
||||||
FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The character type for the output.
|
/// The character type for the output.
|
||||||
@ -2780,7 +2755,7 @@ class context {
|
|||||||
/// Constructs a `context` object. References to the arguments are stored
|
/// Constructs a `context` object. References to the arguments are stored
|
||||||
/// in the object so make sure they have appropriate lifetimes.
|
/// in the object so make sure they have appropriate lifetimes.
|
||||||
FMT_CONSTEXPR context(iterator out, format_args a, detail::locale_ref l = {})
|
FMT_CONSTEXPR context(iterator out, format_args a, detail::locale_ref l = {})
|
||||||
: out_(out), args_(a), loc_(l) {}
|
: locale_ref(l), out_(out), args_(a) {}
|
||||||
context(context&&) = default;
|
context(context&&) = default;
|
||||||
context(const context&) = delete;
|
context(const context&) = delete;
|
||||||
void operator=(const context&) = delete;
|
void operator=(const context&) = delete;
|
||||||
@ -2797,7 +2772,7 @@ class context {
|
|||||||
// Advances the begin iterator to `it`.
|
// Advances the begin iterator to `it`.
|
||||||
void advance_to(iterator) {}
|
void advance_to(iterator) {}
|
||||||
|
|
||||||
FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
|
FMT_CONSTEXPR auto locale() -> detail::locale_ref { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char = char> struct runtime_format_string {
|
template <typename Char = char> struct runtime_format_string {
|
||||||
@ -2844,7 +2819,7 @@ template <typename Char, typename... Args> class basic_format_string {
|
|||||||
static_assert(
|
static_assert(
|
||||||
FMT_USE_CONSTEVAL && sizeof(S) != 0,
|
FMT_USE_CONSTEVAL && sizeof(S) != 0,
|
||||||
"FMT_ENFORCE_COMPILE_STRING requires all format strings to use "
|
"FMT_ENFORCE_COMPILE_STRING requires all format strings to use "
|
||||||
"FMT_STRING.");
|
"FMT_STRING");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
template <typename S,
|
template <typename S,
|
||||||
@ -2918,8 +2893,7 @@ constexpr auto make_format_args(T&... args)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a named argument to be used in a formatting function.
|
* Returns a named argument to be used in a formatting function.
|
||||||
* It should only be used in a call to a formatting function or
|
* It should only be used in a call to a formatting function.
|
||||||
* `dynamic_format_arg_store::push_back`.
|
|
||||||
*
|
*
|
||||||
* **Example**:
|
* **Example**:
|
||||||
*
|
*
|
||||||
@ -2927,7 +2901,6 @@ constexpr auto make_format_args(T&... args)
|
|||||||
*/
|
*/
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
|
inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
|
||||||
static_assert(!detail::is_named_arg<T>(), "nested named arguments");
|
|
||||||
return {name, arg};
|
return {name, arg};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +124,20 @@ FMT_END_NAMESPACE
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
#ifndef FMT_MAYBE_UNUSED
|
#ifndef FMT_MAYBE_UNUSED
|
||||||
# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
|
# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
|
||||||
# define FMT_MAYBE_UNUSED [[maybe_unused]]
|
# define FMT_MAYBE_UNUSED [[maybe_unused]]
|
||||||
@ -1077,14 +1091,11 @@ template <typename OutputIt, typename Char> class generic_context {
|
|||||||
|
|
||||||
class loc_value {
|
class loc_value {
|
||||||
private:
|
private:
|
||||||
basic_format_arg<format_context> value_;
|
basic_format_arg<context> value_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
|
template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
|
||||||
loc_value(T value) {
|
loc_value(T value) : value_(detail::make_arg<context>(value)) {}
|
||||||
value_.type_ = detail::mapped_type_constant<T>::value;
|
|
||||||
value_.value_ = detail::arg_mapper<char>::map(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
|
template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
|
||||||
loc_value(T) {}
|
loc_value(T) {}
|
||||||
|
@ -491,7 +491,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
|||||||
auto arg = get_arg(arg_index);
|
auto arg = get_arg(arg_index);
|
||||||
// For d, i, o, u, x, and X conversion specifiers, if a precision is
|
// For d, i, o, u, x, and X conversion specifiers, if a precision is
|
||||||
// specified, the '0' flag is ignored
|
// specified, the '0' flag is ignored
|
||||||
if (specs.precision >= 0 && arg.is_integral()) {
|
if (specs.precision >= 0 && is_integral_type(arg.type())) {
|
||||||
// Ignore '0' for non-numeric types or if '-' present.
|
// Ignore '0' for non-numeric types or if '-' present.
|
||||||
specs.set_fill(' ');
|
specs.set_fill(' ');
|
||||||
}
|
}
|
||||||
@ -556,7 +556,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
|||||||
// Parse type.
|
// Parse type.
|
||||||
if (it == end) report_error("invalid format string");
|
if (it == end) report_error("invalid format string");
|
||||||
char type = static_cast<char>(*it++);
|
char type = static_cast<char>(*it++);
|
||||||
if (arg.is_integral()) {
|
if (is_integral_type(arg.type())) {
|
||||||
// Normalize type.
|
// Normalize type.
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'i':
|
case 'i':
|
||||||
|
Loading…
Reference in New Issue
Block a user