Last active
December 1, 2017 09:57
-
-
Save fenrir-naru/50624aedd1398f8b71222b7f5b6620b5 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; | |
template <class T> | |
struct A; | |
template <class T, bool is_transposed, bool is_partial> | |
struct A_View : public A<T> { | |
struct { | |
unsigned row_offset, column_offset; | |
} prop_partial; | |
A_View(const A<T> &orig, | |
const unsigned &row_offset = 0, const unsigned &column_offset = 0) : A<T>(orig) { | |
prop_partial.row_offset = row_offset; | |
prop_partial.column_offset = column_offset; | |
} | |
template <bool is_transposed2, bool is_partial2> | |
A_View(const A_View<T, is_transposed2, is_partial2> &orig, | |
const unsigned &row_offset = 0, const unsigned &column_offset = 0) : A<T>(orig) { | |
if(is_partial){ | |
if(is_transposed == is_transposed2){ | |
prop_partial.row_offset = orig.prop_partial.row_offset + row_offset; | |
prop_partial.column_offset = orig.prop_partial.column_offset + column_offset; | |
}else{ | |
prop_partial.row_offset = orig.prop_partial.column_offset + row_offset; | |
prop_partial.column_offset = orig.prop_partial.row_offset + column_offset; | |
} | |
}else{ | |
prop_partial.row_offset = prop_partial.column_offset = 0; | |
} | |
} | |
template <bool is_transposed2, bool is_partial2, class U = void> | |
struct Converter{ | |
typedef A_View<T, true, is_partial2> transposed_t; | |
typedef A_View<T, is_transposed2, true> partial_t; | |
}; | |
template <class U> | |
struct Converter<true, false, U>{ | |
typedef A<T> transposed_t; | |
typedef A_View<T, true, true> partial_t; | |
}; | |
template <class U> | |
struct Converter<true, true, U>{ | |
typedef A_View<T, false, true> transposed_t; | |
typedef A_View<T, true, true> partial_t; | |
}; | |
typename Converter<is_transposed, is_partial>::transposed_t transpose() const { | |
return typename Converter<is_transposed, is_partial>::transposed_t(*this); | |
} | |
typename Converter<is_transposed, is_partial>::partial_t partial( | |
const unsigned &row_offset = 0, const unsigned &column_offset = 0) const { | |
return typename Converter<is_transposed, is_partial>::partial_t(*this, row_offset, column_offset); | |
} | |
const A_View<T, is_transposed, is_partial> &check(const char *label) const { | |
std::cout << label << " => A_View: " | |
<< (is_transposed ? "transposed " : ""); | |
if(is_partial){ | |
std::cout << "partial(" << prop_partial.row_offset << "," << prop_partial.column_offset << ") "; | |
} | |
std::cout << std::endl; | |
return *this; | |
} | |
virtual const T &operator()(const unsigned &i, const unsigned &j) const { | |
if(is_transposed){ | |
if(is_partial){ | |
return A<T>::operator()(prop_partial.row_offset + j, prop_partial.column_offset + i); | |
}else{ | |
return A<T>::operator()(j, i); | |
} | |
}else{ | |
if(is_partial){ | |
return A<T>::operator()(prop_partial.row_offset + i, prop_partial.column_offset + j); | |
}else{ | |
return A<T>::operator()(i, j); | |
} | |
} | |
} | |
}; | |
template <class T> | |
struct A { | |
T buf[10][10]; | |
A() { | |
for(unsigned i(0); i < 10; ++i){ | |
for(unsigned j(i); j < 10; ++j){ | |
buf[i][j] = i * j; | |
} | |
} | |
} | |
typedef A_View<T, true, false> transposed_t; | |
typedef A_View<T, false, true> partial_t; | |
transposed_t transpose() const { | |
return transposed_t(*this); | |
} | |
partial_t partial(const unsigned &row_offset = 0, const unsigned &column_offset = 0) const { | |
return partial_t(*this, row_offset, column_offset); | |
} | |
const A<T> &check(const char *label) const { | |
std::cout << label << " => A" << std::endl; | |
return *this; | |
} | |
virtual const T &operator()(const unsigned &i, const unsigned &j) const { | |
return buf[i][j]; | |
} | |
T &operator()(const unsigned &i, const unsigned &j){ | |
return const_cast<T &>(const_cast<const A<T> &>(*this)(i, j)); | |
} | |
}; | |
int main(){ | |
A<int> a; | |
cout << a.check("A")(3, 4) << endl; | |
cout << a.transpose().check("At")(3, 4) << endl; | |
cout << a.partial(1, 2).check("Ap")(3, 4) << endl; | |
cout << a.transpose().partial(1, 2).check("Atp")(3, 4) << endl; | |
cout << a.transpose().transpose().check("Att")(3, 4) << endl; | |
cout << a.transpose().partial(1, 2).transpose().check("Atpt")(3, 4) << endl; | |
cout << a.transpose().partial(1, 2).transpose().transpose().check("Atptt")(3, 4) << endl; | |
cout << a.transpose().partial(1, 2).partial(1, 2).transpose().check("Atppt")(3, 4) << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment