mirror of
https://github.com/fmtlib/fmt.git
synced 2026-05-05 03:54:10 +02:00
Added formatter for bit_reference-like types (#3570)
* Add test for std::vector<bool>::reference Co-authored-by: Felix <felix-antoine.constantin@polymtl.ca> Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru> * Add test for std::bitset<N>::reference Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru> * Add test for const std::bitset<N>::reference and const std::vector<bool>::reference Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru> * Add bit_reference-like formatter Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru> * Use std::addressof Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru> --------- Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru> Co-authored-by: Felix <felix-antoine.constantin@polymtl.ca>
This commit is contained in:
committed by
GitHub
parent
96d1fa22d4
commit
aeb6ad4dd0
@@ -8,6 +8,7 @@
|
||||
#ifndef FMT_STD_H_
|
||||
#define FMT_STD_H_
|
||||
|
||||
#include <bitset>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
@@ -15,6 +16,7 @@
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "format.h"
|
||||
#include "ostream.h"
|
||||
@@ -389,6 +391,50 @@ struct formatter<
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_flip : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T> struct is_bit_reference_like {
|
||||
static constexpr const bool value =
|
||||
std::is_convertible<T, bool>::value &&
|
||||
std::is_nothrow_assignable<T, bool>::value && has_flip<T>::value;
|
||||
};
|
||||
|
||||
#ifdef _LIBCPP_VERSION
|
||||
|
||||
// Workaround for libc++ incompatibility with C++ standard.
|
||||
// According to the Standard, `bitset::operator[] const` returns bool.
|
||||
template <typename C>
|
||||
struct is_bit_reference_like<std::__bit_const_reference<C>> {
|
||||
static constexpr const bool value = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// We can't use std::vector<bool, Allocator>::reference and
|
||||
// std::bitset<N>::reference because the compiler can't deduce Allocator and N
|
||||
// in partial specialization.
|
||||
FMT_EXPORT
|
||||
template <typename BitRef, typename Char>
|
||||
struct formatter<BitRef, Char,
|
||||
enable_if_t<detail::is_bit_reference_like<BitRef>::value>>
|
||||
: formatter<bool, Char> {
|
||||
template <typename FormatContext>
|
||||
FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return formatter<bool, Char>::format(v, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_STD_H_
|
||||
|
||||
Reference in New Issue
Block a user