diff --git a/src/utf_view/tests/code_unit_view.t.cpp b/src/utf_view/tests/code_unit_view.t.cpp index 4f1a7f0..f8f5d26 100644 --- a/src/utf_view/tests/code_unit_view.t.cpp +++ b/src/utf_view/tests/code_unit_view.t.cpp @@ -65,6 +65,19 @@ static_assert( std::ranges::subrange, test_bidi_iterator>>>>); +static_assert( + std::random_access_iterator< + std::ranges::iterator_t< + as_char8_t_view< + std::ranges::subrange, + std::default_sentinel_t>>>>); +static_assert( + std::random_access_iterator< + std::ranges::sentinel_t< + as_char8_t_view< + std::ranges::subrange, + test_random_access_iterator>>>>); + // TODO: Comprehensive testing for `code_unit_view` constexpr bool smoke_test() { diff --git a/src/utf_view/tests/test_iterators.hpp b/src/utf_view/tests/test_iterators.hpp index 4d7597b..96c311a 100644 --- a/src/utf_view/tests/test_iterators.hpp +++ b/src/utf_view/tests/test_iterators.hpp @@ -245,6 +245,97 @@ test_bidi_iterator(std::initializer_list) -> test_bidi_iterator; static_assert(std::bidirectional_iterator>); +template +struct test_random_access_iterator { + static constexpr std::initializer_list empty{}; + + using value_type = CharT; + using reference_type = CharT const&; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::random_access_iterator_tag; + constexpr test_random_access_iterator() + : begin{empty.begin()}, + end{empty.end()} { } + constexpr explicit test_random_access_iterator(std::initializer_list const& list) + : begin{list.begin()}, + end{list.end()} { } + test_random_access_iterator(test_random_access_iterator const&) = default; + test_random_access_iterator& operator=(test_random_access_iterator const&) = default; + test_random_access_iterator(test_random_access_iterator&&) = default; + test_random_access_iterator& operator=(test_random_access_iterator&&) = default; + constexpr reference_type operator*() const { + return *begin; + } + constexpr test_random_access_iterator& operator++() { + ++begin; + return *this; + } + constexpr test_random_access_iterator operator++(int) { + auto ret = *this; + ++begin; + return ret; + } + constexpr test_random_access_iterator& operator--() { + --begin; + return *this; + } + constexpr test_random_access_iterator operator--(int) { + auto ret = *this; + --begin; + return ret; + } + constexpr reference_type operator[](difference_type n) const { + auto retval = *this; + retval = retval + n; + return *retval; + } + constexpr test_random_access_iterator operator+(difference_type n) const { + auto retval = *this; + retval += n; + return retval; + } + friend constexpr test_random_access_iterator operator+( + difference_type n, test_random_access_iterator it) { + return it + n; + } + constexpr test_random_access_iterator& operator+=(difference_type n) { + begin += n; + return *this; + } + constexpr test_random_access_iterator operator-(difference_type n) const { + auto retval = *this; + retval -= n; + return retval; + } + constexpr difference_type operator-(test_random_access_iterator it) const { + return begin - it.begin; + } + constexpr test_random_access_iterator& operator-=(difference_type n) { + begin -= n; + return *this; + } + friend constexpr auto operator<=>( + test_random_access_iterator lhs, test_random_access_iterator rhs) { + return lhs.begin <=> rhs.begin; + } + + friend constexpr bool operator==(std::default_sentinel_t const&, + test_random_access_iterator const& rhs) { + return rhs.begin == rhs.end; + } + friend constexpr bool operator==(test_random_access_iterator const&, + test_random_access_iterator const&) = default; + + std::initializer_list::iterator begin; + std::initializer_list::iterator end; +}; + +template +test_random_access_iterator(std::initializer_list) -> + test_random_access_iterator; + +static_assert(std::random_access_iterator>); + } // namespace utf_view::tests #endif // UTF_VIEW_TESTS_TEST_ITERATORS_HPP