aboutsummaryrefslogtreecommitdiff
path: root/include/fmt/core.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/fmt/core.h')
-rw-r--r--include/fmt/core.h68
1 files changed, 49 insertions, 19 deletions
diff --git a/include/fmt/core.h b/include/fmt/core.h
index 18ebada2..94f3f22b 100644
--- a/include/fmt/core.h
+++ b/include/fmt/core.h
@@ -18,7 +18,7 @@
#include <type_traits>
// The fmt library version in the form major * 10000 + minor * 100 + patch.
-#define FMT_VERSION 100101
+#define FMT_VERSION 100200
#if defined(__clang__) && !defined(__ibmxl__)
# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
@@ -105,9 +105,12 @@
# define FMT_CONSTEXPR
#endif
-#if ((FMT_CPLUSPLUS >= 202002L) && \
- (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9)) || \
- (FMT_CPLUSPLUS >= 201709L && FMT_GCC_VERSION >= 1002)
+#if (FMT_CPLUSPLUS >= 202002L || \
+ (FMT_CPLUSPLUS >= 201709L && FMT_GCC_VERSION >= 1002)) && \
+ ((!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 10) && \
+ (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 10000) && \
+ (!FMT_MSC_VERSION || FMT_MSC_VERSION >= 1928)) && \
+ defined(__cpp_lib_is_constant_evaluated)
# define FMT_CONSTEXPR20 constexpr
#else
# define FMT_CONSTEXPR20
@@ -224,8 +227,9 @@
__apple_build_version__ >= 14000029L) && \
FMT_CPLUSPLUS >= 202002L) || \
(defined(__cpp_consteval) && \
- (!FMT_MSC_VERSION || _MSC_FULL_VER >= 193030704))
-// consteval is broken in MSVC before VS2022 and Apple clang before 14.
+ (!FMT_MSC_VERSION || FMT_MSC_VERSION >= 1929))
+// consteval is broken in MSVC before VS2019 version 16.10 and Apple clang
+// before 14.
# define FMT_CONSTEVAL consteval
# define FMT_HAS_CONSTEVAL
# else
@@ -244,6 +248,15 @@
# endif
#endif
+// GCC < 5 requires this-> in decltype
+#ifndef FMT_DECLTYPE_THIS
+# if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
+# define FMT_DECLTYPE_THIS this->
+# else
+# define FMT_DECLTYPE_THIS
+# endif
+#endif
+
// Enable minimal optimizations for more compact code in debug mode.
FMT_GCC_PRAGMA("GCC push_options")
#if !defined(__OPTIMIZE__) && !defined(__NVCOMPILER) && !defined(__LCC__) && \
@@ -458,15 +471,15 @@ template <typename Char> class basic_string_view {
size_ -= n;
}
- FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(
- basic_string_view<Char> sv) const noexcept {
+ FMT_CONSTEXPR_CHAR_TRAITS auto starts_with(
+ basic_string_view<Char> sv) const noexcept -> bool {
return size_ >= sv.size_ &&
std::char_traits<Char>::compare(data_, sv.data_, sv.size_) == 0;
}
- FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(Char c) const noexcept {
+ FMT_CONSTEXPR_CHAR_TRAITS auto starts_with(Char c) const noexcept -> bool {
return size_ >= 1 && std::char_traits<Char>::eq(*data_, c);
}
- FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(const Char* s) const {
+ FMT_CONSTEXPR_CHAR_TRAITS auto starts_with(const Char* s) const -> bool {
return starts_with(basic_string_view<Char>(s));
}
@@ -604,10 +617,10 @@ FMT_TYPE_CONSTANT(const Char*, cstring_type);
FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);
FMT_TYPE_CONSTANT(const void*, pointer_type);
-constexpr bool is_integral_type(type t) {
+constexpr auto is_integral_type(type t) -> bool {
return t > type::none_type && t <= type::last_integer_type;
}
-constexpr bool is_arithmetic_type(type t) {
+constexpr auto is_arithmetic_type(type t) -> bool {
return t > type::none_type && t <= type::last_numeric_type;
}
@@ -631,6 +644,7 @@ enum {
pointer_set = set(type::pointer_type)
};
+// DEPRECATED!
FMT_NORETURN FMT_API void throw_format_error(const char* message);
struct error_handler {
@@ -808,7 +822,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)
- buffer(size_t sz) noexcept : size_(sz), capacity_(sz) {}
+ FMT_CONSTEXPR buffer(size_t sz) noexcept : size_(sz), capacity_(sz) {}
FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) noexcept
: ptr_(p), size_(sz), capacity_(cap) {}
@@ -823,6 +837,7 @@ template <typename T> class buffer {
}
/** Increases the buffer capacity to hold at least *capacity* elements. */
+ // DEPRECATED!
virtual FMT_CONSTEXPR20 void grow(size_t capacity) = 0;
public:
@@ -1309,6 +1324,7 @@ template <typename Context> class value {
parse_ctx.advance_to(f.parse(parse_ctx));
using qualified_type =
conditional_t<has_const_formatter<T, Context>(), const T, T>;
+ // Calling format through a mutable reference is deprecated.
ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx));
}
};
@@ -1322,7 +1338,7 @@ using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
template <typename T> struct format_as_result {
template <typename U,
FMT_ENABLE_IF(std::is_enum<U>::value || std::is_class<U>::value)>
- static auto map(U*) -> decltype(format_as(std::declval<U>()));
+ static auto map(U*) -> remove_cvref_t<decltype(format_as(std::declval<U>()))>;
static auto map(...) -> void;
using type = decltype(map(static_cast<T*>(nullptr)));
@@ -1439,7 +1455,8 @@ template <typename Context> struct arg_mapper {
// Only map owning types because mapping views can be unsafe.
template <typename T, typename U = format_as_t<T>,
FMT_ENABLE_IF(std::is_arithmetic<U>::value)>
- FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> decltype(this->map(U())) {
+ FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
+ -> decltype(FMT_DECLTYPE_THIS map(U())) {
return map(format_as(val));
}
@@ -1463,13 +1480,14 @@ template <typename Context> struct arg_mapper {
!is_string<U>::value && !is_char<U>::value &&
!is_named_arg<U>::value &&
!std::is_arithmetic<format_as_t<U>>::value)>
- FMT_CONSTEXPR FMT_INLINE auto map(T& val) -> decltype(this->do_map(val)) {
+ FMT_CONSTEXPR FMT_INLINE auto map(T& val)
+ -> decltype(FMT_DECLTYPE_THIS do_map(val)) {
return do_map(val);
}
template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
FMT_CONSTEXPR FMT_INLINE auto map(const T& named_arg)
- -> decltype(this->map(named_arg.value)) {
+ -> decltype(FMT_DECLTYPE_THIS map(named_arg.value)) {
return map(named_arg.value);
}
@@ -1604,8 +1622,8 @@ FMT_CONSTEXPR inline auto make_arg(T& val) -> basic_format_arg<Context> {
} // namespace detail
FMT_BEGIN_EXPORT
-// A formatting argument. It is a trivially copyable/constructible type to
-// allow storage in basic_memory_buffer.
+// A formatting argument. Context is a template parameter for the compiled API
+// where output can be unbuffered.
template <typename Context> class basic_format_arg {
private:
detail::value<Context> value_;
@@ -1657,6 +1675,15 @@ template <typename Context> class basic_format_arg {
auto is_arithmetic() const -> bool {
return detail::is_arithmetic_type(type_);
}
+
+ FMT_INLINE auto format_custom(const char_type* parse_begin,
+ typename Context::parse_context_type& parse_ctx,
+ Context& ctx) -> bool {
+ if (type_ != detail::type::custom_type) return false;
+ parse_ctx.advance_to(parse_begin);
+ value_.custom.format(value_.custom.value, parse_ctx, ctx);
+ return true;
+ }
};
/**
@@ -1745,6 +1772,7 @@ template <typename OutputIt, typename Char> class basic_format_context {
}
auto args() const -> const format_args& { return args_; }
+ // DEPRECATED!
FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; }
void on_error(const char* message) { error_handler().on_error(message); }
@@ -2417,6 +2445,8 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
case 'G':
return parse_presentation_type(pres::general_upper, float_set);
case 'c':
+ if (arg_type == type::bool_type)
+ throw_format_error("invalid format specifier");
return parse_presentation_type(pres::chr, integral_set);
case 's':
return parse_presentation_type(pres::string,