2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 05:22:45 +00:00

Support a more minimal interface

UPPERCASE_MACRO_NAMES


[SVN r8213]
This commit is contained in:
Dave Abrahams
2000-11-15 05:58:53 +00:00
parent 65dce1d510
commit 4eff7ba8a9

View File

@@ -2,343 +2,418 @@
#define OPERATORS_UK112000_H_
#include "functions.h"
#include <strstream>
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
# include <sstream>
#else
# include <strstream>
#endif
namespace py
{
namespace py {
namespace detail
{
namespace detail {
template <>
struct define_operator<0>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* keywords) const
{
PyErr_SetString(PyExc_TypeError, "operator not implemented");
throw ErrorAlreadySet();
}
template <long> struct define_operator;
const char* description() const
{ return "__error__"; }
struct add_operator_base
{
protected:
static inline void add_method(ExtensionClassBase* target, Function* method, const char* name)
{ target->add_method(method, name); }
};
};
template <class left, class right = left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* keywords) const
{
PyErr_SetString(PyExc_TypeError, "operator not implemented");
throw ErrorAlreadySet();
}
template <long op_selector>
struct choose_op
{
template <class Left, class Right = Left>
struct args : add_operator_base
{
static inline void add(ExtensionClassBase* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
new typename def_op::template operator_function<Left, Right>(),
def_op::name());
}
const char* description() const
{ return "__error__"; }
};
};
template <>
struct choose_op<0>
{
template <class Left, class Right = Left>
struct args
{
static inline void add(ExtensionClassBase*)
{
}
};
};
};
template <long op_selector>
struct choose_unary_op
{
template <class Operand>
struct args : add_operator_base
{
static inline void add(ExtensionClassBase* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
new typename def_op::template operator_function<Operand>(),
def_op::name());
}
static const char * name() { return "__error__"; }
static const char * rname() { return "__error__"; }
};
};
};
template <>
struct choose_unary_op<0>
{
template <class Operand>
struct args
{
static inline void add(ExtensionClassBase*)
{
}
#define py_define_binary_operators(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class left, class right = left> \
struct operator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) oper \
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())); \
} \
\
const char* description() const \
{ return "__" #id "__"; } \
\
}; \
template <class right, class left> \
struct roperator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) oper \
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())); \
} \
\
const char* description() const \
{ return "__r" #id "__"; } \
\
}; \
\
static const char * name() { return "__" #id "__"; } \
static const char * rname() { return "__r" #id "__"; } \
}
#define py_define_unary_operators(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class operand> \
struct operator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
oper(PY_CONVERSION::from_python(args[0].get(), py::Type<operand>()))); \
} \
\
const char* description() const \
{ return "__" #id "__"; } \
\
}; \
\
static const char * name() { return "__" #id "__"; } \
}
#define py_define_conversion_operators(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class operand> \
struct operator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
oper(PY_CONVERSION::from_python(args[0].get(), py::Type<operand>()))); \
} \
\
const char* description() const \
{ return "__" #id "_"; } \
\
}; \
\
static const char * name() { return "__" #id "_"; } \
}
py_define_binary_operators(add, +);
py_define_binary_operators(sub, -);
py_define_binary_operators(mul, *);
py_define_binary_operators(div, /);
py_define_binary_operators(mod, %);
py_define_binary_operators(lshift, <<);
py_define_binary_operators(rshift, >>);
py_define_binary_operators(and, &);
py_define_binary_operators(xor, ^);
py_define_binary_operators(or, |);
};
};
template <long op_selector>
struct choose_rop
{
template <class Left, class Right = Left>
struct args : add_operator_base
{
static inline void add(ExtensionClassBase* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
new typename def_op::template roperator_function<Right, Left>(),
def_op::rname());
}
py_define_unary_operators(neg, -);
py_define_unary_operators(pos, +);
py_define_unary_operators(abs, abs);
py_define_unary_operators(invert, ~);
};
};
template <>
struct choose_rop<0>
{
template <class Left, class Right = Left>
struct args
{
static inline void add(ExtensionClassBase*)
{
}
py_define_conversion_operators(int, int);
py_define_conversion_operators(long, long);
py_define_conversion_operators(float, double);
};
};
#define PY_DEFINE_BINARY_OPERATORS(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class left, class right = left> \
struct operator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) oper \
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())); \
} \
\
const char* description() const \
{ return "__" #id "__"; } \
\
}; \
template <class right, class left> \
struct roperator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) oper \
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())); \
} \
\
const char* description() const \
{ return "__r" #id "__"; } \
\
}; \
\
static const char * name() { return "__" #id "__"; } \
static const char * rname() { return "__r" #id "__"; } \
}
#undef py_define_binary_operators
#undef py_define_unary_operators
#undef py_define_conversion_operators
template <>
struct define_operator<op_pow>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
#define PY_DEFINE_UNARY_OPERATORS(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class operand> \
struct operator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
oper(PY_CONVERSION::from_python(args[0].get(), py::Type<operand>()))); \
} \
\
const char* description() const \
{ return "__" #id "__"; } \
\
}; \
\
static const char * name() { return "__" #id "__"; } \
}
if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
throw ArgumentError();
}
#define PY_DEFINE_CONVERSION_OPERATORS(id, oper) \
template <> \
struct define_operator<op_##id> \
{ \
template <class operand> \
struct operator_function : Function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
\
return PY_CONVERSION::to_python( \
oper(PY_CONVERSION::from_python(args[0].get(), py::Type<operand>()))); \
} \
\
const char* description() const \
{ return "__" #id "_"; } \
\
}; \
\
static const char * name() { return "__" #id "_"; } \
}
return PY_CONVERSION::to_python(
pow(PY_CONVERSION::from_python(args[0].get(), py::Type<left>()),
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())));
}
PY_DEFINE_BINARY_OPERATORS(add, +);
PY_DEFINE_BINARY_OPERATORS(sub, -);
PY_DEFINE_BINARY_OPERATORS(mul, *);
PY_DEFINE_BINARY_OPERATORS(div, /);
PY_DEFINE_BINARY_OPERATORS(mod, %);
PY_DEFINE_BINARY_OPERATORS(lshift, <<);
PY_DEFINE_BINARY_OPERATORS(rshift, >>);
PY_DEFINE_BINARY_OPERATORS(and, &);
PY_DEFINE_BINARY_OPERATORS(xor, ^);
PY_DEFINE_BINARY_OPERATORS(or, |);
const char* description() const
{ return "__pow__"; }
PY_DEFINE_UNARY_OPERATORS(neg, -);
PY_DEFINE_UNARY_OPERATORS(pos, +);
PY_DEFINE_UNARY_OPERATORS(abs, abs);
PY_DEFINE_UNARY_OPERATORS(invert, ~);
};
PY_DEFINE_CONVERSION_OPERATORS(int, int);
PY_DEFINE_CONVERSION_OPERATORS(long, long);
PY_DEFINE_CONVERSION_OPERATORS(float, double);
template <class right, class left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
#undef PY_DEFINE_BINARY_OPERATORS
#undef PY_DEFINE_UNARY_OPERATORS
#undef PY_DEFINE_CONVERSION_OPERATORS
if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
throw ArgumentError();
}
template <>
struct define_operator<op_pow>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
return PY_CONVERSION::to_python(
pow(PY_CONVERSION::from_python(args[1].get(), py::Type<left>()),
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())));
}
if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
throw ArgumentError();
}
const char* description() const
{ return "__rpow__"; }
return PY_CONVERSION::to_python(
pow(PY_CONVERSION::from_python(args[0].get(), py::Type<left>()),
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())));
}
};
const char* description() const
{ return "__pow__"; }
static const char * name() { return "__pow__"; }
static const char * rname() { return "__rpow__"; }
};
};
template <>
struct define_operator<op_divmod>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
PyObject * res = PyTuple_New(2);
template <class right, class left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
PyTuple_SET_ITEM(res, 0,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) /
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())));
PyTuple_SET_ITEM(res, 1,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) %
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())));
if(args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
throw ArgumentError();
}
return res;
}
return PY_CONVERSION::to_python(
pow(PY_CONVERSION::from_python(args[1].get(), py::Type<left>()),
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())));
}
const char* description() const
{ return "__divmod__"; }
const char* description() const
{ return "__rpow__"; }
};
};
template <class right, class left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
PyObject * res = PyTuple_New(2);
static const char * name() { return "__pow__"; }
static const char * rname() { return "__rpow__"; }
};
PyTuple_SET_ITEM(res, 0,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) /
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())));
PyTuple_SET_ITEM(res, 1,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) %
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())));
template <>
struct define_operator<op_divmod>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
PyObject * res = PyTuple_New(2);
return res;
}
PyTuple_SET_ITEM(res, 0,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) /
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())));
PyTuple_SET_ITEM(res, 1,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) %
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())));
const char* description() const
{ return "__rdivmod__"; }
return res;
}
};
const char* description() const
{ return "__divmod__"; }
static const char * name() { return "__divmod__"; }
static const char * rname() { return "__rdivmod__"; }
};
};
template <>
struct define_operator<op_cmp>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
template <class right, class left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
PyObject * res = PyTuple_New(2);
return PY_CONVERSION::to_python(
(PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) <
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())) ?
- 1 :
(PY_CONVERSION::from_python(args[1].get(), py::Type<right>()) <
PY_CONVERSION::from_python(args[0].get(), py::Type<left>())) ?
1 :
0) ;
}
PyTuple_SET_ITEM(res, 0,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) /
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())));
PyTuple_SET_ITEM(res, 1,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) %
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())));
const char* description() const
{ return "__cmp__"; }
return res;
}
};
const char* description() const
{ return "__rdivmod__"; }
template <class right, class left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
};
return PY_CONVERSION::to_python(
(PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) <
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())) ?
- 1 :
(PY_CONVERSION::from_python(args[0].get(), py::Type<right>()) <
PY_CONVERSION::from_python(args[1].get(), py::Type<left>())) ?
1 :
0) ;
}
static const char * name() { return "__divmod__"; }
static const char * rname() { return "__rdivmod__"; }
};
const char* description() const
{ return "__rcmp__"; }
template <>
struct define_operator<op_cmp>
{
template <class left, class right = left>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
};
return PY_CONVERSION::to_python(
(PY_CONVERSION::from_python(args[0].get(), py::Type<left>()) <
PY_CONVERSION::from_python(args[1].get(), py::Type<right>())) ?
- 1 :
(PY_CONVERSION::from_python(args[1].get(), py::Type<right>()) <
PY_CONVERSION::from_python(args[0].get(), py::Type<left>())) ?
1 :
0) ;
}
static const char * name() { return "__cmp__"; }
static const char * rname() { return "__rcmp__"; }
};
const char* description() const
{ return "__cmp__"; }
template <>
struct define_operator<op_str>
{
template <class operand>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* keywords) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
};
std::strstream s;
s << PY_CONVERSION::from_python(args[0].get(), py::Type<operand>());
template <class right, class left>
struct roperator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
return PY_CONVERSION::to_python(const_cast<char const *>(s.str()));
}
return PY_CONVERSION::to_python(
(PY_CONVERSION::from_python(args[1].get(), py::Type<left>()) <
PY_CONVERSION::from_python(args[0].get(), py::Type<right>())) ?
- 1 :
(PY_CONVERSION::from_python(args[0].get(), py::Type<right>()) <
PY_CONVERSION::from_python(args[1].get(), py::Type<left>())) ?
1 :
0) ;
}
const char* description() const
{ return "__str__"; }
const char* description() const
{ return "__rcmp__"; }
};
};
static const char * name() { return "__str__"; }
};
static const char * name() { return "__cmp__"; }
static const char * rname() { return "__rcmp__"; }
};
template <>
struct define_operator<op_str>
{
template <class operand>
struct operator_function : Function
{
PyObject* do_call(PyObject* arguments, PyObject*) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
std::ostringstream s;
#else
std::strstream s;
#endif
s << PY_CONVERSION::from_python(args[0].get(), py::Type<operand>());
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
return PY_CONVERSION::to_python(s.str());
#else
return PY_CONVERSION::to_python(const_cast<char const *>(s.str()));
#endif
}
const char* description() const
{ return "__str__"; }
};
static const char * name() { return "__str__"; }
};
} // namespace detail