Last active
December 9, 2017 05:14
-
-
Save fenrir-naru/12ca24c266d9058559cbb0d1d0944231 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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