mirror of https://github.com/aria2/aria2
Rewrite expression template to make it a bit easier
parent
b63c1dce08
commit
fa5998ba85
120
src/array_fun.h
120
src/array_fun.h
|
@ -75,91 +75,89 @@ public:
|
||||||
|
|
||||||
namespace expr {
|
namespace expr {
|
||||||
|
|
||||||
template<typename L, typename OpTag, typename R>
|
template<typename L, typename R, typename Op>
|
||||||
struct BinExpr {
|
struct BinExpr {
|
||||||
BinExpr(L l, R r):l_(l), r_(r) {}
|
typedef typename Op::result_type value_type;
|
||||||
|
|
||||||
typedef typename OpTag::returnType returnType;
|
BinExpr(L lhs, R rhs, Op op)
|
||||||
|
: lhs(std::move(lhs)), rhs(std::move(rhs)), op(std::move(op))
|
||||||
|
{}
|
||||||
|
|
||||||
returnType operator[](size_t index) const
|
value_type operator[](size_t i) const
|
||||||
{
|
{
|
||||||
return OpTag::apply(l_[index], r_[index]);
|
return op(lhs[i], rhs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const L l_;
|
L lhs;
|
||||||
const R r_;
|
R rhs;
|
||||||
|
Op op;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename OpTag, typename A>
|
template<typename L, typename R,
|
||||||
|
typename Op = std::bit_and<typename L::value_type>>
|
||||||
|
BinExpr<L, R, Op> operator&(L lhs, R rhs)
|
||||||
|
{
|
||||||
|
return BinExpr<L, R, Op>(std::forward<L>(lhs), std::forward<R>(rhs), Op());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename L, typename R,
|
||||||
|
typename Op = std::bit_or<typename L::value_type>>
|
||||||
|
BinExpr<L, R, Op> operator|(L lhs, R rhs)
|
||||||
|
{
|
||||||
|
return BinExpr<L, R, Op>(std::forward<L>(lhs), std::forward<R>(rhs), Op());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Arg, typename Op>
|
||||||
struct UnExpr {
|
struct UnExpr {
|
||||||
UnExpr(A a):a_(a) {}
|
typedef typename Op::result_type value_type;
|
||||||
|
|
||||||
typedef typename OpTag::returnType returnType;
|
UnExpr(Arg arg, Op op)
|
||||||
|
: arg(std::move(arg)), op(std::move(op))
|
||||||
|
{}
|
||||||
|
|
||||||
returnType operator[](size_t index) const
|
value_type operator[](size_t i) const
|
||||||
{
|
{
|
||||||
return OpTag::apply(a_[index]);
|
return op(arg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const A a_;
|
Arg arg;
|
||||||
|
Op op;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct And
|
struct bit_neg : std::function<T(T)> {
|
||||||
{
|
T operator()(T t) const
|
||||||
typedef T returnType;
|
{
|
||||||
static inline returnType apply(T lhs, T rhs) { return lhs&rhs; }
|
return ~t;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename Arg, typename Op = bit_neg<typename Arg::value_type>>
|
||||||
struct Or
|
UnExpr<Arg, Op> operator~(Arg arg)
|
||||||
{
|
{
|
||||||
typedef T returnType;
|
return UnExpr<Arg, Op>(std::forward<Arg>(arg), Op());
|
||||||
static inline returnType apply(T lhs, T rhs) { return lhs|rhs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Negate
|
|
||||||
{
|
|
||||||
typedef T returnType;
|
|
||||||
static inline returnType apply(T a) { return ~a; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Array
|
|
||||||
{
|
|
||||||
typedef T returnType;
|
|
||||||
|
|
||||||
Array(const T* t):t_(t) {}
|
|
||||||
|
|
||||||
const T* t_;
|
|
||||||
|
|
||||||
returnType operator[](size_t index) const { return t_[index]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Array<T>
|
|
||||||
array(const T* t) { return Array<T>(t); }
|
|
||||||
|
|
||||||
template<typename L, typename R>
|
|
||||||
BinExpr<L, And<typename L::returnType>, R>
|
|
||||||
operator&(const L& l, const R& r)
|
|
||||||
{
|
|
||||||
return BinExpr<L, And<typename L::returnType>, R>(l, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename L, typename R>
|
template<typename T>
|
||||||
BinExpr<L, Or<typename L::returnType>, R>
|
struct Array {
|
||||||
operator|(const L& l, const R& r)
|
typedef T value_type;
|
||||||
{
|
|
||||||
return BinExpr<L, Or<typename L::returnType>, R>(l, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename A>
|
Array(T* t)
|
||||||
UnExpr<Negate<typename A::returnType>, A>
|
: t(t)
|
||||||
operator~(const A& a)
|
{}
|
||||||
|
|
||||||
|
T operator[](size_t i) const
|
||||||
|
{
|
||||||
|
return t[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
T* t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Array<T> array(T *t)
|
||||||
{
|
{
|
||||||
return UnExpr<Negate<typename A::returnType>, A>(a);
|
return Array<T>(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace expr
|
} // namespace expr
|
||||||
|
|
Loading…
Reference in New Issue