|
|
|
|
@@ -17,8 +17,6 @@
|
|
|
|
|
# include <stdio.h> // FILE
|
|
|
|
|
# include <string.h> // memcmp
|
|
|
|
|
|
|
|
|
|
// <cstddef> is also included transitively from <type_traits>.
|
|
|
|
|
# include <cstddef> // std::byte
|
|
|
|
|
# include <type_traits> // std::enable_if
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
@@ -309,6 +307,7 @@ using make_unsigned_t = typename std::make_unsigned<T>::type;
|
|
|
|
|
template <typename T>
|
|
|
|
|
using underlying_t = typename std::underlying_type<T>::type;
|
|
|
|
|
template <typename T> using decay_t = typename std::decay<T>::type;
|
|
|
|
|
using nullptr_t = decltype(nullptr);
|
|
|
|
|
|
|
|
|
|
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
|
|
|
|
|
// A workaround for gcc 4.9 to make void_t work in a SFINAE context.
|
|
|
|
|
@@ -506,7 +505,7 @@ template <typename Char> class basic_string_view {
|
|
|
|
|
constexpr basic_string_view(const Char* s, size_t count) noexcept
|
|
|
|
|
: data_(s), size_(count) {}
|
|
|
|
|
|
|
|
|
|
constexpr basic_string_view(std::nullptr_t) = delete;
|
|
|
|
|
constexpr basic_string_view(nullptr_t) = delete;
|
|
|
|
|
|
|
|
|
|
/// Constructs a string reference object from a C string.
|
|
|
|
|
#if FMT_GCC_VERSION
|
|
|
|
|
@@ -643,15 +642,6 @@ struct formatter {
|
|
|
|
|
formatter() = delete;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// This is defined in base.h instead of format.h to avoid injecting in std.
|
|
|
|
|
// It is a template to avoid undesirable implicit conversions to std::byte.
|
|
|
|
|
#ifdef __cpp_lib_byte
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(std::is_same<T, std::byte>::value)>
|
|
|
|
|
inline auto format_as(T b) -> unsigned char {
|
|
|
|
|
return static_cast<unsigned char>(b);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// Reports a format error at compile time or, via a `format_error` exception,
|
|
|
|
|
/// at runtime.
|
|
|
|
|
// This function is intentionally not constexpr to give a compile-time error.
|
|
|
|
|
@@ -1071,14 +1061,24 @@ using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
|
|
|
|
|
template <typename T>
|
|
|
|
|
using format_as_result =
|
|
|
|
|
remove_cvref_t<decltype(format_as(std::declval<const T&>()))>;
|
|
|
|
|
template <typename T>
|
|
|
|
|
using format_as_member_result =
|
|
|
|
|
remove_cvref_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>;
|
|
|
|
|
|
|
|
|
|
template <typename T, typename Enable = std::true_type>
|
|
|
|
|
struct use_format_as : std::false_type {};
|
|
|
|
|
// format_as member is only used to avoid injection into the std namespace.
|
|
|
|
|
template <typename T, typename Enable = std::true_type>
|
|
|
|
|
struct use_format_as_member : std::false_type {};
|
|
|
|
|
|
|
|
|
|
// Only map owning types because mapping views can be unsafe.
|
|
|
|
|
template <typename T>
|
|
|
|
|
struct use_format_as<
|
|
|
|
|
T, bool_constant<std::is_integral<format_as_result<T>>::value>>
|
|
|
|
|
T, bool_constant<std::is_arithmetic<format_as_result<T>>::value>>
|
|
|
|
|
: std::true_type {};
|
|
|
|
|
template <typename T>
|
|
|
|
|
struct use_format_as_member<
|
|
|
|
|
T, bool_constant<std::is_arithmetic<format_as_member_result<T>>::value>>
|
|
|
|
|
: std::true_type {};
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U = remove_const_t<T>>
|
|
|
|
|
@@ -1086,7 +1086,7 @@ using use_formatter =
|
|
|
|
|
bool_constant<(std::is_class<T>::value || std::is_enum<T>::value ||
|
|
|
|
|
std::is_union<T>::value || std::is_array<T>::value) &&
|
|
|
|
|
!has_to_string_view<T>::value && !is_named_arg<T>::value &&
|
|
|
|
|
!use_format_as<T>::value>;
|
|
|
|
|
!use_format_as<T>::value && !use_format_as_member<T>::value>;
|
|
|
|
|
|
|
|
|
|
template <typename Char, typename T, typename U = remove_const_t<T>>
|
|
|
|
|
auto has_formatter_impl(T* p, buffered_context<Char>* ctx = nullptr)
|
|
|
|
|
@@ -1140,13 +1140,15 @@ template <typename Char> struct type_mapper {
|
|
|
|
|
static auto map(const void*) -> const void*;
|
|
|
|
|
static auto map(volatile void*) -> const void*;
|
|
|
|
|
static auto map(const volatile void*) -> const void*;
|
|
|
|
|
static auto map(std::nullptr_t) -> const void*;
|
|
|
|
|
static auto map(nullptr_t) -> const void*;
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
|
|
|
|
|
std::is_member_pointer<T>::value)>
|
|
|
|
|
static auto map(const T&) -> void;
|
|
|
|
|
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
|
|
|
|
|
static auto map(const T& x) -> decltype(map(format_as(x)));
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>
|
|
|
|
|
static auto map(const T& x) -> decltype(map(formatter<T>::format_as(x)));
|
|
|
|
|
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(use_formatter<T>::value)>
|
|
|
|
|
static auto map(T&) -> conditional_t<has_formatter<T, Char>(), T&, void>;
|
|
|
|
|
@@ -2130,7 +2132,7 @@ template <typename Context> class value {
|
|
|
|
|
: pointer(const_cast<const void*>(x)) {}
|
|
|
|
|
FMT_INLINE value(const volatile void* x FMT_BUILTIN)
|
|
|
|
|
: pointer(const_cast<const void*>(x)) {}
|
|
|
|
|
FMT_INLINE value(std::nullptr_t) : pointer(nullptr) {}
|
|
|
|
|
FMT_INLINE value(nullptr_t) : pointer(nullptr) {}
|
|
|
|
|
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
|
|
|
|
|
std::is_member_pointer<T>::value)>
|
|
|
|
|
@@ -2144,6 +2146,8 @@ template <typename Context> class value {
|
|
|
|
|
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
|
|
|
|
|
value(const T& x) : value(format_as(x)) {}
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>
|
|
|
|
|
value(const T& x) : value(formatter<T>::format_as(x)) {}
|
|
|
|
|
|
|
|
|
|
template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
|
|
|
|
|
value(const T& named_arg) : value(named_arg.value) {}
|
|
|
|
|
@@ -2376,9 +2380,9 @@ template <typename T> class basic_appender {
|
|
|
|
|
public:
|
|
|
|
|
using iterator_category = int;
|
|
|
|
|
using value_type = T;
|
|
|
|
|
using difference_type = ptrdiff_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) {}
|
|
|
|
|
|