File indexing completed on 2025-09-18 08:53:51
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_PARSER_DETAIL_TEXT_TRANSCODE_ALGORITHM_HPP
0008 #define BOOST_PARSER_DETAIL_TEXT_TRANSCODE_ALGORITHM_HPP
0009
0010 #include <boost/parser/detail/text/in_out_result.hpp>
0011 #include <boost/parser/detail/text/transcode_iterator.hpp>
0012 #include <boost/parser/detail/text/unpack.hpp>
0013 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0014 #include <algorithm>
0015 #endif
0016
0017 #include <boost/parser/config.hpp>
0018
0019
0020 namespace boost::parser::detail { namespace text {
0021
0022
0023
0024 template<typename Iter, typename OutIter>
0025 using transcode_result = in_out_result<Iter, OutIter>;
0026
0027 namespace detail {
0028 template<typename OutIter>
0029 constexpr OutIter read_into_utf8_iter(uint32_t cp, OutIter out)
0030 {
0031 if (cp < 0x80) {
0032 *out = static_cast<char>(cp);
0033 ++out;
0034 } else if (cp < 0x800) {
0035 *out = static_cast<char>(0xC0 + (cp >> 6));
0036 ++out;
0037 *out = static_cast<char>(0x80 + (cp & 0x3f));
0038 ++out;
0039 } else if (cp < 0x10000) {
0040 *out = static_cast<char>(0xe0 + (cp >> 12));
0041 ++out;
0042 *out = static_cast<char>(0x80 + ((cp >> 6) & 0x3f));
0043 ++out;
0044 *out = static_cast<char>(0x80 + (cp & 0x3f));
0045 ++out;
0046 } else {
0047 *out = static_cast<char>(0xf0 + (cp >> 18));
0048 ++out;
0049 *out = static_cast<char>(0x80 + ((cp >> 12) & 0x3f));
0050 ++out;
0051 *out = static_cast<char>(0x80 + ((cp >> 6) & 0x3f));
0052 ++out;
0053 *out = static_cast<char>(0x80 + (cp & 0x3f));
0054 ++out;
0055 }
0056 return out;
0057 }
0058
0059 template<typename OutIter>
0060 constexpr OutIter read_into_utf16_iter(uint32_t cp, OutIter out)
0061 {
0062 uint16_t const high_surrogate_base = 0xd7c0;
0063 uint16_t const low_surrogate_base = 0xdc00;
0064
0065 if (cp < 0x10000) {
0066 *out = static_cast<uint16_t>(cp);
0067 ++out;
0068 } else {
0069 *out = static_cast<uint16_t>(cp >> 10) + high_surrogate_base;
0070 ++out;
0071 *out = static_cast<uint16_t>(cp & 0x3ff) + low_surrogate_base;
0072 ++out;
0073 }
0074 return out;
0075 }
0076
0077 template<
0078 bool UseN,
0079 typename InputIter,
0080 typename Sentinel,
0081 typename OutIter>
0082 transcode_result<InputIter, OutIter> transcode_utf_8_to_16(
0083 InputIter first,
0084 Sentinel last,
0085 std::ptrdiff_t n,
0086 OutIter out,
0087 std::input_iterator_tag)
0088 {
0089 for (; first != last && (!UseN || n); --n) {
0090 unsigned char const c = *first;
0091 if (c < 0x80) {
0092 *out = *first;
0093 ++first;
0094 ++out;
0095 } else {
0096 auto const cp = detail::advance(first, last);
0097 out = detail::read_into_utf16_iter(cp, out);
0098 }
0099 }
0100 return {first, out};
0101 }
0102
0103 template<bool UseN, typename Iter, typename OutIter>
0104 transcode_result<Iter, OutIter> transcode_utf_8_to_16(
0105 Iter first,
0106 Iter last,
0107 std::ptrdiff_t n,
0108 OutIter out,
0109 std::random_access_iterator_tag)
0110 {
0111 return transcode_utf_8_to_16<UseN>(
0112 first, last, n, out, std::input_iterator_tag{});
0113 }
0114
0115 template<
0116 bool UseN,
0117 typename InputIter,
0118 typename Sentinel,
0119 typename OutIter>
0120 transcode_result<InputIter, OutIter> transcode_utf_8_to_32(
0121 InputIter first,
0122 Sentinel last,
0123 std::ptrdiff_t n,
0124 OutIter out,
0125 std::input_iterator_tag)
0126 {
0127 for (; first != last && (!UseN || n); --n) {
0128 unsigned char const c = *first;
0129 if (c < 0x80) {
0130 *out = *first;
0131 ++first;
0132 ++out;
0133 } else {
0134 *out = detail::advance(first, last);
0135 ++out;
0136 }
0137 }
0138 return {first, out};
0139 }
0140
0141 template<bool UseN, typename Iter, typename OutIter>
0142 transcode_result<Iter, OutIter> transcode_utf_8_to_32(
0143 Iter first,
0144 Iter last,
0145 std::ptrdiff_t n,
0146 OutIter out,
0147 std::random_access_iterator_tag)
0148 {
0149 return transcode_utf_8_to_32<UseN>(
0150 first, last, n, out, std::input_iterator_tag{});
0151 }
0152
0153 template<format Tag>
0154 struct tag_t
0155 {};
0156
0157 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0158 transcode_result<Iter, OutIter> transcode_to_8(
0159 tag_t<format::utf8>,
0160 Iter first,
0161 Sentinel last,
0162 std::ptrdiff_t n,
0163 OutIter out)
0164 {
0165 for (; first != last && (!UseN || n); ++first, ++out) {
0166 *out = *first;
0167 --n;
0168 }
0169 return {first, out};
0170 }
0171
0172 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0173 transcode_result<Iter, OutIter> transcode_to_16(
0174 tag_t<format::utf8>,
0175 Iter first,
0176 Sentinel last,
0177 std::ptrdiff_t n,
0178 OutIter out)
0179 {
0180 return detail::transcode_utf_8_to_16<UseN>(
0181 first,
0182 last,
0183 n,
0184 out,
0185 typename std::iterator_traits<Iter>::iterator_category{});
0186 }
0187
0188 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0189 transcode_result<Iter, OutIter> transcode_to_32(
0190 tag_t<format::utf8>,
0191 Iter first,
0192 Sentinel last,
0193 std::ptrdiff_t n,
0194 OutIter out)
0195 {
0196 return detail::transcode_utf_8_to_32<UseN>(
0197 first,
0198 last,
0199 n,
0200 out,
0201 typename std::iterator_traits<Iter>::iterator_category{});
0202 }
0203
0204 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0205 transcode_result<Iter, OutIter> transcode_to_8(
0206 tag_t<format::utf16>,
0207 Iter first,
0208 Sentinel last,
0209 std::ptrdiff_t n,
0210 OutIter out)
0211 {
0212 uint32_t const high_surrogate_max = 0xdbff;
0213 uint16_t const high_surrogate_base = 0xd7c0;
0214 uint16_t const low_surrogate_base = 0xdc00;
0215
0216 for (; first != last && (!UseN || n); ++first, --n) {
0217 uint32_t const hi = *first;
0218 if (surrogate(hi)) {
0219 if (hi <= high_surrogate_max) {
0220 ++first;
0221 if (first == last) {
0222 uint32_t const cp = replacement_character;
0223 out = detail::read_into_utf8_iter(cp, out);
0224 ++out;
0225 return {first, out};
0226 }
0227 uint32_t const lo = *first;
0228 if (low_surrogate(lo)) {
0229 uint32_t const cp =
0230 ((hi - high_surrogate_base) << 10) +
0231 (lo - low_surrogate_base);
0232 out = detail::read_into_utf8_iter(cp, out);
0233 continue;
0234 }
0235 }
0236 out = detail::read_into_utf8_iter(
0237 replacement_character, out);
0238 } else {
0239 out = detail::read_into_utf8_iter(hi, out);
0240 }
0241 }
0242
0243 return {first, out};
0244 }
0245
0246 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0247 transcode_result<Iter, OutIter> transcode_to_16(
0248 tag_t<format::utf16>,
0249 Iter first,
0250 Sentinel last,
0251 std::ptrdiff_t n,
0252 OutIter out)
0253 {
0254 for (; first != last && (!UseN || n); ++first, ++out, --n) {
0255 *out = *first;
0256 }
0257 return {first, out};
0258 }
0259
0260 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0261 transcode_result<Iter, OutIter> transcode_to_32(
0262 tag_t<format::utf16>,
0263 Iter first,
0264 Sentinel last,
0265 std::ptrdiff_t n,
0266 OutIter out)
0267 {
0268 uint32_t const high_surrogate_max = 0xdbff;
0269 uint16_t const high_surrogate_base = 0xd7c0;
0270 uint16_t const low_surrogate_base = 0xdc00;
0271
0272 for (; first != last && (!UseN || n); ++first, --n) {
0273 uint32_t const hi = *first;
0274 if (surrogate(hi)) {
0275 if (hi <= high_surrogate_max) {
0276 ++first;
0277 if (first == last) {
0278 *out = replacement_character;
0279 ++out;
0280 return {first, out};
0281 }
0282 uint32_t const lo = *first;
0283 if (low_surrogate(lo)) {
0284 uint32_t const cp =
0285 ((hi - high_surrogate_base) << 10) +
0286 (lo - low_surrogate_base);
0287 *out = cp;
0288 ++out;
0289 continue;
0290 }
0291 }
0292 *out = replacement_character;
0293 ++out;
0294 } else {
0295 *out = hi;
0296 ++out;
0297 }
0298 }
0299
0300 return {first, out};
0301 }
0302
0303 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0304 transcode_result<Iter, OutIter> transcode_to_8(
0305 tag_t<format::utf32>,
0306 Iter first,
0307 Sentinel last,
0308 std::ptrdiff_t n,
0309 OutIter out)
0310 {
0311 for (; first != last && (!UseN || n); ++first, --n) {
0312 out = detail::read_into_utf8_iter(*first, out);
0313 }
0314 return {first, out};
0315 }
0316
0317 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0318 transcode_result<Iter, OutIter> transcode_to_16(
0319 tag_t<format::utf32>,
0320 Iter first,
0321 Sentinel last,
0322 std::ptrdiff_t n,
0323 OutIter out)
0324 {
0325 for (; first != last && (!UseN || n); ++first, --n) {
0326 out = detail::read_into_utf16_iter(*first, out);
0327 }
0328 return {first, out};
0329 }
0330
0331 template<bool UseN, typename Iter, typename Sentinel, typename OutIter>
0332 transcode_result<Iter, OutIter> transcode_to_32(
0333 tag_t<format::utf32>,
0334 Iter first,
0335 Sentinel last,
0336 std::ptrdiff_t n,
0337 OutIter out)
0338 {
0339 for (; first != last && (!UseN || n); ++first, ++out, --n) {
0340 *out = *first;
0341 }
0342 return {first, out};
0343 }
0344 }
0345
0346 #if 0
0347
0348
0349 template<typename InputIter, typename Sentinel, typename OutIter>
0350 transcode_result<InputIter, OutIter> transcode_utf_8_to_32_take_n(
0351 InputIter first, Sentinel last, std::ptrdiff_t n, OutIter out)
0352 {
0353 auto const r = detail::unpack_iterator_and_sentinel(first, last);
0354 return detail::transcode_to_32<true>(
0355 detail::tag_t<r.format_tag>{}, r.first, r.last, n, out);
0356 }
0357
0358
0359
0360 template<typename InputIter, typename Sentinel, typename OutIter>
0361 transcode_result<InputIter, OutIter> transcode_utf_8_to_32_take_n(
0362 InputIter first, Sentinel last, std::ptrdiff_t n, OutIter out)
0363 {
0364 auto const r = detail::unpack_iterator_and_sentinel(first, last);
0365 return detail::transcode_to_32<true>(
0366 detail::tag_t<r.format_tag>{}, r.first, r.last, n, out);
0367 }
0368
0369
0370
0371 template<typename InputIter, typename Sentinel, typename OutIter>
0372 transcode_result<InputIter, OutIter>
0373 transcode_utf_8_to_32_take_n(Range && r, std::ptrdiff_t n, OutIter out)
0374 {
0375 return detail::transcode_utf_8_to_32_dispatch<true, Range, OutIter>::
0376 call(r, n, out)
0377 .out;
0378 }
0379 #endif
0380
0381 }}
0382
0383 namespace boost::parser::detail { namespace text { BOOST_PARSER_DETAIL_TEXT_NAMESPACE_V1 {
0384
0385 #if defined(BOOST_TEXT_DOXYGEN)
0386
0387
0388
0389
0390
0391 template<
0392 std::input_iterator I,
0393 std::sentinel_for<I> S,
0394 std::output_iterator<uint8_t> O>
0395 requires(
0396 utf16_code_unit<std::iter_value_t<I>> ||
0397 utf32_code_unit<std::iter_value_t<I>>)
0398 transcode_result<I, O> transcode_to_utf8(I first, S last, O out);
0399
0400
0401
0402 template<typename Ptr, std::output_iterator<uint8_t> O>
0403 requires(utf16_pointer<Ptr> || utf32_pointer<Ptr>)
0404 transcode_result<Ptr, O> transcode_to_utf8(Ptr p, O out);
0405
0406
0407
0408 template<std::size_t N, typename Char, std::output_iterator<uint8_t> O>
0409 requires (utf16_code_unit<Char> || utf32_code_unit<Char>)
0410 transcode_result<Char *, O> transcode_to_utf8(Char (&arr)[N], O out);
0411
0412
0413
0414 template<std::ranges::input_range R, std::output_iterator<uint8_t> O>
0415 requires (utf16_code_unit<std::ranges::range_value_t<R>> ||
0416 utf32_code_unit<std::ranges::range_value_t<R>>)
0417 transcode_result<std::ranges::borrowed_iterator_t<R>, O>
0418 transcode_to_utf8(R && r, O out);
0419
0420
0421
0422
0423
0424
0425 template<
0426 std::input_iterator I,
0427 std::sentinel_for<I> S,
0428 std::output_iterator<char16_t> O>
0429 requires (utf8_code_unit<std::iter_value_t<I>> ||
0430 utf32_code_unit<std::iter_value_t<I>>)
0431 transcode_result<I, O> transcode_to_utf16(I first, S last, O out);
0432
0433
0434
0435 template<typename Ptr, std::output_iterator<char16_t> O>
0436 requires (utf8_pointer<Ptr> || utf32_pointer<Ptr>)
0437 transcode_result<Ptr, O> transcode_to_utf16(Ptr p, O out);
0438
0439
0440
0441 template<std::size_t N, typename Char, std::output_iterator<char16_t> O>
0442 requires (utf8_code_unit<Char> || utf32_code_unit<Char>)
0443 transcode_result<Char *, O> transcode_to_utf16(Char (&arr)[N], O out);
0444
0445
0446
0447 template<std::ranges::input_range R, std::output_iterator<cjar16_t> O>
0448 requires (utf8_code_unit<std::ranges::range_value_t<R>> ||
0449 utf32_code_unit<std::ranges::range_value_t<R>>)
0450 transcode_result<std::ranges::borrowed_iterator_t<R>, O>
0451 transcode_to_utf16(R && r, O out);
0452
0453
0454
0455
0456
0457
0458 template<
0459 std::input_iterator I,
0460 std::sentinel_for<I> S,
0461 std::output_iterator<uint32_t> O>
0462 requires (utf8_code_unit<std::iter_value_t<I>> ||
0463 utf16_code_unit<std::iter_value_t<I>>)
0464 transcode_result<I, O> transcode_to_utf32(I first, S last, O out);
0465
0466
0467
0468 template<typename Ptr, std::output_iterator<uint32_t> O>
0469 requires (utf8_pointer<Ptr> || utf16_pointer<Ptr>)
0470 transcode_result<Ptr, O> transcode_to_utf32(Ptr p, O out);
0471
0472
0473
0474 template<std::size_t N, typename Char, std::output_iterator<uint32_t> O>
0475 requires (utf8_code_unit<Char> || utf16_code_unit<Char>)
0476 transcode_result<Char *, O> transcode_to_utf32(Char (&arr)[N], O out);
0477
0478
0479
0480 template<std::ranges::input_range R, std::output_iterator<uint32_t> O>
0481 requires (utf8_code_unit<std::ranges::range_value_t<R>> ||
0482 utf16_code_unit<std::ranges::range_value_t<R>>)
0483 transcode_result<std::ranges::borrowed_iterator_t<R>, O>
0484 transcode_to_utf32(R && r, O out);
0485
0486 #endif
0487
0488 namespace dtl {
0489 template<
0490 bool UseN,
0491 typename Range,
0492 typename OutIter,
0493 bool _16Ptr = detail::is_16_ptr_v<Range>,
0494 bool CPPtr = detail::is_cp_ptr_v<Range>>
0495 struct transcode_to_8_dispatch
0496 {
0497 static constexpr auto
0498 call(Range && r, std::ptrdiff_t n, OutIter out)
0499 -> transcode_result<decltype(detail::begin(r)), OutIter>
0500 {
0501 auto const u = text::unpack_iterator_and_sentinel(
0502 detail::begin(r), detail::end(r));
0503 auto unpacked = detail::transcode_to_8<UseN>(
0504 detail::tag_t<u.format_tag>{}, u.first, u.last, n, out);
0505 return {u.repack(unpacked.in), unpacked.out};
0506 }
0507 };
0508
0509 template<bool UseN, typename Ptr, typename OutIter>
0510 struct transcode_to_8_dispatch<UseN, Ptr, OutIter, true, false>
0511 {
0512 static constexpr auto
0513 call(Ptr p, std::ptrdiff_t n, OutIter out)
0514 {
0515 return detail::transcode_to_8<UseN>(
0516 detail::tag_t<format::utf16>{}, p, null_sentinel, n, out);
0517 }
0518 };
0519
0520 template<bool UseN, typename Ptr, typename OutIter>
0521 struct transcode_to_8_dispatch<UseN, Ptr, OutIter, false, true>
0522 {
0523 static constexpr auto
0524 call(Ptr p, std::ptrdiff_t n, OutIter out)
0525 {
0526 return detail::transcode_to_8<UseN>(
0527 detail::tag_t<format::utf32>{}, p, null_sentinel, n, out);
0528 }
0529 };
0530
0531 template<
0532 bool UseN,
0533 typename Range,
0534 typename OutIter,
0535 bool CharPtr = detail::is_char_ptr_v<Range>,
0536 bool CPPtr = detail::is_cp_ptr_v<Range>>
0537 struct transcode_to_16_dispatch
0538 {
0539 static constexpr auto
0540 call(Range && r, std::ptrdiff_t n, OutIter out)
0541 -> transcode_result<decltype(detail::begin(r)), OutIter>
0542 {
0543 auto const u = text::unpack_iterator_and_sentinel(
0544 detail::begin(r), detail::end(r));
0545 auto unpacked = detail::transcode_to_16<UseN>(
0546 detail::tag_t<u.format_tag>{}, u.first, u.last, n, out);
0547 return {u.repack(unpacked.in), unpacked.out};
0548 }
0549 };
0550
0551 template<bool UseN, typename Ptr, typename OutIter>
0552 struct transcode_to_16_dispatch<UseN, Ptr, OutIter, true, false>
0553 {
0554 static constexpr auto
0555 call(Ptr p, std::ptrdiff_t n, OutIter out)
0556 {
0557 return detail::transcode_to_16<UseN>(
0558 detail::tag_t<format::utf8>{}, p, null_sentinel, n, out);
0559 }
0560 };
0561
0562 template<bool UseN, typename Ptr, typename OutIter>
0563 struct transcode_to_16_dispatch<UseN, Ptr, OutIter, false, true>
0564 {
0565 static constexpr auto
0566 call(Ptr p, std::ptrdiff_t n, OutIter out)
0567 {
0568 return detail::transcode_to_16<UseN>(
0569 detail::tag_t<format::utf32>{}, p, null_sentinel, n, out);
0570 }
0571 };
0572
0573 template<
0574 bool UseN,
0575 typename Range,
0576 typename OutIter,
0577 bool CharPtr = detail::is_char_ptr_v<Range>,
0578 bool _16Ptr = detail::is_16_ptr_v<Range>>
0579 struct transcode_to_32_dispatch
0580 {
0581 static constexpr auto
0582 call(Range && r, std::ptrdiff_t n, OutIter out)
0583 -> transcode_result<decltype(detail::begin(r)), OutIter>
0584 {
0585 auto const u = text::unpack_iterator_and_sentinel(
0586 detail::begin(r), detail::end(r));
0587 auto unpacked = detail::transcode_to_32<UseN>(
0588 detail::tag_t<u.format_tag>{}, u.first, u.last, n, out);
0589 return {u.repack(unpacked.in), unpacked.out};
0590 }
0591 };
0592
0593 template<bool UseN, typename Ptr, typename OutIter>
0594 struct transcode_to_32_dispatch<UseN, Ptr, OutIter, true, false>
0595 {
0596 static constexpr auto
0597 call(Ptr p, std::ptrdiff_t n, OutIter out)
0598 {
0599 return detail::transcode_to_32<UseN>(
0600 detail::tag_t<format::utf8>{}, p, null_sentinel, n, out);
0601 }
0602 };
0603
0604 template<bool UseN, typename Ptr, typename OutIter>
0605 struct transcode_to_32_dispatch<UseN, Ptr, OutIter, false, true>
0606 {
0607 static constexpr auto
0608 call(Ptr p, std::ptrdiff_t n, OutIter out)
0609 {
0610 return detail::transcode_to_32<UseN>(
0611 detail::tag_t<format::utf16>{}, p, null_sentinel, n, out);
0612 }
0613 };
0614 }
0615
0616 template<typename Iter, typename Sentinel, typename OutIter>
0617 transcode_result<Iter, OutIter> transcode_to_utf8(
0618 Iter first, Sentinel last, OutIter out)
0619 {
0620 auto const r = text::unpack_iterator_and_sentinel(first, last);
0621 auto unpacked = detail::transcode_to_8<false>(
0622 detail::tag_t<r.format_tag>{}, r.first, r.last, -1, out);
0623 return {r.repack(unpacked.in), unpacked.out};
0624 }
0625
0626 template<typename Range, typename OutIter>
0627 transcode_result<detail::iterator_t<Range>, OutIter>
0628 transcode_to_utf8(Range && r, OutIter out)
0629 {
0630 return dtl::transcode_to_8_dispatch<false, Range, OutIter>::call(
0631 r, -1, out);
0632 }
0633
0634 template<typename Iter, typename Sentinel, typename OutIter>
0635 transcode_result<Iter, OutIter> transcode_to_utf16(
0636 Iter first, Sentinel last, OutIter out)
0637 {
0638 auto const r = text::unpack_iterator_and_sentinel(first, last);
0639 auto unpacked = detail::transcode_to_16<false>(
0640 detail::tag_t<r.format_tag>{}, r.first, r.last, -1, out);
0641 return {r.repack(unpacked.in), unpacked.out};
0642 }
0643
0644 template<typename Range, typename OutIter>
0645 transcode_result<detail::iterator_t<Range>, OutIter>
0646 transcode_to_utf16(Range && r, OutIter out)
0647 {
0648 return dtl::transcode_to_16_dispatch<false, Range, OutIter>::call(
0649 r, -1, out);
0650 }
0651
0652 template<typename Iter, typename Sentinel, typename OutIter>
0653 transcode_result<Iter, OutIter> transcode_to_utf32(
0654 Iter first, Sentinel last, OutIter out)
0655 {
0656 auto const r = text::unpack_iterator_and_sentinel(first, last);
0657 auto unpacked = detail::transcode_to_32<false>(
0658 detail::tag_t<r.format_tag>{}, r.first, r.last, -1, out);
0659 return {r.repack(unpacked.in), unpacked.out};
0660 }
0661
0662 template<typename Range, typename OutIter>
0663 transcode_result<detail::iterator_t<Range>, OutIter>
0664 transcode_to_utf32(Range && r, OutIter out)
0665 {
0666 return dtl::transcode_to_32_dispatch<false, Range, OutIter>::call(
0667 r, -1, out);
0668 }
0669
0670 }}}
0671
0672 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0673
0674 namespace boost::parser::detail { namespace text { BOOST_PARSER_DETAIL_TEXT_NAMESPACE_V2 {
0675
0676
0677
0678 template<
0679 std::input_iterator I,
0680 std::sentinel_for<I> S,
0681 std::output_iterator<uint8_t> O>
0682 requires(
0683 utf16_code_unit<std::iter_value_t<I>> ||
0684 utf32_code_unit<std::iter_value_t<I>>)
0685 transcode_result<I, O> transcode_to_utf8(I first, S last, O out)
0686 {
0687 auto const r = text::unpack_iterator_and_sentinel(first, last);
0688 auto unpacked = detail::transcode_to_8<false>(
0689 detail::tag_t<r.format_tag>{}, r.first, r.last, -1, out);
0690 return {r.repack(unpacked.in), unpacked.out};
0691 }
0692
0693 template<typename R, std::output_iterator<uint32_t> O>
0694 requires(utf16_range<R> || utf32_range<R>)
0695 transcode_result<dtl::uc_result_iterator<R>, O> transcode_to_utf8(
0696 R && r, O out)
0697 {
0698 return text::transcode_to_utf8(
0699 std::ranges::begin(r), std::ranges::end(r), out);
0700 }
0701
0702
0703
0704
0705 template<
0706 std::input_iterator I,
0707 std::sentinel_for<I> S,
0708 std::output_iterator<char16_t> O>
0709 requires(
0710 utf8_code_unit<std::iter_value_t<I>> ||
0711 utf32_code_unit<std::iter_value_t<I>>)
0712 transcode_result<I, O> transcode_to_utf16(I first, S last, O out)
0713 {
0714 auto const r = text::unpack_iterator_and_sentinel(first, last);
0715 auto unpacked = detail::transcode_to_16<false>(
0716 detail::tag_t<r.format_tag>{}, r.first, r.last, -1, out);
0717 return {r.repack(unpacked.in), unpacked.out};
0718 }
0719
0720 template<typename R, std::output_iterator<uint32_t> O>
0721 requires(utf8_range<R> || utf32_range<R>)
0722 transcode_result<dtl::uc_result_iterator<R>, O> transcode_to_utf16(
0723 R && r, O out)
0724 {
0725 return text::transcode_to_utf16(
0726 std::ranges::begin(r), std::ranges::end(r), out);
0727 }
0728
0729
0730
0731
0732 template<
0733 std::input_iterator I,
0734 std::sentinel_for<I> S,
0735 std::output_iterator<uint32_t> O>
0736 requires(
0737 utf8_code_unit<std::iter_value_t<I>> ||
0738 utf16_code_unit<std::iter_value_t<I>>)
0739 transcode_result<I, O> transcode_to_utf32(I first, S last, O out)
0740 {
0741 auto const r = text::unpack_iterator_and_sentinel(first, last);
0742 auto unpacked = detail::transcode_to_32<false>(
0743 detail::tag_t<r.format_tag>{}, r.first, r.last, -1, out);
0744 return {r.repack(unpacked.in), unpacked.out};
0745 }
0746
0747 template<typename R, std::output_iterator<uint32_t> O>
0748 requires(utf8_range<R> || utf16_range<R>)
0749 transcode_result<dtl::uc_result_iterator<R>, O> transcode_to_utf32(
0750 R && r, O out)
0751 {
0752 return text::transcode_to_utf32(
0753 std::ranges::begin(r), std::ranges::end(r), out);
0754 }
0755
0756 }}}
0757
0758 #endif
0759
0760 #endif