// R = return type
// variables a, b, c, r must exist and are available for use in FUNCTION.
// Writes to r.
// #define FUNCTION(i,j,k)
{
    if constexpr(R::type==ten_zero){}
    else if constexpr(R::type==ten_perm){r.x=(FUNCTION(0,1,2));}
    else if constexpr(R::type==ten_diag)
    {
        []<int... i>(auto&& a,auto&& b,auto&& r,std::integer_sequence<int,i...>)
            {
                (...,(r.v(i)=(FUNCTION(i,i,i))));
            }(a,b,r,std::make_integer_sequence<int,R::m>{});
    }
    else if constexpr(R::type>=ten_vec_id && R::type<=ten_vec_id+2)
    {
        static constexpr int di=(R::type==ten_vec_id+0);
        static constexpr int dj=(R::type==ten_vec_id+1);
        static constexpr int dk=(R::type==ten_vec_id+2);
        []<int... i>(auto&& a,auto&& b,auto&& r,std::integer_sequence<int,i...>)
            {
                (...,(r.v(i)=(FUNCTION(i*di,i*dj,i*dk))));
            }(a,b,r,std::make_integer_sequence<int,R::um>{});
    }
    else if constexpr(R::type>=ten_vec_id_sym && R::type<=ten_vec_id_sym+2)
    {
        static constexpr int di=(R::type!=ten_vec_id_sym+2);
        static constexpr int dj=(R::type!=ten_vec_id_sym+0);
        static constexpr int dk=(R::type!=ten_vec_id_sym+1);
        if constexpr(R::m==1){r.v(0)=(FUNCTION(0,0,0))/2;}
        else []<int... i>(auto&& a,auto&& b,auto&& r,std::integer_sequence<int,i...>)
                 {
                     (...,(r.v(i)=(FUNCTION((i+di)%R::m,(i+dj)%R::m,(i+dk)%R::m))));
                 }(a,b,r,std::make_integer_sequence<int,R::m>{});
    }
    else if constexpr(R::type>=ten_sym && R::type<=ten_sym+2)
    {
        static constexpr int ss=R::un*(R::un+1)/2;
        []<int... i>(auto&& a,auto&& b,auto&& r,std::integer_sequence<int,i...>)
            {
                if constexpr(R::u==0)
                    (...,(set<i/ss,sym_i(R::un,i%ss),sym_j(R::un,i%ss)>(r,(FUNCTION(i/ss,sym_i(R::un,i%ss),sym_j(R::un,i%ss))))));
                if constexpr(R::u==1)
                    (...,(set<sym_i(R::un,i%ss),i/ss,sym_j(R::un,i%ss)>(r,(FUNCTION(sym_i(R::un,i%ss),i/ss,sym_j(R::un,i%ss))))));
                if constexpr(R::u==2)
                    (...,(set<sym_i(R::un,i%ss),sym_j(R::un,i%ss),i/ss>(r,(FUNCTION(sym_i(R::un,i%ss),sym_j(R::un,i%ss),i/ss)))));
            }(a,b,r,std::make_integer_sequence<int,R::um*ss>{});
    }
    else
    {
        static_assert(R::type==ten_gen);
        []<int... i>(auto&& a,auto&& b,auto&& r,std::integer_sequence<int,i...>)
            {
                (...,(r(i/R::n/R::p,i%R::n,i/R::n%R::p)=(FUNCTION(i/R::n/R::p,i%R::n,i/R::n%R::p))));
            }(a,b,r,std::make_integer_sequence<int,R::m*R::n*R::p>{});
    }
}
#undef FUNCTION
