Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright (C) 2020 T. Zachary Laine
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
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         // Using this custom template is quite a bit faster than using lambdas.
0028         // Unexpected.
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