#ifndef TENSOR_META_H #define TENSOR_META_H #include "Fastor/config/config.h" #include "Fastor/meta/meta.h" namespace Fastor { //----------------------------------------------------------------------------------------------------------// // UpLoType namespace UpLoType { struct General {}; struct Lower {}; struct UniLower {}; struct StrictlyLower {}; struct Upper {}; struct UniUpper {}; struct StrictlyUpper {}; struct Diagonal {}; struct BiDiagonal {}; struct TriDiagonal {}; struct BlockDiagonal {}; struct Symmetric {}; struct SymmetricPositiveDefinite {}; } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// template struct is_unique : std::integral_constant {}; template struct is_unique : std::integral_constant::value> {}; template struct no_of_unique : std::integral_constant {}; template struct no_of_unique : std::integral_constant::value + no_of_unique::value> {}; //----------------------------------------------------------------------------------------------------------// // Note that Intel's ICC 2017 does not support make_index_sequence and the following // version also seems faster than c++14's built-in (for clang) on Linux systems namespace std_ext // back port to c++11 { template struct index_sequence { using type = index_sequence; using value_type = size_t; static constexpr std::size_t size() { return sizeof...(Ints); } }; // -------------------------------------------------------------- template struct _merge_and_renumber; template struct _merge_and_renumber, index_sequence> : index_sequence { }; // -------------------------------------------------------------- template struct make_index_sequence : _merge_and_renumber::type, typename make_index_sequence::type> { }; template<> struct make_index_sequence<0> : index_sequence<> { }; template<> struct make_index_sequence<1> : index_sequence<0> { }; } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// template struct typelist { }; template using typelist_c = typelist...>; template struct concat; template <> struct concat<> { using type = typelist<>; }; template struct concat> { using type = typelist; }; template struct concat, typelist, Args...> : concat, Args...> { }; template struct filter_out; template struct filter_out> : concat< conditional_t_, typelist<>, typelist>...> { }; template using filter_out_t = typename filter_out::type; template struct uniq; template using uniq_t = typename uniq::type; template <> struct uniq> { using type = typelist<>; }; template struct uniq> : concat, uniq_t>>> { }; template using size_t_ = std::integral_constant; template struct length; template using length_t = typename length::type; template struct length> : size_t_ { }; template using no_of_uniques = length_t...>>>; //----------------------------------------------------------------------------------------------------------// //////////////// template class Z> struct quote_c { template using apply = Z; }; template struct apply_typelist; template using apply_typelist_t = typename apply_typelist::type; template struct apply_typelist> { using type = typename MFC::template apply; }; //----------------------------------------------------------------------------------------------------------// // Check if indices appear more than twice [for Einstein summation] //----------------------------------------------------------------------------------------------------------// namespace useless { template constexpr const T& ct_max(T const& t1, T const& t2) { return t1 < t2 ? t2 : t1; } template struct count__; template struct count__ { static constexpr size_t value = std::integral_constant::value; }; template struct count__ { static constexpr size_t value = std::integral_constant::value>::value; }; template struct count__ { static constexpr size_t value = count__::value; }; template struct max_count; template <> struct max_count<> { static constexpr size_t value = std::integral_constant::value; }; template struct max_count { static constexpr size_t value = std::integral_constant::value, max_count::value)>::value; }; } // useless template struct no_more_than_two { static constexpr size_t value = std::integral_constant::value <= 2>::value; }; //----------------------------------------------------------------------------------------------------------// } #endif // TENSOR_META_H