📄 operators.hpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// binary_operator<TagT, T0, T1>
//
// The binary_operator class implements most of the C++ binary
// operators. Each specialization is basically a simple static eval
// function plus a result_type typedef that determines the return
// type of the eval function.
//
// TagT is one of the binary operator tags above T0 and T1 are the
// (arguments') data types involved in the operation.
//
// Only the behavior of C/C++ built-in types are taken into account
// in the specializations provided below. For user-defined types,
// these specializations may still be used provided that the
// operator overloads of such types adhere to the standard behavior
// of built-in types.
//
// T1 separate special_ops.hpp file implements more stl savvy
// specializations. Other more specialized unary_operator
// implementations may be defined by the client for specific
// unary operator tags/data types.
//
// All binary_operator except the logical_and_op and logical_or_op
// have an eval static function that carries out the actual operation.
// The logical_and_op and logical_or_op d are special because these
// two operators are short-circuit evaluated.
//
///////////////////////////////////////////////////////////////////////////////
template <typename TagT, typename T0, typename T1>
struct binary_operator;
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs = rhs; }
};
//////////////////////////////////
template <typename T1>
struct binary_operator<index_op, nil_t, T1> {
// G++ eager template instantiation
// somehow requires this.
typedef nil_t result_type;
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<index_op, T0*, T1> {
typedef T0& result_type;
static result_type eval(T0* ptr, T1 const& index)
{ return ptr[index]; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<index_op, T0* const, T1> {
typedef T0& result_type;
static result_type eval(T0* const ptr, T1 const& index)
{ return ptr[index]; }
};
//////////////////////////////////
template <typename T0, int N, typename T1>
struct binary_operator<index_op, T0[N], T1> {
typedef T0& result_type;
static result_type eval(T0* ptr, T1 const& index)
{ return ptr[index]; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<plus_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs += rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<minus_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs -= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<times_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs *= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<divide_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs /= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<mod_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs %= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<and_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs &= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<or_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs |= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<xor_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs ^= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<shift_l_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs <<= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<shift_r_assign_op, T0, T1> {
typedef T0& result_type;
static result_type eval(T0& lhs, T1 const& rhs)
{ return lhs >>= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<plus_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs + rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<minus_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs - rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<times_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs * rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<divide_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs / rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<mod_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs % rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<and_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs & rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<or_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs | rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<xor_op, T0, T1> {
typedef typename higher_rank<T0, T1>::type const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs ^ rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<shift_l_op, T0, T1> {
typedef T0 const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs << rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<shift_r_op, T0, T1> {
typedef T0 const result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs >> rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<eq_op, T0, T1> {
typedef bool result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs == rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<not_eq_op, T0, T1> {
typedef bool result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs != rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<lt_op, T0, T1> {
typedef bool result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs < rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<lt_eq_op, T0, T1> {
typedef bool result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs <= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<gt_op, T0, T1> {
typedef bool result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs > rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<gt_eq_op, T0, T1> {
typedef bool result_type;
static result_type eval(T0 const& lhs, T1 const& rhs)
{ return lhs >= rhs; }
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<logical_and_op, T0, T1> {
typedef bool result_type;
// no eval function, see comment above.
};
//////////////////////////////////
template <typename T0, typename T1>
struct binary_operator<logical_or_op, T0, T1> {
typedef bool result_type;
// no eval function, see comment above.
};
///////////////////////////////////////////////////////////////////////////////
//
// negative lazy operator (prefix -)
//
///////////////////////////////////////////////////////////////////////////////
struct negative_op {
template <typename T0>
struct result {
typedef typename unary_operator<negative_op, T0>::result_type type;
};
template <typename T0>
typename unary_operator<negative_op, T0>::result_type
operator()(T0& _0) const
{ return unary_operator<negative_op, T0>::eval(_0); }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_unary<negative_op, BaseT>::type
operator-(actor<BaseT> const& _0)
{
return impl::make_unary<negative_op, BaseT>::construct(_0);
}
///////////////////////////////////////////////////////////////////////////////
//
// positive lazy operator (prefix +)
//
///////////////////////////////////////////////////////////////////////////////
struct positive_op {
template <typename T0>
struct result {
typedef typename unary_operator<positive_op, T0>::result_type type;
};
template <typename T0>
typename unary_operator<positive_op, T0>::result_type
operator()(T0& _0) const
{ return unary_operator<positive_op, T0>::eval(_0); }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_unary<positive_op, BaseT>::type
operator+(actor<BaseT> const& _0)
{
return impl::make_unary<positive_op, BaseT>::construct(_0);
}
///////////////////////////////////////////////////////////////////////////////
//
// logical not lazy operator (prefix !)
//
///////////////////////////////////////////////////////////////////////////////
struct logical_not_op {
template <typename T0>
struct result {
typedef typename unary_operator<logical_not_op, T0>::result_type type;
};
template <typename T0>
typename unary_operator<logical_not_op, T0>::result_type
operator()(T0& _0) const
{ return unary_operator<logical_not_op, T0>::eval(_0); }
};
//////////////////////////////////
template <typename BaseT>
inline typename impl::make_unary<logical_not_op, BaseT>::type
operator!(actor<BaseT> const& _0)
{
return impl::make_unary<logical_not_op, BaseT>::construct(_0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -