Skip to content

Commit

Permalink
Make STLIterator move only
Browse files Browse the repository at this point in the history
This gets us closer to making it work with any IteratorConcept.

* ra/ply.hh (STLIterator): As stated. Poison postincrement op.
* ra/big.hh, ra/small.hh: Use ranges variants of copy_n, copy.

Elsewhere fix tests by using ranges variants of std::equal.
  • Loading branch information
lloda committed Nov 28, 2023
1 parent c734252 commit 6d84e6b
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 54 deletions.
10 changes: 5 additions & 5 deletions ra/big.hh
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ struct View
{
auto xsize = ssize(x);
RA_CHECK(size()==xsize, "Mismatched sizes ", View::size(), " ", xsize, ".");
std::copy_n(x.begin(), xsize, begin());
std::ranges::copy_n(x.begin(), xsize, begin());
return *this;
}
constexpr View const & operator=(braces<T, RANK> x) const requires (RANK!=ANY) { ra::iter<-1>(*this) = x; return *this; }
Expand Down Expand Up @@ -441,10 +441,10 @@ struct Container: public View<typename storage_traits<Store>::T, RANK>

// FIXME requires T to be copiable, which conflicts with the semantics of view_.operator=. store(x) avoids it for Big, but doesn't work for Unique. Should construct in place like std::vector does.
constexpr void
fill1(auto xbegin, dim_t xsize)
fill1(auto && xbegin, dim_t xsize)
{
RA_CHECK(size()==xsize, "Mismatched sizes ", size(), " ", xsize, ".");
std::ranges::copy_n(xbegin, xsize, begin());
std::ranges::copy_n(RA_FWD(xbegin), xsize, begin());
}

// shape + row-major ravel.
Expand All @@ -457,8 +457,8 @@ struct Container: public View<typename storage_traits<Store>::T, RANK>
Container(shape_arg const & s, auto * p)
: Container(s, none) { fill1(p, size()); } // FIXME fake check
// FIXME remove
Container(shape_arg const & s, auto pbegin, dim_t psize)
: Container(s, none) { fill1(pbegin, psize); }
Container(shape_arg const & s, auto && pbegin, dim_t psize)
: Container(s, none) { fill1(RA_FWD(pbegin), psize); }

// for shape arguments that doesn't convert implicitly to shape_arg
Container(auto && s, none_t)
Expand Down
34 changes: 12 additions & 22 deletions ra/ply.hh
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ ply_fixed(A && a, Early && early = Nop {})


// ---------------------------
// ply, best for each type
// default ply
// ---------------------------

template <IteratorConcept A, class Early = Nop>
Expand All @@ -321,11 +321,6 @@ ply(A && a, Early && early = Nop {})
constexpr void
for_each(auto && op, auto && ... a) { ply(map(RA_FWD(op), RA_FWD(a) ...)); }


// ---------------------------
// ply, short-circuiting
// ---------------------------

template <class T> struct Default { T def; };
template <class T> Default(T &&) -> Default<T>;

Expand Down Expand Up @@ -362,20 +357,15 @@ struct STLIterator
ii.c.cp = nullptr;
}
}
constexpr STLIterator &
operator=(STLIterator const & it)
{
ind = it.ind;
ii.Iterator::~Iterator(); // no-op except for View<ANY>. Still...
new (&ii) Iterator(it.ii); // avoid ii = it.ii [ra11]
return *this;
}

constexpr STLIterator(STLIterator && it) = default;
constexpr STLIterator(STLIterator const & it) = delete;
constexpr STLIterator & operator=(STLIterator && it) = default;
constexpr STLIterator & operator=(STLIterator const & it) = delete;
bool operator==(std::default_sentinel_t end) const { return !(ii.c.cp); }
decltype(auto) operator*() const { return *ii; }

constexpr void
cube_next(rank_t k)
next(rank_t k)
{
for (; k>=0; --k) {
if (++ind[k]<ii.len(k)) {
Expand All @@ -390,15 +380,15 @@ struct STLIterator
}
template <int k>
constexpr void
cube_next()
next()
{
if constexpr (k>=0) {
if (++ind[k]<ii.len(k)) {
ii.adv(k, 1);
} else {
ind[k] = 0;
ii.adv(k, 1-ii.len(k));
cube_next<k-1>();
next<k-1>();
}
return;
}
Expand All @@ -407,14 +397,14 @@ struct STLIterator
STLIterator & operator++()
{
if constexpr (ANY==rank_s<Iterator>()) {
cube_next(rank(ii)-1);
next(rank(ii)-1);
} else {
cube_next<rank_s<Iterator>()-1>();
next<rank_s<Iterator>()-1>();
}
return *this;
}
// required by std::input_or_output_iterator
STLIterator & operator++(int) { auto old = *this; ++(*this); return old; }
// std::input_iterator allows void, but std::output_iterator doesn't (p0541). Avoid
STLIterator & operator++(int) { static_assert(always_false<Iterator>); }
};


Expand Down
2 changes: 1 addition & 1 deletion ra/small.hh
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ struct SmallView: public SmallBase<T, lens, steps>
constexpr SmallView const &
operator=(T (&&x)[size()]) const requires ((rank()>1) && (size()>1))
{
std::copy(std::begin(x), std::end(x), begin()); return *this;
std::ranges::copy(std::ranges::subrange(x), begin()); return *this;
}

template <int k>
Expand Down
45 changes: 23 additions & 22 deletions test/ra-0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ int main()
auto it = r.iter();
tr.test_seq(r.data(), it.c.data());
std::ranges::copy(r.begin(), r.end(), chk);
tr.test(std::equal(pool, pool+6, r.begin()));
tr.test(std::ranges::equal(pool, pool+6, r.begin(), r.end()));
}
tr.section("iterator for View (II)");
{
Expand All @@ -212,7 +212,7 @@ int main()
auto it = r.iter();
tr.test_seq(r.data(), it.c.data());
std::ranges::copy(r.begin(), r.end(), chk);
tr.test(std::equal(pool, pool+6, r.begin()));
tr.test(std::ranges::equal(pool, pool+6, r.begin(), r.end()));
}
// some of these tests are disabled depending on CellBig::operator=.
tr.section("[ra11a] (skipped) CellBig operator= (from CellBig) does NOT copy contents");
Expand Down Expand Up @@ -250,25 +250,26 @@ int main()
tr.test_eq(ra::_0 - ra::_1, AA);
tr.test_eq(A, AA);
}
tr.section("[ra11c] STL-type iterators never copy contents");
{
double a[6] = { 0, 0, 0, 0, 0, 0 };
double b[6] = { 1, 2, 3, 4, 5, 6 };
ra::View<double> ra { {{3, 2}, {2, 1}}, a };
ra::View<double> rb { {{3, 2}, {2, 1}}, b };
auto aiter = ra.begin();
{
auto biter = rb.begin();
aiter = biter;
tr.test_eq(0, ra); // ra unchanged
tr.test(std::ranges::equal(rb.begin(), rb.end(), aiter, rb.end())); // aiter changed
}
{
aiter = rb.begin();
tr.test_eq(0, ra); // ra unchanged
tr.test(std::ranges::equal(rb.begin(), rb.end(), aiter, rb.end())); // aiter changed
}
}
// FIXME re-enable if STL-type iterators become copyable again.
// tr.section("[ra11c] STL-type iterators never copy contents");
// {
// double a[6] = { 0, 0, 0, 0, 0, 0 };
// double b[6] = { 1, 2, 3, 4, 5, 6 };
// ra::View<double> ra { {{3, 2}, {2, 1}}, a };
// ra::View<double> rb { {{3, 2}, {2, 1}}, b };
// auto aiter = ra.begin();
// {
// auto biter = rb.begin();
// aiter = biter;
// tr.test_eq(0, ra); // ra unchanged
// tr.test(std::ranges::equal(rb.begin(), rb.end(), aiter, rb.end())); // aiter changed
// }
// {
// aiter = rb.begin();
// tr.test_eq(0, ra); // ra unchanged
// tr.test(std::ranges::equal(rb.begin(), rb.end(), aiter, rb.end())); // aiter changed
// }
// }
tr.section("shape of .iter()");
{
auto test = [&tr](auto && A)
Expand Down Expand Up @@ -321,7 +322,7 @@ int main()

ra::View<double> r { {{3, 1}, {2, 3}}, rpool };
std::ranges::copy(r.begin(), r.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
tr.test(std::equal(check, check+6, r.begin()));
tr.test(std::ranges::equal(check, check+6, r.begin(), r.end()));

ra::Unique<double> u({3, 2}, r.begin(), r.size());
std::ranges::copy(u.begin(), u.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
Expand Down
5 changes: 4 additions & 1 deletion test/ra-11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ int main()
double rpool[6] = { 1, 2, 3, 4, 5, 6 };
ra::View<double, 2> r { {{3, 1}, {2, 3}}, rpool };
double rcheck[6] = { 1, 4, 2, 5, 3, 6 };
tr.test(std::equal(rcheck, rcheck+6, r.at(ra::Big<int>({0}, {})).begin()));
// kinda... long
auto v = r.at(ra::Big<int>({0}, {}));
tr.test(std::ranges::equal(std::ranges::subrange(rcheck, rcheck+6),
std::ranges::subrange(v)));
}
return tr.summary();
}
6 changes: 3 additions & 3 deletions test/view-ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void CheckReverse(TestRecorder & tr, A && a)
double check0[24] = { 17, 18, 19, 20, 21, 22, 23, 24,
9, 10, 11, 12, 13, 14, 15, 16,
1, 2, 3, 4, 5, 6, 7, 8 };
tr.test(std::equal(check0, check0+24, b0.begin()));
tr.test(std::ranges::equal(check0, check0+24, b0.begin(), b0.end()));
tr.test_eq(b0, c0);

auto b1 = reverse(a, 1);
Expand All @@ -37,7 +37,7 @@ void CheckReverse(TestRecorder & tr, A && a)
double check1[24] = { 5, 6, 7, 8, 1, 2, 3, 4,
13, 14, 15, 16, 9, 10, 11, 12,
21, 22, 23, 24, 17, 18, 19, 20 };
tr.test(std::equal(check1, check1+24, b1.begin()));
tr.test(std::ranges::equal(check1, check1+24, b1.begin(), b1.end()));
tr.test_eq(b1, c1);

auto b2 = reverse(a, 2);
Expand All @@ -47,7 +47,7 @@ void CheckReverse(TestRecorder & tr, A && a)
double check2[24] = { 4, 3, 2, 1, 8, 7, 6, 5,
12, 11, 10, 9, 16, 15, 14, 13,
20, 19, 18, 17, 24, 23, 22, 21 };
tr.test(std::equal(check2, check2+24, b2.begin()));
tr.test(std::ranges::equal(check2, check2+24, b2.begin(), b2.end()));
tr.test_eq(b2, c2);
}

Expand Down

0 comments on commit 6d84e6b

Please sign in to comment.