mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 05:42:30 +00:00
Integrating scott snyder's inplace operator improvements
[SVN r12043]
This commit is contained in:
149
src/types.cpp
149
src/types.cpp
@@ -455,6 +455,61 @@ static PyObject* do_instance_nb_hex(PyObject* obj)
|
||||
return call(obj, &type_object_base::instance_number_hex);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_add(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_add, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_subtract(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_subtract, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_multiply(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_multiply, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_divide(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_divide, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_remainder(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_remainder, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_power, exponent, modulus);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_lshift(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_lshift, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_rshift(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_rshift, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_and(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_and, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_or(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_or, other);
|
||||
}
|
||||
|
||||
static PyObject* do_instance_nb_inplace_xor(PyObject* obj, PyObject* other)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_number_inplace_xor, other);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
namespace
|
||||
@@ -511,6 +566,41 @@ bool add_capability_richcompare(type_object_base::capability capability, PyTypeO
|
||||
return false;
|
||||
}
|
||||
|
||||
#if PYTHON_API_VERSION >= 1010
|
||||
# define ENABLE_INPLACE_CAPABILITY1 \
|
||||
dest->tp_flags |= Py_TPFLAGS_HAVE_INPLACEOPS;
|
||||
#else
|
||||
# define ENABLE_INPLACE_CAPABILITY1
|
||||
#endif
|
||||
#define ENABLE_INPLACE_CAPABILITY(field) \
|
||||
case type_object_base::number_##field: \
|
||||
create_method_table_if_null(dest->tp_as_number); \
|
||||
dest->tp_as_number->nb_##field = &do_instance_nb_##field; \
|
||||
detail::shared_pod_manager::replace_if_equal(dest->tp_as_number); \
|
||||
ENABLE_INPLACE_CAPABILITY1 \
|
||||
return true
|
||||
|
||||
bool add_capability_inplace(type_object_base::capability capability, PyTypeObject* dest)
|
||||
{
|
||||
assert(dest != 0);
|
||||
switch (capability)
|
||||
{
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_add);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_subtract);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_multiply);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_divide);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_remainder);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_power);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_lshift);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_rshift);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_and);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_or);
|
||||
ENABLE_INPLACE_CAPABILITY (inplace_xor);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define ENABLE_MAPPING_CAPABILITY(field) \
|
||||
case type_object_base::mapping_##field: \
|
||||
create_method_table_if_null(dest); \
|
||||
@@ -626,6 +716,8 @@ namespace detail {
|
||||
return;
|
||||
if(add_capability_richcompare(capability, dest_))
|
||||
return;
|
||||
if(add_capability_inplace(capability, dest_))
|
||||
return;
|
||||
if(add_capability_mapping(capability, dest_->tp_as_mapping))
|
||||
return;
|
||||
if(add_capability_sequence(capability, dest_->tp_as_sequence))
|
||||
@@ -970,7 +1062,7 @@ PyObject* type_object_base::instance_number_divmod(PyObject*, PyObject*) const
|
||||
|
||||
PyObject* type_object_base::instance_number_power(PyObject*, PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_divmod");
|
||||
return unimplemented("instance_number_power");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_negative(PyObject*) const
|
||||
@@ -1053,6 +1145,61 @@ PyObject* type_object_base::instance_number_hex(PyObject*) const
|
||||
return unimplemented("instance_number_hex");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_add(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_add");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_subtract(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_subtract");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_multiply(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_multiply");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_divide(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_divide");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_remainder(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_remainder");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_power");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_lshift(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_lshift");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_rshift(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_rshift");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_and(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_and");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_or(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_or");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_number_inplace_xor(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_number_inplace_xor");
|
||||
}
|
||||
|
||||
PyObject* type_object_base::instance_lt(PyObject*, PyObject*) const
|
||||
{
|
||||
return unimplemented("instance_lt");
|
||||
|
||||
@@ -667,7 +667,7 @@ int total_Ints = 0;
|
||||
|
||||
struct Int
|
||||
{
|
||||
explicit Int(int i) : i_(i) {
|
||||
explicit Int(int i) : i_(i), j_(0) {
|
||||
#ifndef NDEBUG
|
||||
++total_Ints;
|
||||
#endif
|
||||
@@ -675,12 +675,29 @@ struct Int
|
||||
|
||||
#ifndef NDEBUG
|
||||
~Int() { --total_Ints; }
|
||||
Int(const Int& rhs) : i_(rhs.i_) { ++total_Ints; }
|
||||
Int(const Int& rhs) : i_(rhs.i_), j_(rhs.j_) { ++total_Ints; }
|
||||
#endif
|
||||
|
||||
int i() const { return i_; }
|
||||
int j() const { return j_; }
|
||||
|
||||
int i_;
|
||||
int j_;
|
||||
|
||||
Int& operator +=(Int const& r) { ++j_; i_ += r.i_; return *this; }
|
||||
Int& operator -=(Int const& r) { ++j_; i_ -= r.i_; return *this; }
|
||||
Int& operator *=(Int const& r) { ++j_; i_ *= r.i_; return *this; }
|
||||
Int& operator /=(Int const& r) { ++j_; i_ /= r.i_; return *this; }
|
||||
Int& operator %=(Int const& r) { ++j_; i_ %= r.i_; return *this; }
|
||||
Int& ipow (Int const& r) { ++j_;
|
||||
int o=i_;
|
||||
for (int k=1; k<r.i_; k++) i_ *= o;
|
||||
return *this; }
|
||||
Int& operator <<=(Int const& r) { ++j_; i_ <<= r.i_; return *this; }
|
||||
Int& operator >>=(Int const& r) { ++j_; i_ >>= r.i_; return *this; }
|
||||
Int& operator &=(Int const& r) { ++j_; i_ &= r.i_; return *this; }
|
||||
Int& operator |=(Int const& r) { ++j_; i_ |= r.i_; return *this; }
|
||||
Int& operator ^=(Int const& r) { ++j_; i_ ^= r.i_; return *this; }
|
||||
};
|
||||
|
||||
Int operator+(Int const & l, Int const & r) { return Int(l.i_ + r.i_); }
|
||||
@@ -868,6 +885,19 @@ namespace bpl_test {
|
||||
double freal(const std::complex<float>& c) { return c.real(); }
|
||||
double fimag(std::complex<float> c) { return c.imag(); }
|
||||
|
||||
// Wrappers for inplace operators.
|
||||
Int& int_iadd(Int& self, const Int& r) { self += r; return self; }
|
||||
Int& int_isub(Int& self, const Int& r) { self -= r; return self; }
|
||||
Int& int_imul(Int& self, const Int& r) { self *= r; return self; }
|
||||
Int& int_idiv(Int& self, const Int& r) { self /= r; return self; }
|
||||
Int& int_imod(Int& self, const Int& r) { self %= r; return self; }
|
||||
Int& int_ipow(Int& self, const Int& r) { self.ipow (r); return self; }
|
||||
Int& int_ilshift(Int& self, const Int& r) { self <<= r; return self; }
|
||||
Int& int_irshift(Int& self, const Int& r) { self >>= r; return self; }
|
||||
Int& int_iand(Int& self, const Int& r) { self &= r; return self; }
|
||||
Int& int_ior(Int& self, const Int& r) { self |= r; return self; }
|
||||
Int& int_ixor(Int& self, const Int& r) { self ^= r; return self; }
|
||||
|
||||
/************************************************************/
|
||||
/* */
|
||||
/* init the module */
|
||||
@@ -1042,6 +1072,7 @@ void init_module(boost::python::module_builder& m)
|
||||
boost::python::class_builder<Int> int_class(m, "Int");
|
||||
int_class.def(boost::python::constructor<int>());
|
||||
int_class.def(&Int::i, "i");
|
||||
int_class.def(&Int::j, "j");
|
||||
|
||||
// wrap homogeneous operators
|
||||
int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_neg |
|
||||
@@ -1061,6 +1092,19 @@ void init_module(boost::python::module_builder& m)
|
||||
boost::python::left_operand<int const & >());
|
||||
// export non-operator function as heterogeneous reverse-argument operator
|
||||
int_class.def(&rmul, "__rmul__");
|
||||
|
||||
// inplace operators.
|
||||
int_class.def(&int_iadd, "__iadd__");
|
||||
int_class.def(&int_isub, "__isub__");
|
||||
int_class.def(&int_imul, "__imul__");
|
||||
int_class.def(&int_idiv, "__idiv__");
|
||||
int_class.def(&int_imod, "__imod__");
|
||||
int_class.def(&int_ipow, "__ipow__");
|
||||
int_class.def(&int_ilshift, "__ilshift__");
|
||||
int_class.def(&int_irshift, "__irshift__");
|
||||
int_class.def(&int_iand, "__iand__");
|
||||
int_class.def(&int_ior, "__ior__");
|
||||
int_class.def(&int_ixor, "__ixor__");
|
||||
|
||||
|
||||
boost::python::class_builder<EnumOwner> enum_owner(m, "EnumOwner");
|
||||
|
||||
Reference in New Issue
Block a user