mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-28 16:11:28 +00:00
Cleanup core
This commit is contained in:
parent
8f1902c05a
commit
d35f1ad5c1
@ -32,35 +32,16 @@
|
||||
# define FMT_GCC_PRAGMA(arg)
|
||||
#endif
|
||||
|
||||
#if defined(__INTEL_COMPILER)
|
||||
# define FMT_ICC_VERSION __INTEL_COMPILER
|
||||
#else
|
||||
# define FMT_ICC_VERSION 0
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION
|
||||
#else
|
||||
# define FMT_HAS_GXX_CXX11 0
|
||||
#endif
|
||||
|
||||
// Check if constexpr std::char_traits<>::compare,length is supported.
|
||||
#if defined(__GLIBCXX__)
|
||||
# if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \
|
||||
_GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE.
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
|
||||
# endif
|
||||
#elif defined(_LIBCPP_VERSION)
|
||||
# if __cplusplus >= 201703L && _LIBCPP_VERSION >= 4000
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# if _MSVC_LANG >= 201703L && _MSC_VER >= 1914
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
|
||||
# endif
|
||||
#endif
|
||||
#ifndef FMT_CONSTEXPR_CHAR_TRAITS
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS
|
||||
#if defined(__INTEL_COMPILER)
|
||||
# define FMT_ICC_VERSION __INTEL_COMPILER
|
||||
#else
|
||||
# define FMT_ICC_VERSION 0
|
||||
#endif
|
||||
|
||||
#ifdef __NVCC__
|
||||
@ -118,6 +99,22 @@
|
||||
# define FMT_CONSTEXPR_DECL
|
||||
#endif
|
||||
|
||||
// Check if constexpr std::char_traits<>::compare,length is supported.
|
||||
#if defined(__GLIBCXX__)
|
||||
# if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \
|
||||
_GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE.
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
|
||||
# endif
|
||||
#elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && \
|
||||
_LIBCPP_VERSION >= 4000
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
|
||||
#elif FMT_MSC_VER >= 1914 && _MSVC_LANG >= 201703L
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
|
||||
#endif
|
||||
#ifndef FMT_CONSTEXPR_CHAR_TRAITS
|
||||
# define FMT_CONSTEXPR_CHAR_TRAITS
|
||||
#endif
|
||||
|
||||
#ifndef FMT_OVERRIDE
|
||||
# if FMT_HAS_FEATURE(cxx_override_control) || \
|
||||
(FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
|
||||
@ -194,27 +191,6 @@
|
||||
# define FMT_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#ifndef FMT_DEPRECATED
|
||||
# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900
|
||||
# define FMT_DEPRECATED [[deprecated]]
|
||||
# else
|
||||
# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
|
||||
# define FMT_DEPRECATED __attribute__((deprecated))
|
||||
# elif FMT_MSC_VER
|
||||
# define FMT_DEPRECATED __declspec(deprecated)
|
||||
# else
|
||||
# define FMT_DEPRECATED /* deprecated */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers.
|
||||
#if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC
|
||||
# define FMT_DEPRECATED_ALIAS
|
||||
#else
|
||||
# define FMT_DEPRECATED_ALIAS FMT_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef FMT_USE_FLOAT
|
||||
# define FMT_USE_FLOAT 1
|
||||
#endif
|
||||
@ -262,17 +238,9 @@
|
||||
|
||||
#ifndef FMT_MODULE_EXPORT
|
||||
# define FMT_MODULE_EXPORT
|
||||
#endif
|
||||
#ifndef FMT_MODULE_EXPORT_BEGIN
|
||||
# define FMT_MODULE_EXPORT_BEGIN
|
||||
#endif
|
||||
#ifndef FMT_MODULE_EXPORT_END
|
||||
# define FMT_MODULE_EXPORT_END
|
||||
#endif
|
||||
#ifndef FMT_BEGIN_DETAIL_NAMESPACE
|
||||
# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail {
|
||||
#endif
|
||||
#ifndef FMT_END_DETAIL_NAMESPACE
|
||||
# define FMT_END_DETAIL_NAMESPACE }
|
||||
#endif
|
||||
|
||||
@ -370,7 +338,7 @@ constexpr FMT_INLINE bool is_constant_evaluated() FMT_NOEXCEPT {
|
||||
#endif
|
||||
}
|
||||
|
||||
// A helper function to suppress "conditional expression is constant" warnings.
|
||||
// A function to suppress "conditional expression is constant" warnings.
|
||||
template <typename T> constexpr T const_check(T value) { return value; }
|
||||
|
||||
FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||
@ -408,8 +376,10 @@ using uint128_t = __uint128_t;
|
||||
# define FMT_USE_INT128 0
|
||||
#endif
|
||||
#if !FMT_USE_INT128
|
||||
struct int128_t {};
|
||||
struct uint128_t {};
|
||||
enum class int128_t {};
|
||||
enum class uint128_t {};
|
||||
inline monostate operator+(int128_t) { return {}; }
|
||||
inline monostate operator+(uint128_t) { return {}; }
|
||||
#endif
|
||||
|
||||
// Casts a nonnegative integer to unsigned.
|
||||
@ -425,7 +395,6 @@ template <typename Char> constexpr bool is_unicode() {
|
||||
return FMT_UNICODE || sizeof(Char) != 1 ||
|
||||
(sizeof(micro) == 3 && micro[0] == 0xC2 && micro[1] == 0xB5);
|
||||
}
|
||||
|
||||
FMT_END_DETAIL_NAMESPACE
|
||||
|
||||
/**
|
||||
@ -620,7 +589,6 @@ struct error_handler {
|
||||
// This function is intentionally not constexpr to give a compile-time error.
|
||||
FMT_NORETURN FMT_API void on_error(const char* message);
|
||||
};
|
||||
|
||||
FMT_END_DETAIL_NAMESPACE
|
||||
|
||||
/** String's character type. */
|
||||
@ -1414,9 +1382,8 @@ template <typename Context> class basic_format_arg {
|
||||
\endrst
|
||||
*/
|
||||
template <typename Visitor, typename Context>
|
||||
FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg(
|
||||
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(
|
||||
Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
|
||||
using char_type = typename Context::char_type;
|
||||
switch (arg.type_) {
|
||||
case detail::type::none_type:
|
||||
break;
|
||||
@ -1428,16 +1395,11 @@ FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg(
|
||||
return vis(arg.value_.long_long_value);
|
||||
case detail::type::ulong_long_type:
|
||||
return vis(arg.value_.ulong_long_value);
|
||||
#if FMT_USE_INT128
|
||||
case detail::type::int128_type:
|
||||
return vis(arg.value_.int128_value);
|
||||
// + converts fallback to monostate to reduce template instantations.
|
||||
return vis(+arg.value_.int128_value);
|
||||
case detail::type::uint128_type:
|
||||
return vis(arg.value_.uint128_value);
|
||||
#else
|
||||
case detail::type::int128_type:
|
||||
case detail::type::uint128_type:
|
||||
break;
|
||||
#endif
|
||||
return vis(+arg.value_.uint128_value);
|
||||
case detail::type::bool_type:
|
||||
return vis(arg.value_.bool_value);
|
||||
case detail::type::char_type:
|
||||
@ -1451,8 +1413,8 @@ FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg(
|
||||
case detail::type::cstring_type:
|
||||
return vis(arg.value_.string.data);
|
||||
case detail::type::string_type:
|
||||
return vis(basic_string_view<char_type>(arg.value_.string.data,
|
||||
arg.value_.string.size));
|
||||
using sv = basic_string_view<typename Context::char_type>;
|
||||
return vis(sv(arg.value_.string.data, arg.value_.string.size));
|
||||
case detail::type::pointer_type:
|
||||
return vis(arg.value_.pointer);
|
||||
case detail::type::custom_type:
|
||||
@ -1546,7 +1508,6 @@ template <bool IS_PACKED, typename Context, type, typename T,
|
||||
inline basic_format_arg<Context> make_arg(const T& value) {
|
||||
return make_arg<Context>(value);
|
||||
}
|
||||
|
||||
FMT_END_DETAIL_NAMESPACE
|
||||
|
||||
// Formatting context.
|
||||
@ -1879,7 +1840,6 @@ template <typename Char> struct fill_t {
|
||||
return data_[index];
|
||||
}
|
||||
};
|
||||
|
||||
FMT_END_DETAIL_NAMESPACE
|
||||
|
||||
// Format specifiers for built-in and string types.
|
||||
@ -1947,6 +1907,9 @@ struct auto_id {};
|
||||
|
||||
// A format specifier handler that sets fields in basic_format_specs.
|
||||
template <typename Char> class specs_setter {
|
||||
protected:
|
||||
basic_format_specs<Char>& specs_;
|
||||
|
||||
public:
|
||||
explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs)
|
||||
: specs_(specs) {}
|
||||
@ -1958,9 +1921,7 @@ template <typename Char> class specs_setter {
|
||||
FMT_CONSTEXPR void on_fill(basic_string_view<Char> fill) {
|
||||
specs_.fill = fill;
|
||||
}
|
||||
FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; }
|
||||
FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; }
|
||||
FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; }
|
||||
FMT_CONSTEXPR void on_sign(sign_t s) { specs_.sign = s; }
|
||||
FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
|
||||
FMT_CONSTEXPR void on_localized() { specs_.localized = true; }
|
||||
|
||||
@ -1978,9 +1939,6 @@ template <typename Char> class specs_setter {
|
||||
FMT_CONSTEXPR void on_type(Char type) {
|
||||
specs_.type = static_cast<char>(type);
|
||||
}
|
||||
|
||||
protected:
|
||||
basic_format_specs<Char>& specs_;
|
||||
};
|
||||
|
||||
// Format spec handler that saves references to arguments representing dynamic
|
||||
@ -2062,6 +2020,23 @@ FMT_CONSTEXPR int code_point_length(const Char* begin) {
|
||||
return len + !len;
|
||||
}
|
||||
|
||||
// Return the result via the out param to workaround gcc bug 77539.
|
||||
template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
|
||||
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr& out) {
|
||||
for (out = first; out != last; ++out) {
|
||||
if (*out == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool find<false, char>(const char* first, const char* last, char value,
|
||||
const char*& out) {
|
||||
out = static_cast<const char*>(
|
||||
std::memchr(first, value, to_unsigned(last - first)));
|
||||
return out != nullptr;
|
||||
}
|
||||
|
||||
// Parses the range [begin, end) as an unsigned integer. This function assumes
|
||||
// that the range is non-empty and the first character is a digit.
|
||||
template <typename Char, typename ErrorHandler>
|
||||
@ -2261,15 +2236,15 @@ FMT_CONSTEXPR_DECL FMT_INLINE const Char* parse_format_specs(
|
||||
// Parse sign.
|
||||
switch (to_ascii(*begin)) {
|
||||
case '+':
|
||||
handler.on_plus();
|
||||
handler.on_sign(sign::plus);
|
||||
++begin;
|
||||
break;
|
||||
case '-':
|
||||
handler.on_minus();
|
||||
handler.on_sign(sign::minus);
|
||||
++begin;
|
||||
break;
|
||||
case ' ':
|
||||
handler.on_space();
|
||||
handler.on_sign(sign::space);
|
||||
++begin;
|
||||
break;
|
||||
default:
|
||||
@ -2307,23 +2282,6 @@ FMT_CONSTEXPR_DECL FMT_INLINE const Char* parse_format_specs(
|
||||
return begin;
|
||||
}
|
||||
|
||||
// Return the result via the out param to workaround gcc bug 77539.
|
||||
template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
|
||||
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr& out) {
|
||||
for (out = first; out != last; ++out) {
|
||||
if (*out == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool find<false, char>(const char* first, const char* last, char value,
|
||||
const char*& out) {
|
||||
out = static_cast<const char*>(
|
||||
std::memchr(first, value, to_unsigned(last - first)));
|
||||
return out != nullptr;
|
||||
}
|
||||
|
||||
template <typename Handler, typename Char> struct id_adapter {
|
||||
Handler& handler;
|
||||
int arg_id;
|
||||
@ -2564,34 +2522,6 @@ FMT_CONSTEXPR float_specs parse_float_type_spec(
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename ErrorHandler> class numeric_specs_checker {
|
||||
public:
|
||||
FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, detail::type arg_type)
|
||||
: error_handler_(eh), arg_type_(arg_type) {}
|
||||
|
||||
FMT_CONSTEXPR void require_numeric_argument() {
|
||||
if (!is_arithmetic_type(arg_type_))
|
||||
error_handler_.on_error("format specifier requires numeric argument");
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void check_sign() {
|
||||
require_numeric_argument();
|
||||
if (is_integral_type(arg_type_) && arg_type_ != type::int_type &&
|
||||
arg_type_ != type::long_long_type && arg_type_ != type::char_type) {
|
||||
error_handler_.on_error("format specifier requires signed argument");
|
||||
}
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void check_precision() {
|
||||
if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type)
|
||||
error_handler_.on_error("precision not allowed for this argument type");
|
||||
}
|
||||
|
||||
private:
|
||||
ErrorHandler& error_handler_;
|
||||
detail::type arg_type_;
|
||||
};
|
||||
|
||||
template <typename ErrorHandler>
|
||||
class cstring_type_checker : public ErrorHandler {
|
||||
public:
|
||||
@ -2626,54 +2556,50 @@ FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) {
|
||||
// argument type.
|
||||
template <typename Handler> class specs_checker : public Handler {
|
||||
private:
|
||||
numeric_specs_checker<Handler> checker_;
|
||||
detail::type arg_type_;
|
||||
|
||||
// Suppress an MSVC warning about using this in initializer list.
|
||||
FMT_CONSTEXPR Handler& error_handler() { return *this; }
|
||||
FMT_CONSTEXPR void require_numeric_argument() {
|
||||
if (!is_arithmetic_type(arg_type_))
|
||||
this->on_error("format specifier requires numeric argument");
|
||||
}
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type)
|
||||
: Handler(handler), checker_(error_handler(), arg_type) {}
|
||||
|
||||
FMT_CONSTEXPR specs_checker(const specs_checker& other)
|
||||
: Handler(other), checker_(error_handler(), other.arg_type_) {}
|
||||
: Handler(handler), arg_type_(arg_type) {}
|
||||
|
||||
FMT_CONSTEXPR void on_align(align_t align) {
|
||||
if (align == align::numeric) checker_.require_numeric_argument();
|
||||
if (align == align::numeric) require_numeric_argument();
|
||||
Handler::on_align(align);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_plus() {
|
||||
checker_.check_sign();
|
||||
Handler::on_plus();
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_minus() {
|
||||
checker_.check_sign();
|
||||
Handler::on_minus();
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_space() {
|
||||
checker_.check_sign();
|
||||
Handler::on_space();
|
||||
FMT_CONSTEXPR void on_sign(sign_t s) {
|
||||
require_numeric_argument();
|
||||
if (is_integral_type(arg_type_) && arg_type_ != type::int_type &&
|
||||
arg_type_ != type::long_long_type && arg_type_ != type::char_type) {
|
||||
this->on_error("format specifier requires signed argument");
|
||||
}
|
||||
Handler::on_sign(s);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_hash() {
|
||||
checker_.require_numeric_argument();
|
||||
require_numeric_argument();
|
||||
Handler::on_hash();
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_localized() {
|
||||
checker_.require_numeric_argument();
|
||||
require_numeric_argument();
|
||||
Handler::on_localized();
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_zero() {
|
||||
checker_.require_numeric_argument();
|
||||
require_numeric_argument();
|
||||
Handler::on_zero();
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void end_precision() { checker_.check_precision(); }
|
||||
FMT_CONSTEXPR void end_precision() {
|
||||
if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type)
|
||||
this->on_error("precision not allowed for this argument type");
|
||||
}
|
||||
};
|
||||
|
||||
constexpr int invalid_arg_index = -1;
|
||||
@ -2703,6 +2629,16 @@ FMT_CONSTEXPR int get_arg_index_by_name(basic_string_view<Char> name) {
|
||||
|
||||
template <typename Char, typename ErrorHandler, typename... Args>
|
||||
class format_string_checker {
|
||||
private:
|
||||
using parse_context_type = compile_parse_context<Char, ErrorHandler>;
|
||||
enum { num_args = sizeof...(Args) };
|
||||
|
||||
// Format specifier parsing function.
|
||||
using parse_func = const Char* (*)(parse_context_type&);
|
||||
|
||||
parse_context_type context_;
|
||||
parse_func parse_funcs_[num_args > 0 ? num_args : 1];
|
||||
|
||||
public:
|
||||
explicit FMT_CONSTEXPR format_string_checker(
|
||||
basic_string_view<Char> format_str, ErrorHandler eh)
|
||||
@ -2737,16 +2673,6 @@ class format_string_checker {
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
context_.on_error(message);
|
||||
}
|
||||
|
||||
private:
|
||||
using parse_context_type = compile_parse_context<Char, ErrorHandler>;
|
||||
enum { num_args = sizeof...(Args) };
|
||||
|
||||
// Format specifier parsing function.
|
||||
using parse_func = const Char* (*)(parse_context_type&);
|
||||
|
||||
parse_context_type context_;
|
||||
parse_func parse_funcs_[num_args > 0 ? num_args : 1];
|
||||
};
|
||||
|
||||
template <typename... Args, typename S,
|
||||
@ -2760,20 +2686,17 @@ void check_format_string(S format_str) {
|
||||
(void)invalid_format;
|
||||
}
|
||||
|
||||
// Converts string literals to basic_string_view.
|
||||
// Converts a compile-time string to basic_string_view.
|
||||
template <typename Char, size_t N>
|
||||
FMT_CONSTEXPR basic_string_view<Char> compile_string_to_view(
|
||||
const Char (&s)[N]) {
|
||||
// Remove trailing null character if needed. Won't be present if this is used
|
||||
// with raw character array (i.e. not defined as a string).
|
||||
return {s,
|
||||
N - ((std::char_traits<Char>::to_int_type(s[N - 1]) == 0) ? 1 : 0)};
|
||||
constexpr auto compile_string_to_view(const Char (&s)[N])
|
||||
-> basic_string_view<Char> {
|
||||
// Remove trailing NUL character if needed. Won't be present if this is used
|
||||
// with a raw character array (i.e. not defined as a string).
|
||||
return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
|
||||
}
|
||||
|
||||
// Converts string_view to basic_string_view.
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR basic_string_view<Char> compile_string_to_view(
|
||||
const std_string_view<Char>& s) {
|
||||
constexpr auto compile_string_to_view(std_string_view<Char> s)
|
||||
-> basic_string_view<Char> {
|
||||
return {s.data(), s.size()};
|
||||
}
|
||||
|
||||
@ -2832,6 +2755,10 @@ template <typename T, typename Char>
|
||||
struct formatter<T, Char,
|
||||
enable_if_t<detail::type_constant<T, Char>::value !=
|
||||
detail::type::custom_type>> {
|
||||
private:
|
||||
detail::dynamic_format_specs<Char> specs_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR formatter() = default;
|
||||
|
||||
// Parses format specifiers stopping either at the end of the range or at the
|
||||
@ -2902,11 +2829,8 @@ struct formatter<T, Char,
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
FMT_CONSTEXPR FMT_INLINE auto format(const T& val, FormatContext& ctx) const
|
||||
FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
|
||||
-> decltype(ctx.out());
|
||||
|
||||
private:
|
||||
detail::dynamic_format_specs<Char> specs_;
|
||||
};
|
||||
|
||||
/** Formats a string and writes the output to ``out``. */
|
||||
|
@ -110,6 +110,27 @@ FMT_END_NAMESPACE
|
||||
# define FMT_CATCH(x) if (false)
|
||||
#endif
|
||||
|
||||
#ifndef FMT_DEPRECATED
|
||||
# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900
|
||||
# define FMT_DEPRECATED [[deprecated]]
|
||||
# else
|
||||
# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
|
||||
# define FMT_DEPRECATED __attribute__((deprecated))
|
||||
# elif FMT_MSC_VER
|
||||
# define FMT_DEPRECATED __declspec(deprecated)
|
||||
# else
|
||||
# define FMT_DEPRECATED /* deprecated */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers.
|
||||
#if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC
|
||||
# define FMT_DEPRECATED_ALIAS
|
||||
#else
|
||||
# define FMT_DEPRECATED_ALIAS FMT_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef FMT_USE_USER_DEFINED_LITERALS
|
||||
// EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
|
||||
# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
|
||||
@ -2481,9 +2502,7 @@ template <typename Char = char> class dynamic_formatter {
|
||||
private:
|
||||
struct null_handler : detail::error_handler {
|
||||
void on_align(align_t) {}
|
||||
void on_plus() {}
|
||||
void on_minus() {}
|
||||
void on_space() {}
|
||||
void on_sign(sign_t) {}
|
||||
void on_hash() {}
|
||||
};
|
||||
|
||||
@ -2502,19 +2521,7 @@ template <typename Char = char> class dynamic_formatter {
|
||||
detail::specs_checker<null_handler> checker(
|
||||
null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
|
||||
checker.on_align(specs_.align);
|
||||
switch (specs_.sign) {
|
||||
case sign::none:
|
||||
break;
|
||||
case sign::plus:
|
||||
checker.on_plus();
|
||||
break;
|
||||
case sign::minus:
|
||||
checker.on_minus();
|
||||
break;
|
||||
case sign::space:
|
||||
checker.on_space();
|
||||
break;
|
||||
}
|
||||
if (specs_.sign != sign::none) checker.on_sign(specs_.sign);
|
||||
if (specs_.alt) checker.on_hash();
|
||||
if (specs_.precision >= 0) checker.end_precision();
|
||||
using af = detail::arg_formatter<typename FormatContext::iterator,
|
||||
|
@ -2048,10 +2048,11 @@ TEST(format_test, constexpr_parse_arg_id) {
|
||||
}
|
||||
|
||||
struct test_format_specs_handler {
|
||||
enum result { none, plus, minus, space, hash, zero, loc, error };
|
||||
enum result { none, hash, zero, loc, error };
|
||||
result res = none;
|
||||
|
||||
fmt::align_t alignment = fmt::align::none;
|
||||
fmt::sign_t sign = fmt::sign::none;
|
||||
char fill = 0;
|
||||
int width = 0;
|
||||
fmt::detail::arg_ref<char> width_ref;
|
||||
@ -2063,21 +2064,11 @@ struct test_format_specs_handler {
|
||||
// to a constant" with compiler-generated copy ctor.
|
||||
FMT_CONSTEXPR test_format_specs_handler() {}
|
||||
FMT_CONSTEXPR test_format_specs_handler(
|
||||
const test_format_specs_handler& other)
|
||||
: res(other.res),
|
||||
alignment(other.alignment),
|
||||
fill(other.fill),
|
||||
width(other.width),
|
||||
width_ref(other.width_ref),
|
||||
precision(other.precision),
|
||||
precision_ref(other.precision_ref),
|
||||
type(other.type) {}
|
||||
const test_format_specs_handler& other) = default;
|
||||
|
||||
FMT_CONSTEXPR void on_align(fmt::align_t a) { alignment = a; }
|
||||
FMT_CONSTEXPR void on_fill(fmt::string_view f) { fill = f[0]; }
|
||||
FMT_CONSTEXPR void on_plus() { res = plus; }
|
||||
FMT_CONSTEXPR void on_minus() { res = minus; }
|
||||
FMT_CONSTEXPR void on_space() { res = space; }
|
||||
FMT_CONSTEXPR void on_sign(fmt::sign_t s) { sign = s; }
|
||||
FMT_CONSTEXPR void on_hash() { res = hash; }
|
||||
FMT_CONSTEXPR void on_zero() { res = zero; }
|
||||
FMT_CONSTEXPR void on_localized() { res = loc; }
|
||||
@ -2108,9 +2099,9 @@ TEST(format_test, constexpr_parse_format_specs) {
|
||||
using handler = test_format_specs_handler;
|
||||
static_assert(parse_test_specs("<").alignment == fmt::align::left, "");
|
||||
static_assert(parse_test_specs("*^").fill == '*', "");
|
||||
static_assert(parse_test_specs("+").res == handler::plus, "");
|
||||
static_assert(parse_test_specs("-").res == handler::minus, "");
|
||||
static_assert(parse_test_specs(" ").res == handler::space, "");
|
||||
static_assert(parse_test_specs("+").sign == fmt::sign::plus, "");
|
||||
static_assert(parse_test_specs("-").sign == fmt::sign::minus, "");
|
||||
static_assert(parse_test_specs(" ").sign == fmt::sign::space, "");
|
||||
static_assert(parse_test_specs("#").res == handler::hash, "");
|
||||
static_assert(parse_test_specs("0").res == handler::zero, "");
|
||||
static_assert(parse_test_specs("L").res == handler::loc, "");
|
||||
@ -2220,9 +2211,9 @@ TEST(format_test, constexpr_specs_checker) {
|
||||
using handler = test_format_specs_handler;
|
||||
static_assert(check_specs("<").alignment == fmt::align::left, "");
|
||||
static_assert(check_specs("*^").fill == '*', "");
|
||||
static_assert(check_specs("+").res == handler::plus, "");
|
||||
static_assert(check_specs("-").res == handler::minus, "");
|
||||
static_assert(check_specs(" ").res == handler::space, "");
|
||||
static_assert(check_specs("+").sign == fmt::sign::plus, "");
|
||||
static_assert(check_specs("-").sign == fmt::sign::minus, "");
|
||||
static_assert(check_specs(" ").sign == fmt::sign::space, "");
|
||||
static_assert(check_specs("#").res == handler::hash, "");
|
||||
static_assert(check_specs("0").res == handler::zero, "");
|
||||
static_assert(check_specs("42").width == 42, "");
|
||||
|
Loading…
x
Reference in New Issue
Block a user