File indexing completed on 2025-01-18 09:53:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
0011 #define BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
0012
0013 #include <boost/url/pct_string_view.hpp>
0014 #include <boost/static_assert.hpp>
0015 #include <cstddef>
0016 #include <iterator>
0017 #include <type_traits>
0018
0019 namespace boost {
0020 namespace urls {
0021 namespace detail {
0022
0023 struct BOOST_SYMBOL_VISIBLE
0024 any_segments_iter
0025 {
0026 protected:
0027 explicit
0028 any_segments_iter(
0029 core::string_view s_ = {}) noexcept
0030 : s(s_)
0031 {
0032 }
0033
0034 virtual ~any_segments_iter() = default;
0035
0036 public:
0037
0038
0039 core::string_view s;
0040
0041
0042
0043 core::string_view front;
0044
0045
0046
0047
0048
0049 int fast_nseg = 0;
0050
0051
0052
0053
0054
0055
0056
0057 bool encode_colons = false;
0058
0059
0060 virtual void rewind() noexcept = 0;
0061
0062
0063
0064
0065
0066 virtual bool measure(std::size_t& n) = 0;
0067
0068
0069
0070 virtual void copy(char*& dest,
0071 char const* end) noexcept = 0;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct BOOST_SYMBOL_VISIBLE
0083 segment_iter
0084 : any_segments_iter
0085 {
0086 virtual ~segment_iter() = default;
0087
0088 explicit
0089 segment_iter(
0090 core::string_view s) noexcept;
0091
0092 private:
0093 bool at_end_ = false;
0094 void rewind() noexcept override;
0095 bool measure(std::size_t&) noexcept override;
0096 void copy(char*&, char const*) noexcept override;
0097 };
0098
0099
0100
0101
0102
0103
0104
0105 struct segments_iter_base
0106 {
0107 protected:
0108 BOOST_URL_DECL static void
0109 measure_impl(std::size_t&,
0110 core::string_view, bool) noexcept;
0111 BOOST_URL_DECL static void
0112 copy_impl(char*&, char const*,
0113 core::string_view, bool) noexcept;
0114 };
0115
0116
0117
0118 template<class FwdIt>
0119 struct segments_iter
0120 : any_segments_iter
0121 , segments_iter_base
0122 {
0123 BOOST_STATIC_ASSERT(
0124 std::is_convertible<
0125 typename std::iterator_traits<
0126 FwdIt>::reference,
0127 core::string_view>::value);
0128
0129 segments_iter(
0130 FwdIt first,
0131 FwdIt last) noexcept
0132 : it_(first)
0133 , it0_(first)
0134 , end_(last)
0135 {
0136 if(first != last)
0137 {
0138 front = *first;
0139 auto it = first;
0140 if(++it == last)
0141 fast_nseg = 1;
0142 else
0143 fast_nseg = 2;
0144 }
0145 else
0146 {
0147 fast_nseg = 0;
0148 }
0149 }
0150
0151 private:
0152 FwdIt it_;
0153 FwdIt it0_;
0154 FwdIt end_;
0155
0156 void
0157 rewind() noexcept override
0158 {
0159 it_ = it0_;
0160 }
0161
0162 bool
0163 measure(
0164 std::size_t& n) noexcept override
0165 {
0166 if(it_ == end_)
0167 return false;
0168 measure_impl(n,
0169 detail::to_sv(*it_),
0170 encode_colons);
0171 ++it_;
0172 return true;
0173 }
0174
0175 void
0176 copy(
0177 char*& dest,
0178 char const* end) noexcept override
0179 {
0180 copy_impl(dest, end,
0181 detail::to_sv(*it_++),
0182 encode_colons);
0183 }
0184 };
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194 struct BOOST_SYMBOL_VISIBLE
0195 segment_encoded_iter
0196 : any_segments_iter
0197 {
0198 virtual ~segment_encoded_iter() = default;
0199
0200 explicit
0201 segment_encoded_iter(
0202 pct_string_view const& s) noexcept;
0203
0204 private:
0205 bool at_end_ = false;
0206 void rewind() noexcept override;
0207 bool measure(std::size_t&) noexcept override;
0208 void copy(char*&, char const*) noexcept override;
0209 };
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 struct segments_encoded_iter_base
0220 {
0221 protected:
0222 BOOST_URL_DECL static void
0223 measure_impl(std::size_t&,
0224 core::string_view, bool) noexcept;
0225 BOOST_URL_DECL static void
0226 copy_impl(char*&, char const*,
0227 core::string_view, bool) noexcept;
0228 };
0229
0230
0231
0232 template<class FwdIt>
0233 struct segments_encoded_iter
0234 : public any_segments_iter
0235 , public segments_encoded_iter_base
0236 {
0237 BOOST_STATIC_ASSERT(
0238 std::is_convertible<
0239 typename std::iterator_traits<
0240 FwdIt>::reference,
0241 core::string_view>::value);
0242
0243 segments_encoded_iter(
0244 FwdIt first,
0245 FwdIt last)
0246 : it_(first)
0247 , it0_(first)
0248 , end_(last)
0249 {
0250 if(it_ != end_)
0251 {
0252
0253 front = pct_string_view(
0254 detail::to_sv(*first));
0255 auto it = first;
0256 if(++it == last)
0257 fast_nseg = 1;
0258 else
0259 fast_nseg = 2;
0260 }
0261 else
0262 {
0263 fast_nseg = 0;
0264 }
0265 }
0266
0267 private:
0268 FwdIt it_;
0269 FwdIt it0_;
0270 FwdIt end_;
0271
0272 void
0273 rewind() noexcept override
0274 {
0275 it_ = it0_;
0276 }
0277
0278 bool
0279 measure(
0280 std::size_t& n) override
0281 {
0282 if(it_ == end_)
0283 return false;
0284
0285 measure_impl(n,
0286 pct_string_view(
0287 detail::to_sv(*it_++)),
0288 encode_colons);
0289 return true;
0290 }
0291
0292 void
0293 copy(
0294 char*& dest,
0295 char const* end) noexcept override
0296 {
0297 copy_impl(dest, end,
0298 detail::to_sv(*it_++),
0299 encode_colons);
0300 }
0301 };
0302
0303
0304
0305 template<class FwdIt>
0306 segments_iter<FwdIt>
0307 make_segments_iter(
0308 FwdIt first, FwdIt last)
0309 {
0310 return segments_iter<
0311 FwdIt>(first, last);
0312 }
0313
0314 template<class FwdIt>
0315 segments_encoded_iter<FwdIt>
0316 make_segments_encoded_iter(
0317 FwdIt first, FwdIt last)
0318 {
0319 return segments_encoded_iter<
0320 FwdIt>(first, last);
0321 }
0322
0323 }
0324 }
0325 }
0326
0327 #endif