2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-24 06:02:14 +00:00

detail-ification

[SVN r8270]
This commit is contained in:
Dave Abrahams
2000-11-21 06:54:33 +00:00
parent b34a2a3754
commit 9e376229d8
24 changed files with 577 additions and 568 deletions

View File

@@ -14,7 +14,7 @@
# include "wrap_python.h"
# include <cstring>
namespace py {
namespace py { namespace detail {
// BaseObject - adds a constructor and non-virtual destructor to a
// base Python type (e.g. PyObject, PyTypeObject).
@@ -57,6 +57,6 @@ inline BaseObject<PythonType>::~BaseObject()
Py_DECREF(ob_type);
}
}
}} // namespace py::detail
#endif // BASE_OBJECT_DWA051600_H_

View File

@@ -262,7 +262,7 @@ struct Caller<void>
return 0;
T& target = from_python(self, Type<T&>());
(target.*pmf)();
return none();
return detail::none();
}
template <class T, class A1>
@@ -273,7 +273,7 @@ struct Caller<void>
return 0;
T& target = from_python(self, Type<T&>());
(target.*pmf)(from_python(a1, Type<A1>()));
return none();
return detail::none();
}
template <class T, class A1, class A2>
@@ -286,7 +286,7 @@ struct Caller<void>
T& target = from_python(self, Type<T&>());
(target.*pmf)(from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()));
return none();
return detail::none();
}
template <class T, class A1, class A2, class A3>
@@ -301,7 +301,7 @@ struct Caller<void>
(target.*pmf)(from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>()));
return none();
return detail::none();
}
template <class T, class A1, class A2, class A3, class A4>
@@ -318,7 +318,7 @@ struct Caller<void>
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>()),
from_python(a4, Type<A4>()));
return none();
return detail::none();
}
template <class T, class A1, class A2, class A3, class A4, class A5>
@@ -337,7 +337,7 @@ struct Caller<void>
from_python(a3, Type<A3>()),
from_python(a4, Type<A4>()),
from_python(a5, Type<A5>()));
return none();
return detail::none();
}
@@ -348,7 +348,7 @@ struct Caller<void>
return 0;
T& target = from_python(self, Type<T&>());
(target.*pmf)();
return none();
return detail::none();
}
template <class T, class A1>
@@ -359,7 +359,7 @@ struct Caller<void>
return 0;
T& target = from_python(self, Type<T&>());
(target.*pmf)(from_python(a1, Type<A1>()));
return none();
return detail::none();
}
template <class T, class A1, class A2>
@@ -372,7 +372,7 @@ struct Caller<void>
T& target = from_python(self, Type<T&>());
(target.*pmf)(from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()));
return none();
return detail::none();
}
template <class T, class A1, class A2, class A3>
@@ -387,7 +387,7 @@ struct Caller<void>
(target.*pmf)(from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>()));
return none();
return detail::none();
}
template <class T, class A1, class A2, class A3, class A4>
@@ -404,7 +404,7 @@ struct Caller<void>
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>()),
from_python(a4, Type<A4>()));
return none();
return detail::none();
}
template <class T, class A1, class A2, class A3, class A4, class A5>
@@ -423,7 +423,7 @@ struct Caller<void>
from_python(a3, Type<A3>()),
from_python(a4, Type<A4>()),
from_python(a5, Type<A5>()));
return none();
return detail::none();
}
@@ -432,7 +432,7 @@ struct Caller<void>
if (!PyArg_ParseTuple(args, const_cast<char*>("")))
return 0;
f();
return none();
return detail::none();
}
template <class A1>
@@ -441,7 +441,7 @@ struct Caller<void>
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &a1))
return 0;
f(from_python(a1, Type<A1>()));
return none();
return detail::none();
}
template <class A1, class A2>
@@ -452,7 +452,7 @@ struct Caller<void>
return 0;
f(from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()));
return none();
return detail::none();
}
template <class A1, class A2, class A3>
@@ -465,7 +465,7 @@ struct Caller<void>
f(from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>()));
return none();
return detail::none();
}
template <class A1, class A2, class A3, class A4>
@@ -480,7 +480,7 @@ struct Caller<void>
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>()),
from_python(a4, Type<A4>()));
return none();
return detail::none();
}
template <class A1, class A2, class A3, class A4, class A5>
@@ -497,7 +497,7 @@ struct Caller<void>
from_python(a3, Type<A3>()),
from_python(a4, Type<A4>()),
from_python(a5, Type<A5>()));
return none();
return detail::none();
}
};

60
cast.h
View File

@@ -14,33 +14,35 @@
namespace py {
// The default way of converting a PyObject* or PyTypeObject* to a T*
template <class T>
struct DowncastTraits
{
template <class U>
static T* cast(U* p) { return static_cast<T*>(p); }
};
namespace detail {
// The default way of converting a PyObject* or PyTypeObject* to a T*
template <class T>
struct DowncastTraits
{
template <class U>
static T* cast(U* p) { return static_cast<T*>(p); }
};
inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p)
{
return reinterpret_cast<PyTypeObject*>(p);
}
inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p)
{
return reinterpret_cast<PyTypeObject*>(p);
}
inline PyObject* as_base_object(const PyObject*, PyObject* p)
{
return p;
}
inline PyObject* as_base_object(const PyObject*, PyObject* p)
{
return p;
}
inline const PyTypeObject* as_base_object(const PyTypeObject*, const PyObject* p)
{
return reinterpret_cast<const PyTypeObject*>(p);
}
inline const PyTypeObject* as_base_object(const PyTypeObject*, const PyObject* p)
{
return reinterpret_cast<const PyTypeObject*>(p);
}
inline const PyObject* as_base_object(const PyObject*, const PyObject* p)
{
return p;
}
inline const PyObject* as_base_object(const PyObject*, const PyObject* p)
{
return p;
}
} // namespace detail
// Convert a pointer to any type derived from PyObject or PyTypeObject to a PyObject*
inline PyObject* as_object(PyObject* p) { return p; }
@@ -52,28 +54,28 @@ template <class T>
struct Downcast : boost::dereferenceable<Downcast<T>, T*>
{
Downcast(PyObject* p)
: m_p(DowncastTraits<T>::cast(as_base_object((T*)0, p)))
: m_p(detail::DowncastTraits<T>::cast(detail::as_base_object((T*)0, p)))
{}
Downcast(const PyObject* p)
: m_p(DowncastTraits<T>::cast(as_base_object((const T*)0, p)))
: m_p(detail::DowncastTraits<T>::cast(detail::as_base_object((const T*)0, p)))
{}
Downcast(PyTypeObject* p)
: m_p(DowncastTraits<T>::cast(p))
: m_p(detail::DowncastTraits<T>::cast(p))
{}
Downcast(const PyTypeObject* p)
: m_p(DowncastTraits<T>::cast(p))
: m_p(detail::DowncastTraits<T>::cast(p))
{}
operator T*() const { return m_p; }
T* get() const { return m_p; }
T& operator*() const { return *m_p; }
private:
private:
T* m_p;
};
}
} // namespace py
#endif // CAST_DWA052500_H_

View File

@@ -11,13 +11,13 @@
namespace py {
// Syntactic sugar to make wrapping classes more convenient
template <class T, class U = HeldInstance<T> >
template <class T, class U = detail::HeldInstance<T> >
class ClassWrapper
: PyExtensionClassConverters<T, U> // Works around MSVC6.x/GCC2.95.2 bug described below
{
public:
ClassWrapper(Module& module, const char* name)
: m_class(new ExtensionClass<T, U>(name))
: m_class(new detail::ExtensionClass<T, U>(name))
{
module.add(Ptr(as_object(m_class.get()), Ptr::new_ref), name);
}
@@ -108,24 +108,8 @@ class ClassWrapper
m_class->declare_base(base.get_extension_class(), without_downcast);
}
// declare the given class a base class of this one and register
// conversion functions
template <class S, class V>
void declare_base(ExtensionClass<S, V> * base)
{
m_class->declare_base(base);
}
// declare the given class a base class of this one and register
// upcast conversion function
template <class S, class V>
void declare_base(ExtensionClass<S, V> * base, WithoutDowncast)
{
m_class->declare_base(base, without_downcast);
}
// get the embedded ExtensioClass object
ExtensionClass<T, U> * get_extension_class() const
detail::ExtensionClass<T, U> * get_extension_class() const
{
return m_class.get();
}
@@ -137,7 +121,23 @@ class ClassWrapper
void add(Ptr x, const char* name)
{ m_class->set_attribute(name, x); }
private:
PyPtr<ExtensionClass<T, U> > m_class;
// declare the given class a base class of this one and register
// conversion functions
template <class S, class V>
void declare_base(detail::ExtensionClass<S, V> * base)
{
m_class->declare_base(base);
}
// declare the given class a base class of this one and register
// upcast conversion function
template <class S, class V>
void declare_base(detail::ExtensionClass<S, V> * base, WithoutDowncast)
{
m_class->declare_base(base, without_downcast);
}
PyPtr<detail::ExtensionClass<T, U> > m_class;
};
// The bug mentioned at the top of this file is that on certain compilers static

View File

@@ -132,7 +132,6 @@ namespace detail {
return 2;
}
}
} // namespace detail
ExtensionInstance* get_extension_instance(PyObject* p)
{
@@ -448,9 +447,6 @@ void ExtensionClassBase::set_attribute(const char* name, Ptr x)
detail::enable_named_method(this, name);
}
namespace detail
{
operator_dispatcher::operator_dispatcher(const Ptr& o, const Ptr& s)
: m_object(o), m_self(s), m_free_list_link(0)

View File

@@ -25,12 +25,26 @@
namespace py {
// forward declarations
template <long which, class operand> struct operators;
template <class T> struct left_operand;
template <class T> struct right_operand;
enum WithoutDowncast { without_downcast };
namespace detail {
// forward declarations
class ExtensionInstance;
class ExtensionClassBase;
template <class T> class InstanceHolder;
template <class T, class U> class InstanceValueHolder;
template <class Ptr, class T> class InstancePtrHolder;
template <class Specified> struct operand_select;
template <long> struct choose_op;
template <long> struct choose_rop;
template <long> struct choose_unary_op;
template <long> struct define_operator;
MetaClass<ExtensionInstance>* extension_meta_class();
ExtensionInstance* get_extension_instance(PyObject* p);
@@ -49,23 +63,21 @@ T* check_non_null(T* p)
template <class T> class HeldInstance;
namespace detail {
typedef void* (*ConversionFunction)(void*);
typedef void* (*ConversionFunction)(void*);
struct BaseClassInfo
{
BaseClassInfo(ExtensionClassBase* t, ConversionFunction f)
:class_object(t), convert(f)
{}
struct BaseClassInfo
{
BaseClassInfo(ExtensionClassBase* t, ConversionFunction f)
:class_object(t), convert(f)
{}
ExtensionClassBase* class_object;
ConversionFunction convert;
};
ExtensionClassBase* class_object;
ConversionFunction convert;
};
typedef BaseClassInfo DerivedClassInfo;
typedef BaseClassInfo DerivedClassInfo;
struct add_operator_base;
}
struct add_operator_base;
class ExtensionClassBase : public Class<ExtensionInstance>
{
@@ -84,11 +96,11 @@ class ExtensionClassBase : public Class<ExtensionInstance>
private:
virtual void* extract_object_from_holder(InstanceHolderBase* v) const = 0;
virtual std::vector<py::detail::BaseClassInfo> const& base_classes() const = 0;
virtual std::vector<py::detail::DerivedClassInfo> const& derived_classes() const = 0;
virtual std::vector<BaseClassInfo> const& base_classes() const = 0;
virtual std::vector<DerivedClassInfo> const& derived_classes() const = 0;
protected:
friend struct detail::add_operator_base;
friend struct add_operator_base;
void add_method(PyPtr<Function> method, const char* name);
void add_method(Function* method, const char* name);
@@ -109,19 +121,19 @@ class ClassRegistry
static void unregister_class(ExtensionClassBase*);
// Establish C++ inheritance relationships
static void register_base_class(py::detail::BaseClassInfo const&);
static void register_derived_class(py::detail::DerivedClassInfo const&);
static void register_base_class(BaseClassInfo const&);
static void register_derived_class(DerivedClassInfo const&);
// Query the C++ inheritance relationships
static std::vector<py::detail::BaseClassInfo> const& base_classes();
static std::vector<py::detail::DerivedClassInfo> const& derived_classes();
static std::vector<BaseClassInfo> const& base_classes();
static std::vector<DerivedClassInfo> const& derived_classes();
private:
static ExtensionClassBase* static_class_object;
static std::vector<py::detail::BaseClassInfo> static_base_class_info;
static std::vector<py::detail::DerivedClassInfo> static_derived_class_info;
static std::vector<BaseClassInfo> static_base_class_info;
static std::vector<DerivedClassInfo> static_derived_class_info;
};
}
}} // namespace py::detail
PY_BEGIN_CONVERSION_NAMESPACE
@@ -129,7 +141,7 @@ PY_BEGIN_CONVERSION_NAMESPACE
// and U. T is the class the user really intends to wrap. U is a class derived
// from T with some virtual function overriding boilerplate, or if there are no
// virtual functions, U = HeldInstance<T>.
template <class T, class U = py::HeldInstance<T> >
template <class T, class U = py::detail::HeldInstance<T> >
class PyExtensionClassConverters
{
public:
@@ -160,10 +172,10 @@ class PyExtensionClassConverters
// writes code which causes us to try to copy a T.
PyObject* to_python(const T& x) const
{
py::PyPtr<py::ExtensionInstance> result(create_instance());
py::PyPtr<py::detail::ExtensionInstance> result(create_instance());
result->add_implementation(
std::auto_ptr<py::InstanceHolderBase>(
new py::InstanceValueHolder<T,U>(result.get(), x)));
std::auto_ptr<py::detail::InstanceHolderBase>(
new py::detail::InstanceValueHolder<T,U>(result.get(), x)));
return result.release();
}
@@ -171,21 +183,21 @@ class PyExtensionClassConverters
friend T* from_python(PyObject* obj, py::Type<T*>)
{
// Downcast to an ExtensionInstance, then find the actual T
py::ExtensionInstance* self = py::get_extension_instance(obj);
typedef std::vector<py::InstanceHolderBase*>::const_iterator Iterator;
py::detail::ExtensionInstance* self = py::detail::get_extension_instance(obj);
typedef std::vector<py::detail::InstanceHolderBase*>::const_iterator Iterator;
for (Iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
py::InstanceHolder<T>* held = dynamic_cast<py::InstanceHolder<T>*>(*p);
py::detail::InstanceHolder<T>* held = dynamic_cast<py::detail::InstanceHolder<T>*>(*p);
if (held != 0)
return held->target();
// see extclass.cpp for an explanation of try_class_conversions()
void* target = py::ClassRegistry<T>::class_object()->try_class_conversions(*p);
void* target = py::detail::ClassRegistry<T>::class_object()->try_class_conversions(*p);
if(target)
return static_cast<T*>(target);
}
py::report_missing_instance_data(self, py::ClassRegistry<T>::class_object(), typeid(T));
py::detail::report_missing_instance_data(self, py::detail::ClassRegistry<T>::class_object(), typeid(T));
throw py::ArgumentError();
}
@@ -194,38 +206,38 @@ class PyExtensionClassConverters
static PtrType& ptr_from_python(PyObject* obj, py::Type<PtrType>)
{
// Downcast to an ExtensionInstance, then find the actual T
py::ExtensionInstance* self = py::get_extension_instance(obj);
typedef std::vector<py::InstanceHolderBase*>::const_iterator Iterator;
py::detail::ExtensionInstance* self = py::detail::get_extension_instance(obj);
typedef std::vector<py::detail::InstanceHolderBase*>::const_iterator Iterator;
for (Iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
py::InstancePtrHolder<PtrType, T>* held =
dynamic_cast<py::InstancePtrHolder<PtrType, T>*>(*p);
py::detail::InstancePtrHolder<PtrType, T>* held =
dynamic_cast<py::detail::InstancePtrHolder<PtrType, T>*>(*p);
if (held != 0)
return held->ptr();
}
py::report_missing_ptr_data(self, py::ClassRegistry<T>::class_object(), typeid(T));
py::detail::report_missing_ptr_data(self, py::detail::ClassRegistry<T>::class_object(), typeid(T));
throw py::ArgumentError();
}
template <class PtrType>
static PyObject* ptr_to_python(PtrType x)
{
py::PyPtr<py::ExtensionInstance> result(create_instance());
py::PyPtr<py::detail::ExtensionInstance> result(create_instance());
result->add_implementation(
std::auto_ptr<py::InstanceHolderBase>(
new py::InstancePtrHolder<PtrType,T>(x)));
std::auto_ptr<py::detail::InstanceHolderBase>(
new py::detail::InstancePtrHolder<PtrType,T>(x)));
return result.release();
}
static py::PyPtr<py::ExtensionInstance> create_instance()
static py::PyPtr<py::detail::ExtensionInstance> create_instance()
{
PyTypeObject* class_object = py::ClassRegistry<T>::class_object();
PyTypeObject* class_object = py::detail::ClassRegistry<T>::class_object();
if (class_object == 0)
py::report_missing_class_object(typeid(T));
py::detail::report_missing_class_object(typeid(T));
return py::PyPtr<py::ExtensionInstance>(
new py::ExtensionInstance(class_object));
return py::PyPtr<py::detail::ExtensionInstance>(
new py::detail::ExtensionInstance(class_object));
}
// Convert to const T*
@@ -242,7 +254,7 @@ class PyExtensionClassConverters
// Convert to T&
friend T& from_python(PyObject* p, py::Type<T&>)
{ return *py::check_non_null(from_python(p, py::Type<T*>())); }
{ return *py::detail::check_non_null(from_python(p, py::Type<T*>())); }
// Convert to const T&
friend const T& from_python(PyObject* p, py::Type<const T&>)
@@ -293,6 +305,8 @@ namespace py {
PY_IMPORT_CONVERSION(PyExtensionClassConverters);
namespace detail {
template <class T> class InstanceHolder;
class ReadOnlySetattrFunction : public Function
@@ -305,72 +319,6 @@ class ReadOnlySetattrFunction : public Function
String m_name;
};
enum operator_id
{
op_add = 0x1,
op_sub = 0x2,
op_mul = 0x4,
op_div = 0x8,
op_mod = 0x10,
op_divmod =0x20,
op_pow = 0x40,
op_lshift = 0x80,
op_rshift = 0x100,
op_and = 0x200,
op_xor = 0x400,
op_or = 0x800,
op_neg = 0x1000,
op_pos = 0x2000,
op_abs = 0x4000,
op_invert = 0x8000,
op_int = 0x10000,
op_long = 0x20000,
op_float = 0x40000,
op_str = 0x80000,
op_cmp = 0x100000
};
namespace detail
{
struct auto_operand {};
template <class Specified>
struct operand_select
{
template <class WrappedType>
struct wrapped
{
typedef Specified type;
};
};
template <>
struct operand_select<auto_operand>
{
template <class WrappedType>
struct wrapped
{
typedef const WrappedType& type;
};
};
template <long> struct define_operator;
template <long> struct choose_op;
template <long> struct choose_rop;
template <long> struct choose_unary_op;
}
template <long which, class operand = py::detail::auto_operand>
struct operators {};
template <class T>
struct left_operand {};
template <class T>
struct right_operand {};
namespace detail
{
template <class From, class To>
struct DefineConversion
{
@@ -384,9 +332,6 @@ namespace detail
return dynamic_cast<To*>(static_cast<From*>(v));
}
};
}
enum WithoutDowncast { without_downcast };
// An easy way to make an extension base class which wraps T. Note that Python
// subclasses of this class will simply be Class<ExtensionInstance> objects.
@@ -439,7 +384,7 @@ class ExtensionClass
template <long which, class Operand>
inline void def(operators<which,Operand>)
{
typedef typename detail::operand_select<Operand>::template wrapped<T>::type true_operand;
typedef typename operand_select<Operand>::template wrapped<T>::type true_operand;
def_operators(operators<which,true_operand>());
}
@@ -453,7 +398,7 @@ class ExtensionClass
template <long which, class Left, class Right>
inline void def(operators<which,Left>, right_operand<Right> r)
{
typedef typename detail::operand_select<Left>::template wrapped<T>::type true_left;
typedef typename operand_select<Left>::template wrapped<T>::type true_left;
def_operators(operators<which,true_left>(), r);
}
@@ -469,7 +414,7 @@ class ExtensionClass
template <long which, class Left, class Right>
inline void def(operators<which,Right>, left_operand<Left> l)
{
typedef typename detail::operand_select<Right>::template wrapped<T>::type true_right;
typedef typename operand_select<Right>::template wrapped<T>::type true_right;
def_operators(operators<which,true_right>(), l);
}
@@ -482,7 +427,7 @@ class ExtensionClass
template <class Fn>
inline void def_raw(Fn fn, const char* name)
{
this->add_method(py::detail::new_raw_arguments_function(fn), name);
this->add_method(new_raw_arguments_function(fn), name);
}
// define member functions. In fact this works for free functions, too -
@@ -501,7 +446,7 @@ class ExtensionClass
template <class Fn, class DefaultFn>
inline void def(Fn fn, const char* name, DefaultFn default_fn)
{
this->add_method(py::detail::new_virtual_function(Type<T>(), fn, default_fn), name);
this->add_method(new_virtual_function(Type<T>(), fn, default_fn), name);
}
// Provide a function which implements x.<name>, reading from the given
@@ -543,13 +488,13 @@ class ExtensionClass
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
detail::BaseClassInfo baseInfo(base,
&detail::DefineConversion<S, T>::downcast_ptr);
BaseClassInfo baseInfo(base,
&DefineConversion<S, T>::downcast_ptr);
ClassRegistry<T>::register_base_class(baseInfo);
add_base(Ptr(as_object(base), Ptr::new_ref));
detail::DerivedClassInfo derivedInfo(this,
&detail::DefineConversion<T, S>::upcast_ptr);
DerivedClassInfo derivedInfo(this,
&DefineConversion<T, S>::upcast_ptr);
ClassRegistry<S>::register_derived_class(derivedInfo);
}
@@ -560,12 +505,12 @@ class ExtensionClass
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
detail::BaseClassInfo baseInfo(base, 0);
BaseClassInfo baseInfo(base, 0);
ClassRegistry<T>::register_base_class(baseInfo);
add_base(Ptr(as_object(base), Ptr::new_ref));
detail::DerivedClassInfo derivedInfo(this,
&detail::DefineConversion<T, S>::upcast_ptr);
DerivedClassInfo derivedInfo(this,
&DefineConversion<T, S>::upcast_ptr);
ClassRegistry<S>::register_derived_class(derivedInfo);
}
@@ -573,8 +518,8 @@ class ExtensionClass
typedef InstanceValueHolder<T,U> Holder;
private: // ExtensionClassBase virtual function implementations
std::vector<detail::BaseClassInfo> const& base_classes() const;
std::vector<detail::DerivedClassInfo> const& derived_classes() const;
std::vector<BaseClassInfo> const& base_classes() const;
std::vector<DerivedClassInfo> const& derived_classes() const;
void* extract_object_from_holder(InstanceHolderBase* v) const;
private: // Utility functions
@@ -582,28 +527,32 @@ class ExtensionClass
inline void def_operators(operators<which,Operand>)
{
register_coerce();
detail::choose_op<(which & op_add)>::template args<Operand>::add(this);
detail::choose_op<(which & op_sub)>::template args<Operand>::add(this);
detail::choose_op<(which & op_mul)>::template args<Operand>::add(this);
detail::choose_op<(which & op_div)>::template args<Operand>::add(this);
detail::choose_op<(which & op_mod)>::template args<Operand>::add(this);
detail::choose_op<(which & op_divmod)>::template args<Operand>::add(this);
detail::choose_op<(which & op_pow)>::template args<Operand>::add(this);
detail::choose_op<(which & op_lshift)>::template args<Operand>::add(this);
detail::choose_op<(which & op_rshift)>::template args<Operand>::add(this);
detail::choose_op<(which & op_and)>::template args<Operand>::add(this);
detail::choose_op<(which & op_xor)>::template args<Operand>::add(this);
detail::choose_op<(which & op_or)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_invert)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_int)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_long)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_float)>::template args<Operand>::add(this);
detail::choose_op<(which & op_cmp)>::template args<Operand>::add(this);
detail::choose_unary_op<(which & op_str)>::template args<Operand>::add(this);
// for some strange reason, this prevents MSVC from having an
// "unrecoverable block scoping error"!
typedef choose_op<(which & op_add)> choose_add;
choose_op<(which & op_add)>::template args<Operand>::add(this);
choose_op<(which & op_sub)>::template args<Operand>::add(this);
choose_op<(which & op_mul)>::template args<Operand>::add(this);
choose_op<(which & op_div)>::template args<Operand>::add(this);
choose_op<(which & op_mod)>::template args<Operand>::add(this);
choose_op<(which & op_divmod)>::template args<Operand>::add(this);
choose_op<(which & op_pow)>::template args<Operand>::add(this);
choose_op<(which & op_lshift)>::template args<Operand>::add(this);
choose_op<(which & op_rshift)>::template args<Operand>::add(this);
choose_op<(which & op_and)>::template args<Operand>::add(this);
choose_op<(which & op_xor)>::template args<Operand>::add(this);
choose_op<(which & op_or)>::template args<Operand>::add(this);
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
choose_unary_op<(which & op_invert)>::template args<Operand>::add(this);
choose_unary_op<(which & op_int)>::template args<Operand>::add(this);
choose_unary_op<(which & op_long)>::template args<Operand>::add(this);
choose_unary_op<(which & op_float)>::template args<Operand>::add(this);
choose_op<(which & op_cmp)>::template args<Operand>::add(this);
choose_unary_op<(which & op_str)>::template args<Operand>::add(this);
}
template <long which, class Left, class Right>
@@ -611,19 +560,19 @@ class ExtensionClass
{
register_coerce();
detail::choose_op<(which & op_add)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_sub)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_mul)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_div)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_mod)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_divmod)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_pow)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_lshift)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_rshift)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_and)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_or)>::template args<Left,Right>::add(this);
detail::choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
choose_op<(which & op_add)>::template args<Left,Right>::add(this);
choose_op<(which & op_sub)>::template args<Left,Right>::add(this);
choose_op<(which & op_mul)>::template args<Left,Right>::add(this);
choose_op<(which & op_div)>::template args<Left,Right>::add(this);
choose_op<(which & op_mod)>::template args<Left,Right>::add(this);
choose_op<(which & op_divmod)>::template args<Left,Right>::add(this);
choose_op<(which & op_pow)>::template args<Left,Right>::add(this);
choose_op<(which & op_lshift)>::template args<Left,Right>::add(this);
choose_op<(which & op_rshift)>::template args<Left,Right>::add(this);
choose_op<(which & op_and)>::template args<Left,Right>::add(this);
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
}
template <long which, class Left, class Right>
@@ -631,19 +580,19 @@ class ExtensionClass
{
register_coerce();
detail::choose_rop<(which & op_add)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_sub)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_mul)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_div)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_mod)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_divmod)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_pow)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_lshift)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_rshift)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_and)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_xor)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_or)>::template args<Left,Right>::add(this);
detail::choose_rop<(which & op_cmp)>::template args<Left,Right>::add(this);
choose_rop<(which & op_add)>::template args<Left,Right>::add(this);
choose_rop<(which & op_sub)>::template args<Left,Right>::add(this);
choose_rop<(which & op_mul)>::template args<Left,Right>::add(this);
choose_rop<(which & op_div)>::template args<Left,Right>::add(this);
choose_rop<(which & op_mod)>::template args<Left,Right>::add(this);
choose_rop<(which & op_divmod)>::template args<Left,Right>::add(this);
choose_rop<(which & op_pow)>::template args<Left,Right>::add(this);
choose_rop<(which & op_lshift)>::template args<Left,Right>::add(this);
choose_rop<(which & op_rshift)>::template args<Left,Right>::add(this);
choose_rop<(which & op_and)>::template args<Left,Right>::add(this);
choose_rop<(which & op_xor)>::template args<Left,Right>::add(this);
choose_rop<(which & op_or)>::template args<Left,Right>::add(this);
choose_rop<(which & op_cmp)>::template args<Left,Right>::add(this);
}
template <class Signature>
@@ -770,10 +719,7 @@ class ExtensionInstance : public Instance
// Template function implementations
//
namespace detail
{
Tuple extension_class_coerce(Ptr l, Ptr r);
}
Tuple extension_class_coerce(Ptr l, Ptr r);
template <class T, class U>
ExtensionClass<T, U>::ExtensionClass()
@@ -795,12 +741,12 @@ void ExtensionClass<T, U>::register_coerce()
Ptr coerce_fct = dict().get_item(String("__coerce__"));
if(coerce_fct.get() == 0) // not yet defined
this->def(&py::detail::extension_class_coerce, "__coerce__");
this->def(&extension_class_coerce, "__coerce__");
}
template <class T, class U>
inline
std::vector<detail::BaseClassInfo> const&
std::vector<BaseClassInfo> const&
ExtensionClass<T, U>::base_classes() const
{
return ClassRegistry<T>::base_classes();
@@ -808,7 +754,7 @@ ExtensionClass<T, U>::base_classes() const
template <class T, class U>
inline
std::vector<detail::DerivedClassInfo> const&
std::vector<DerivedClassInfo> const&
ExtensionClass<T, U>::derived_classes() const
{
return ClassRegistry<T>::derived_classes();
@@ -817,7 +763,7 @@ ExtensionClass<T, U>::derived_classes() const
template <class T, class U>
void* ExtensionClass<T, U>::extract_object_from_holder(InstanceHolderBase* v) const
{
py::InstanceHolder<T>* held = dynamic_cast<py::InstanceHolder<T>*>(v);
InstanceHolder<T>* held = dynamic_cast<InstanceHolder<T>*>(v);
if(held)
return held->target();
return 0;
@@ -847,25 +793,25 @@ inline void ClassRegistry<T>::unregister_class(ExtensionClassBase* p)
}
template <class T>
void ClassRegistry<T>::register_base_class(py::detail::BaseClassInfo const& i)
void ClassRegistry<T>::register_base_class(BaseClassInfo const& i)
{
static_base_class_info.push_back(i);
}
template <class T>
void ClassRegistry<T>::register_derived_class(py::detail::DerivedClassInfo const& i)
void ClassRegistry<T>::register_derived_class(DerivedClassInfo const& i)
{
static_derived_class_info.push_back(i);
}
template <class T>
std::vector<py::detail::BaseClassInfo> const& ClassRegistry<T>::base_classes()
std::vector<BaseClassInfo> const& ClassRegistry<T>::base_classes()
{
return static_base_class_info;
}
template <class T>
std::vector<py::detail::DerivedClassInfo> const& ClassRegistry<T>::derived_classes()
std::vector<DerivedClassInfo> const& ClassRegistry<T>::derived_classes()
{
return static_derived_class_info;
}
@@ -876,11 +822,11 @@ std::vector<py::detail::DerivedClassInfo> const& ClassRegistry<T>::derived_class
template <class T>
ExtensionClassBase* ClassRegistry<T>::static_class_object;
template <class T>
std::vector<py::detail::BaseClassInfo> ClassRegistry<T>::static_base_class_info;
std::vector<BaseClassInfo> ClassRegistry<T>::static_base_class_info;
template <class T>
std::vector<py::detail::DerivedClassInfo> ClassRegistry<T>::static_derived_class_info;
std::vector<DerivedClassInfo> ClassRegistry<T>::static_derived_class_info;
} // namespace py
}} // namespace py::detail
#endif // EXTENSION_CLASS_DWA052000_H_

View File

@@ -44,15 +44,8 @@ std::string FooCallback::pure() const
return py::Callback<std::string>::call_method(m_self, "pure");
}
// The initializer for ExtensionClass<Foo,FooCallback> is entirely optional. It
// only affects the way that instances of this class _print_ in Python. If you
// need an absolutely predictable name for the type, use the
// initializer. Otherwise, C++ will generate an implementation-dependent
// representation of the type name, usually something like "class
// extclass_demo::Foo". I've supplied it here in part so that I can write
// doctests that exactly anticipate the generated error messages.
Foo::PythonClass::PythonClass()
: py::ExtensionClass<Foo,FooCallback>("Foo") // optional
Foo::PythonClass::PythonClass(py::Module& m)
: py::ClassWrapper<Foo,FooCallback>(m, "Foo")
{
def(py::Constructor<int>());
def(&Foo::mumble, "mumble");
@@ -66,8 +59,8 @@ Foo::PythonClass::PythonClass()
// Since pure() is pure virtual, we are leaving it undefined.
}
BarPythonClass::BarPythonClass()
: py::ExtensionClass<Bar>("Bar") // optional
BarPythonClass::BarPythonClass(py::Module& m)
: py::ClassWrapper<Bar>(m, "Bar")
{
def(py::Constructor<int, int>());
def(&Bar::first, "first");
@@ -75,10 +68,10 @@ BarPythonClass::BarPythonClass()
def(&Bar::pass_baz, "pass_baz");
}
BazPythonClass::BazPythonClass()
: py::ExtensionClass<Baz>("Baz") // optional
BazPythonClass::BazPythonClass(py::Module& m)
: py::ClassWrapper<Baz>(m, "Baz") // optional
{
def(py::Constructor<py::Void>());
def(py::Constructor<>());
def(&Baz::pass_bar, "pass_bar");
def(&Baz::clone, "clone");
def(&Baz::create_foo, "create_foo");
@@ -86,10 +79,10 @@ BazPythonClass::BazPythonClass()
def(&Baz::eat_baz, "eat_baz");
}
StringMapPythonClass::StringMapPythonClass()
: py::ExtensionClass<StringMap >("StringMap")
StringMapPythonClass::StringMapPythonClass(py::Module& m)
: py::ClassWrapper<StringMap >(m, "StringMap")
{
def(py::Constructor<py::Void>());
def(py::Constructor<>());
def(&StringMap::size, "__len__");
def(&get_item, "__getitem__");
def(&set_item, "__setitem__");
@@ -112,8 +105,8 @@ void del_first(const IntPair&)
throw py::ErrorAlreadySet();
}
IntPairPythonClass::IntPairPythonClass()
: py::ExtensionClass<IntPair>("IntPair")
IntPairPythonClass::IntPairPythonClass(py::Module& m)
: py::ClassWrapper<IntPair>(m, "IntPair")
{
def(py::Constructor<int, int>());
def(&getattr, "__getattr__");
@@ -721,7 +714,7 @@ const Record* get_record()
return &v;
}
template class py::ExtensionClass<Record>; // explicitly instantiate
template class py::ClassWrapper<Record>; // explicitly instantiate
} // namespace extclass_demo
@@ -841,14 +834,14 @@ void init_module(py::Module& m)
py::ClassWrapper<Fubar> fubar(m, "Fubar");
fubar.def(py::Constructor<Foo&>());
fubar.def(py::Constructor<int>());
m.add(new Foo::PythonClass);
m.add(new BarPythonClass);
m.add(new BazPythonClass);
m.add(new StringMapPythonClass);
m.add(new IntPairPythonClass);
Foo::PythonClass foo(m);
BarPythonClass bar(m);
BazPythonClass baz(m);
StringMapPythonClass string_map(m);
IntPairPythonClass int_pair(m);
m.def(make_pair, "make_pair");
m.add(new CompareIntPairPythonClass);
CompareIntPairPythonClass compare_int_pair(m);
py::ClassWrapper<StringPair> string_pair(m, "StringPair");
string_pair.def(py::Constructor<std::string, std::string>());
@@ -896,7 +889,7 @@ void init_module(py::Module& m)
m.def(&test5, "overloaded");
py::ClassWrapper<OverloadTest> over(m, "OverloadTest");
over.def(py::Constructor<py::Void>());
over.def(py::Constructor<>());
over.def(py::Constructor<OverloadTest const &>());
over.def(py::Constructor<int>());
over.def(py::Constructor<int, int>());
@@ -937,7 +930,7 @@ void init_module(py::Module& m)
m.def(&testCallback, "testCallback");
py::ClassWrapper<CallbackTest, CallbackTestCallback> callbackTest(m, "CallbackTest");
callbackTest.def(py::Constructor<py::Void>());
callbackTest.def(py::Constructor<>());
callbackTest.def(&CallbackTest::callback, "callback",
&CallbackTestCallback::default_callback);
callbackTest.def(&CallbackTest::callbackString, "callback",
@@ -1083,10 +1076,10 @@ void initdemo()
} // Need a way to report other errors here
}
CompareIntPairPythonClass::CompareIntPairPythonClass()
: py::ExtensionClass<CompareIntPair>("CompareIntPair")
CompareIntPairPythonClass::CompareIntPairPythonClass(py::Module& m)
: py::ClassWrapper<CompareIntPair>(m, "CompareIntPair")
{
def(py::Constructor<py::Void>());
def(py::Constructor<>());
def(&CompareIntPair::operator(), "__call__");
}

View File

@@ -12,7 +12,7 @@
// Example code demonstrating extension class usage
//
# include "extclass.h"
# include "class_wrapper.h"
# include "callback.h"
# include <boost/utility.hpp>
# include <cstring>
@@ -184,21 +184,21 @@ class FooCallback : public Foo
};
// Define the Python base class
struct Foo::PythonClass : py::ExtensionClass<Foo, FooCallback> { PythonClass(); };
struct Foo::PythonClass : py::ClassWrapper<Foo, FooCallback> { PythonClass(py::Module&); };
// No virtual functions on Bar or Baz which are actually supposed to behave
// virtually from C++, so we'll rely on the library to define a wrapper for
// us. Even so, Python Class types for each type we're wrapping should be
// _defined_ here in a header where they can be seen by other extension class
// definitions, since it is the definition of the py::ExtensionClass<> that
// definitions, since it is the definition of the py::ClassWrapper<> that
// causes to_python/from_python conversion functions to be generated.
struct BarPythonClass : py::ExtensionClass<Bar> { BarPythonClass(); };
struct BazPythonClass : py::ExtensionClass<Baz> { BazPythonClass(); };
struct BarPythonClass : py::ClassWrapper<Bar> { BarPythonClass(py::Module&); };
struct BazPythonClass : py::ClassWrapper<Baz> { BazPythonClass(py::Module&); };
struct StringMapPythonClass
: py::ExtensionClass<StringMap>
: py::ClassWrapper<StringMap>
{
StringMapPythonClass();
StringMapPythonClass(py::Module&);
// These static functions implement the right argument protocols for
// implementing the Python "special member functions" for mapping on
@@ -209,9 +209,9 @@ struct StringMapPythonClass
};
struct IntPairPythonClass
: py::ExtensionClass<IntPair>
: py::ClassWrapper<IntPair>
{
IntPairPythonClass();
IntPairPythonClass(py::Module&);
// The following could just as well be a free function; it implements the
// getattr functionality for IntPair.
@@ -221,9 +221,9 @@ struct IntPairPythonClass
};
struct CompareIntPairPythonClass
: py::ExtensionClass<CompareIntPair>
: py::ClassWrapper<CompareIntPair>
{
CompareIntPairPythonClass();
CompareIntPairPythonClass(py::Module&);
};
} // namespace extclass_demo

View File

@@ -12,10 +12,10 @@
#include "objects.h"
#include "errors.h"
namespace py {
namespace py { namespace detail {
struct Function::TypeObject :
Singleton<Function::TypeObject, Callable<py::TypeObject<Function> > >
Singleton<Function::TypeObject, Callable<py::detail::TypeObject<Function> > >
{
TypeObject() : SingletonBase(&PyType_Type) {}
};
@@ -115,7 +115,7 @@ BoundFunction* BoundFunction::create(const Ptr& target, const Ptr& fn)
// attribute of built-in Python functions can be accessed when bound.
struct BoundFunction::TypeObject :
Singleton<BoundFunction::TypeObject,
Getattrable<Callable<py::TypeObject<BoundFunction> > > >
Getattrable<Callable<py::detail::TypeObject<BoundFunction> > > >
{
TypeObject() : SingletonBase(&PyType_Type) {}
@@ -164,4 +164,4 @@ void BoundFunction::TypeObject::dealloc(BoundFunction* instance) const
BoundFunction* BoundFunction::free_list;
}
}} // namespace py::detail

View File

@@ -20,7 +20,7 @@
# include <typeinfo>
# include <vector>
namespace py {
namespace py { namespace detail {
// forward declaration
class ExtensionInstance;
@@ -158,41 +158,39 @@ inline Function* new_wrapped_function(F pmf)
return new_wrapped_function_aux(return_value(pmf), pmf);
}
namespace detail {
template <class R, class Args, class Keywords>
Function* new_raw_arguments_function(R (*pmf)(Args, Keywords))
{
return new raw_arguments_function<R, Args, Keywords>(pmf);
}
template <class R, class Args, class Keywords>
Function* new_raw_arguments_function(R (*pmf)(Args, Keywords))
{
return new raw_arguments_function<R, Args, Keywords>(pmf);
}
// A helper function for new_virtual_function(), below. Implements the core
// functionality once the return type has already been deduced. R is expected to
// be Type<X>, where X is the actual return type of V.
template <class T, class R, class V, class D>
inline Function* new_virtual_function_aux(
Type<T>, R, V virtual_function_ptr, D default_implementation
)
{
// We can't just use "typename R::Type" below because MSVC (incorrectly) pukes.
typedef typename R::Type ReturnType;
return new virtual_function<T, ReturnType, V, D>(
virtual_function_ptr, default_implementation);
}
// A helper function for new_virtual_function(), below. Implements the core
// functionality once the return type has already been deduced. R is expected to
// be Type<X>, where X is the actual return type of V.
template <class T, class R, class V, class D>
inline Function* new_virtual_function_aux(
Type<T>, R, V virtual_function_ptr, D default_implementation
)
{
// We can't just use "typename R::Type" below because MSVC (incorrectly) pukes.
typedef typename R::Type ReturnType;
return new virtual_function<T, ReturnType, V, D>(
virtual_function_ptr, default_implementation);
}
// Create and return a new virtual_function object wrapping the given
// virtual_function_ptr and default_implementation
template <class T, class V, class D>
inline Function* new_virtual_function(
Type<T>, V virtual_function_ptr, D default_implementation
)
{
// Deduce the return type and pass it off to the helper function above
return new_virtual_function_aux(
Type<T>(), return_value(virtual_function_ptr),
virtual_function_ptr, default_implementation);
}
} // namespace detail
// Create and return a new virtual_function object wrapping the given
// virtual_function_ptr and default_implementation
template <class T, class V, class D>
inline Function* new_virtual_function(
Type<T>, V virtual_function_ptr, D default_implementation
)
{
// Deduce the return type and pass it off to the helper function above
return new_virtual_function_aux(
Type<T>(), return_value(virtual_function_ptr),
virtual_function_ptr, default_implementation);
}
// A function with a bundled "bound target" object. This is what is produced by
// the expression a.b where a is an Instance or ExtensionInstance object and b
@@ -303,7 +301,6 @@ PyObject* virtual_function<T,R,V,D>::do_call(PyObject* args, PyObject* keywords)
return Caller<R>::call(m_default_implementation, args, keywords);
}
}
}} // namespace py::detail
#endif // FUNCTIONS_DWA051400_H_

View File

@@ -11,26 +11,26 @@
#include "extclass.h"
#include <utility>
namespace py {
namespace py { namespace detail {
PyObject* Init::do_call(PyObject* args_, PyObject* keywords) const
{
Tuple args(Ptr(args_, Ptr::borrowed));
if (args[0]->ob_type->ob_type != extension_meta_class())
{
PyErr_SetString(PyExc_TypeError, "argument 1 to __init__ must be an ExtensionInstance");
return 0;
}
ExtensionInstance *self = static_cast<ExtensionInstance*>(args[0].get());
Tuple ctor_args = args.slice(1, args.size());
std::auto_ptr<InstanceHolderBase> result(
create_holder(self, ctor_args.get(), keywords));
self->add_implementation(result);
return none();
}
PyObject* Init::do_call(PyObject* args_, PyObject* keywords) const
{
Tuple args(Ptr(args_, Ptr::borrowed));
if (args[0]->ob_type->ob_type != extension_meta_class())
{
PyErr_SetString(PyExc_TypeError, "argument 1 to __init__ must be an ExtensionInstance");
return 0;
}
}
ExtensionInstance *self = static_cast<ExtensionInstance*>(args[0].get());
Tuple ctor_args = args.slice(1, args.size());
std::auto_ptr<InstanceHolderBase> result(
create_holder(self, ctor_args.get(), keywords));
self->add_implementation(result);
return none();
}
}} // namespace py::detail

View File

@@ -99,7 +99,6 @@ namespace detail {
private:
const_reference value;
};
}
class ExtensionInstance;
class InstanceHolderBase;
@@ -283,6 +282,6 @@ struct Init5 : Init
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5)).name(); }
};
}
}} // namespace py::detail
#endif // INIT_FUNCTION_DWA052000_H_

View File

@@ -26,14 +26,14 @@ Module::Module(const char* name)
{
// If this fails, you've created more than 1 Module object in your module
assert(name_holder.get() == 0);
name_holder = Ptr(PyObject_GetAttrString(m_module, "__name__"));
name_holder = Ptr(PyObject_GetAttrString(m_module, const_cast<char*>("__name__")));
}
void
Module::add(Function* x, const char* name)
Module::add(detail::Function* x, const char* name)
{
PyPtr<Function> f(x); // First take possession of the object.
Function::add_to_namespace(f, name, PyModule_GetDict(m_module));
PyPtr<detail::Function> f(x); // First take possession of the object.
detail::Function::add_to_namespace(f, name, PyModule_GetDict(m_module));
}
void Module::add(Ptr x, const char* name)

View File

@@ -25,20 +25,20 @@ class Module
Module(const char* name);
// Add elements to the module
void add(Function* x, const char* name);
void add(detail::Function* x, const char* name);
void add(PyTypeObject* x, const char* name = 0);
void add(Ptr x, const char*name);
template <class Fn>
void def_raw(Fn fn, const char* name)
{
add(py::detail::new_raw_arguments_function(fn), name);
add(detail::new_raw_arguments_function(fn), name);
}
template <class Fn>
void def(Fn fn, const char* name)
{
add(new_wrapped_function(fn), name);
add(detail::new_wrapped_function(fn), name);
}
static String name();

View File

@@ -22,131 +22,133 @@ namespace py {
namespace {
PyObject* call(PyObject* instance, PyObject* (TypeObjectBase::*f)(PyObject*) const)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance);
}
catch(...)
{
handle_exception();
return 0;
}
}
using detail::TypeObjectBase;
// Naming this differently allows us to use it for functions returning long on
// compilers without partial ordering
template <class R>
R int_call(PyObject* instance, R (TypeObjectBase::*f)(PyObject*) const)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance);
}
catch(...)
{
handle_exception();
return -1;
}
}
PyObject* call(PyObject* instance, PyObject* (TypeObjectBase::*f)(PyObject*) const)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance);
}
catch(...)
{
handle_exception();
return 0;
}
}
// Implemented in terms of int_call, above
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*) const)
{
return int_call(instance, f);
}
// Naming this differently allows us to use it for functions returning long on
// compilers without partial ordering
template <class R>
R int_call(PyObject* instance, R (TypeObjectBase::*f)(PyObject*) const)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance);
}
catch(...)
{
handle_exception();
return -1;
}
}
template <class A1>
PyObject* call(PyObject* instance, PyObject* (TypeObjectBase::*f)(PyObject*, A1) const, A1 a1)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1);
}
catch(...)
{
handle_exception();
return 0;
}
}
// Implemented in terms of int_call, above
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*) const)
{
return int_call(instance, f);
}
template <class A1>
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*, A1) const, A1 a1)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1);
}
catch(...)
{
handle_exception();
return -1;
}
}
template <class A1>
PyObject* call(PyObject* instance, PyObject* (TypeObjectBase::*f)(PyObject*, A1) const, A1 a1)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1);
}
catch(...)
{
handle_exception();
return 0;
}
}
template <class A1, class A2>
PyObject* call(PyObject* instance, PyObject* (TypeObjectBase::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1, a2);
}
catch(...)
{
handle_exception();
return 0;
}
}
template <class A1, class A2>
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1, a2);
}
catch(...)
{
handle_exception();
return -1;
}
}
template <class A1, class A2, class A3>
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*, A1, A2, A3) const, A1 a1, A2 a2, A3 a3)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1, a2, a3);
}
catch(...)
{
handle_exception();
return -1;
}
}
template <class A1>
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*, A1) const, A1 a1)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1);
}
catch(...)
{
handle_exception();
return -1;
}
}
int call_length_function(PyObject* instance, int (TypeObjectBase::*f)(PyObject*) const)
{
try
{
const int outcome =
(static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance);
if (outcome < 0)
{
PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0");
return -1;
}
return outcome;
}
catch(...)
{
handle_exception();
return -1;
}
}
template <class A1, class A2>
PyObject* call(PyObject* instance, PyObject* (TypeObjectBase::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1, a2);
}
catch(...)
{
handle_exception();
return 0;
}
}
template <class A1, class A2>
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1, a2);
}
catch(...)
{
handle_exception();
return -1;
}
}
template <class A1, class A2, class A3>
int call(PyObject* instance, int (TypeObjectBase::*f)(PyObject*, A1, A2, A3) const, A1 a1, A2 a2, A3 a3)
{
try
{
return (static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance, a1, a2, a3);
}
catch(...)
{
handle_exception();
return -1;
}
}
int call_length_function(PyObject* instance, int (TypeObjectBase::*f)(PyObject*) const)
{
try
{
const int outcome =
(static_cast<TypeObjectBase*>(instance->ob_type)->*f)(instance);
if (outcome < 0)
{
PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0");
return -1;
}
return outcome;
}
catch(...)
{
handle_exception();
return -1;
}
}
} // anonymous namespace

View File

@@ -32,6 +32,9 @@
namespace py {
class String;
namespace detail {
class InstanceHolderBase;
class TypeObjectBase : public PythonType
@@ -295,8 +298,6 @@ PyObject* Reprable<Base>::instance_repr(PyObject* instance) const
return Downcast<Instance>(instance)->repr();
}
namespace detail {
class shared_pod_manager
{
typedef std::pair<char*, std::size_t> Holder;
@@ -353,6 +354,8 @@ namespace detail {
void add_capability(TypeObjectBase::Capability capability,
PyTypeObject* dest);
// This macro gets the length of an array as a compile-time constant, and will
// fail to compile if the parameter is a pointer.
# define PY_ARRAY_LENGTH(a) \
(sizeof(::py::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0)
@@ -361,8 +364,7 @@ namespace detail {
template<typename T>
inline int countof_validate(const void*, T);
}
}
}} // namespace py::detail
#endif // TYPES_DWA051800_H_

4
none.h
View File

@@ -12,10 +12,10 @@
# include "pyconfig.h"
# include "wrap_python.h"
namespace py {
namespace py { namespace detail {
inline PyObject* none() { Py_INCREF(Py_None); return Py_None; }
}
}} // namespace py::detail
#endif // NONE_DWA_052000_H_

View File

@@ -97,7 +97,7 @@ Tuple::Tuple(std::size_t n)
: Object(Ptr(PyTuple_New(n)))
{
for (std::size_t i = 0; i < n; ++i)
PyTuple_SET_ITEM(get(), i, none());
PyTuple_SET_ITEM(get(), i, detail::none());
}
Tuple::Tuple(Ptr p)

View File

@@ -11,6 +11,64 @@
namespace py {
namespace detail {
struct auto_operand {};
}
enum operator_id
{
op_add = 0x1,
op_sub = 0x2,
op_mul = 0x4,
op_div = 0x8,
op_mod = 0x10,
op_divmod =0x20,
op_pow = 0x40,
op_lshift = 0x80,
op_rshift = 0x100,
op_and = 0x200,
op_xor = 0x400,
op_or = 0x800,
op_neg = 0x1000,
op_pos = 0x2000,
op_abs = 0x4000,
op_invert = 0x8000,
op_int = 0x10000,
op_long = 0x20000,
op_float = 0x40000,
op_str = 0x80000,
op_cmp = 0x100000
};
template <long which, class operand = py::detail::auto_operand>
struct operators {};
template <class T>
struct left_operand {};
template <class T>
struct right_operand {};
namespace detail
{
template <class Specified>
struct operand_select
{
template <class WrappedType>
struct wrapped
{
typedef Specified type;
};
};
template <>
struct operand_select<auto_operand>
{
template <class WrappedType>
struct wrapped
{
typedef const WrappedType& type;
};
};
template <long> struct define_operator;

2
py.h
View File

@@ -235,7 +235,7 @@ inline PyObject* to_python(bool b)
inline PyObject* to_python(void)
{
return py::none();
return py::detail::none();
}
inline PyObject* to_python(const char* s)

View File

@@ -12,11 +12,13 @@
# include "pyconfig.h"
namespace py {
namespace py {
namespace detail {
// A stand-in for the built-in void. This one can be passed to functions and
// (under MSVC, which has a bug, be used as a default template type parameter).
struct Void {};
}
// An envelope in which type information can be delivered for the purposes
// of selecting an overloaded from_python() function. This is needed to work
@@ -35,11 +37,12 @@ struct Type
};
template <>
struct Type<Void>
struct Type<py::detail::Void>
{
typedef Void Id;
typedef py::detail::Void Id;
};
namespace detail {
// These basically encapsulate a chain of types, , used to make the syntax of
// add(Constructor<T1, ...>()) work. We need to produce a unique type for each number
// of non-default parameters to Constructor<>. Q: why not use a recursive
@@ -89,11 +92,15 @@ inline Signature1<X> prepend(Type<X>, Signature0)
// signature results in a Void signature again.
inline Signature0 prepend(Void, Signature0) { return Signature0(); }
template <class A1 = Void, class A2 = Void, class A3 = Void, class A4 = Void, class A5 = Void>
} // namespace detail
template <class A1 = detail::Void, class A2 = detail::Void, class A3 = detail::Void, class A4 = detail::Void, class A5 = detail::Void>
struct Constructor
{
};
namespace detail {
// Return value extraction:
// This is just another little envelope for carrying a typedef (see Type,
@@ -160,6 +167,6 @@ ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4) const) { return ReturnValue
template <class R, class T, class A1, class A2, class A3, class A4, class A5>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5) const) { return ReturnValue<R>(); }
}
}} // namespace py::detail
#endif

View File

@@ -11,7 +11,7 @@
# include "pyconfig.h"
namespace py {
namespace py { namespace detail {
struct Empty {};
template <class Derived, class Base = Empty>
@@ -48,6 +48,6 @@ Derived* Singleton<Derived,Base>::singleton()
return &x;
}
}
}} // namespace py::detail
#endif

View File

@@ -62,21 +62,21 @@ namespace {
//
PyObject* class_reduce(PyObject* klass)
{
return PyObject_GetAttrString(klass, "__name__");
return PyObject_GetAttrString(klass, const_cast<char*>("__name__"));
}
Ptr global_class_reduce()
{
static Ptr result(py::new_wrapped_function(class_reduce));
static Ptr result(detail::new_wrapped_function(class_reduce));
return result;
}
Tuple instance_reduce(PyObject* instance)
{
Ptr instance_class(PyObject_GetAttrString(instance, "__class__"));
Ptr instance_class(PyObject_GetAttrString(instance, const_cast<char*>("__class__")));
Ptr getinitargs(PyObject_GetAttrString(instance, "__getinitargs__"),
Ptr getinitargs(PyObject_GetAttrString(instance, const_cast<char*>("__getinitargs__")),
Ptr::null_ok);
PyErr_Clear();
Ptr initargs;
@@ -90,7 +90,7 @@ namespace {
initargs = Ptr(PyTuple_New(0));
}
Ptr getstate(PyObject_GetAttrString(instance, "__getstate__"),
Ptr getstate(PyObject_GetAttrString(instance, const_cast<char*>("__getstate__")),
Ptr::null_ok);
PyErr_Clear();
if (getstate.get() != 0)
@@ -99,7 +99,7 @@ namespace {
return Tuple(instance_class, initargs, state);
}
Ptr state(PyObject_GetAttrString(instance, "__dict__"), Ptr::null_ok);
Ptr state(PyObject_GetAttrString(instance, const_cast<char*>("__dict__")), Ptr::null_ok);
PyErr_Clear();
if (state.get() != 0 && Dict(state).size() > 0)
{
@@ -111,7 +111,7 @@ namespace {
Ptr global_instance_reduce()
{
static Ptr result(py::new_wrapped_function(instance_reduce));
static Ptr result(detail::new_wrapped_function(instance_reduce));
return result;
}
}
@@ -120,7 +120,7 @@ namespace {
namespace detail {
ClassBase::ClassBase(PyTypeObject* meta_class, String name, Tuple bases, const Dict& name_space)
: py::TypeObjectBase(meta_class),
: TypeObjectBase(meta_class),
m_name(name),
m_bases(bases),
m_name_space(name_space)
@@ -319,7 +319,7 @@ namespace detail {
}
Instance::Instance(PyTypeObject* class_)
: PythonObject(class_)
: py::detail::BaseObject<PyObject>(class_)
{
}
@@ -348,7 +348,7 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
if (!PY_CSTD_::strcmp(name, "__reduce__"))
{
return new BoundFunction(Ptr(this, Ptr::new_ref), global_instance_reduce());
return new detail::BoundFunction(Ptr(this, Ptr::new_ref), global_instance_reduce());
}
Ptr local_attribute = m_name_space.get_item(String(name).reference());
@@ -418,7 +418,7 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
}
else
{
return BoundFunction::create(Ptr(this, Ptr::borrowed), class_attribute);
return detail::BoundFunction::create(Ptr(this, Ptr::borrowed), class_attribute);
}
}
@@ -712,52 +712,52 @@ namespace {
struct NamedCapability
{
const char* name;
TypeObjectBase::Capability capability;
detail::TypeObjectBase::Capability capability;
};
const NamedCapability enablers[] =
{
{ "__hash__", TypeObjectBase::hash },
{ "__cmp__", TypeObjectBase::compare },
{ "__repr__", TypeObjectBase::repr },
{ "__str__", TypeObjectBase::str },
{ "__call__", TypeObjectBase::call },
{ "__getattr__", TypeObjectBase::getattr },
{ "__setattr__", TypeObjectBase::setattr },
{ "__len__", TypeObjectBase::mapping_length },
{ "__len__", TypeObjectBase::sequence_length },
{ "__getitem__", TypeObjectBase::mapping_subscript },
{ "__getitem__", TypeObjectBase::sequence_item },
{ "__setitem__", TypeObjectBase::mapping_ass_subscript },
{ "__setitem__", TypeObjectBase::sequence_ass_item },
{ "__delitem__", TypeObjectBase::mapping_ass_subscript },
{ "__delitem__", TypeObjectBase::sequence_ass_item },
{ "__getslice__", TypeObjectBase::sequence_slice },
{ "__setslice__", TypeObjectBase::sequence_ass_slice },
{ "__delslice__", TypeObjectBase::sequence_ass_slice },
{ "__add__", TypeObjectBase::number_add },
{ "__sub__", TypeObjectBase::number_subtract },
{ "__mul__", TypeObjectBase::number_multiply },
{ "__div__", TypeObjectBase::number_divide },
{ "__mod__", TypeObjectBase::number_remainder },
{ "__divmod__", TypeObjectBase::number_divmod },
{ "__pow__", TypeObjectBase::number_power },
{ "__neg__", TypeObjectBase::number_negative },
{ "__pos__", TypeObjectBase::number_positive },
{ "__abs__", TypeObjectBase::number_absolute },
{ "__nonzero__", TypeObjectBase::number_nonzero },
{ "__invert__", TypeObjectBase::number_invert },
{ "__lshift__", TypeObjectBase::number_lshift },
{ "__rshift__", TypeObjectBase::number_rshift },
{ "__and__", TypeObjectBase::number_and },
{ "__xor__", TypeObjectBase::number_xor },
{ "__or__", TypeObjectBase::number_or },
{ "__coerce__", TypeObjectBase::number_coerce },
{ "__int__", TypeObjectBase::number_int },
{ "__long__", TypeObjectBase::number_long },
{ "__float__", TypeObjectBase::number_float },
{ "__oct__", TypeObjectBase::number_oct },
{ "__hex__", TypeObjectBase::number_hex }
{ "__hash__", detail::TypeObjectBase::hash },
{ "__cmp__", detail::TypeObjectBase::compare },
{ "__repr__", detail::TypeObjectBase::repr },
{ "__str__", detail::TypeObjectBase::str },
{ "__call__", detail::TypeObjectBase::call },
{ "__getattr__", detail::TypeObjectBase::getattr },
{ "__setattr__", detail::TypeObjectBase::setattr },
{ "__len__", detail::TypeObjectBase::mapping_length },
{ "__len__", detail::TypeObjectBase::sequence_length },
{ "__getitem__", detail::TypeObjectBase::mapping_subscript },
{ "__getitem__", detail::TypeObjectBase::sequence_item },
{ "__setitem__", detail::TypeObjectBase::mapping_ass_subscript },
{ "__setitem__", detail::TypeObjectBase::sequence_ass_item },
{ "__delitem__", detail::TypeObjectBase::mapping_ass_subscript },
{ "__delitem__", detail::TypeObjectBase::sequence_ass_item },
{ "__getslice__", detail::TypeObjectBase::sequence_slice },
{ "__setslice__", detail::TypeObjectBase::sequence_ass_slice },
{ "__delslice__", detail::TypeObjectBase::sequence_ass_slice },
{ "__add__", detail::TypeObjectBase::number_add },
{ "__sub__", detail::TypeObjectBase::number_subtract },
{ "__mul__", detail::TypeObjectBase::number_multiply },
{ "__div__", detail::TypeObjectBase::number_divide },
{ "__mod__", detail::TypeObjectBase::number_remainder },
{ "__divmod__", detail::TypeObjectBase::number_divmod },
{ "__pow__", detail::TypeObjectBase::number_power },
{ "__neg__", detail::TypeObjectBase::number_negative },
{ "__pos__", detail::TypeObjectBase::number_positive },
{ "__abs__", detail::TypeObjectBase::number_absolute },
{ "__nonzero__", detail::TypeObjectBase::number_nonzero },
{ "__invert__", detail::TypeObjectBase::number_invert },
{ "__lshift__", detail::TypeObjectBase::number_lshift },
{ "__rshift__", detail::TypeObjectBase::number_rshift },
{ "__and__", detail::TypeObjectBase::number_and },
{ "__xor__", detail::TypeObjectBase::number_xor },
{ "__or__", detail::TypeObjectBase::number_or },
{ "__coerce__", detail::TypeObjectBase::number_coerce },
{ "__int__", detail::TypeObjectBase::number_int },
{ "__long__", detail::TypeObjectBase::number_long },
{ "__float__", detail::TypeObjectBase::number_float },
{ "__oct__", detail::TypeObjectBase::number_oct },
{ "__hex__", detail::TypeObjectBase::number_hex }
};
bool is_prefix(const char* s1, const char* s2)

View File

@@ -20,7 +20,8 @@
namespace py {
// A simple type which acts something like a built-in Python class instance.
class Instance : public PythonObject
class Instance
: public py::detail::PythonObject
{
public:
Instance(PyTypeObject* class_);
@@ -83,7 +84,7 @@ class Instance : public PythonObject
template <class T> class MetaClass;
namespace detail {
class ClassBase : public py::TypeObjectBase
class ClassBase : public TypeObjectBase
{
public:
ClassBase(PyTypeObject* meta_class, String name, Tuple bases, const Dict& name_space);
@@ -185,7 +186,11 @@ class Class
// The type of a Class<T> object.
template <class T>
class MetaClass
: public Reprable<Callable<Getattrable<Setattrable<TypeObject<Class<T> > > > > >,
: public py::detail::Reprable<
py::detail::Callable<
py::detail::Getattrable<
py::detail::Setattrable<
py::detail::TypeObject<Class<T> > > > > >,
boost::noncopyable
{
public:
@@ -195,7 +200,9 @@ class MetaClass
PyObject* call(PyObject* args, PyObject* keywords);
struct TypeObject
: Singleton<TypeObject, Callable<py::TypeObject<MetaClass> > >
: py::detail::Singleton<TypeObject,
py::detail::Callable<
py::detail::TypeObject<MetaClass> > >
{
TypeObject() : SingletonBase(&PyType_Type) {}
};