1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
// 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 <list>
#include <vector>
#include <sstream>
#include <range/v3/core.hpp>
#include <range/v3/utility/copy.hpp>
#include <range/v3/view/delimit.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
template<typename BidiRange>
struct my_reverse_view
: ranges::view_adaptor<my_reverse_view<BidiRange>, BidiRange>
{
private:
CPP_assert(ranges::bidirectional_range<BidiRange>);
CPP_assert(ranges::common_range<BidiRange>);
friend ranges::range_access;
using base_iterator_t = ranges::iterator_t<BidiRange>;
struct adaptor : ranges::adaptor_base
{
template<class base_mixin>
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<BidiRange> read(base_iterator_t it) const
{
return *ranges::prev(it);
}
CPP_member
auto advance(base_iterator_t &it,
ranges::range_difference_t<BidiRange> n) const ->
CPP_ret(void)(
requires ranges::random_access_range<BidiRange>)
{
it -= n;
}
CPP_member
auto distance_to(base_iterator_t const &here,
base_iterator_t const &there) const ->
CPP_ret(ranges::range_difference_t<BidiRange>)(
requires ranges::sized_sentinel_for<base_iterator_t, base_iterator_t>)
{
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<ranges::istream_view<int>, int>>
{
using view_adaptor::view_adaptor;
struct adaptor : ranges::adaptor_base
{
template<class base_mixin>
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<int> v{1, 2, 3, 4};
my_reverse_view<std::vector<int>&> retro{v};
CPP_assert(common_range<decltype(retro)>);
CPP_assert(view_<decltype(retro)>);
CPP_assert(random_access_iterator<decltype(retro.begin())>);
::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<int> l{1, 2, 3, 4};
my_reverse_view<std::list<int>& > retro2{l};
CPP_assert(common_range<decltype(retro2)>);
CPP_assert(view_<decltype(retro2)>);
CPP_assert(bidirectional_iterator<decltype(retro2.begin())>);
CPP_assert(!random_access_iterator<decltype(retro2.begin())>);
::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<int>(sinx), 42)};
CPP_assert(view_<decltype(r)>);
CPP_assert(!common_range<decltype(r)>);
CPP_assert(input_iterator<decltype(r.begin())>);
CPP_assert(!forward_iterator<decltype(r.begin())>);
::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();
}
|