diff --git a/include/fmt/std.h b/include/fmt/std.h index a71a59db..b0e78e10 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -8,6 +8,7 @@ #ifndef FMT_STD_H_ #define FMT_STD_H_ +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include "format.h" #include "ostream.h" @@ -389,6 +391,50 @@ struct formatter< #endif } }; + +namespace detail { + +template +struct has_flip : std::false_type {}; + +template +struct has_flip().flip())>> + : std::true_type {}; + +template struct is_bit_reference_like { + static constexpr const bool value = + std::is_convertible::value && + std::is_nothrow_assignable::value && has_flip::value; +}; + +#ifdef _LIBCPP_VERSION + +// Workaround for libc++ incompatibility with C++ standard. +// According to the Standard, `bitset::operator[] const` returns bool. +template +struct is_bit_reference_like> { + static constexpr const bool value = true; +}; + +#endif + +} // namespace detail + +// We can't use std::vector::reference and +// std::bitset::reference because the compiler can't deduce Allocator and N +// in partial specialization. +FMT_EXPORT +template +struct formatter::value>> + : formatter { + template + FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter::format(v, ctx); + } +}; + FMT_END_NAMESPACE #endif // FMT_STD_H_