Skip to content

Instantly share code, notes, and snippets.

@nikhedonia
Created November 10, 2015 21:14
Show Gist options
  • Save nikhedonia/09bb0763a59bd4c559f6 to your computer and use it in GitHub Desktop.
Save nikhedonia/09bb0763a59bd4c559f6 to your computer and use it in GitHub Desktop.
buggy...
#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