// Range v3 library // // Copyright Eric Niebler 2014-present // // Use, modification and distribution is subject to 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) // // Project home: https://github.com/ericniebler/range-v3 #include #include #include #include #include #include #include "../simple_test.hpp" #include "../test_utils.hpp" template struct my_reverse_view : ranges::view_adaptor, BidiRange> { private: CPP_assert(ranges::bidirectional_range); CPP_assert(ranges::common_range); friend ranges::range_access; using base_iterator_t = ranges::iterator_t; struct adaptor : ranges::adaptor_base { template struct mixin : base_mixin { mixin() = default; using base_mixin::base_mixin; int mixin_int = 120; int base_plus_adaptor() const { int y = this->get().t; return *this->base() + y; } }; int t = 20; // Cross-wire begin and end. base_iterator_t begin(my_reverse_view const &rng) const { return ranges::end(rng.base()); } base_iterator_t end(my_reverse_view const &rng) const { return ranges::begin(rng.base()); } void next(base_iterator_t &it) const { --it; } void prev(base_iterator_t &it) const { ++it; } ranges::range_reference_t read(base_iterator_t it) const { return *ranges::prev(it); } CPP_member auto advance(base_iterator_t &it, ranges::range_difference_t n) const -> CPP_ret(void)( requires ranges::random_access_range) { it -= n; } CPP_member auto distance_to(base_iterator_t const &here, base_iterator_t const &there) const -> CPP_ret(ranges::range_difference_t)( requires ranges::sized_sentinel_for) { return here - there; } }; adaptor begin_adaptor() const { return {}; } adaptor end_adaptor() const { return {}; } public: using my_reverse_view::view_adaptor::view_adaptor; }; struct my_delimited_range : ranges::view_adaptor< my_delimited_range, ranges::delimit_view, int>> { using view_adaptor::view_adaptor; struct adaptor : ranges::adaptor_base { template struct mixin : base_mixin { mixin() = default; using base_mixin::base_mixin; int mixin_int = 120; int adaptor_access_test() const { int y = this->get().t; return y; } }; int t = 20; }; adaptor begin_adaptor() const { return {}; } adaptor end_adaptor() const { return {}; } }; int main() { using namespace ranges; std::vector v{1, 2, 3, 4}; my_reverse_view&> retro{v}; CPP_assert(common_range); CPP_assert(view_); CPP_assert(random_access_iterator); ::check_equal(retro, {4, 3, 2, 1}); // test cursor mixin CHECK( retro.begin().mixin_int == 120 ); CHECK( *((retro.begin()+1).base()) == 4 ); CHECK( (retro.begin()+1).base_plus_adaptor() == 24 ); std::list l{1, 2, 3, 4}; my_reverse_view& > retro2{l}; CPP_assert(common_range); CPP_assert(view_); CPP_assert(bidirectional_iterator); CPP_assert(!random_access_iterator); ::check_equal(retro2, {4, 3, 2, 1}); std::stringstream sinx("1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 42 6 7 8 9 "); my_delimited_range r{views::delimit(istream(sinx), 42)}; CPP_assert(view_); CPP_assert(!common_range); CPP_assert(input_iterator); CPP_assert(!forward_iterator); ::check_equal(r, {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4}); // test sentinel mixin CHECK(r.end().mixin_int == 120); CHECK(r.end().adaptor_access_test() == 20); return ::test_result(); }