diff --git a/include/boost/url.hpp b/include/boost/url.hpp index 934a26ba..fdb53405 100644 --- a/include/boost/url.hpp +++ b/include/boost/url.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/include/boost/url/bnf/parse.hpp b/include/boost/url/bnf/parse.hpp index 0000f99a..ba91256d 100644 --- a/include/boost/url/bnf/parse.hpp +++ b/include/boost/url/bnf/parse.hpp @@ -12,8 +12,8 @@ #include #include +#include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/impl/url_view.ipp b/include/boost/url/impl/url_view.ipp index 628b6fd4..08e0beae 100644 --- a/include/boost/url/impl/url_view.ipp +++ b/include/boost/url/impl/url_view.ipp @@ -56,15 +56,14 @@ encoded_origin() const noexcept // //---------------------------------------------------------- -string_view +optional url_view:: scheme() const noexcept { auto s = pt_.get( - detail::id_scheme, - s_); + detail::id_scheme, s_); if(s.empty()) - return s; + return boost::none; BOOST_ASSERT(s.back() == ':'); s.remove_suffix(1); // ':' return s; diff --git a/include/boost/url/optional.hpp b/include/boost/url/optional.hpp new file mode 100644 index 00000000..bc14b807 --- /dev/null +++ b/include/boost/url/optional.hpp @@ -0,0 +1,266 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/CPPAllinace/url +// + +#ifndef BOOST_URL_OPTIONAL_HPP +#define BOOST_URL_OPTIONAL_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace urls { + +/** A simplified C++11 optional +*/ +template +class optional +{ + union + { + T t_; + }; + + bool has_value_ = false; + +public: + using value_type = T; + + ~optional() + { + if(has_value_) + t_.~T(); + } + + optional() noexcept + { + } + + optional( + none_t) noexcept + : optional() + { + } + + optional( + optional const& t) noexcept + : has_value_(t.has_value()) + { + if(has_value) + ::new(&t_) T(*t); + } + + optional( + T const& t) noexcept + : t_(t) + , has_value_(true) + { + } + + T const* + operator->() const noexcept + { + BOOST_ASSERT( + has_value_); + return &t_; + } + + T* + operator->() noexcept + { + BOOST_ASSERT( + has_value_); + return &t_; + } + + T const& + operator*() const noexcept + { + BOOST_ASSERT( + has_value_); + return t_; + } + + T& + operator*() noexcept + { + BOOST_ASSERT( + has_value_); + return t_; + } + + T& + value() + { + if(! has_value_) + detail::throw_invalid_argument( + "empty optional", + BOOST_CURRENT_LOCATION); + return t_; + } + + T const& + value() const + { + if(! has_value_) + detail::throw_invalid_argument( + "empty optional", + BOOST_CURRENT_LOCATION); + return t_; + } + + explicit + operator bool() const noexcept + { + return has_value_; + } + + bool + has_value() const noexcept + { + return has_value_; + } + + void + reset() noexcept + { + if(has_value_) + { + t_.~T(); + has_value_ = false; + } + } + + template + T& + emplace(Args&&... args) noexcept + { + if(has_value_) + t_.~T(); + ::new(&t_) T(std::forward< + Args>(args)...); + has_value_ = true; + return t_; + } +}; + +//-------------------------------------- + +template +bool +operator==( + optional const& t, + optional const& u) noexcept +{ + if(! t.has_value()) + return ! u.has_value(); + if(! u.has_value()) + return false; + return *t == *u; +} + +template +bool +operator!=( + optional const& t, + optional const& u) noexcept +{ + return !(t == u); +} + +//-------------------------------------- + +template +bool +operator==( + optional const& t, + none_t) noexcept +{ + return ! t.has_value(); +} + +template +bool +operator!=( + optional const& t, + none_t) noexcept +{ + return t.has_value(); +} + +template +bool +operator==( + none_t, + optional const& t) noexcept +{ + return ! t.has_value(); +} + +template +bool +operator!=( + none_t, + optional const& t) noexcept +{ + return t.has_value(); +} + +//-------------------------------------- + +template +bool +operator==( + optional const& t, + U const& u) noexcept +{ + if(! t.has_value()) + return false; + return *t == u; +} + +template +bool +operator!=( + optional const& t, + U const& u) noexcept +{ + if(! t.has_value()) + return true; + return *t != u; +} + +template +bool +operator==( + T const& t, + optional const& u) noexcept +{ + if(! u.has_value()) + return false; + return t == *u; +} + +template +bool +operator!=( + T const& t, + optional const& u) noexcept +{ + if(! u.has_value()) + return true; + return t != *u; +} + +} // urls +} // boost + +#endif diff --git a/include/boost/url/rfc/absolute_uri_bnf.hpp b/include/boost/url/rfc/absolute_uri_bnf.hpp index b7c1ed5f..3eaaaf33 100644 --- a/include/boost/url/rfc/absolute_uri_bnf.hpp +++ b/include/boost/url/rfc/absolute_uri_bnf.hpp @@ -12,12 +12,12 @@ #include #include +#include #include #include #include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/authority_bnf.hpp b/include/boost/url/rfc/authority_bnf.hpp index 46e25c8b..8be97df3 100644 --- a/include/boost/url/rfc/authority_bnf.hpp +++ b/include/boost/url/rfc/authority_bnf.hpp @@ -12,10 +12,10 @@ #include #include +#include #include #include #include -#include #include #include diff --git a/include/boost/url/rfc/fragment_bnf.hpp b/include/boost/url/rfc/fragment_bnf.hpp index e1f0b1b1..b60facc0 100644 --- a/include/boost/url/rfc/fragment_bnf.hpp +++ b/include/boost/url/rfc/fragment_bnf.hpp @@ -12,8 +12,8 @@ #include #include +#include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/hier_part_bnf.hpp b/include/boost/url/rfc/hier_part_bnf.hpp index 7ce3d90e..eebb91e7 100644 --- a/include/boost/url/rfc/hier_part_bnf.hpp +++ b/include/boost/url/rfc/hier_part_bnf.hpp @@ -12,10 +12,10 @@ #include #include +#include #include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/port_bnf.hpp b/include/boost/url/rfc/port_bnf.hpp index b530e589..f3ae880c 100644 --- a/include/boost/url/rfc/port_bnf.hpp +++ b/include/boost/url/rfc/port_bnf.hpp @@ -12,8 +12,8 @@ #include #include +#include #include -#include #include namespace boost { diff --git a/include/boost/url/rfc/query_bnf.hpp b/include/boost/url/rfc/query_bnf.hpp index db83300e..abf4a20d 100644 --- a/include/boost/url/rfc/query_bnf.hpp +++ b/include/boost/url/rfc/query_bnf.hpp @@ -12,9 +12,9 @@ #include #include +#include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/relative_part_bnf.hpp b/include/boost/url/rfc/relative_part_bnf.hpp index 54377d4b..aa46ff78 100644 --- a/include/boost/url/rfc/relative_part_bnf.hpp +++ b/include/boost/url/rfc/relative_part_bnf.hpp @@ -12,10 +12,10 @@ #include #include +#include #include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/relative_ref_bnf.hpp b/include/boost/url/rfc/relative_ref_bnf.hpp index 6458e846..2624740c 100644 --- a/include/boost/url/rfc/relative_ref_bnf.hpp +++ b/include/boost/url/rfc/relative_ref_bnf.hpp @@ -12,12 +12,12 @@ #include #include +#include #include #include #include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/uri_bnf.hpp b/include/boost/url/rfc/uri_bnf.hpp index 66439e07..2c4c1934 100644 --- a/include/boost/url/rfc/uri_bnf.hpp +++ b/include/boost/url/rfc/uri_bnf.hpp @@ -12,12 +12,12 @@ #include #include +#include #include #include #include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/rfc/userinfo_bnf.hpp b/include/boost/url/rfc/userinfo_bnf.hpp index 2a2545ce..4aefed75 100644 --- a/include/boost/url/rfc/userinfo_bnf.hpp +++ b/include/boost/url/rfc/userinfo_bnf.hpp @@ -12,9 +12,9 @@ #include #include +#include #include #include -#include namespace boost { namespace urls { diff --git a/include/boost/url/url_view.hpp b/include/boost/url/url_view.hpp index 9bf7431f..173888eb 100644 --- a/include/boost/url/url_view.hpp +++ b/include/boost/url/url_view.hpp @@ -11,9 +11,9 @@ #define BOOST_URL_URL_VIEW_HPP #include +#include #include #include -#include #include #include #include @@ -48,27 +48,11 @@ public: @param s The string to construct from. */ + // VFALCO DEPRECATED BOOST_URL_DECL explicit url_view(string_view s); - /** Return the number of characters in the URL. - */ - std::size_t - size() const noexcept - { - return pt_.offset[ - detail::id_end]; - } - - /** Return a pointer to the characters in the URL. - */ - char const* - data() const noexcept - { - return s_; - } - //------------------------------------------------------ /** Return the complete serialized URL. @@ -92,7 +76,7 @@ public: /** Return the scheme. */ BOOST_URL_DECL - string_view + optional scheme() const noexcept; //------------------------------------------------------ @@ -101,6 +85,23 @@ public: // //------------------------------------------------------ + /* + VFALCO This can't work because authority + cannot be sanely percent-decoded + */ + /* + BOOST_URL_DECL + optional< + bnf::pct_encoded_str> + authority() const noexcept; + */ + + /* + BOOST_URL_DECL + optional + authority() const noexcept; + */ + /** Return true if an authority is present. This function returns diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 663896e3..9084271b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,7 @@ set(BOOST_URL_TESTS_FILES _detail_parse.cpp error.cpp host_type.cpp + optional.cpp sandbox.cpp scheme.cpp static_pool.cpp diff --git a/test/optional.cpp b/test/optional.cpp new file mode 100644 index 00000000..f6425f0e --- /dev/null +++ b/test/optional.cpp @@ -0,0 +1,31 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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 +// + +#include + +#include "test_suite.hpp" + +namespace boost { +namespace urls { + +class optional_test +{ +public: + void + run() + { + } +}; + +TEST_SUITE( + optional_test, + "boost.url.optional"); + +} // urls +} // boost