// Description: SliceViewCursor class
// Documentation: concrete_views.txt
#ifndef PASTELSYS_SLICEVIEWCURSOR_H
#define PASTELSYS_SLICEVIEWCURSOR_H
#include "pastel/sys/view/sliceview.h"
namespace Pastel
{
namespace SliceView_
{
template <integer N, typename ConstCursor>
class ConstSliceViewCursor
{
public:
static constexpr int Dimension = N - 1;
using Element = typename ConstCursor::Element;
using ConstReference = typename ConstCursor::ConstReference;
ConstSliceViewCursor()
: cursor_()
, fixedIndex_(0)
{
}
explicit ConstSliceViewCursor(
const ConstCursor& cursor, integer fixedIndex)
: cursor_(cursor)
, fixedIndex_(fixedIndex)
{
}
void swap(ConstSliceViewCursor& that)
{
cursor_.swap(that.cursor_);
std::swap(fixedIndex_, that.fixedIndex_);
}
void increment(integer index)
{
if (index >= fixedIndex_)
{
cursor_.increment(index + 1);
}
else
{
cursor_.increment(index);
}
}
void decrement(integer index)
{
if (index >= fixedIndex_)
{
cursor_.decrement(fixedIndex_ + 1);
}
else
{
cursor_.decrement(fixedIndex_);
}
}
void move(integer index, integer amount)
{
if (index >= fixedIndex_)
{
cursor_.move(fixedIndex_ + 1, amount);
}
else
{
cursor_.move(fixedIndex_, amount);
}
}
void move(const Vector<integer, ModifyN<N, N - 1>::Result>& amount)
{
cursor_.move(fixedIndex_, extend(amount, 0, fixedIndex_));
}
const Element* operator->() const
{
return cursor_.operator->();
}
ConstReference operator*() const
{
return *cursor_;
}
protected:
ConstCursor cursor_;
integer fixedIndex_;
};
template <integer N, typename Cursor>
class SliceViewCursor
: public ConstSliceViewCursor<N, Cursor>
{
private:
using Base = ConstSliceViewCursor<N, Cursor>;
using Base::cursor_;
public:
using Element = typename Base::Element;
using ConstReference = typename Base::ConstReference;
using Base::increment;
using Base::decrement;
using Base::move;
using Reference = typename Cursor::Reference;
friend class ConstSliceViewCursor<N, Cursor>;
SliceViewCursor()
: Base()
{
}
explicit SliceViewCursor(
const Cursor& cursor,
integer fixedIndex)
: Base(cursor, fixedIndex)
{
}
void swap(SliceViewCursor& that)
{
Base::swap(that);
}
Element* operator->() const
{
return cursor_.operator->();
}
Reference operator*() const
{
return *cursor_;
}
};
}
}
#endif