From 2fc3bdafe8842fe34d66ae15f1e0b383dbfc3f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rimas=20Misevi=C4=8Dius?= Date: Sat, 26 Oct 2024 22:55:31 +0300 Subject: [PATCH] Add support for strings convertible to std::basic_string_view --- include/upa/str_arg.h | 139 +++++++++++++++++++++++++++++---------- include/upa/url_for_qt.h | 11 +++- 2 files changed, 112 insertions(+), 38 deletions(-) diff --git a/include/upa/str_arg.h b/include/upa/str_arg.h index 0868461..5c19a3e 100644 --- a/include/upa/str_arg.h +++ b/include/upa/str_arg.h @@ -122,56 +122,123 @@ class str_arg { template using remove_cvptr_t = std::remove_cv_t>; +template +using remove_cvref_t = std::remove_cv_t>; + namespace detail { - // See: https://stackoverflow.com/a/9154394 - - // test class T has data() member - template - auto test_data(int) -> decltype(std::declval().data()); - template - auto test_data(long) -> void; - - // test class T has size() member - template - auto test_size(int) -> decltype(std::declval().size()); - template - auto test_size(long) -> void; - - // T::data() return type (void - if no such member) - template - using data_member_t = decltype(detail::test_data(0)); - - // T::size() return type (void - if no such member) - template - using size_member_t = decltype(detail::test_size(0)); + +// See: https://stackoverflow.com/a/9154394 + +// test class T has data() member +template +auto test_data(int) -> decltype(std::declval().data()); +template +auto test_data(long) -> void; + +// test class T has size() member +template +auto test_size(int) -> decltype(std::declval().size()); +template +auto test_size(long) -> void; + +// T::data() return type (void - if no such member) +template +using data_member_t = decltype(detail::test_data(0)); + +// T::size() return type (void - if no such member) +template +using size_member_t = decltype(detail::test_size(0)); + +// Check that StrT has data() and size() members of supported types + +template +constexpr bool has_data_and_size_v = + std::is_pointer_v> && + is_char_type_v>> && + is_size_type_v>; + +// Check StrT is convertible to std::basic_string_view + +template +constexpr bool convertible_to_string_view_v = + std::is_convertible_v> && + !has_data_and_size_v && + !std::is_same_v; + +// Common class for converting input to str_arg + +template +struct str_arg_char_common { + using type = CharT; + static str_arg to_str_arg(ArgT str) { + return { str.data(), str.size() }; + } +}; + +// Default str_arg_char implementation + +template +struct str_arg_char_default {}; + +// StrT has data() and size() members +template +struct str_arg_char_default>> + : str_arg_char_common< + remove_cvptr_t>, + remove_cvref_t const&> {}; + +// StrT is convertible to std::basic_string_view +template +struct str_arg_char_default>> + : str_arg_char_common> {}; + +#ifdef __cpp_char8_t +template +struct str_arg_char_default>> + : str_arg_char_common> {}; +#endif + +template +struct str_arg_char_default>> + : str_arg_char_common> {}; + +template +struct str_arg_char_default>> + : str_arg_char_common> {}; + +template +struct str_arg_char_default>> + : str_arg_char_common> {}; + } // namespace detail // Requirements for string arguments template -struct str_arg_char {}; +struct str_arg_char : detail::str_arg_char_default {}; // Null terminated string template -struct str_arg_char : std::remove_cv { - - template - static str_arg to_str_arg(const T* s) { +struct str_arg_char>>> { + using type = remove_cvref_t; + static str_arg to_str_arg(const type* s) { return s; } }; -// String that has data() and size() members -template -struct str_arg_char : std::enable_if< - std::is_pointer_v> && - is_size_type_v>, - remove_cvptr_t>> { - - template - static str_arg to_str_arg(const STR& str) { - return { str.data(), str.size() }; +// str_arg input +template +struct str_arg_char> { + using type = CharT; + static str_arg to_str_arg(str_arg s) { + return s; } }; diff --git a/include/upa/url_for_qt.h b/include/upa/url_for_qt.h index f461252..4f5afba 100644 --- a/include/upa/url_for_qt.h +++ b/include/upa/url_for_qt.h @@ -10,12 +10,17 @@ #define UPA_URL_FOR_QT_H #include "url.h" // IWYU pragma: export -#include #if __has_include() # include #else # include #endif + +// As of version 6.7, Qt string classes are convertible to +// std::basic_string_view, and such strings are supported in the +// str_arg.h file. +#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0) +#include #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) # include #endif @@ -32,7 +37,7 @@ struct str_arg_char_for_qt { using type = CharT; static str_arg to_str_arg(const StrT& str) { - return { reinterpret_cast(str.data()), str.length() }; + return { reinterpret_cast(str.data()), str.size() }; } }; @@ -54,4 +59,6 @@ struct str_arg_char : } // namespace upa +#endif // QT_VERSION < QT_VERSION_CHECK(6, 7, 0) + #endif // UPA_URL_FOR_QT_H