PEPPHER Composition Tool Prototype - Matrix

template <typename T>
class Matrix : public IContainer<T>

//-- Friend --//

    friend std::ostream& operator<< (std::ostream& output, Matrix<T>& vec);

//-- Constructors & Destructor --//

    Matrix(size_type _rows, size_type _cols);
    Matrix(size_type _rows, size_type _cols, const T& val);
    Matrix(T * const ptr, size_type _rows, size_type _cols, size_type _ld, ContainerBehavior _behav= INSIDE_COMPONENT_CONTAINER);
    Matrix(const Matrix<T>& copy);
    virtual ~Matrix();

//-- Member classes --//

    class iterator;

    class proxy_elem;

//-- Methods related to StarPU memory management and implementation of the IContainer interface --//
    void acquireRead() const;
    void acquireReadWrite();
    void release_acquire();
    bool supportPartitioning();
    int totalPartitions(int dimension = 1);
    T* getRawType();
    starpu_data_handle_t registerWithStarPU();
    void unregisterWithStarPU(bool update=true);
    starpu_data_handle_t registerSubWithStarPU(int partSizes[], int dimensions);

    starpu_data_handle_t registerPartitions(int _xparts=1, int _yparts=1);
    starpu_data_handle_t getSubHandle(int parts[], int dimensions);
    void unpartitionMatrix(); 

//-- Operators --//

    T& operator[](const size_type index);
    const T& operator[](const size_type index) const;
//-- Helpers --//	

   size_type size() const;
   size_type total_rows() const;
   size_type total_cols() const;

   void change_layout();

//-- Regular STL like operators --//

    void reserve(size_type size);

    void resize(size_type _rows, size_type _cols, T val = T());

    Matrix<T>& operator=(Matrix<T>& other);
    Matrix<T>& operator=(const T& elem);

    bool operator==(const Matrix<T>& c1);
    bool operator!=(const Matrix<T>& c1);

    iterator begin();

    iterator end();
    size_type capacity() const;    
    bool empty() const;

    void clear();

    void swap(Matrix<T>& from);

//-- Additions to interface --//  

    void flush(); 
    proxy_elem operator()(const size_type row, const size_type col);
    const T& operator()(const size_type row, const size_type col) const;
    proxy_elem at(size_type row, size_type col);
    const T& at(size_type row, size_type col) const;

    proxy_elem row_back(size_type row);
    const T& row_back(size_type row) const;

    proxy_elem row_front(size_type row);
    const T& row_front(size_type row) const;

    proxy_elem col_back(size_type col);
    const T& col_back(size_type col) const;

    proxy_elem col_front(size_type col);
    const T& col_front(size_type col) const;

    Matrix<T>& subsection(size_type row, size_type col, size_type rowWidth, size_type colWidth);
    iterator begin(unsigned row);
    iterator end(unsigned row);
    // Does not care about device data, use with care
    T& operator()(const size_type index);
    // Does not care about device data, use with care
    T& operator[](const size_type index);
    // unary transpose operator
    Matrix<T> operator~();

    const Matrix<T>& operator+=(const Matrix<T>& rhs);
    const Matrix<T>& operator+=(const T& rhs);
    const Matrix<T>& operator-=(const Matrix<T>& rhs);
    const Matrix<T>& operator-=(const T& rhs);
    const Matrix<T>& operator*=(const Matrix<T>& rhs);
    const Matrix<T>& operator*=(const T& rhs);
    const Matrix<T>& operator/=(const Matrix<T>& rhs);
    const Matrix<T>& operator/=(const T& rhs);
    const Matrix<T>& operator%=(const Matrix<T>& rhs);
    const Matrix<T>& operator%=(const T& rhs);