std::filesystem::path is not format as a range

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
This commit is contained in:
Vladislav Shchapov 2023-02-26 11:23:50 +05:00
parent 5b8302079d
commit 140edee780
3 changed files with 25 additions and 4 deletions

View File

@ -59,6 +59,17 @@ template <typename T> class is_std_string_like {
!std::is_void<decltype(check<T>(nullptr))>::value;
};
// Returns true if T has a std::filesystem::path-like interface.
template <typename T> class is_std_filesystem_path_like {
template <typename U>
static auto check(U* p) -> decltype((void)U::preferred_separator, int());
template <typename> static void check(...);
public:
static constexpr const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value;
};
template <typename Char>
struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type {};
@ -383,7 +394,8 @@ template <typename T, typename Char> struct is_range {
static constexpr const bool value =
detail::is_range_<T>::value && !detail::is_std_string_like<T>::value &&
!std::is_convertible<T, std::basic_string<Char>>::value &&
!std::is_convertible<T, detail::std_string_view<Char>>::value;
!std::is_convertible<T, detail::std_string_view<Char>>::value &&
!detail::is_std_filesystem_path_like<T>::value;
};
namespace detail {

View File

@ -179,15 +179,18 @@ TEST(ranges_test, format_to) {
EXPECT_STREQ(buf, "[1, 2, 3]");
}
struct path_like {
template <typename Char> struct path_like {
const path_like* begin() const;
const path_like* end() const;
operator std::string() const;
operator std::basic_string<Char>() const;
static constexpr const Char preferred_separator = Char();
};
TEST(ranges_test, path_like) {
EXPECT_FALSE((fmt::is_range<path_like, char>::value));
EXPECT_FALSE((fmt::is_range<path_like<char>, char>::value));
EXPECT_FALSE((fmt::is_range<path_like<wchar_t>, char>::value));
}
// A range that provides non-const only begin()/end() to test fmt::join

View File

@ -46,6 +46,12 @@ TEST(ranges_std_test, format_vector_path) {
#endif
}
TEST(ranges_std_test, path) {
#ifdef __cpp_lib_filesystem
EXPECT_FALSE((fmt::is_range<std::filesystem::path, char>::value));
#endif
}
TEST(std_test, thread_id) {
EXPECT_FALSE(fmt::format("{}", std::this_thread::get_id()).empty());
}