Warning, file /include/boost/parser/detail/text/unpack.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PARSER_DETAIL_TEXT_UNPACK_HPP
0007 #define BOOST_PARSER_DETAIL_TEXT_UNPACK_HPP
0008
0009 #include <boost/parser/detail/text/transcode_iterator_fwd.hpp>
0010
0011 #include <type_traits>
0012 #include <optional>
0013
0014
0015 namespace boost::parser::detail { namespace text {
0016
0017 struct no_op_repacker
0018 {
0019 template<class T>
0020 T operator()(T x) const
0021 {
0022 return x;
0023 }
0024 };
0025
0026 namespace detail {
0027
0028
0029 template<
0030 typename RepackedIterator,
0031 typename I,
0032 typename S,
0033 typename Then,
0034 bool Bidi>
0035 struct repacker
0036 {
0037 repacker() = default;
0038 #if !BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0039 template<bool Enable = Bidi, typename = std::enable_if_t<Enable>>
0040 #endif
0041 repacker(I first, S last, Then then)
0042 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0043 requires Bidi
0044 #endif
0045 : first{first},
0046 last{last},
0047 then{then}
0048 {}
0049 #if !BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0050 template<bool Enable = !Bidi, typename = std::enable_if_t<Enable>>
0051 #endif
0052 repacker(S last, Then then)
0053 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0054 requires(!Bidi)
0055 #endif
0056 :
0057 last{last}, then{then}
0058 {}
0059
0060 auto operator()(I it) const
0061 {
0062 if constexpr (Bidi) {
0063 return then(RepackedIterator(*first, it, last));
0064 } else {
0065 return then(RepackedIterator(it, last));
0066 }
0067 }
0068
0069 std::optional<I> first;
0070 [[no_unique_address]] S last;
0071 [[no_unique_address]] Then then;
0072 };
0073
0074 template<typename I, typename S, typename Repack>
0075 constexpr auto
0076 unpack_iterator_and_sentinel_impl(I first, S last, Repack repack);
0077
0078 template<
0079 format FromFormat,
0080 format ToFormat,
0081 typename I,
0082 typename S,
0083 typename ErrorHandler,
0084 typename Repack>
0085 constexpr auto unpack_iterator_and_sentinel_impl(
0086 utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler> first,
0087 utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler> last,
0088 Repack repack);
0089
0090 template<
0091 format FromFormat,
0092 format ToFormat,
0093 typename I,
0094 typename S,
0095 typename ErrorHandler,
0096 typename Repack>
0097 constexpr auto unpack_iterator_and_sentinel_impl(
0098 utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler> first,
0099 S last,
0100 Repack repack);
0101
0102 template<typename I, typename S, typename Repack>
0103 constexpr auto
0104 unpack_iterator_and_sentinel(I first, S last, Repack repack)
0105 {
0106 return detail::unpack_iterator_and_sentinel_impl(
0107 first, last, repack);
0108 }
0109
0110 struct unpack_iterator_and_sentinel_cpo
0111 {
0112 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0113 template<
0114 utf_iter I,
0115 std::sentinel_for<I> S,
0116 typename Repack = no_op_repacker>
0117 requires std::forward_iterator<I>
0118 #else
0119 template<typename I, typename S, typename Repack = no_op_repacker>
0120 #endif
0121 constexpr auto
0122 operator()(I first, S last, Repack repack = Repack()) const
0123 {
0124 return unpack_iterator_and_sentinel(first, last, repack);
0125 }
0126 };
0127 }
0128
0129 inline namespace cpo {
0130 inline constexpr detail::unpack_iterator_and_sentinel_cpo
0131 unpack_iterator_and_sentinel{};
0132 }
0133
0134 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0135 template<format FormatTag, utf_iter I, std::sentinel_for<I> S, class Repack>
0136 #else
0137 template<format FormatTag, typename I, typename S, class Repack>
0138 #endif
0139 struct unpack_result
0140 {
0141 static constexpr format format_tag = FormatTag;
0142
0143 I first;
0144 [[no_unique_address]] S last;
0145 [[no_unique_address]] Repack repack;
0146 };
0147
0148 namespace detail {
0149 struct no_such_type
0150 {};
0151 template<typename I, typename S, typename Repack>
0152 constexpr auto
0153 unpack_iterator_and_sentinel_impl(I first, S last, Repack repack)
0154 {
0155 using value_type = detail::iter_value_t<I>;
0156 if constexpr (
0157 std::is_same_v<value_type, char>
0158 #if defined(__cpp_char8_t)
0159 || std::is_same_v<value_type, char8_t>
0160 #endif
0161 ) {
0162 return unpack_result<format::utf8, I, S, Repack>{
0163 first, last, repack};
0164 } else if constexpr (
0165 #if defined(_MSC_VER)
0166 std::is_same_v<value_type, wchar_t> ||
0167 #endif
0168 std::is_same_v<value_type, char16_t>) {
0169 return unpack_result<format::utf16, I, S, Repack>{
0170 first, last, repack};
0171 } else if constexpr (
0172 #if !defined(_MSC_VER)
0173 std::is_same_v<value_type, wchar_t> ||
0174 #endif
0175 std::is_same_v<value_type, char32_t>) {
0176 return unpack_result<format::utf32, I, S, Repack>{
0177 first, last, repack};
0178 } else {
0179 static_assert(
0180 std::is_same_v<Repack, no_such_type>,
0181 "Unpacked iterator is not a utf_iter!");
0182 return 0;
0183 }
0184 }
0185
0186 }
0187 }}
0188
0189 #include <boost/parser/detail/text/transcode_iterator.hpp>
0190
0191 namespace boost::parser::detail { namespace text { namespace detail {
0192
0193 template<
0194 format FromFormat,
0195 format ToFormat,
0196 typename I,
0197 typename S,
0198 typename ErrorHandler,
0199 typename Repack>
0200 constexpr auto unpack_iterator_and_sentinel_impl(
0201 utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler> first,
0202 utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler> last,
0203 Repack repack)
0204 {
0205 using iterator = utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler>;
0206 if constexpr (
0207 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0208 std::bidirectional_iterator<I>
0209 #else
0210 std::is_base_of_v<
0211 std::bidirectional_iterator_tag,
0212 typename std::iterator_traits<I>::iterator_category>
0213 #endif
0214 ) {
0215 return boost::parser::detail::text::unpack_iterator_and_sentinel(
0216 first.base(),
0217 last.base(),
0218 repacker<
0219 iterator,
0220 decltype(first.begin()),
0221 decltype(first.end()),
0222 Repack,
0223 true>(first.begin(), first.end(), repack));
0224 } else {
0225 return boost::parser::detail::text::unpack_iterator_and_sentinel(
0226 first.base(),
0227 last.base(),
0228 repacker<iterator, int, decltype(first.end()), Repack, false>(
0229 first.end(), repack));
0230 }
0231 }
0232
0233 template<
0234 format FromFormat,
0235 format ToFormat,
0236 typename I,
0237 typename S,
0238 typename ErrorHandler,
0239 typename Repack>
0240 constexpr auto unpack_iterator_and_sentinel_impl(
0241 utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler> first,
0242 S last,
0243 Repack repack)
0244 {
0245 using iterator = utf_iterator<FromFormat, ToFormat, I, S, ErrorHandler>;
0246 if constexpr (
0247 #if BOOST_PARSER_DETAIL_TEXT_USE_CONCEPTS
0248 std::bidirectional_iterator<I>
0249 #else
0250 std::is_base_of_v<
0251 std::bidirectional_iterator_tag,
0252 typename std::iterator_traits<I>::iterator_category>
0253 #endif
0254 ) {
0255 return boost::parser::detail::text::unpack_iterator_and_sentinel(
0256 first.base(),
0257 last,
0258 repacker<
0259 iterator,
0260 decltype(first.begin()),
0261 decltype(first.end()),
0262 Repack,
0263 true>(first.begin(), first.end(), repack));
0264 } else {
0265 return boost::parser::detail::text::unpack_iterator_and_sentinel(
0266 first.base(),
0267 last,
0268 repacker<iterator, int, S, Repack, false>(last, repack));
0269 }
0270 }
0271
0272 }}}
0273
0274 #endif