File indexing completed on 2026-08-17 09:02:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_URL_DETAIL_SEGMENTS_RANGE_HPP
0011 #define BOOST_URL_DETAIL_SEGMENTS_RANGE_HPP
0012
0013 #include <boost/url/detail/config.hpp>
0014 #include <boost/url/detail/url_impl.hpp>
0015 #include <boost/url/segments_base.hpp>
0016 #include <boost/url/segments_encoded_base.hpp>
0017 #include <boost/core/detail/string_view.hpp>
0018 #include <boost/assert.hpp>
0019
0020 namespace boost {
0021 namespace urls {
0022 namespace detail {
0023
0024 struct segments_iter_access
0025 {
0026 static
0027 segments_iter_impl const&
0028 impl(segments_base::iterator const& it) noexcept
0029 {
0030 return it.it_;
0031 }
0032
0033 static
0034 segments_iter_impl const&
0035 impl(segments_encoded_base::iterator const& it) noexcept
0036 {
0037 return it.it_;
0038 }
0039 };
0040
0041 inline
0042 path_ref
0043 make_subref_from_impls(
0044 segments_iter_impl const& first,
0045 segments_iter_impl const& last) noexcept
0046 {
0047 BOOST_ASSERT(first.ref.alias_of(last.ref));
0048 path_ref const& ref = first.ref;
0049
0050 std::size_t const i0 = first.index;
0051 std::size_t const i1 = last.index;
0052 BOOST_ASSERT(i0 <= i1);
0053 std::size_t const nseg = i1 - i0;
0054
0055 bool const absolute = ref.buffer().starts_with('/');
0056
0057
0058 if (nseg == 0)
0059 {
0060 std::size_t off0;
0061 if (i0 == 0)
0062 {
0063
0064
0065 if (absolute)
0066 {
0067 off0 = 1;
0068 }
0069
0070 else
0071 {
0072 off0 = first.pos;
0073 }
0074 }
0075 else
0076 {
0077
0078
0079 off0 = first.pos + 1;
0080 }
0081
0082 core::string_view const sub(ref.data() + off0, 0);
0083 return {sub, 0, 0};
0084 }
0085
0086
0087
0088 std::size_t off0;
0089 if (i0 == 0)
0090 {
0091 if (absolute)
0092 {
0093
0094 off0 = 0;
0095 }
0096 else
0097 {
0098
0099 off0 = first.pos;
0100 }
0101 }
0102 else
0103 {
0104
0105 off0 = first.pos;
0106 }
0107
0108
0109 std::size_t off1;
0110 if(i1 == ref.nseg())
0111 {
0112 off1 = ref.size();
0113 }
0114 else
0115 {
0116
0117 off1 = last.pos;
0118 }
0119
0120 BOOST_ASSERT(off1 >= off0);
0121 core::string_view const sub(ref.data() + off0, off1 - off0);
0122
0123
0124 std::size_t start_dn = (i0 == 0) ? 0 : first.decoded_prefix_size();
0125 std::size_t const end_dn = last.decoded_prefix_size();
0126 BOOST_ASSERT(end_dn >= start_dn);
0127 std::size_t const dn_sum = end_dn - start_dn;
0128
0129 return {sub, dn_sum, nseg};
0130 }
0131
0132 template<class Iter>
0133 inline
0134 path_ref
0135 make_subref(Iter const& first, Iter const& last) noexcept
0136 {
0137 auto const& f = segments_iter_access::impl(first);
0138 auto const& l = segments_iter_access::impl(last);
0139 return make_subref_from_impls(f, l);
0140 }
0141
0142 }
0143 }
0144 }
0145
0146 #endif