Created
November 10, 2015 21:14
-
-
Save nikhedonia/09bb0763a59bd4c559f6 to your computer and use it in GitHub Desktop.
buggy...
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> | |
#include <array> | |
#include <tuple> | |
#include <type_traits> | |
#include <algorithm> | |
using namespace std; | |
auto Valid = [](auto...x) -> integral_constant<bool,1> {}; | |
template<class F,class...X> | |
constexpr auto is_callable(F f,X...x) -> decltype( f(x...), true_type{} ){ | |
return{}; | |
} | |
constexpr auto is_callable(...)-> false_type { | |
return{}; | |
} | |
template<class F, class...X> | |
auto Fail(F f,X...x) -> enable_if_t<!is_callable(f,x...),true_type> { | |
return{}; | |
} | |
template<class F, class...X> | |
auto Check(F f, X...x) -> decltype( Valid( f(x)...) ){} | |
auto Not = [](auto f){ | |
return [f](auto...x)-> decltype( Fail(f,x...) ){ | |
return Fail(f,x...); | |
}; | |
}; | |
//....... | |
template<class T> | |
constexpr T ID(T const X){ | |
return X; | |
} | |
auto HasReduce = [](auto f, auto...x) -> decltype( f(x...), true_type{} ) { | |
return{}; | |
}; | |
template<class Contract, class...X> | |
constexpr auto reduceIF(Contract const C, X...x) -> decltype ( | |
C(x...) | |
){ | |
return C(x...); | |
} | |
template<class Contract> | |
constexpr auto reduceIF(Contract const C, ...) -> decltype ( | |
C() | |
){ | |
return C(); | |
} | |
template<class Contract, class...X> | |
constexpr auto reduceIF(Contract const C, X...) -> decltype ( | |
Check( Not(HasReduce), C ) , ID(C) | |
) { | |
return C; | |
} | |
template<class...Rs> | |
struct Mixin; | |
template<class...X> | |
auto mix(X const...x){ | |
return Mixin<decay_t<X>...>{x...}; | |
} | |
template<class...Rs> | |
struct Mixin | |
: Rs... | |
{ | |
template<class...X> | |
Mixin(X const...x) | |
: Rs{x}... | |
{} | |
template<class...X> | |
constexpr auto operator()(X...x)const { | |
return mix( reduceIF( Rs(*this) , x... )... ); | |
} | |
}; | |
//....... | |
template<class T,size_t...> | |
struct MultiArray { | |
using type = T; | |
}; | |
template<class T,size_t D, size_t...Ds> | |
struct MultiArray<T,D,Ds...> : | |
MultiArray< | |
array<T,D>, | |
Ds... | |
> | |
{}; | |
template<class T,size_t...I> | |
using Array = typename MultiArray<T,I...>::type; | |
template<size_t...D> | |
struct StaticSize { | |
constexpr static std::array<size_t, 1> dims = {0}; | |
constexpr static size_t deg(){ return 0; } | |
constexpr StaticSize<> operator()()const{ return {}; } | |
}; | |
template<size_t D, size_t...Ds> | |
struct StaticSize<D,Ds...> { | |
constexpr static std::array<size_t, sizeof...(Ds)+1> dims(){ return {D,Ds...}; } | |
constexpr static size_t deg(){ return sizeof...(Ds)+1; } | |
constexpr auto operator()(...)const{ return StaticSize<Ds...>{}; } | |
}; | |
template<size_t deg> | |
struct DynSize { | |
std::array<size_t,deg> dims; | |
}; | |
struct Dense { | |
constexpr static bool dense(){ return 1; } | |
}; | |
struct Diagonal { | |
constexpr static bool diagonal(){ return 1; } | |
}; | |
template<bool t, bool l=1, bool diag=1> | |
struct Triangular { | |
constexpr static bool triangular(){ return t; } | |
constexpr static bool left(){ return l; } | |
constexpr static bool right(){ return !l; } | |
constexpr static bool hasDiag(){ return diag; } | |
}; | |
template<class Data> | |
struct DataStore{ | |
Data data; | |
}; | |
template<class Data> | |
constexpr auto Store( Data const& D ) { | |
return DataStore<Data>{D}; | |
} | |
template<class Getter, class C> | |
struct VectorF { | |
Getter Get; | |
C contract; | |
decltype(auto) operator[](size_t i){ return Get(i); } | |
auto const operator[](size_t i)const{ return Get(i); } | |
}; | |
template<class G, class C> | |
auto vectorize(G g, C c){ | |
return VectorF<G,C>{g,c}; | |
} | |
template<class Getter, class C> | |
struct MatrixF { | |
Getter Get; | |
C contract; | |
auto const operator[](size_t i)const{ | |
return vectorize( | |
[g = Get, i](size_t j){ | |
return g(i,j); | |
},reduceIF(contract,i) | |
); | |
} | |
}; | |
template<class G, class C> | |
auto matrixfy(G g, C c){ | |
return MatrixF<G,C>{g,c}; | |
} | |
template<class L,class R> | |
auto operator*(L l, R r ) -> decltype( l.contract.isDiagonal() && r.contract.isDiagonal() , l*r ) | |
int main() { | |
auto M = matrixfy( | |
[](auto i, auto j){ return i+j; }, | |
mix(StaticSize<2,2>()) | |
); | |
cout << M[2][0]; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment