subview.h

Back to Concrete views

pastel/sys/view/

// Description: SubView class
// Detail: An adapter view for an n-dimensional subset
// Documentation: concrete_views.txt

#ifndef PASTELSYS_SUBVIEW_H
#define PASTELSYS_SUBVIEW_H

#include "pastel/sys/alignedbox.h"

#include "pastel/sys/view/view.h"

namespace Pastel
{

    template <integer N, typename Contained_ConstView>
    class ConstSubView
    {
    public:
        static constexpr int Dimension = N;

        using Element = typename Contained_ConstView::Element;
        using ConstReference = typename Contained_ConstView::ConstReference;
        using ConstCursor = typename Contained_ConstView::ConstCursor;

        ConstSubView()
            : view_()
            , window_()
            , extent_()
        {
        }

        ConstSubView(
            const Contained_ConstView& view,
            const AlignedBox<integer, N>& window)
            : view_(view)
            , window_(window)
            , extent_(window.extent())
        {
            ENSURE(allGreaterEqual(window.min(), 0) && allLess(window.min(), view.extent()));
            ENSURE(allGreaterEqual(window.max(), 0) && allLessEqual(window.max(), view.extent()));
            ENSURE(allLessEqual(window.min(), window.max()));
        }

        const Vector<integer, N>& extent() const
        {
            return extent_;
        }

        ConstCursor constCursor(
            const Vector<integer, N>& position) const
        {
            return view_.constCursor(
                position + window_.min());
        }

    protected:
        Contained_ConstView view_;
        AlignedBox<integer, N> window_;
        Vector<integer, N> extent_;
    };

    template <integer N, typename Input_Element, typename Input_ConstView>
    ConstView<N, Input_Element, ConstSubView<N, Input_ConstView> >
        constSubView(
        const ConstView<N, Input_Element, Input_ConstView>& view,
        const AlignedBox<integer, N>& window)
    {
        return wrapConstView(
            ConstSubView<N, Input_ConstView>(view.contained(), window));
    }

    template <integer N, typename Contained_View>
    class SubView
        : public ConstSubView<N, Contained_View>
    {
    private:
        using Base = ConstSubView<N, Contained_View>;
        using Base::view_;
        using Base::window_;

    public:
        //using Base::Dimension;
        using Element = typename Base::Element;
        using ConstReference = typename Base::ConstReference;
        using ConstCursor = typename Base::ConstCursor;
        using Base::extent;
        using Base::constCursor;

        using Reference = typename Contained_View::Reference;
        using Cursor = typename Contained_View::Cursor;

        SubView()
            : Base()
        {
        }

        SubView(
            const Contained_View& view,
            const AlignedBox<integer, N>& window)
            : Base(view, window)
        {
        }

        Cursor cursor(
            const Vector<integer, N>& position) const
        {
            return view_.cursor(
                position + window_.min());
        }
    };

    template <integer N, typename Input_Element, typename Input_View>
    View<N, Input_Element, SubView<N, Input_View> >
        subView(const View<N, Input_Element, Input_View>& view,
            const AlignedBox<integer, N>& window)
    {
        return wrapView(SubView<N, Input_View>(view.contained(), window));
    }

}

#endif