diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index 1b2ccad7..53e7d14d 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -140,11 +140,6 @@
pct_encoded_rule
- Types
-
- parsed_path
-
-
CharSets
gen_delim_chars
diff --git a/include/boost/url.hpp b/include/boost/url.hpp
index c4b84f34..c2752d60 100644
--- a/include/boost/url.hpp
+++ b/include/boost/url.hpp
@@ -42,7 +42,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/include/boost/url/detail/empty_value.hpp b/include/boost/url/detail/empty_value.hpp
new file mode 100644
index 00000000..284bc2f0
--- /dev/null
+++ b/include/boost/url/detail/empty_value.hpp
@@ -0,0 +1,162 @@
+/*
+Copyright 2018 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Copyright 2022 Vinnie Falco
+(vinnie dot falco at gmail dot com)
+* Added constexpr
+* removed pre-C++11 support
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_URL_DETAIL_EMPTY_VALUE_HPP
+#define BOOST_URL_DETAIL_EMPTY_VALUE_HPP
+
+#include
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#include
+#endif
+
+#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700)
+#define BOOST_DETAIL_EMPTY_VALUE_BASE
+#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800)
+#define BOOST_DETAIL_EMPTY_VALUE_BASE
+#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800)
+#define BOOST_DETAIL_EMPTY_VALUE_BASE
+#elif defined(BOOST_CLANG) && !defined(__CUDACC__)
+#if __has_feature(is_empty) && __has_feature(is_final)
+#define BOOST_DETAIL_EMPTY_VALUE_BASE
+#endif
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4510)
+#endif
+
+namespace boost {
+namespace urls {
+namespace detail {
+
+template
+struct use_empty_value_base {
+ enum {
+#if defined(BOOST_DETAIL_EMPTY_VALUE_BASE)
+ value = __is_empty(T) && !__is_final(T)
+#else
+ value = false
+#endif
+ };
+};
+
+struct empty_init_t { };
+
+namespace empty_ {
+
+template<
+ class T,
+ unsigned N = 0,
+ bool E = use_empty_value_base::value>
+class empty_value
+{
+ T value_;
+
+public:
+ typedef T type;
+
+ constexpr
+ empty_value() = default;
+
+ constexpr
+ empty_value(
+ empty_init_t) noexcept
+ : value_()
+ {
+ }
+
+ template<
+ class U, class... Args>
+ constexpr
+ empty_value(
+ empty_init_t,
+ U&& value,
+ Args&&... args) noexcept
+ : value_(
+ std::forward(value),
+ std::forward(args)...)
+ {
+ }
+
+ T const&
+ get() const noexcept
+ {
+ return value_;
+ }
+
+ T&
+ get() noexcept
+ {
+ return value_;
+ }
+};
+
+//------------------------------------------------
+
+template
+class empty_value
+ : T
+{
+public:
+ typedef T type;
+
+ constexpr
+ empty_value() noexcept = default;
+
+ constexpr
+ empty_value(
+ empty_init_t) noexcept
+ : T()
+ {
+ }
+
+ template<
+ class U, class... Args>
+ constexpr
+ empty_value(
+ empty_init_t,
+ U&& value,
+ Args&&... args) noexcept
+ : T(std::forward(value),
+ std::forward(args)...)
+ {
+ }
+
+ T const&
+ get() const noexcept
+ {
+ return *this;
+ }
+
+ T&
+ get() noexcept
+ {
+ return *this;
+ }
+};
+
+} /* empty_ */
+
+using empty_::empty_value;
+
+constexpr empty_init_t empty_init{};
+
+} // detail
+} // urls
+} // boost
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp b/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp
index 20d13d30..e7340e40 100644
--- a/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp
+++ b/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp
@@ -12,7 +12,7 @@
#define BOOST_URL_DETAIL_IMPL_SEGMENTS_ENCODED_ITERATOR_IMPL_IPP
#include
-#include
+#include
#include
namespace boost {
@@ -72,8 +72,8 @@ increment() noexcept
// "/" segment
auto rv = grammar::parse(
next_, end_,
- detail::path_increment);
- if(rv == grammar::error::end)
+ detail::slash_segment_rule);
+ if(rv.has_error())
{
next_ = nullptr;
return;
@@ -103,7 +103,7 @@ decrement() noexcept
next_ = pos_;
auto rv = grammar::parse(
next_, end_,
- detail::path_increment);
+ detail::slash_segment_rule);
s_ = rv->encoded();
return;
}
@@ -113,7 +113,7 @@ decrement() noexcept
// "/" segment
auto rv = grammar::parse(
next_, end_,
- detail::path_increment);
+ detail::slash_segment_rule);
s_ = rv->encoded();
}
else
@@ -121,7 +121,7 @@ decrement() noexcept
// segment-nz
auto rv = grammar::parse(
next_, end_,
- detail::path_increment);
+ detail::slash_segment_rule);
s_ = rv->encoded();
}
}
diff --git a/include/boost/url/detail/impl/segments_iterator_impl.ipp b/include/boost/url/detail/impl/segments_iterator_impl.ipp
index 2bff347d..311b5a84 100644
--- a/include/boost/url/detail/impl/segments_iterator_impl.ipp
+++ b/include/boost/url/detail/impl/segments_iterator_impl.ipp
@@ -12,7 +12,7 @@
#define BOOST_URL_DETAIL_IMPL_SEGMENTS_ITERATOR_IMPL_IPP
#include
-#include
+#include
#include
namespace boost {
@@ -39,7 +39,7 @@ segments_iterator_impl(
pos_ += n;
t_ = grammar::parse(
next_, end_,
- detail::segment_rule).value();
+ segment_rule).value();
}
segments_iterator_impl::
@@ -76,8 +76,8 @@ increment() noexcept
// "/" segment
auto rv = grammar::parse(
next_, end_,
- detail::path_increment);
- if(rv == grammar::error::end)
+ detail::slash_segment_rule);
+ if(rv.has_error())
{
next_ = nullptr;
return;
@@ -108,7 +108,7 @@ decrement() noexcept
next_ = pos_;
t_ = grammar::parse(
next_, end_,
- detail::path_increment).value();
+ detail::slash_segment_rule).value();
return;
}
next_ = pos_;
@@ -117,14 +117,14 @@ decrement() noexcept
// "/" segment
t_ = grammar::parse(
next_, end_,
- detail::path_increment).value();
+ detail::slash_segment_rule).value();
}
else
{
// segment-nz
t_ = grammar::parse(
next_, end_,
- detail::path_increment).value();
+ detail::slash_segment_rule).value();
}
}
diff --git a/include/boost/url/detail/impl/url_impl.ipp b/include/boost/url/detail/impl/url_impl.ipp
index d69497f6..0a1588cb 100644
--- a/include/boost/url/detail/impl/url_impl.ipp
+++ b/include/boost/url/detail/impl/url_impl.ipp
@@ -126,14 +126,14 @@ apply_authority(
void
url_impl::
apply_path(
- parsed_path const& t) noexcept
+ string_view s,
+ std::size_t nseg) noexcept
{
- auto s = t.path;
set_size(id_path, s.size());
+ // VFALCO we are decoding twice
decoded_[id_path] =
- pct_decode_bytes_unchecked(t.path);
- nseg_ = detail::path_segments(
- t.path, t.count);
+ pct_decode_bytes_unchecked(s);
+ nseg_ = detail::path_segments(s, nseg);
}
void
diff --git a/include/boost/url/detail/over_allocator.hpp b/include/boost/url/detail/over_allocator.hpp
index 3d144600..97cad201 100644
--- a/include/boost/url/detail/over_allocator.hpp
+++ b/include/boost/url/detail/over_allocator.hpp
@@ -11,8 +11,8 @@
#define BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
#include
+#include
#include
-#include
#include
#include
#ifdef BOOST_NO_CXX11_ALLOCATOR
@@ -41,7 +41,7 @@ using allocator_traits = std::allocator_traits;
template
class over_allocator
- : private empty_value
+ : private detail::empty_value
{
template
friend class over_allocator;
@@ -75,16 +75,16 @@ public:
over_allocator(
std::size_t extra,
Allocator const& alloc)
- : empty_value(
- boost::empty_init_t{}, alloc)
+ : detail::empty_value(
+ detail::empty_init, alloc)
, extra_(extra)
{
}
template
over_allocator(over_allocator const& other) noexcept
- : empty_value(
- boost::empty_init_t{}, other.get())
+ : detail::empty_value(
+ detail::empty_init, other.get())
, extra_(other.extra_)
{
}
diff --git a/include/boost/url/detail/url_impl.hpp b/include/boost/url/detail/url_impl.hpp
index 62889de2..0bc63b3e 100644
--- a/include/boost/url/detail/url_impl.hpp
+++ b/include/boost/url/detail/url_impl.hpp
@@ -18,11 +18,6 @@
#include
#include
-// VFALCO These structs used to be forward
-// declared, but the parsers now use a
-// nested type.
-#include
-
namespace boost {
namespace urls {
@@ -93,7 +88,7 @@ struct url_impl : parts_base
unsigned char const*, pct_encoded_view const&) noexcept;
void apply_port(string_view, unsigned short) noexcept;
void apply_authority(authority_view const&) noexcept;
- void apply_path(parsed_path const&) noexcept;
+ void apply_path(string_view, std::size_t) noexcept;
void apply_query(string_view, std::size_t) noexcept;
void apply_frag(pct_encoded_view) noexcept;
};
diff --git a/include/boost/url/grammar/error.hpp b/include/boost/url/grammar/error.hpp
index 06e77837..936c31f1 100644
--- a/include/boost/url/grammar/error.hpp
+++ b/include/boost/url/grammar/error.hpp
@@ -35,7 +35,15 @@ enum class error
success = 0,
/**
- * A list parser reached the end.
+ * A rule reached the end of a range
+ *
+ * This indicates that the input was consumed
+ * when parsing a @ref range. The @ref range_rule
+ * will avoid rewinding the input buffer when
+ * this error is returned. Thus the consumed
+ * characters will be considered part of the
+ * range without contributing additional
+ * elements.
*/
end,
diff --git a/include/boost/url/grammar/impl/not_empty_rule.hpp b/include/boost/url/grammar/impl/not_empty_rule.hpp
index 837c8b31..84eb2ccc 100644
--- a/include/boost/url/grammar/impl/not_empty_rule.hpp
+++ b/include/boost/url/grammar/impl/not_empty_rule.hpp
@@ -32,7 +32,7 @@ parse(
result
{
auto const it0 = it;
- auto rv = r_.parse(it, end);
+ auto rv = this->get().parse(it, end);
if( rv.has_error() ||
it != it0)
return rv;
diff --git a/include/boost/url/grammar/impl/range_rule.hpp b/include/boost/url/grammar/impl/range_rule.hpp
index 430ab0ce..8d20abfe 100644
--- a/include/boost/url/grammar/impl/range_rule.hpp
+++ b/include/boost/url/grammar/impl/range_rule.hpp
@@ -11,6 +11,7 @@
#define BOOST_URL_GRAMMAR_IMPL_RANGE_HPP
#include
+#include
#include
#include
#include
@@ -38,6 +39,10 @@ struct range::
void
destroy() const noexcept = 0;
+ virtual
+ any_rule const*
+ move(void*) const noexcept = 0;
+
virtual
any_rule const*
copy(void*) const noexcept = 0;
@@ -55,6 +60,153 @@ struct range::
char const*) const noexcept = 0;
};
+//------------------------------------------------
+
+template
+template
+struct range::impl1
+ : any_rule
+ , private urls::detail::empty_value
+{
+ explicit
+ impl1(R const& next) noexcept
+ : urls::detail::empty_value(
+ urls::detail::empty_init,
+ next)
+ {
+ }
+
+private:
+ void
+ destroy() const noexcept override
+ {
+ static constexpr auto small =
+ sizeof(*this) <= BufferSize;
+ if(small)
+ this->~impl1();
+ else
+ delete this;
+ }
+
+ any_rule const*
+ move(void* dest)
+ const noexcept override
+ {
+ static constexpr auto small =
+ sizeof(*this) <= BufferSize;
+ if(small)
+ return ::new(dest) impl1(*this);
+ return this;
+ }
+
+ any_rule const*
+ copy(void* dest)
+ const noexcept override
+ {
+ static constexpr auto small =
+ sizeof(*this) <= BufferSize;
+ if(small)
+ return ::new(dest) impl1(*this);
+ return new impl1(*this);
+ }
+
+ result
+ first(
+ char const*& it,
+ char const* end)
+ const noexcept override
+ {
+ return grammar::parse(
+ it, end, this->get());
+ }
+
+ result
+ next(
+ char const*& it,
+ char const* end)
+ const noexcept override
+ {
+ return grammar::parse(
+ it, end, this->get());
+ }
+};
+
+//------------------------------------------------
+
+template
+template
+struct range::impl2
+ : any_rule
+ , private urls::detail::empty_value
+ , private urls::detail::empty_value
+{
+ impl2(
+ R0 const& first,
+ R1 const& next) noexcept
+ : urls::detail::empty_value(
+ urls::detail::empty_init, first)
+ , urls::detail::empty_value(
+ urls::detail::empty_init, next)
+ {
+ }
+
+private:
+ void
+ destroy() const noexcept override
+ {
+ static constexpr auto small =
+ sizeof(*this) <= BufferSize;
+ if(small)
+ this->~impl2();
+ else
+ delete this;
+ }
+
+ any_rule const*
+ move(void* dest)
+ const noexcept override
+ {
+ static constexpr auto small =
+ sizeof(*this) <= BufferSize;
+ if(small)
+ return ::new(dest) impl2(*this);
+ return this;
+ }
+
+ any_rule const*
+ copy(void* dest)
+ const noexcept override
+ {
+ static constexpr auto small =
+ sizeof(*this) <= BufferSize;
+ if(small)
+ return ::new(dest) impl2(*this);
+ return new impl2(*this);
+ }
+
+ result
+ first(
+ char const*& it,
+ char const* end)
+ const noexcept override
+ {
+ return grammar::parse(it, end,
+ urls::detail::empty_value<
+ R0,0>::get());
+ }
+
+ result
+ next(
+ char const*& it,
+ char const* end)
+ const noexcept override
+ {
+ return grammar::parse(it, end,
+ urls::detail::empty_value<
+ R1,1>::get());
+ }
+};
+
//------------------------------------------------
//
// iterator
@@ -114,12 +266,7 @@ public:
r_->s_.size();
rv_ = r_->pr_->next(p_, end);
if(rv_.has_error())
- {
- BOOST_ASSERT(
- rv_.error() ==
- error::end);
p_ = nullptr;
- }
return *this;
}
@@ -148,44 +295,103 @@ private:
r_->s_.size();
rv_ = r_->pr_->first(p_, end);
if(rv_.has_error())
- {
- BOOST_ASSERT(
- rv_.error() ==
- error::end);
p_ = nullptr;
- }
}
constexpr
iterator(
range const& r,
int) noexcept
- : p_(nullptr)
- , r_(&r)
+ : r_(&r)
+ , p_(nullptr)
{
}
};
//------------------------------------------------
+template
+template
+range::
+range(
+ string_view s,
+ std::size_t n,
+ R const& next)
+ : s_(s)
+ , n_(n)
+{
+ using U = impl1;
+
+ static constexpr auto small =
+ sizeof(U) <= BufferSize;
+ if(small)
+ {
+ pr_ = ::new(reinterpret_cast<
+ void*>(buf_)) U(next);
+ }
+ else
+ {
+ pr_ = new U(next);
+ }
+}
+
+//------------------------------------------------
+
+template
+template<
+ class R0, class R1>
+range::
+range(
+ string_view s,
+ std::size_t n,
+ R0 const& first,
+ R1 const& next)
+ : s_(s)
+ , n_(n)
+{
+ using U = impl2;
+
+ static constexpr auto small =
+ sizeof(U) <= BufferSize;
+ if(small)
+ {
+ pr_ = ::new(reinterpret_cast<
+ void*>(buf_)) U(first, next);
+ }
+ else
+ {
+ pr_ = new U(first, next);
+ }
+}
+
+//------------------------------------------------
+
template
range::
~range()
{
if(pr_)
+ pr_->destroy();
+}
+
+template
+range::
+range(
+ range&& other) noexcept
+ : s_(other.s_)
+ , n_(other.n_)
+{
+ if(other.pr_)
{
- if(pr_ == reinterpret_cast<
- any_rule*>(buf_))
- pr_->~any_rule();
- else
- pr_->destroy();
+ pr_ = other.pr_->move(buf_);
+ other.pr_ = nullptr;
}
}
template
range::
range(
- range const& other) noexcept
+ range const& other)
: s_(other.s_)
, n_(other.n_)
{
@@ -193,6 +399,51 @@ range(
pr_ = other.pr_->copy(buf_);
}
+template
+auto
+range::
+operator=(
+ range&& other) noexcept ->
+ range&
+{
+ if(pr_)
+ pr_->destroy();
+ if(other.pr_)
+ {
+ s_ = other.s_;
+ n_ = other.n_;
+ pr_ = other.pr_->move(buf_);
+ other.s_ = {};
+ other.n_ = 0;
+ other.pr_ = nullptr;
+ }
+ else
+ {
+ s_ = {};
+ n_ = 0;
+ pr_ = nullptr;
+ }
+
+ return *this;
+}
+
+template
+auto
+range::
+operator=(
+ range const& other) ->
+ range&
+{
+ range tmp(other);
+ if(pr_)
+ pr_->destroy();
+ s_ = tmp.s_;
+ n_ = tmp.n_;
+ pr_ = tmp.pr_;
+ tmp.pr_ = nullptr;
+ return *this;
+}
+
template
auto
range::
@@ -213,142 +464,6 @@ end() const noexcept ->
//------------------------------------------------
-template
-template
-range::
-range(
- string_view s,
- std::size_t n,
- R const& next)
- : s_(s)
- , n_(n)
-{
- struct impl : any_rule
- {
- explicit
- impl(
- R const& next) noexcept
- : next_(next)
- {
- }
-
- private:
- R const next_;
-
- void
- destroy() const noexcept override
- {
- delete this;
- }
-
- any_rule const*
- copy(void* dest)
- const noexcept override
- {
- static constexpr auto small =
- sizeof(*this) <= BufferSize;
- if(small)
- return ::new(dest) impl(*this);
- return new impl(*this);
- }
-
- result
- first(
- char const*& it,
- char const* end)
- const noexcept override
- {
- return grammar::parse(
- it, end, next_);
- }
-
- result
- next(
- char const*& it,
- char const* end)
- const noexcept override
- {
- return grammar::parse(
- it, end, next_);
- }
- };
-
- pr_ = ::new(reinterpret_cast<
- void*>(buf_)) impl(next);
-}
-
-//------------------------------------------------
-
-template
-template<
- class R0, class R1>
-range::
-range(
- string_view s,
- std::size_t n,
- R0 const& first,
- R1 const& next)
- : s_(s)
- , n_(n)
-{
- struct impl : any_rule
- {
- impl(
- R0 const& first,
- R1 const& next) noexcept
- : first_(first)
- , next_(next)
- {
- }
-
- private:
- R0 const first_;
- R1 const next_;
-
- void
- destroy() const noexcept override
- {
- delete this;
- }
-
- any_rule const*
- copy(void* dest)
- const noexcept override
- {
- static constexpr auto small =
- sizeof(*this) <= BufferSize;
- if(small)
- return ::new(dest) impl(*this);
- return new impl(*this);
- }
-
- result
- first(
- char const*& it,
- char const* end)
- const noexcept override
- {
- return grammar::parse(
- it, end, first_);
- }
-
- result
- next(
- char const*& it,
- char const* end)
- const noexcept override
- {
- return grammar::parse(
- it, end, next_);
- }
- };
-
- pr_ = ::new(reinterpret_cast<
- void*>(buf_)) impl(first, next);
-}
-
-//------------------------------------------------
-
template
auto
range_rule_t::
@@ -361,12 +476,16 @@ parse(
std::size_t n = 0;
auto const it0 = it;
+ auto it1 = it;
auto rv = (grammar::parse)(
it, end, next_);
if(rv.has_error())
{
if(rv.error() != error::end)
- return rv.error();
+ {
+ // rewind unless error::end
+ it = it1;
+ }
if(n < N_)
{
// too few
@@ -382,12 +501,16 @@ parse(
for(;;)
{
++n;
+ it1 = it;
rv = (grammar::parse)(
it, end, next_);
if(rv.has_error())
{
if(rv.error() != error::end)
- return rv.error();
+ {
+ // rewind unless error::end
+ it = it1;
+ }
break;
}
if(n > M_)
@@ -418,12 +541,16 @@ parse(
std::size_t n = 0;
auto const it0 = it;
+ auto it1 = it;
auto rv = (grammar::parse)(
it, end, first_);
if(rv.has_error())
{
if(rv.error() != error::end)
- return rv.error();
+ {
+ // rewind unless error::end
+ it = it1;
+ }
if(n < N_)
{
// too few
@@ -439,12 +566,16 @@ parse(
for(;;)
{
++n;
+ it1 = it;
rv = (grammar::parse)(
it, end, next_);
if(rv.has_error())
{
if(rv.error() != error::end)
- return rv.error();
+ {
+ // rewind unless error::end
+ it = it1;
+ }
break;
}
if(n > M_)
diff --git a/include/boost/url/grammar/impl/sequence_rule.hpp b/include/boost/url/grammar/impl/sequence_rule.hpp
index 6f932769..af08c4a6 100644
--- a/include/boost/url/grammar/impl/sequence_rule.hpp
+++ b/include/boost/url/grammar/impl/sequence_rule.hpp
@@ -272,7 +272,7 @@ parse(
result
{
detail::parse_sequence<
- IsList, R0, Rn...> t(rn_);
+ IsList, R0, Rn...> t(this->get());
t.apply(it, end);
return t.make_result();
}
diff --git a/include/boost/url/grammar/impl/variant_rule.hpp b/include/boost/url/grammar/impl/variant_rule.hpp
index e7a2195e..0a0d9e4e 100644
--- a/include/boost/url/grammar/impl/variant_rule.hpp
+++ b/include/boost/url/grammar/impl/variant_rule.hpp
@@ -89,7 +89,7 @@ parse(
result
{
return detail::parse_variant(
- it, end, rn_,
+ it, end, this->get(),
std::integral_constant<
std::size_t, 0>{},
std::true_type{});
diff --git a/include/boost/url/grammar/not_empty_rule.hpp b/include/boost/url/grammar/not_empty_rule.hpp
index 4d04c4cd..a6d6de97 100644
--- a/include/boost/url/grammar/not_empty_rule.hpp
+++ b/include/boost/url/grammar/not_empty_rule.hpp
@@ -12,6 +12,7 @@
#include
#include
+#include
#include
namespace boost {
@@ -47,6 +48,7 @@ not_empty_rule( Rule r );
#else
template
struct not_empty_rule_t
+ : urls::detail::empty_value
{
using value_type =
typename R::value_type;
@@ -69,11 +71,10 @@ private:
constexpr
not_empty_rule_t(
R const& r) noexcept
- : r_(r)
+ : urls::detail::empty_value(
+ urls::detail::empty_init, r)
{
}
-
- R const r_;
};
template
diff --git a/include/boost/url/grammar/optional_rule.hpp b/include/boost/url/grammar/optional_rule.hpp
index 11d27669..82cdad93 100644
--- a/include/boost/url/grammar/optional_rule.hpp
+++ b/include/boost/url/grammar/optional_rule.hpp
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
namespace boost {
@@ -57,6 +58,7 @@ optional_rule( Rule r ) noexcept;
#else
template
class optional_rule_t
+ : private urls::detail::empty_value
{
public:
using value_type = optional<
@@ -69,7 +71,7 @@ public:
result
{
auto const it0 = it;
- auto rv = r_.parse(it, end);
+ auto rv = this->get().parse(it, end);
if(! rv.has_error())
return value_type(*rv);
it = it0;
@@ -88,11 +90,10 @@ private:
constexpr
optional_rule_t(
Rule const& r) noexcept
- : r_(r)
+ : urls::detail::empty_value(
+ urls::detail::empty_init, r)
{
}
-
- Rule const r_;
};
template
diff --git a/include/boost/url/grammar/range_rule.hpp b/include/boost/url/grammar/range_rule.hpp
index 3ae7e017..0b8ee1e2 100644
--- a/include/boost/url/grammar/range_rule.hpp
+++ b/include/boost/url/grammar/range_rule.hpp
@@ -54,11 +54,35 @@ class range
struct any_rule;
+ template
+ struct impl1;
+
+ template
+ struct impl2;
+
string_view s_;
std::size_t n_ = 0;
char buf_[BufferSize];
any_rule const* pr_ = nullptr;
+ template<
+ class R0, class R1>
+ friend struct range_rule_t;
+
+ template
+ range(
+ string_view s,
+ std::size_t n,
+ R const& r);
+
+ template<
+ class R0, class R1>
+ range(
+ string_view s,
+ std::size_t n,
+ R0 const& first,
+ R1 const& next);
+
public:
/** The type of each element of the range
*/
@@ -96,12 +120,19 @@ public:
*/
~range();
-#ifndef BOOST_URL_DOCS
-#if BOOST_WORKAROUND( BOOST_GCC_VERSION, < 50000 ) || \
- BOOST_WORKAROUND( BOOST_CLANG_VERSION, < 40000 )
+ /** Constructor
+
+ Default-constructed ranges have
+ zero elements.
+ */
range() noexcept = default;
-#endif
-#endif
+
+ /** Constructor
+
+ After construction, the moved-from
+ object will be the empty range.
+ */
+ range(range&&) noexcept;
/** Constructor
@@ -111,7 +142,17 @@ public:
for ensuring that the lifetime of the
buffer extends until no longer in use.
*/
- range(range const&) noexcept;
+ range(range const&);
+
+ /** Assignment
+ */
+ range&
+ operator=(range const&);
+
+ /** Assignment
+ */
+ range&
+ operator=(range&&) noexcept;
/** Return an iterator to the beginning
*/
@@ -144,25 +185,6 @@ public:
{
return n_ == 0;
}
-
-private:
- template
- range(
- string_view s,
- std::size_t n,
- R const& r);
-
- template<
- class R0, class R1>
- range(
- string_view s,
- std::size_t n,
- R0 const& first,
- R1 const& next);
-
- template<
- class R0, class R1>
- friend struct range_rule_t;
};
//------------------------------------------------
@@ -185,7 +207,7 @@ struct range_rule_t;
@par BNF
@code
- range = *rule
+ range = *next
@endcode
@par Specification
@@ -276,8 +298,8 @@ range_rule(
@par BNF
@code
- range = <1>*<1>rule1
- / rule1 *rule2
+ range = <1>*<1>first
+ / first *next
@endcode
@par Specification
diff --git a/include/boost/url/grammar/sequence_rule.hpp b/include/boost/url/grammar/sequence_rule.hpp
index e3fd3e59..c66759f9 100644
--- a/include/boost/url/grammar/sequence_rule.hpp
+++ b/include/boost/url/grammar/sequence_rule.hpp
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#include
namespace boost {
@@ -69,6 +70,8 @@ template<
class R0,
class... Rn>
class sequence_rule_t
+ : urls::detail::empty_value<
+ detail::tuple>
{
using T = mp11::mp_remove<
std::tuple<
@@ -104,11 +107,12 @@ private:
sequence_rule_t(
R0 const& r0,
Rn const&... rn) noexcept
- : rn_(r0, rn...)
+ : urls::detail::empty_value<
+ detail::tuple>(
+ urls::detail::empty_init,
+ r0, rn...)
{
}
-
- detail::tuple const rn_;
};
template<
diff --git a/include/boost/url/grammar/variant_rule.hpp b/include/boost/url/grammar/variant_rule.hpp
index df54782a..9b82b479 100644
--- a/include/boost/url/grammar/variant_rule.hpp
+++ b/include/boost/url/grammar/variant_rule.hpp
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
namespace boost {
@@ -69,6 +70,8 @@ variant_rule( Rules... rn ) noexcept;
template<
class R0, class... Rn>
class variant_rule_t
+ : private urls::detail::empty_value<
+ detail::tuple>
{
public:
using value_type = variant<
@@ -97,11 +100,12 @@ private:
variant_rule_t(
R0 const& r0,
Rn const&... rn) noexcept
- : rn_(r0, rn...)
+ : urls::detail::empty_value<
+ detail::tuple>(
+ urls::detail::empty_init,
+ r0, rn...)
{
}
-
- detail::tuple rn_;
};
template<
diff --git a/include/boost/url/impl/segments_encoded_view.hpp b/include/boost/url/impl/segments_encoded_view.hpp
index f4a1fd68..9b4d2cc8 100644
--- a/include/boost/url/impl/segments_encoded_view.hpp
+++ b/include/boost/url/impl/segments_encoded_view.hpp
@@ -13,7 +13,6 @@
#include
#include
-#include
#include
#include
diff --git a/include/boost/url/impl/segments_encoded_view.ipp b/include/boost/url/impl/segments_encoded_view.ipp
index fda7b3c1..c8b6b097 100644
--- a/include/boost/url/impl/segments_encoded_view.ipp
+++ b/include/boost/url/impl/segments_encoded_view.ipp
@@ -13,11 +13,11 @@
#include
#include
-#include
-#include
-#include
#include
#include
+#include
+#include
+#include
#include
namespace boost {
diff --git a/include/boost/url/impl/segments_view.ipp b/include/boost/url/impl/segments_view.ipp
index d45ee9b8..056d6c21 100644
--- a/include/boost/url/impl/segments_view.ipp
+++ b/include/boost/url/impl/segments_view.ipp
@@ -12,9 +12,6 @@
#define BOOST_URL_IMPL_SEGMENTS_VIEW_IPP
#include
-#include
-#include
-#include
#include
namespace boost {
diff --git a/include/boost/url/impl/url.ipp b/include/boost/url/impl/url.ipp
index af31d765..235148b1 100644
--- a/include/boost/url/impl/url.ipp
+++ b/include/boost/url/impl/url.ipp
@@ -20,7 +20,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/include/boost/url/impl/url_view.ipp b/include/boost/url/impl/url_view.ipp
index e0650039..a8ead099 100644
--- a/include/boost/url/impl/url_view.ipp
+++ b/include/boost/url/impl/url_view.ipp
@@ -18,7 +18,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/include/boost/url/rfc/detail/fragment_rule.hpp b/include/boost/url/rfc/detail/fragment_rule.hpp
index ae6bd2ed..e2dba168 100644
--- a/include/boost/url/rfc/detail/fragment_rule.hpp
+++ b/include/boost/url/rfc/detail/fragment_rule.hpp
@@ -33,7 +33,7 @@ namespace detail {
*/
constexpr auto fragment_rule =
pct_encoded_rule(
- pchars + '/' + '?');
+ &detail::fragment_chars);
/** Rule for fragment-part
diff --git a/include/boost/url/rfc/detail/hier_part_rule.hpp b/include/boost/url/rfc/detail/hier_part_rule.hpp
index dc1c7173..e0f76601 100644
--- a/include/boost/url/rfc/detail/hier_part_rule.hpp
+++ b/include/boost/url/rfc/detail/hier_part_rule.hpp
@@ -11,9 +11,9 @@
#define BOOST_URL_RFC_DETAIL_HIER_PART_RULE_HPP
#include
-#include
+#include
#include
-#include
+#include
namespace boost {
namespace urls {
@@ -39,7 +39,9 @@ struct hier_part_rule_t
{
bool has_authority = false;
authority_view authority;
- parsed_path path;
+
+ // VFALCO This doesn't belong here
+ grammar::range path;
};
BOOST_URL_DECL
diff --git a/include/boost/url/rfc/detail/impl/hier_part_rule.ipp b/include/boost/url/rfc/detail/impl/hier_part_rule.ipp
index f37038dd..a3121a7c 100644
--- a/include/boost/url/rfc/detail/impl/hier_part_rule.ipp
+++ b/include/boost/url/rfc/detail/impl/hier_part_rule.ipp
@@ -11,8 +11,8 @@
#define BOOST_URL_RFC_DETAIL_IMPL_HIER_PART_RULE_IPP
#include
+#include
#include
-#include
#include
namespace boost {
@@ -43,9 +43,7 @@ parse(
path_rootless_rule);
if(rv.has_value())
{
- auto const& v = *rv;
- t.path.path = v.string();
- t.path.count = v.size();
+ t.path = std::move(*rv);
return t;
}
it = it0;
@@ -62,9 +60,7 @@ parse(
path_absolute_rule);
if(! rv)
return rv.error();
- auto const& p = *rv;
- t.path.path = p.string();
- t.path.count = p.size();
+ t.path = std::move(*rv);
t.has_authority = false;
return t;
}
@@ -86,10 +82,7 @@ parse(
it, end, path_abempty_rule);
if(! rv)
return rv.error();
-
- auto const& v = *rv;
- t.path.path = v.string();
- t.path.count = v.size();
+ t.path = std::move(*rv);
t.has_authority = true;
}
diff --git a/include/boost/url/rfc/detail/impl/path_rules.ipp b/include/boost/url/rfc/detail/impl/path_rules.ipp
new file mode 100644
index 00000000..f12ccca6
--- /dev/null
+++ b/include/boost/url/rfc/detail/impl/path_rules.ipp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/CPPAlliance/url
+//
+
+#ifndef BOOST_URL_RFC_DETAIL_IMPL_PATH_RULES_IPP
+#define BOOST_URL_RFC_DETAIL_IMPL_PATH_RULES_IPP
+
+#include
+#include
+#include
+#include
+#include
+
+namespace boost {
+namespace urls {
+namespace detail {
+
+auto
+segment_ns_rule_t::
+parse(
+ char const*& it,
+ char const* end) const noexcept ->
+ result
+{
+ if(it == end)
+ return value_type{};
+ if(*it == '/')
+ return grammar::error::syntax;
+ auto rv = grammar::parse(
+ it, end, segment_rule);
+ if(rv.has_error())
+ return rv.error();
+ return *rv;
+}
+
+} // detail
+} // urls
+} // boost
+
+#endif
diff --git a/include/boost/url/rfc/detail/impl/relative_part_rule.ipp b/include/boost/url/rfc/detail/impl/relative_part_rule.ipp
index 1f0cc859..b64352a0 100644
--- a/include/boost/url/rfc/detail/impl/relative_part_rule.ipp
+++ b/include/boost/url/rfc/detail/impl/relative_part_rule.ipp
@@ -11,7 +11,7 @@
#define BOOST_URL_RFC_DETAIL_IMPL_RELATIVE_PART_RULE_IPP
#include
-#include
+#include
#include
namespace boost {
@@ -42,9 +42,7 @@ parse(
if(rv.has_value())
{
// path-noscheme
- auto const& v = *rv;
- t.path.path = v.string();
- t.path.count = v.size();
+ t.path = std::move(*rv);
t.has_authority = false;
return t;
}
@@ -60,9 +58,7 @@ parse(
auto rv = grammar::parse(
it, end,
path_absolute_rule);
- auto const& v = *rv;
- t.path.path = v.string();
- t.path.count = v.size();
+ t.path = std::move(*rv);
t.has_authority = false;
return t;
}
@@ -81,9 +77,7 @@ parse(
it, end, path_abempty_rule);
if(! rv)
return rv.error();
- auto const& v = *rv;
- t.path.path = v.string();
- t.path.count = v.size();
+ t.path = std::move(*rv);
t.has_authority = true;
}
return t;
diff --git a/include/boost/url/rfc/detail/impl/userinfo_rule.ipp b/include/boost/url/rfc/detail/impl/userinfo_rule.ipp
index 507c8b7f..2afc2dc6 100644
--- a/include/boost/url/rfc/detail/impl/userinfo_rule.ipp
+++ b/include/boost/url/rfc/detail/impl/userinfo_rule.ipp
@@ -38,7 +38,7 @@ parse(
// user
auto rv = grammar::parse(
it, end,
- pct_encoded_rule(uchars));
+ pct_encoded_rule(&uchars));
if(! rv)
return rv.error();
t.user = *rv;
@@ -56,7 +56,7 @@ parse(
// pass
rv = grammar::parse(
it, end,
- pct_encoded_rule(pwchars));
+ pct_encoded_rule(&pwchars));
if(! rv)
return rv.error();
diff --git a/include/boost/url/rfc/detail/path_increment.hpp b/include/boost/url/rfc/detail/path_increment.hpp
deleted file mode 100644
index c3bffeb3..00000000
--- a/include/boost/url/rfc/detail/path_increment.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// Official repository: https://github.com/CPPAlliance/url
-//
-
-#ifndef BOOST_URL_RFC_DETAIL_PATH_INCREMENT_IPP
-#define BOOST_URL_RFC_DETAIL_PATH_INCREMENT_IPP
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace boost {
-namespace urls {
-namespace detail {
-
-struct path_increment_t
-{
- using value_type = pct_encoded_view;
-
- result
- parse(
- char const *&it,
- char const* end) const noexcept
- {
- auto it0 = it;
- auto rv = grammar::parse(
- it, end,
- grammar::sequence_rule(
- grammar::char_rule('/'),
- segment_rule));
- if(rv.has_value())
- return *rv;
- it = it0;
- return BOOST_URL_ERR(
- grammar::error::end);
- }
-};
-
-constexpr path_increment_t path_increment{};
-
-} // detail
-} // urls
-} // boost
-
-#endif
diff --git a/include/boost/url/rfc/detail/segment_rule.hpp b/include/boost/url/rfc/detail/path_rules.hpp
similarity index 61%
rename from include/boost/url/rfc/detail/segment_rule.hpp
rename to include/boost/url/rfc/detail/path_rules.hpp
index 9187c76a..d27bab51 100644
--- a/include/boost/url/rfc/detail/segment_rule.hpp
+++ b/include/boost/url/rfc/detail/path_rules.hpp
@@ -7,10 +7,11 @@
// Official repository: https://github.com/CPPAlliance/url
//
-#ifndef BOOST_URL_RFC_DETAIL_SEGMENT_RULE_HPP
-#define BOOST_URL_RFC_DETAIL_SEGMENT_RULE_HPP
+#ifndef BOOST_URL_RFC_DETAIL_PATH_RULES_HPP
+#define BOOST_URL_RFC_DETAIL_PATH_RULES_HPP
-#include
+#include
+#include
#include
#include
@@ -30,16 +31,10 @@ namespace detail {
>3.3. Path (rfc3986)
@see
- @ref path_abempty_rule,
- @ref path_absolute_rule,
- @ref path_noscheme_rule,
- @ref path_rootless_rule,
- @ref pchars,
- @ref segment_nz_rule,
- @ref segment_nz_nc_rule
+ @ref parse.
*/
constexpr auto segment_rule =
- pct_encoded_rule(pchars);
+ pct_encoded_rule(&pchars);
//------------------------------------------------
@@ -65,7 +60,7 @@ constexpr auto segment_rule =
*/
constexpr auto segment_nz_rule =
grammar::not_empty_rule(
- pct_encoded_rule(pchars));
+ pct_encoded_rule(&pchars));
//------------------------------------------------
@@ -82,20 +77,52 @@ constexpr auto segment_nz_rule =
>3.3. Path (rfc3986)
@see
- @ref path_abempty_rule,
- @ref path_absolute_rule,
- @ref path_noscheme_rule,
- @ref path_rootless_rule,
- @ref pchars,
- @ref segment_rule,
- @ref segment_nz_rule,
- @ref sub_delim_chars,
- @ref unreserved_chars
+ @ref parse.
*/
constexpr auto segment_nz_nc_rule =
grammar::not_empty_rule(
pct_encoded_rule(pchars - ':'));
+//------------------------------------------------
+
+/** Rule for slash-segment
+
+ @par BNF
+ @code
+ slash-segment = "/" segment
+
+ @endcode
+*/
+constexpr auto slash_segment_rule =
+ grammar::sequence_rule(
+ grammar::char_rule('/'),
+ pct_encoded_rule(&pchars));
+
+//------------------------------------------------
+
+// VFALCO This is an alternate rule not found
+// in the rfc3986, to reformulate the rfc path
+// BNFs into something the range_rule can use.
+
+/** Rule for segment-ns
+*/
+#ifdef BOOST_URL_DOCS
+constexpr __implementation_defined__ segment_ns_rule;
+#else
+struct segment_ns_rule_t
+{
+ using value_type = pct_encoded_view;
+
+ BOOST_URL_DECL
+ result
+ parse(
+ char const*& it,
+ char const* end) const noexcept;
+};
+
+constexpr segment_ns_rule_t segment_ns_rule{};
+#endif
+
} // detail
} // urls
} // boost
diff --git a/include/boost/url/rfc/detail/relative_part_rule.hpp b/include/boost/url/rfc/detail/relative_part_rule.hpp
index 6c1ab722..f43a558b 100644
--- a/include/boost/url/rfc/detail/relative_part_rule.hpp
+++ b/include/boost/url/rfc/detail/relative_part_rule.hpp
@@ -12,8 +12,9 @@
#include
#include
+#include
#include
-#include
+#include
namespace boost {
namespace urls {
@@ -45,7 +46,7 @@ struct relative_part_rule_t
{
bool has_authority = false;
decltype(authority_rule)::value_type authority;
- parsed_path path;
+ grammar::range path;
};
auto
diff --git a/include/boost/url/rfc/impl/absolute_uri_rule.ipp b/include/boost/url/rfc/impl/absolute_uri_rule.ipp
index cd0596bb..1223f371 100644
--- a/include/boost/url/rfc/impl/absolute_uri_rule.ipp
+++ b/include/boost/url/rfc/impl/absolute_uri_rule.ipp
@@ -53,7 +53,9 @@ parse(
return rv.error();
if(rv->has_authority)
u.apply_authority(rv->authority);
- u.apply_path(rv->path);
+ u.apply_path(
+ rv->path.string(),
+ rv->path.size());
}
// [ "?" query ]
diff --git a/include/boost/url/rfc/impl/paths_rule.ipp b/include/boost/url/rfc/impl/paths_rule.ipp
deleted file mode 100644
index 52c1e9b1..00000000
--- a/include/boost/url/rfc/impl/paths_rule.ipp
+++ /dev/null
@@ -1,122 +0,0 @@
-//
-// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// Official repository: https://github.com/CPPAlliance/url
-//
-
-#ifndef BOOST_URL_RFC_IMPL_PATHS_RULE_IPP
-#define BOOST_URL_RFC_IMPL_PATHS_RULE_IPP
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace boost {
-namespace urls {
-
-auto
-path_abempty_rule_t::
-parse(
- char const*& it,
- char const* end
- ) const noexcept ->
- result
-{
- return grammar::parse(
- it, end, grammar::range_rule(
- detail::path_increment));
-}
-
-//------------------------------------------------
-
-auto
-path_absolute_rule_t::
-parse(
- char const*& it,
- char const* end
- ) const noexcept ->
- result
-{
- struct begin
- {
- using value_type = pct_encoded_view;
-
- result
- parse(
- char const *&it,
- char const* end) const noexcept
- {
- if(it == end)
- {
- // expected '/'
- return error::missing_path_segment;
- }
- if(*it != '/')
- {
- // expected '/'
- return error::missing_path_separator;
- }
- ++it;
- if(it == end)
- return pct_encoded_view{};
- if(*it == '/')
- {
- // can't begin with "//"
- return error::empty_path_segment;
- }
- return grammar::parse(
- it, end, detail::segment_rule);
- }
- };
-
- return grammar::parse(
- it, end, grammar::range_rule(
- begin{}, detail::path_increment));
-}
-
-//------------------------------------------------
-
-auto
-path_noscheme_rule_t::
-parse(
- char const*& it,
- char const* end
- ) const noexcept ->
- result
-{
- return grammar::parse(
- it, end,
- grammar::range_rule(
- detail::segment_nz_nc_rule,
- detail::path_increment));
-}
-
-//------------------------------------------------
-
-auto
-path_rootless_rule_t::
-parse(
- char const*& it,
- char const* end
- ) const noexcept ->
- result
-{
- return grammar::parse(
- it, end,
- grammar::range_rule(
- detail::segment_nz_rule,
- detail::path_increment));
-}
-
-} // urls
-} // boost
-
-#endif
diff --git a/include/boost/url/rfc/impl/pct_encoded_rule.hpp b/include/boost/url/rfc/impl/pct_encoded_rule.hpp
index c61995c7..efe7429c 100644
--- a/include/boost/url/rfc/impl/pct_encoded_rule.hpp
+++ b/include/boost/url/rfc/impl/pct_encoded_rule.hpp
@@ -16,13 +16,15 @@
namespace boost {
namespace urls {
+namespace detail {
+
template
auto
-pct_encoded_rule_t::
-parse(
+parse_pct_encoded(
char const*& it,
- char const* end) const noexcept ->
- result
+ char const* end,
+ CharSet const& cs) noexcept ->
+ result
{
auto const start = it;
// VFALCO TODO
@@ -32,7 +34,7 @@ parse(
skip:
it0 = it;
it = grammar::find_if_not(
- it0, end, cs_);
+ it0, end, cs);
n += it - it0;
if(it == end)
goto finish;
@@ -71,10 +73,38 @@ skip:
goto skip;
}
finish:
- return detail::access::construct(
+ return access::construct(
string_view(start, it - start), n);
}
+} // detail
+
+//------------------------------------------------
+
+template
+auto
+pct_encoded_rule_t::
+parse(
+ char const*& it,
+ char const* end) const noexcept ->
+ result
+{
+ return detail::parse_pct_encoded(
+ it, end, this->get());
+}
+
+template
+auto
+pct_encoded_ref_rule_t::
+parse(
+ char const*& it,
+ char const* end) const noexcept ->
+ result
+{
+ return detail::parse_pct_encoded(
+ it, end, *cs_);
+}
+
} // urls
} // boost
diff --git a/include/boost/url/rfc/impl/query_rule.ipp b/include/boost/url/rfc/impl/query_rule.ipp
index 94770a77..9c26ccde 100644
--- a/include/boost/url/rfc/impl/query_rule.ipp
+++ b/include/boost/url/rfc/impl/query_rule.ipp
@@ -56,7 +56,7 @@ struct query_param_rule_t
// key
{
auto rv = grammar::parse(it, end,
- pct_encoded_rule(detail::key_chars));
+ pct_encoded_rule(&detail::key_chars));
if(! rv)
return rv.error();
t.key = *rv;
@@ -78,7 +78,7 @@ struct query_param_rule_t
// value
{
auto rv = grammar::parse(it, end,
- pct_encoded_rule(detail::value_chars));
+ pct_encoded_rule(&detail::value_chars));
if(! rv)
return rv.error();
t.value = *rv;
@@ -115,10 +115,7 @@ parse(
it, end,
grammar::char_rule('&'));
if(! rv)
- {
- // end of list
- return grammar::error::end;
- }
+ return rv.error();
}
return grammar::parse(it, end,
diff --git a/include/boost/url/rfc/impl/relative_ref_rule.ipp b/include/boost/url/rfc/impl/relative_ref_rule.ipp
index 7b146153..3d66f783 100644
--- a/include/boost/url/rfc/impl/relative_ref_rule.ipp
+++ b/include/boost/url/rfc/impl/relative_ref_rule.ipp
@@ -42,7 +42,9 @@ parse(
return rv.error();
if(rv->has_authority)
u.apply_authority(rv->authority);
- u.apply_path(rv->path);
+ u.apply_path(
+ rv->path.string(),
+ rv->path.size());
}
// [ "?" query ]
diff --git a/include/boost/url/rfc/impl/uri_rule.ipp b/include/boost/url/rfc/impl/uri_rule.ipp
index 6e483b7e..b79aaba3 100644
--- a/include/boost/url/rfc/impl/uri_rule.ipp
+++ b/include/boost/url/rfc/impl/uri_rule.ipp
@@ -55,7 +55,9 @@ parse(
return rv.error();
if(rv->has_authority)
u.apply_authority(rv->authority);
- u.apply_path(rv->path);
+ u.apply_path(
+ rv->path.string(),
+ rv->path.size());
}
// [ "?" query ]
diff --git a/include/boost/url/rfc/paths_rule.hpp b/include/boost/url/rfc/path_rules.hpp
similarity index 60%
rename from include/boost/url/rfc/paths_rule.hpp
rename to include/boost/url/rfc/path_rules.hpp
index 4a9ed55b..35dda748 100644
--- a/include/boost/url/rfc/paths_rule.hpp
+++ b/include/boost/url/rfc/path_rules.hpp
@@ -7,32 +7,23 @@
// Official repository: https://github.com/CPPAlliance/url
//
-#ifndef BOOST_URL_RFC_PATHS_RULE_HPP
-#define BOOST_URL_RFC_PATHS_RULE_HPP
+#ifndef BOOST_URL_RFC_PATH_RULES_HPP
+#define BOOST_URL_RFC_PATH_RULES_HPP
#include
#include
+#include