/usr/include/boost/python
Edit: /usr/include/boost/python/operators.hpp (14278B)
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef OPERATORS_DWA2002530_HPP
# define OPERATORS_DWA2002530_HPP
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
namespace boost { namespace python {
namespace detail
{
// This is essentially the old v1 to_python(). It will be eliminated
// once the public interface for to_python is settled on.
template
PyObject* convert_result(T const& x)
{
return converter::arg_to_python(x).release();
}
// Operator implementation template declarations. The nested apply
// declaration here keeps MSVC6 happy.
template struct operator_l
{
template struct apply;
};
template struct operator_r
{
template struct apply;
};
template struct operator_1
{
template struct apply;
};
// MSVC6 doesn't want us to do this sort of inheritance on a nested
// class template, so we use this layer of indirection to avoid
// ::template<...> on the nested apply functions below
template
struct operator_l_inner
: operator_l::template apply
{};
template
struct operator_r_inner
: operator_r::template apply
{};
template
struct operator_1_inner
: operator_1::template apply
{};
// Define three different binary_op templates which take care of
// these cases:
// self op self
// self op R
// L op self
//
// The inner apply metafunction is used to adjust the operator to
// the class type being defined. Inheritance of the outer class is
// simply used to provide convenient access to the operation's
// name().
// self op self
template
struct binary_op : operator_l
{
template
struct apply : operator_l_inner
{
};
};
// self op R
template
struct binary_op_l : operator_l
{
template
struct apply : operator_l_inner
{
};
};
// L op self
template
struct binary_op_r : operator_r
{
template
struct apply : operator_r_inner
{
};
};
template
struct unary_op : operator_1
{
template
struct apply : operator_1_inner
{
};
};
// This type is what actually gets returned from operators used on
// self_t
template
struct operator_
: def_visitor >
{
private:
template
void visit(ClassT& cl) const
{
typedef typename mpl::eval_if<
is_same
, mpl::if_<
is_same
, binary_op
, binary_op_l<
id
, BOOST_DEDUCED_TYPENAME unwrap_other::type
>
>
, mpl::if_<
is_same
, unary_op
, binary_op_r<
id
, BOOST_DEDUCED_TYPENAME unwrap_other::type
>
>
>::type generator;
cl.def(
generator::name()
, &generator::template apply<
BOOST_DEDUCED_TYPENAME ClassT::wrapped_type
>::execute
);
}
friend class python::def_visitor_access;
};
}
# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
namespace detail \
{ \
template <> \
struct operator_l \
{ \
template \
struct apply \
{ \
typedef typename unwrap_wrapper_::type lhs; \
typedef typename unwrap_wrapper_::type rhs; \
static PyObject* execute(lhs& l, rhs const& r) \
{ \
return detail::convert_result(expr); \
} \
}; \
static char const* name() { return "__" #id "__"; } \
}; \
\
template <> \
struct operator_r \
{ \
template \
struct apply \
{ \
typedef typename unwrap_wrapper_::type lhs; \
typedef typename unwrap_wrapper_::type rhs; \
static PyObject* execute(rhs& r, lhs const& l) \
{ \
return detail::convert_result(expr); \
} \
}; \
static char const* name() { return "__" #rid "__"; } \
}; \
}
# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
namespace self_ns \
{ \
template \
inline detail::operator_ \
operator op(L const&, R const&) \
{ \
return detail::operator_(); \
} \
}
BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_BINARY_OPERATOR(truediv, rtruediv, /)
#else
BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
#endif
BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
BOOST_PYTHON_BINARY_OPERATOR(and, rand, &)
BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^)
BOOST_PYTHON_BINARY_OPERATOR(or, ror, |)
BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >)
BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=)
BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <)
BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
# undef BOOST_PYTHON_BINARY_OPERATOR
// pow isn't an operator in C++; handle it specially.
BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
# undef BOOST_PYTHON_BINARY_OPERATION
namespace self_ns
{
# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
template
inline detail::operator_
pow(L const&, R const&)
{
return detail::operator_();
}
# else
// When there's no argument-dependent lookup, we need these
// overloads to handle the case when everything is imported into the
// global namespace. Note that the plain overload below does /not/
// take const& arguments. This is needed by MSVC6 at least, or it
// complains of ambiguities, since there's no partial ordering.
inline detail::operator_
pow(self_t, self_t)
{
return detail::operator_();
}
template
inline detail::operator_
pow(self_t const&, R const&)
{
return detail::operator_();
}
template
inline detail::operator_
pow(L const&, self_t const&)
{
return detail::operator_();
}
# endif
}
# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
namespace detail \
{ \
template <> \
struct operator_l \
{ \
template \
struct apply \
{ \
typedef typename unwrap_wrapper_::type lhs; \
typedef typename unwrap_wrapper_::type rhs; \
static PyObject* \
execute(back_reference l, rhs const& r) \
{ \
l.get() op r; \
return python::incref(l.source().ptr()); \
} \
}; \
static char const* name() { return "__" #id "__"; } \
}; \
} \
namespace self_ns \
{ \
template \
inline detail::operator_ \
operator op(self_t const&, R const&) \
{ \
return detail::operator_(); \
} \
}
BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=)
BOOST_PYTHON_INPLACE_OPERATOR(isub,-=)
BOOST_PYTHON_INPLACE_OPERATOR(imul,*=)
BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=)
BOOST_PYTHON_INPLACE_OPERATOR(imod,%=)
BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=)
BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=)
BOOST_PYTHON_INPLACE_OPERATOR(iand,&=)
BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=)
BOOST_PYTHON_INPLACE_OPERATOR(ior,|=)
# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \
namespace detail \
{ \
template <> \
struct operator_1 \
{ \
template \
struct apply \
{ \
typedef typename unwrap_wrapper_::type self_t; \
static PyObject* execute(self_t& x) \
{ \
return detail::convert_result(op(x)); \
} \
}; \
static char const* name() { return "__" #id "__"; } \
}; \
} \
namespace self_ns \
{ \
inline detail::operator_ \
func_name(self_t const&) \
{ \
return detail::operator_(); \
} \
}
# undef BOOST_PYTHON_INPLACE_OPERATOR
BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_UNARY_OPERATOR(bool, !!, operator!)
#else
BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
#endif
BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_)
BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str)
BOOST_PYTHON_UNARY_OPERATOR(repr, lexical_cast, repr)
# undef BOOST_PYTHON_UNARY_OPERATOR
}} // namespace boost::python
# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
using boost::python::self_ns::abs;
using boost::python::self_ns::int_;
using boost::python::self_ns::long_;
using boost::python::self_ns::float_;
using boost::python::self_ns::complex_;
using boost::python::self_ns::str;
using boost::python::self_ns::repr;
using boost::python::self_ns::pow;
# endif
#endif // OPERATORS_DWA2002530_HPP