2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-19 04:22:13 +00:00

Add special-case logic for detail::range_utf_format() to recognize that

utf8_view is UTF-8-encoded in non-concpets mode.
This commit is contained in:
Zach Laine
2024-02-10 23:25:51 -06:00
parent 150e09e309
commit cdb86d8c23
2 changed files with 41 additions and 28 deletions

View File

@@ -19,39 +19,51 @@ namespace boost::parser {
template<typename T>
constexpr text::format range_utf_format()
{
using value_t = typename decltype(range_value_type<T>)::type;
if constexpr (std::is_same_v<value_t, char>) {
return no_format;
#if defined(__cpp_char8_t)
} else if constexpr (std::is_same_v<value_t, char8_t>) {
#if !BOOST_PARSER_USE_CONCEPTS
// Special case: the metafunctions above will not detect char8_t
// in C++17 mode, since it does not exit yet! So, we need to
// detect utf8_view in particular, and know that its use implies
// format::utf8.
if constexpr (is_utf8_view<T>{}) {
return format::utf8;
#endif
} else if constexpr (
std::is_same_v<value_t, char16_t>
#ifdef _MSC_VER
|| std::is_same_v<T, wchar_t>
#endif
) {
return format::utf16;
} else if constexpr (
std::is_same_v<value_t, char32_t>
#ifndef _MSC_VER
|| std::is_same_v<T, wchar_t>
#endif
) {
return format::utf32;
} else {
static_assert(
sizeof(T) && false,
"Looks like you're trying to pass a range to replace or "
"transform_replace that has a non-character type for its "
"value type. This is not supported.");
#endif
using value_t = typename decltype(range_value_type<T>)::type;
if constexpr (std::is_same_v<value_t, char>) {
return no_format;
#if defined(__cpp_char8_t)
} else if constexpr (std::is_same_v<value_t, char8_t>) {
return format::utf8;
#endif
} else if constexpr (
std::is_same_v<value_t, char16_t>
#ifdef _MSC_VER
|| std::is_same_v<T, wchar_t>
#endif
) {
return format::utf16;
} else if constexpr (
std::is_same_v<value_t, char32_t>
#ifndef _MSC_VER
|| std::is_same_v<T, wchar_t>
#endif
) {
return format::utf32;
} else {
static_assert(
sizeof(T) && false,
"Looks like you're trying to pass a range to replace "
"or transform_replace that has a non-character type "
"for its value type. This is not supported.");
}
#if !BOOST_PARSER_USE_CONCEPTS
}
#endif
}
template<typename T>
constexpr text::format
range_utf_format_v = detail::range_utf_format<T>();
range_utf_format_v = detail::range_utf_format<remove_cv_ref_t<T>>();
template<typename V1, typename V2>
using concat_reference_t =

View File

@@ -283,7 +283,8 @@ TEST(replace, replace_unicode)
{
char const str_[] = "aaXYZbaabaXYZ";
auto str = str_ | bp::as_utf8;
auto r = str | bp::replace(bp::lit("XYZ"), "foo", bp::trace::off);
auto r = str | bp::replace(
bp::lit("XYZ"), "foo" | bp::as_utf8, bp::trace::off);
int count = 0;
std::string_view const strs[] = {"aa", "foo", "baaba", "foo"};
for (auto subrange : r) {
@@ -322,7 +323,7 @@ TEST(replace, replace_unicode)
{
char const str_[] = "XYZaaXYZbaabaXYZXYZ";
auto str = str_ | bp::as_utf8;
auto r = str | bp::replace(bp::lit("XYZ"), "foo");
auto r = str | bp::replace(bp::lit("XYZ"), "foo" | bp::as_utf8);
int count = 0;
std::string_view const strs[] = {
"foo", "aa", "foo", "baaba", "foo", "foo"};