Fix is_formattable for tuple-like types.
This commit is contained in:
parent
eaa8efb950
commit
0203853868
@ -202,6 +202,24 @@ template <size_t N>
|
||||
using make_index_sequence = make_integer_sequence<size_t, N>;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
using tuple_index_sequence = make_index_sequence<std::tuple_size_v<T>>;
|
||||
|
||||
template <typename T, bool = is_tuple_like_<T>::value>
|
||||
struct is_tuple_formattable_ {
|
||||
static constexpr const bool value = false;
|
||||
};
|
||||
template <typename T> struct is_tuple_formattable_<T, true> {
|
||||
template <std::size_t... I>
|
||||
static std::integral_constant<
|
||||
bool, (fmt::is_formattable<std::tuple_element_t<I, T>>::value && ...)>
|
||||
check(index_sequence<I...>);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
decltype(check(tuple_index_sequence<T>{}))::value;
|
||||
};
|
||||
|
||||
template <class Tuple, class F, size_t... Is>
|
||||
void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) noexcept {
|
||||
using std::get;
|
||||
@ -283,8 +301,14 @@ template <typename T> struct is_tuple_like {
|
||||
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||
};
|
||||
|
||||
template <typename T> struct is_tuple_formattable {
|
||||
static constexpr const bool value = detail::is_tuple_formattable_<T>::value;
|
||||
};
|
||||
|
||||
template <typename TupleT, typename Char>
|
||||
struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
|
||||
struct formatter<TupleT, Char,
|
||||
enable_if_t<fmt::is_tuple_like<TupleT>::value &&
|
||||
fmt::is_tuple_formattable<TupleT>::value>> {
|
||||
private:
|
||||
// C++11 generic lambda for format().
|
||||
template <typename FormatContext> struct format_each {
|
||||
|
||||
@ -90,6 +90,18 @@ TEST(ranges_test, format_tuple) {
|
||||
std::tuple<int, float, std::string, char>(42, 1.5f, "this is tuple", 'i');
|
||||
EXPECT_EQ(fmt::format("{}", t), "(42, 1.5, \"this is tuple\", 'i')");
|
||||
EXPECT_EQ(fmt::format("{}", std::tuple<>()), "()");
|
||||
|
||||
enum class noformatenum{b};
|
||||
struct noformatstruct{};
|
||||
EXPECT_TRUE((fmt::is_formattable<std::tuple<>>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<noformatenum>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<noformatstruct>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<std::tuple<noformatenum>>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<std::tuple<noformatstruct>>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<std::tuple<noformatstruct,int>>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<std::tuple<int,noformatenum>>::value));
|
||||
EXPECT_FALSE((fmt::is_formattable<std::tuple<noformatstruct,noformatenum>>::value));
|
||||
EXPECT_TRUE((fmt::is_formattable<std::tuple<int,float>>::value));
|
||||
}
|
||||
|
||||
#ifdef FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
|
||||
|
||||
@ -315,10 +315,12 @@ TEST(xchar_test, ostream) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FMT_XCHAR_TEST_ENABLE_FORMAT_MAP
|
||||
TEST(xchar_test, format_map) {
|
||||
auto m = std::map<std::wstring, int>{{L"one", 1}, {L"t\"wo", 2}};
|
||||
EXPECT_EQ(fmt::format(L"{}", m), L"{\"one\": 1, \"t\\\"wo\": 2}");
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(xchar_test, escape_string) {
|
||||
using vec = std::vector<std::wstring>;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user