74 lines
1.6 KiB
C++
74 lines
1.6 KiB
C++
#ifndef PFOR_PFOR_INDEX_INDEX_H
|
|
#define PFOR_PFOR_INDEX_INDEX_H
|
|
|
|
#include "../mp/meta.h"
|
|
#include "../mp/pack.h"
|
|
#include "op.h"
|
|
#include "tag.h"
|
|
|
|
namespace pfor {
|
|
namespace index {
|
|
|
|
using Value = long;
|
|
|
|
/**
|
|
* @param first the expression
|
|
* @param second a list of properties
|
|
*/
|
|
template<typename, typename> struct IndexImpl;
|
|
|
|
template<typename... ExprArgs>
|
|
using IndexImplExpr = IndexImpl<Pack<ExprArgs...>, Pack<>>;
|
|
|
|
template<typename P>
|
|
struct IndexImpl<Pack<>, P> {
|
|
using IsIndex = tag::Index;
|
|
using Properties = P;
|
|
|
|
inline static Value eval(Value i) { return i; }
|
|
};
|
|
|
|
template<Value n, typename P>
|
|
struct IndexImpl<Pack<IntToType<n>>, P> {
|
|
using IsIndex = tag::Index;
|
|
using Properties = P;
|
|
|
|
inline static Value eval(Value) { return n; }
|
|
};
|
|
|
|
template<typename Op, typename... Ts, typename P>
|
|
struct IndexImpl<Pack<Op, IndexImpl<Ts...>>, P> {
|
|
using IsIndex = tag::Index;
|
|
using Index = IndexImpl<Ts...>;
|
|
using Properties = P;
|
|
|
|
inline static Value eval(Value i) { return Op::eval(Index::eval(i)); }
|
|
};
|
|
|
|
template<typename Op, typename... LTs, typename... RTs, typename P>
|
|
struct IndexImpl<Pack<Op, IndexImpl<LTs...>, IndexImpl<RTs...>>, P> {
|
|
using IsIndex = tag::Index;
|
|
using LIndex = IndexImpl<LTs...>;
|
|
using RIndex = IndexImpl<RTs...>;
|
|
using Properties = P;
|
|
|
|
inline static Value eval(Value i) { return Op::eval(LIndex::eval(i), RIndex::eval(i)); }
|
|
};
|
|
|
|
template<Value n, typename P = Pack<>>
|
|
using Index = IndexImpl<Pack<IntToType<n>>, P>;
|
|
|
|
}
|
|
|
|
template<typename P = Pack<>>
|
|
using IndexP = index::IndexImpl<Pack<>, P>;
|
|
|
|
using Index = IndexP<>;
|
|
|
|
template<index::Value n, typename P = Pack<>>
|
|
constexpr index::Index<n, P> ctv;
|
|
|
|
}
|
|
|
|
#endif
|