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:
@@ -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_
|
||||
|
||||
36
caller.h
36
caller.h
@@ -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
60
cast.h
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
330
extclass.h
330
extclass.h
@@ -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_
|
||||
|
||||
|
||||
@@ -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__");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
67
functions.h
67
functions.h
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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)
|
||||
|
||||
6
module.h
6
module.h
@@ -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();
|
||||
|
||||
240
newtypes.cpp
240
newtypes.cpp
@@ -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
|
||||
|
||||
|
||||
10
newtypes.h
10
newtypes.h
@@ -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
4
none.h
@@ -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_
|
||||
|
||||
@@ -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)
|
||||
|
||||
58
operators.h
58
operators.h
@@ -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
2
py.h
@@ -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)
|
||||
|
||||
17
signatures.h
17
signatures.h
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
106
subclass.cpp
106
subclass.cpp
@@ -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)
|
||||
|
||||
15
subclass.h
15
subclass.h
@@ -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) {}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user