FMT_ENABLE_IF(
std::is_pointer<T>::value || std::is_member_pointer<T>::value ||
std::is_function<typename std::remove_pointer<T>::type>::value ||
- (std::is_convertible<const T&, const void*>::value &&
- !std::is_convertible<const T&, const char_type*>::value &&
- !has_formatter<T, Context>::value))>
+ (std::is_array<T>::value &&
+ !std::is_convertible<T, const char_type*>::value))>
FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer {
return {};
}
\endrst
*/
// DEPRECATED!
-FMT_EXPORT
template <typename Visitor, typename Context>
FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(
Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
# if FMT_CPLUSPLUS >= 202002L
# if FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
-# elif FMT_MSC_VERSION >= 1929 // VS2019 v16.10 and later
+// 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
# endif
private:
uint64_t lo_, hi_;
- friend uint128_fallback umul128(uint64_t x, uint64_t y) noexcept;
-
public:
constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
FMT_API bool write_console(std::FILE* f, string_view text);
FMT_API void print(std::FILE*, string_view);
} // namespace detail
+
FMT_BEGIN_EXPORT
// Suppress a misleading warning in older versions of clang.
}
template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
-inline auto format_uint(It out, UInt value, int num_digits, bool upper = false)
- -> It {
+FMT_CONSTEXPR inline auto format_uint(It out, UInt value, int num_digits,
+ bool upper = false) -> It {
if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
format_uint<BASE_BITS>(ptr, value, num_digits, upper);
return out;
++p;
if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {
if (policy == to_utf8_error_policy::abort) return false;
- buf.append(string_view("�"));
+ buf.append(string_view("\xEF\xBF\xBD"));
--p;
} else {
c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;
auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);
return {static_cast<uint64_t>(p >> 64), static_cast<uint64_t>(p)};
#elif defined(_MSC_VER) && defined(_M_X64)
- auto result = uint128_fallback();
- result.lo_ = _umul128(x, y, &result.hi_);
- return result;
+ auto hi = uint64_t();
+ auto lo = _umul128(x, y, &hi);
+ return {hi, lo};
#else
const uint64_t mask = static_cast<uint64_t>(max_value<uint32_t>());
std::string answer = fmt::to_string(42);
\endrst
*/
-template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
+template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
+ !detail::has_format_as<T>::value)>
inline auto to_string(const T& value) -> std::string {
auto buffer = memory_buffer();
detail::write<char>(appender(buffer), value);
return std::basic_string<Char>(buf.data(), size);
}
+template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
+ detail::has_format_as<T>::value)>
+inline auto to_string(const T& value) -> std::string {
+ return to_string(format_as(value));
+}
+
+FMT_END_EXPORT
+
namespace detail {
template <typename Char>
detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
}
+FMT_BEGIN_EXPORT
+
#ifndef FMT_HEADER_ONLY
extern template FMT_API void vformat_to(buffer<char>&, string_view,
typename vformat_args<>::type,
#ifndef FMT_STD_H_
#define FMT_STD_H_
+#include <atomic>
#include <bitset>
#include <cstdlib>
#include <exception>
}
};
-FMT_END_NAMESPACE
+FMT_EXPORT
+template <typename T, typename Char>
+struct formatter<std::atomic<T>, Char,
+ enable_if_t<is_formattable<T, Char>::value>>
+ : formatter<T, Char> {
+ template <typename FormatContext>
+ auto format(const std::atomic<T>& v, FormatContext& ctx) const
+ -> decltype(ctx.out()) {
+ return formatter<T, Char>::format(v.load(), ctx);
+ }
+};
+
+#ifdef __cpp_lib_atomic_flag_test
+FMT_EXPORT
+template <typename Char>
+struct formatter<std::atomic_flag, Char>
+ : formatter<bool, Char> {
+ template <typename FormatContext>
+ auto format(const std::atomic_flag& v, FormatContext& ctx) const
+ -> decltype(ctx.out()) {
+ return formatter<bool, Char>::format(v.test(), ctx);
+ }
+};
+#endif // __cpp_lib_atomic_flag_test
+FMT_END_NAMESPACE
#endif // FMT_STD_H_