// // Copyright (c) 2022 Alan de Freitas (alandefreitas@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/boostorg/url // #ifndef BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP #define BOOST_URL_IMPL_PCT_ENCODED_VIEW_HPP #include #include namespace boost { namespace urls { class decode_view::iterator { char const* begin_ = nullptr; char const* pos_ = nullptr; bool space_as_plus_ = true; friend decode_view; iterator( char const* str, bool space_as_plus) noexcept : begin_(str) , pos_(str) , space_as_plus_( space_as_plus) { } // end ctor iterator( char const* str, size_type n, bool space_as_plus) noexcept : begin_(str) , pos_(str + n) , space_as_plus_(space_as_plus) { } public: using value_type = char; using reference = char; using pointer = void const*; using const_reference = char; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using iterator_category = std::bidirectional_iterator_tag; iterator() = default; iterator(iterator const&) = default; iterator& operator=(iterator const&) = default; BOOST_URL_DECL reference operator*() const noexcept; iterator& operator++() noexcept { BOOST_ASSERT(pos_ != nullptr); if (*pos_ != '%') ++pos_; else pos_ += 3; return *this; } iterator& operator--() noexcept { BOOST_ASSERT(pos_ != begin_); if (pos_ - begin_ < 3 || pos_[-3] != '%') --pos_; else pos_ -= 3; return *this; } iterator operator++(int) noexcept { auto tmp = *this; ++*this; return tmp; } iterator operator--(int) noexcept { auto tmp = *this; --*this; return tmp; } char const* base() { return pos_; } bool operator==( iterator const& other) const noexcept { return pos_ == other.pos_; } bool operator!=( iterator const& other) const noexcept { return !(*this == other); } }; //------------------------------------------------ inline auto decode_view:: begin() const noexcept -> const_iterator { return {p_, space_as_plus_}; } inline auto decode_view:: end() const noexcept -> const_iterator { return {p_, n_, space_as_plus_}; } inline auto decode_view:: front() const noexcept -> const_reference { BOOST_ASSERT( !empty() ); return *begin(); } inline auto decode_view:: back() const noexcept -> const_reference { BOOST_ASSERT( !empty() ); return *--end(); } namespace detail { template BOOST_CXX14_CONSTEXPR int decoded_strcmp(decode_view s0, T s1) { auto const n0 = s0.size(); auto const n1 = s1.size(); auto n = (std::min)(n0, n1); auto it0 = s0.begin(); auto it1 = s1.begin(); while (n--) { const char c0 = *it0++; const char c1 = *it1++; if (c0 == c1) continue; return 1 - 2 * (static_cast(c0) < static_cast(c1)); } return 1 - (n0 == n1) - 2 * (n0 < n1); } } // detail #if defined(BOOST_NO_CXX14_CONSTEXPR) inline #else BOOST_CXX14_CONSTEXPR #endif int decode_view:: compare(core::string_view other) const noexcept { return detail::decoded_strcmp(*this, other); } #if defined(BOOST_NO_CXX14_CONSTEXPR) inline #else BOOST_CXX14_CONSTEXPR #endif int decode_view:: compare(decode_view other) const noexcept { return detail::decoded_strcmp(*this, other); } } // urls } // boost #endif