Skip to content

Instantly share code, notes, and snippets.

@fenrir-naru
Last active December 9, 2017 05:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fenrir-naru/12ca24c266d9058559cbb0d1d0944231 to your computer and use it in GitHub Desktop.
Save fenrir-naru/12ca24c266d9058559cbb0d1d0944231 to your computer and use it in GitHub Desktop.
#include <iostream>
using namespace std;
struct MatrixView;
template <class BaseView>
struct MatrixViewTranspose;
template <class BaseView>
struct MatrixViewPartial;
template <class View>
struct MatrixViewBuilder {
template <template <class> class V, class U = void>
struct priority_t {
static const int priority = 0;
};
template <class U>
struct priority_t<MatrixViewTranspose, U> {
static const int priority = 1;
};
template <template <class> class V1, class V2>
struct sort_t {
typedef V1<V2> res_t;
};
template <template <class> class V1, template <class> class V2, class V3>
struct sort_t<V1, V2<V3> > {
template <bool, class U = void>
struct rebuild_t {
typedef V1<V2<V3> > res_t;
};
template <class U>
struct rebuild_t<false, U> {
typedef V2<V1<V3> > res_t;
};
typedef typename rebuild_t<
(priority_t<V1>::priority >= priority_t<V2>::priority)>::res_t res_t;
};
template <template <class> class NextView>
struct switch_t { // off => on => off => ...
template <class V>
struct rebuild_t {
typedef NextView<V> res_t;
};
template <class V1, template <class> class V2>
struct rebuild_t<V2<V1> > {
typedef typename sort_t<V2, typename rebuild_t<V1>::res_t>::res_t res_t;
};
template <class V1>
struct rebuild_t<NextView<V1> > {
typedef V1 res_t;
};
typedef typename rebuild_t<View>::res_t res_t;
};
template <template <class> class NextView>
struct once_t { // off => on => on => ...
template <class V>
struct rebuild_t {
typedef NextView<V> res_t;
};
template <class V1, template <class> class V2>
struct rebuild_t<V2<V1> > {
typedef typename sort_t<V2, typename rebuild_t<V1>::res_t>::res_t res_t;
};
template <class V1>
struct rebuild_t<NextView<V1> > {
typedef NextView<V1> res_t;
};
typedef typename rebuild_t<View>::res_t res_t;
};
typedef typename switch_t<MatrixViewTranspose>::res_t transposed_t;
typedef typename once_t<MatrixViewPartial>::res_t partialized_t;
};
template <class BaseView>
struct MatrixViewTranspose : /*protected*/ BaseView {
typedef MatrixViewTranspose<BaseView> self_t;
static const bool transposed = true;
using BaseView::partialized;
MatrixViewTranspose() : BaseView() {}
template <class BaseView2>
MatrixViewTranspose(const BaseView2 &view)
: BaseView(view) {}
typedef typename MatrixViewBuilder<self_t>::transposed_t transposed_t;
//friend transposed_t;
transposed_t transpose() const {
return transposed_t((const BaseView &)*this);
}
typedef typename MatrixViewBuilder<self_t>::partialized_t partialized_t;
//friend partialized_t;
partialized_t partial(
const unsigned int &rows,
const unsigned int &columns,
const unsigned int &row_offset,
const unsigned int &column_offset){
return partialized_t(*this).set_partial(columns, rows, column_offset, row_offset);
}
friend ostream &operator<<(ostream &out, const MatrixViewTranspose<BaseView> &view){
return out << " [T]" << (const BaseView &)view;
}
};
template <class BaseView>
struct MatrixViewPartial : /*protected*/ BaseView {
typedef MatrixViewPartial<BaseView> self_t;
using BaseView::transposed;
static const bool partialized = true;
struct partial_prop_t {
unsigned int rows, row_offset;
unsigned int columns, column_offset;
partial_prop_t()
: rows(0), row_offset(0), columns(0), column_offset(0){}
template <class BaseView2>
partial_prop_t(const BaseView2 &view)
: rows(0), row_offset(0), columns(0), column_offset(0){}
template <class BaseView2>
partial_prop_t(const MatrixViewPartial<BaseView2> &view){
rows = view.partial_prop.rows;
row_offset = view.partial_prop.row_offset;
columns = view.partial_prop.columns;
column_offset = view.partial_prop.column_offset;
}
} partial_prop;
MatrixViewPartial() : BaseView(), partial_prop() {}
template <class BaseView2>
MatrixViewPartial(const BaseView2 &view)
: BaseView(view), partial_prop(view) {
}
self_t &set_partial(
const unsigned int &rows,
const unsigned int &columns,
const unsigned int &row_offset,
const unsigned int &column_offset){
partial_prop.rows = rows;
partial_prop.columns = columns;
partial_prop.row_offset += row_offset;
partial_prop.column_offset += column_offset;
return *this;
}
typedef typename MatrixViewBuilder<self_t>::transposed_t transposed_t;
//friend transposed_t;
transposed_t transpose() const {
return transposed_t(*this);
}
typedef typename MatrixViewBuilder<self_t>::partialized_t partialized_t;
//friend partialized_t;
partialized_t partial(
const unsigned int &rows,
const unsigned int &columns,
const unsigned int &row_offset,
const unsigned int &column_offset){
return partialized_t(*this).set_partial(
transposed ? columns : rows,
transposed ? rows : columns,
(transposed ? column_offset : row_offset),
(transposed ? row_offset : column_offset));
}
friend ostream &operator<<(ostream &out, const MatrixViewPartial<BaseView> &view){
return out << " [P]("
<< view.partial_prop.rows << ","
<< view.partial_prop.columns << ","
<< view.partial_prop.row_offset << ","
<< view.partial_prop.column_offset << ")"
<< (const BaseView &)view;
}
};
struct MatrixView {
typedef MatrixView self_t;
static const bool transposed = false;
static const bool partialized = false;
typedef typename MatrixViewBuilder<self_t>::transposed_t transposed_t;
//friend transposed_t;
transposed_t transpose() const {
return transposed_t(*this);
}
typedef typename MatrixViewBuilder<self_t>::partialized_t partialized_t;
//friend partialized_t;
partialized_t partial(
const unsigned int &rows,
const unsigned int &columns,
const unsigned int &row_offset,
const unsigned int &column_offset){
return partialized_t(*this).set_partial(rows, columns, row_offset, column_offset);
}
friend ostream &operator<<(ostream &out, const MatrixView &view){
return out << " [V]";
}
};
int main(){
/*
cerr << "t" << MatrixView::transposed_t() << endl;
cerr << "tt" << MatrixView::transposed_t::transposed_t() << endl;
cerr << "tp" << MatrixView::transposed_t::partialized_t() << endl;
cerr << "tpt" << MatrixView::transposed_t::partialized_t::transposed_t() << endl;
cerr << "tpp" << MatrixView::transposed_t::partialized_t::partialized_t() << endl;
cerr << "pt" << MatrixView::partialized_t::transposed_t() << endl;
cerr << "ptt" << MatrixView::partialized_t::transposed_t::transposed_t() << endl;
cerr << "pttp" << MatrixView::partialized_t::transposed_t::transposed_t::partialized_t() << endl;
*/
MatrixView v;
cerr << "t" << v.transpose() << endl;
cerr << "tt" << v.transpose().transpose() << endl;
cerr << "tp" << v.transpose().partial(5,6,3,4) << endl;
cerr << "tpt" << v.transpose().partial(5,6,3,4).transpose() << endl;
cerr << "tpp" << v.transpose().partial(5,6,3,4).partial(1,2,1,2) << endl;
cerr << "pt" << v.partial(5,6,3,4).transpose() << endl;
cerr << "ptt" << v.partial(5,6,3,4).transpose().transpose() << endl;
cerr << "pttp" << v.partial(5,6,3,4).transpose().transpose().partial(1,2,1,2) << endl;
cerr << "ptpt" << v.partial(5,6,3,4).transpose().partial(1,2,1,2).transpose() << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment