// Description: PermutedView class
// Detail: An adapter view to permute dimensions
// Documentation: concrete_views.txt
#ifndef PASTELSYS_PERMUTEDVIEW_H
#define PASTELSYS_PERMUTEDVIEW_H
#include "pastel/sys/view/view.h"
#include "pastel/sys/view/permutedviewcursor.h"
namespace Pastel
{
//! Permutes the dimensions of the view.
/*!
More specifically:
permutedView(x_1, ..., x_n) =
view(x_p(1), ..., x_p(n))
Where
p is in [1, n]^n
*/
template <integer N, typename Contained_ConstView>
class ConstPermutedView
{
public:
static constexpr int Dimension = N;
using Element = typename Contained_ConstView::Element;
using ConstReference = typename Contained_ConstView::ConstReference;
typedef PermutedView_::ConstPermutedViewCursor<N, typename Contained_ConstView::ConstCursor>
ConstCursor;
explicit ConstPermutedView(
const Contained_ConstView& view,
const Tuple<integer, N>& permutation)
: view_(view)
, permutation_(permutation)
, extent_(permute(view.extent(), permutation))
{
}
const Vector<integer, N>& extent() const
{
return extent_;
}
ConstCursor constCursor(
const Vector<integer, N>& position) const
{
return ConstCursor(view_.constCursor(
Vector<integer, N>(permute(position, permutation_))),
permutation_);
}
protected:
Contained_ConstView view_;
Tuple<integer, N> permutation_;
Vector<integer, N> extent_;
};
template <integer N, typename Input_Element, typename Input_ConstView>
ConstView<N, Input_Element, ConstPermutedView<N, Input_ConstView> >
constPermutedView(
const ConstView<N, Input_Element, Input_ConstView>& view,
const Tuple<integer, N>& permutation)
{
return wrapConstView(
ConstPermutedView<N, Input_ConstView>(view.contained(), permutation));
}
//! Permutes the dimensions of the view.
/*!
More specifically:
permutedView(x_1, ..., x_n) =
view(x_p(1), ..., x_p(n))
Where
p is in [1, n]^n
*/
template <integer N, typename Contained_View>
class PermutedView
: public ConstPermutedView<N, Contained_View>
{
private:
using Base = ConstPermutedView<N, Contained_View>;
using Base::view_;
using Base::permutation_;
public:
//using Base::Dimension;
using ConstCursor = typename Base::ConstCursor;
using Element = typename Base::Element;
using ConstReference = typename Base::ConstReference;
using Base::extent;
using Base::constCursor;
using Reference = typename Contained_View::Reference;
typedef PermutedView_::PermutedViewCursor<N, typename Contained_View::Cursor>
Cursor;
explicit PermutedView(
const Contained_View& view,
const Tuple<integer, N>& permutation)
: Base(view, permutation)
{
}
Cursor cursor(const Vector<integer, N>& position) const
{
return Cursor(view_.cursor(
asPoint(permute(position, permutation_))),
permutation_);
}
};
template <integer N, typename Input_Element, typename Input_View>
View<N, Input_Element, PermutedView<N, Input_View> > permutedView(
const View<N, Input_Element, Input_View>& view,
const Tuple<integer, N>& permutation)
{
return wrapView(PermutedView<N, Input_View>(view.contained(), permutation));
}
}
#endif