From 4d14fba7fd813ef7005eb2b80be440da1bad49c6 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Sun, 28 Jan 2024 14:55:37 -0600 Subject: [PATCH] Change concept can_utf_view to use the form MSVC uses in its std lib, and turn off code relying on alias CTAD on MSVC. Add test cases for {w,}string{,_view} | as_utfN in C++20 builds. --- include/boost/parser/detail/text/config.hpp | 3 +- .../parser/detail/text/transcode_view.hpp | 2 +- test/parser.cpp | 166 ++++++++++++++++++ 3 files changed, 169 insertions(+), 2 deletions(-) diff --git a/include/boost/parser/detail/text/config.hpp b/include/boost/parser/detail/text/config.hpp index be765875..8d6be582 100644 --- a/include/boost/parser/detail/text/config.hpp +++ b/include/boost/parser/detail/text/config.hpp @@ -20,7 +20,8 @@ // GCC 12 claims to support 201907L <= __cpp_deduction_guides, but does not. #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS && defined(__cpp_deduction_guides) && \ - 201907L <= __cpp_deduction_guides && (!defined(__GNUC__) || 13 <= __GNUC__) + 201907L <= __cpp_deduction_guides && (!defined(__GNUC__) || 13 <= __GNUC__) && \ + !defined(_MSC_VER) #define BOOST_PARSER_DETAIL_TEXT_USE_ALIAS_CTAD 1 #else #define BOOST_PARSER_DETAIL_TEXT_USE_ALIAS_CTAD 0 diff --git a/include/boost/parser/detail/text/transcode_view.hpp b/include/boost/parser/detail/text/transcode_view.hpp index b304df58..04a20c4f 100644 --- a/include/boost/parser/detail/text/transcode_view.hpp +++ b/include/boost/parser/detail/text/transcode_view.hpp @@ -701,7 +701,7 @@ namespace boost::parser::detail { namespace text { namespace detail { #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS template class View> - concept can_utf_view = requires { View(std::declval()); }; + concept can_utf_view = requires(R && r) { View((R &&)r); }; #else template using can_utf_view_expr = decltype(View(std::declval())); diff --git a/test/parser.cpp b/test/parser.cpp index 9d6d652b..e2907e02 100644 --- a/test/parser.cpp +++ b/test/parser.cpp @@ -21,6 +21,172 @@ using namespace boost::parser; +#if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS && defined(_MSC_VER) +#include + +TEST(parser, msvc_string_view) +{ + std::string_view sv = "text"; + std::wstring_view wsv = L"text"; + + { + auto r = detail::text::as_utf8(sv); + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = detail::text::as_utf8(wsv); + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + { + auto r = sv | detail::text::as_utf8; + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = wsv | detail::text::as_utf8; + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + + { + auto r = detail::text::as_utf16(sv); + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = detail::text::as_utf16(wsv); + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + { + auto r = sv | detail::text::as_utf16; + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = wsv | detail::text::as_utf16; + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + + { + auto r = detail::text::as_utf32(sv); + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = detail::text::as_utf32(wsv); + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + { + auto r = sv | detail::text::as_utf32; + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = wsv | detail::text::as_utf32; + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } +} + +TEST(parser, msvc_string) +{ + std::string sv = "text"; + std::wstring wsv = L"text"; + + { + auto r = detail::text::as_utf8(sv); + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = detail::text::as_utf8(wsv); + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + { + auto r = sv | detail::text::as_utf8; + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = wsv | detail::text::as_utf8; + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + + { + auto r = detail::text::as_utf16(sv); + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = detail::text::as_utf16(wsv); + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + { + auto r = sv | detail::text::as_utf16; + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = wsv | detail::text::as_utf16; + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + + { + auto r = detail::text::as_utf32(sv); + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = detail::text::as_utf32(wsv); + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } + { + auto r = sv | detail::text::as_utf32; + std::string str = " "; + std::ranges::copy(r, str.begin()); + EXPECT_EQ(str, sv); + } + { + auto r = wsv | detail::text::as_utf32; + std::wstring wstr = L" "; + std::ranges::copy(r, wstr.begin()); + EXPECT_EQ(wstr, wsv); + } +} +#endif + #if TEST_BOOST_OPTIONAL template constexpr bool boost::parser::enable_optional> = true;