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

lowercase type names

[SVN r8284]
This commit is contained in:
Dave Abrahams
2000-11-22 00:54:46 +00:00
parent 511a6e84db
commit 0f04631513
51 changed files with 3390 additions and 3300 deletions

View File

@@ -10,53 +10,53 @@
# define BASE_OBJECT_DWA051600_H_
# include "pyconfig.h"
# include "signatures.h" // really just for Type<>
# include "signatures.h" // really just for type<>
# include "wrap_python.h"
# include <cstring>
namespace py { namespace detail {
namespace python { namespace detail {
// BaseObject - adds a constructor and non-virtual destructor to a
// base_object - adds a constructor and non-virtual destructor to a
// base Python type (e.g. PyObject, PyTypeObject).
template <class PythonType>
struct BaseObject : PythonType
template <class python_type>
struct base_object : python_type
{
typedef PythonType BasePythonType;
typedef python_type base_python_type;
// Initializes type and reference count. All other fields of BasePythonType are 0
BaseObject(PyTypeObject* type_object);
// Initializes type and reference count. All other fields of base_python_type are 0
base_object(PyTypeObject* type_obj);
// Decrements reference count on the type
~BaseObject();
~base_object();
};
// Easy typedefs for common usage
typedef BaseObject<PyObject> PythonObject;
typedef BaseObject<PyTypeObject> PythonType;
typedef base_object<PyObject> python_object;
typedef base_object<PyTypeObject> python_type;
//
// Class template member function implementations
// class_t template member function implementations
//
template <class PythonType>
BaseObject<PythonType>::BaseObject(PyTypeObject* type_object)
template <class python_type>
base_object<python_type>::base_object(PyTypeObject* type_obj)
{
BasePythonType* bp = this;
base_python_type* bp = this;
#if !defined(_MSC_VER) || defined(__STLPORT)
std::
#endif
memset(bp, 0, sizeof(BasePythonType));
memset(bp, 0, sizeof(base_python_type));
ob_refcnt = 1;
ob_type = type_object;
Py_INCREF(type_object);
ob_type = type_obj;
Py_INCREF(type_obj);
}
template <class PythonType>
inline BaseObject<PythonType>::~BaseObject()
template <class python_type>
inline base_object<python_type>::~base_object()
{
Py_DECREF(ob_type);
}
}} // namespace py::detail
}} // namespace python::detail
#endif // BASE_OBJECT_DWA051600_H_

File diff suppressed because it is too large Load Diff

800
caller.h

File diff suppressed because it is too large Load Diff

24
cast.h
View File

@@ -12,12 +12,12 @@
# include "wrap_python.h"
# include <boost/operators.hpp>
namespace py {
namespace python {
namespace detail {
// The default way of converting a PyObject* or PyTypeObject* to a T*
template <class T>
struct DowncastTraits
struct downcast_traits
{
template <class U>
static T* cast(U* p) { return static_cast<T*>(p); }
@@ -51,22 +51,22 @@ inline PyObject* as_object(PyTypeObject* p) { return reinterpret_cast<PyObject*>
// If I didn't have to support stupid MSVC6 we could just use a simple template function:
// template <class T> T* downcast(PyObject*).
template <class T>
struct Downcast : boost::dereferenceable<Downcast<T>, T*>
struct downcast : boost::dereferenceable<downcast<T>, T*>
{
Downcast(PyObject* p)
: m_p(detail::DowncastTraits<T>::cast(detail::as_base_object((T*)0, p)))
downcast(PyObject* p)
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((T*)0, p)))
{}
Downcast(const PyObject* p)
: m_p(detail::DowncastTraits<T>::cast(detail::as_base_object((const T*)0, p)))
downcast(const PyObject* p)
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((const T*)0, p)))
{}
Downcast(PyTypeObject* p)
: m_p(detail::DowncastTraits<T>::cast(p))
downcast(PyTypeObject* p)
: m_p(detail::downcast_traits<T>::cast(p))
{}
Downcast(const PyTypeObject* p)
: m_p(detail::DowncastTraits<T>::cast(p))
downcast(const PyTypeObject* p)
: m_p(detail::downcast_traits<T>::cast(p))
{}
operator T*() const { return m_p; }
@@ -76,6 +76,6 @@ struct Downcast : boost::dereferenceable<Downcast<T>, T*>
T* m_p;
};
} // namespace py
} // namespace python
#endif // CAST_DWA052500_H_

View File

@@ -8,45 +8,45 @@
#include "cast.h"
#include "pyptr.h"
namespace py {
namespace python {
// Syntactic sugar to make wrapping classes more convenient
template <class T, class U = detail::HeldInstance<T> >
class ClassWrapper
template <class T, class U = detail::held_instance<T> >
class class_builder
: PyExtensionClassConverters<T, U> // Works around MSVC6.x/GCC2.95.2 bug described below
{
public:
ClassWrapper(Module& module, const char* name)
: m_class(new detail::ExtensionClass<T, U>(name))
class_builder(module_builder& module, const char* name)
: m_class(new detail::extension_class<T, U>(name))
{
module.add(Ptr(as_object(m_class.get()), Ptr::new_ref), name);
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
}
~ClassWrapper()
~class_builder()
{}
// define constructors
template <class Signature>
void def(const Signature& signature)
template <class signature>
void def(const signature& signature)
{ m_class->def(signature); }
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>(),
// py::left_operand<int const &>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>(),
// python::left_operand<int const &>());
template <long which, class left, class right>
void def(operators<which, right> o1, left_operand<left> o2)
{ m_class->def(o1, o2); }
// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>(),
// py::right_operand<int const &>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>(),
// python::right_operand<int const &>());
template <long which, class left, class right>
void def(operators<which, left> o1, right_operand<right> o2)
{ m_class->def(o1, o2); }
// define a function that passes Python arguments and keywords
// to C++ verbatim (as a 'Tuple const &' and 'Dict const &'
// to C++ verbatim (as a 'tuple const &' and 'dictionary const &'
// respectively). This is useful for manual argument passing.
// It's also the only possibility to pass keyword arguments to C++.
// Fn must have a signatur that is compatible to
@@ -71,23 +71,23 @@ class ClassWrapper
{ m_class->def(fn, name, default_fn); }
// Provide a function which implements x.<name>, reading from the given
// member (pm) of the T instance
// member (pm) of the T obj
template <class MemberType>
void def_getter(MemberType T::*pm, const char* name)
{ m_class->def_getter(pm, name); }
// Provide a function which implements assignment to x.<name>, writing to
// the given member (pm) of the T instance
// the given member (pm) of the T obj
template <class MemberType>
void def_setter(MemberType T::*pm, const char* name)
{ m_class->def_getter(pm, name); }
// Expose the given member (pm) of the T instance as a read-only attribute
// Expose the given member (pm) of the T obj as a read-only attribute
template <class MemberType>
void def_readonly(MemberType T::*pm, const char* name)
{ m_class->def_readonly(pm, name); }
// Expose the given member (pm) of the T instance as a read/write attribute
// Expose the given member (pm) of the T obj as a read/write attribute
template <class MemberType>
void def_read_write(MemberType T::*pm, const char* name)
{ m_class->def_read_write(pm, name); }
@@ -99,7 +99,7 @@ class ClassWrapper
// declare the given class a base class of this one and register
// conversion functions
template <class S, class V>
void declare_base(ClassWrapper<S, V> const & base)
void declare_base(class_builder<S, V> const & base)
{
m_class->declare_base(base.get_extension_class());
}
@@ -107,13 +107,13 @@ class ClassWrapper
// declare the given class a base class of this one and register
// upcast conversion function
template <class S, class V>
void declare_base(ClassWrapper<S, V> const & base, WithoutDowncast)
void declare_base(class_builder<S, V> const & base, without_downcast_t)
{
m_class->declare_base(base.get_extension_class(), without_downcast);
}
// get the embedded ExtensioClass object
detail::ExtensionClass<T, U> * get_extension_class() const
detail::extension_class<T, U> * get_extension_class() const
{
return m_class.get();
}
@@ -122,13 +122,13 @@ class ClassWrapper
// e.g. enums
void add(PyObject* x, const char* name)
{ m_class->set_attribute(name, x); }
void add(Ptr x, const char* name)
void add(ref x, const char* name)
{ m_class->set_attribute(name, x); }
private:
// 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)
void declare_base(detail::extension_class<S, V> * base)
{
m_class->declare_base(base);
}
@@ -136,12 +136,12 @@ class ClassWrapper
// 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)
void declare_base(detail::extension_class<S, V> * base, without_downcast_t)
{
m_class->declare_base(base, without_downcast);
}
PyPtr<detail::ExtensionClass<T, U> > m_class;
reference<detail::extension_class<T, U> > m_class;
};
// The bug mentioned at the top of this file is that on certain compilers static

View File

@@ -31,7 +31,7 @@
with the C++ Standard Library (a.k.a. STL) by providing iterators into
Python Lists and Dictionaries, but the claim is unfortunately
unsupportable. The problem is that in general, access to Python sequence and
mapping elements through iterators requires the use of Proxy objects as
mapping elements through iterators requires the use of proxy objects as
the return value of iterator dereference operations. This usage
conflicts with the basic ForwardIterator requirements in <a
href="http://anubis.dkuug.dk/jtc1/sc22/open/n2356/lib-iterators.html#lib.forward.iterators">

View File

@@ -4,7 +4,7 @@
# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
"""Module doctest -- a framework for running examples in docstrings.
"""module_builder doctest -- a framework for running examples in docstrings.
NORMAL USAGE
@@ -20,7 +20,7 @@ if __name__ == "__main__":
Then running the module as a script will cause the examples in the
docstrings to get executed and verified:
python M.py
python M.python
This won't display anything unless an example fails, in which case
the failing example(s) and the cause(s) of the failure(s) are printed
@@ -29,7 +29,7 @@ and the final line of output is "Test failed.".
Run it with the -v switch instead:
python M.py -v
python M.python -v
and a detailed report of all examples tried is printed to stdout, along
with assorted summaries at the end.
@@ -55,7 +55,7 @@ WHICH DOCSTRINGS ARE EXAMINED?
+ If M.__test__ exists and "is true", it must be a dict, and
each entry maps a (string) name to a function object, class object, or
string. Function and class object docstrings found from M.__test__
string. function and class object docstrings found from M.__test__
are searched even if the name is private, and strings are searched
directly as if they were docstrings. In output, a key K in M.__test__
appears with name
@@ -74,7 +74,7 @@ by passing your own "isprivate" function to testmod.
If you want to test docstrings in objects with private names too, stuff
them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your
own isprivate function to Tester's constructor, or call the rundoc method
of a Tester instance).
of a Tester obj).
Warning: imports can cause trouble; e.g., if you do
@@ -112,7 +112,7 @@ of M.__dict__ merged with the globals from other imported modules.
WHAT IF I WANT TO TEST A WHOLE PACKAGE?
Piece o' cake, provided the modules do their testing from docstrings.
Here's the test.py I use for the world's most elaborate Rational/
Here's the test.python I use for the world's most elaborate Rational/
floating-base-conversion pkg (which I'll distribute some day):
from Rational import Cvt
@@ -172,9 +172,9 @@ ADVANCED USAGE
doctest.testmod() captures the testing policy I find most useful most
often. You may want other policies.
testmod() actually creates a local instance of class doctest.Tester,
testmod() actually creates a local obj of class doctest.Tester,
runs appropriate methods of that class, and merges the results into
global Tester instance doctest.master.
global Tester obj doctest.master.
You can create your own instances of doctest.Tester, and so build your
own policies, or even run methods of doctest.master directly. See
@@ -326,7 +326,7 @@ Test passed.
# function
# by default a name now considered to be private iff it begins with
# an underscore but doesn't both begin & end with two of 'em; so
# e.g. Class.__init__ etc are searched now -- as they always
# e.g. class_t.__init__ etc are searched now -- as they always
# should have been
# 0,9,3 18-Mar-1999
# added .flush stub to _SpoofOut (JPython buglet diagnosed by
@@ -472,7 +472,7 @@ def _tag_out(printer, *tag_msg_pairs):
printer("\n")
# Run list of examples, in context globs. "out" can be used to display
# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut
# stuff to "the real" stdout, and fakeout is an obj of _SpoofOut
# that captures the examples' std output. Return (#failures, #tries).
def _run_examples_inner(out, fakeout, examples, globs, verbose, name):
@@ -592,7 +592,7 @@ def is_private(prefix, base):
return base[:1] == "_" and not base[:2] == "__" == base[-2:]
class Tester:
"""Class Tester -- runs docstring examples and accumulates stats.
"""class_t Tester -- runs docstring examples and accumulates stats.
In normal use, function doctest.testmod() hides all this from you,
so use that if you can. Create your own instances of Tester to do
@@ -619,7 +619,7 @@ Methods:
(#failures, #tries).
merge(other)
Merge in the test results from Tester instance "other".
Merge in the test results from Tester obj "other".
>>> from doctest import Tester
>>> t = Tester(globs={'x': 42}, verbose=0)
@@ -900,7 +900,7 @@ see its docs for details.
def merge(self, other):
"""
other -> merge in test results from the other Tester instance.
other -> merge in test results from the other Tester obj.
If self and other both have a test result for something
with the same name, the (#failures, #tests) results are
@@ -1007,9 +1007,9 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
else prints nothing at the end. In verbose mode, the summary is
detailed, else very brief (in fact, empty if all tests passed).
Advanced tomfoolery: testmod runs methods of a local instance of
Advanced tomfoolery: testmod runs methods of a local obj of
class doctest.Tester, then merges the results into (or creates)
global Tester instance doctest.master. Methods of doctest.master
global Tester obj doctest.master. Methods of doctest.master
can be called directly too, if you want to do something unusual.
Passing report=0 to testmod is especially useful then, to delay
displaying a summary. Invoke doctest.master.summarize(verbose)

View File

@@ -17,22 +17,22 @@ you can write some simple <code>from_python()</code> and
<p>If you are satisfied with a Python int as a way to represent your enum
values, py_cpp provides a shorthand for these functions. You just need to
instantiate <code>py::enum_as_int_converters&lt;EnumType&gt;</code> where
instantiate <code>python::enum_as_int_converters&lt;EnumType&gt;</code> where
<code>EnumType</code> is your enumerated type. There are two convenient ways to do this:
<ol>
<li><blockquote>
<pre>
// drop into namespace py and explicitly instantiate
namespace py {
// drop into namespace python and explicitly instantiate
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
template class enum_as_int_converters<extclass_demo::EnumOwner::enum_type>;
}
BOOST_PYTHON_END_CONVERSION_NAMESPACE
</pre>
</blockquote>
<li><blockquote><pre>
// instantiate as base class in any namespace
struct EnumTypeConverters
: py::py_enum_as_int_converters<EnumType>
: python::py_enum_as_int_converters<EnumType>
{
};
</blockquote></pre>
@@ -40,25 +40,25 @@ struct EnumTypeConverters
<p>Either of the above is equivalent to the following declarations:
<blockquote><pre>
PY_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
MyEnumType from_python(PyObject* x, py::Type&lt;MyEnumType&gt;)
MyEnumType from_python(PyObject* x, python::type&lt;MyEnumType&gt;)
{
return static_cast&lt;MyEnum&gt;(
from_python(x, py::Type&lt;long&gt;()));
from_python(x, python::type&lt;long&gt;()));
}
MyEnumType from_python(PyObject* x, py::Type&lt;const MyEnumType&amp;&gt;)
MyEnumType from_python(PyObject* x, python::type&lt;const MyEnumType&amp;&gt;)
{
return static_cast&lt;MyEnum&gt;(
from_python(x, py::Type&lt;long&gt;()));
from_python(x, python::type&lt;long&gt;()));
}
PyObject* to_python(MyEnumType x)
{
return to_python(static_cast&lt;long&gt;(x));
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
</pre></blockquote>
<p>This technique defines the conversions of
@@ -69,8 +69,8 @@ You may also want to add a bunch of lines like this to your module
initialization:
<blockquote><pre>
mymodule.add(py::to_python(enum_value_1), "enum_value_1");
mymodule.add(py::to_python(enum_value_2), "enum_value_2");
mymodule.add(python::to_python(enum_value_1), "enum_value_1");
mymodule.add(python::to_python(enum_value_2), "enum_value_2");
...
</pre></blockquote>
@@ -78,8 +78,8 @@ You can also add these to an extension class definition, if your enum happens to
be local to a class and you want the analogous interface in Python:
<blockquote><pre>
my_class.add(py::to_python(enum_value_1), "enum_value_1");
my_class.add(py::to_python(enum_value_2), "enum_value_2");
my_class.add(python::to_python(enum_value_1), "enum_value_1");
my_class.add(python::to_python(enum_value_2), "enum_value_2");
...
</pre></blockquote>
<p>

View File

@@ -9,10 +9,10 @@
#ifndef ERRORS_DWA052500_H_
# define ERRORS_DWA052500_H_
namespace py {
namespace python {
struct ErrorAlreadySet {};
struct ArgumentError : ErrorAlreadySet {};
struct error_already_set {};
struct argument_error : error_already_set {};
// Handles exceptions caught just before returning to Python code.
void handle_exception();
@@ -21,10 +21,10 @@ template <class T>
T* expect_non_null(T* x)
{
if (x == 0)
throw ErrorAlreadySet();
throw error_already_set();
return x;
}
} // namespace py
} // namespace python
#endif // ERRORS_DWA052500_H_

View File

@@ -25,13 +25,13 @@ void inithello()
try
{
// create an object representing this extension module
py::Module hello("hello");
python::module_builder hello("hello");
// Create the Python type object for our extension class
py::ClassWrapper<hello::world> world_class(hello, "world");
python::class_builder<hello::world> world_class(hello, "world");
// Add the __init__ function
world_class.def(py::Constructor<int>());
world_class.def(python::constructor<int>());
// Add a regular member function
world_class.def(&hello::world::get, "get");
@@ -40,7 +40,7 @@ void inithello()
}
catch(...)
{
py::handle_exception(); // Deal with the exception for Python
python::handle_exception(); // Deal with the exception for Python
}
}

View File

@@ -47,11 +47,11 @@ void inithello()
    try
    {
       // create an object representing this extension module
       py::Module hello("hello");
       python::module_builder hello("hello");
       // Create the Python type object for our extension class
       py::ClassWrapper&lt;hello::world&gt; world_class(hello, "world");
       python::class_builder&lt;hello::world&gt; world_class(hello, "world");
       // Add the __init__ function
       world_class.def(py::Constructor&lt;int&gt;());
       world_class.def(python::constructor&lt;int&gt;());
       // Add a regular member function
       world_class.def(&amp;hello::world::get, "get");
       // Add a regular function to the module
@@ -59,7 +59,7 @@ void inithello()
    }
    catch(...)
    {
       py::handle_exception();    // Deal with the exception for Python
       python::handle_exception();    // Deal with the exception for Python
    }
}
// Win32 DLL boilerplate

View File

@@ -10,19 +10,19 @@
#include <cstring>
#include <boost/utility.hpp>
namespace py {
namespace python {
namespace detail {
struct operator_dispatcher
: public PyObject
{
static PyTypeObject type_object;
static PyTypeObject type_obj;
static PyNumberMethods number_methods;
static operator_dispatcher* create(const Ptr& o, const Ptr& s);
static operator_dispatcher* create(const ref& o, const ref& s);
Ptr m_object;
Ptr m_self;
ref m_object;
ref m_self;
// data members for allocation/deallocation optimization
operator_dispatcher* m_free_list_link;
@@ -30,55 +30,55 @@ namespace detail {
private:
// only accessible through create()
operator_dispatcher(const Ptr& o, const Ptr& s);
operator_dispatcher(const ref& o, const ref& s);
};
operator_dispatcher* operator_dispatcher::free_list = 0;
}}
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
inline PyObject* to_python(py::detail::operator_dispatcher* n) { return n; }
inline PyObject* to_python(python::detail::operator_dispatcher* n) { return n; }
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace py{
namespace python{
namespace detail {
Tuple extension_class_coerce(Ptr l, Ptr r)
tuple extension_class_coerce(ref l, ref r)
{
// Introduced sequence points for exception-safety.
Ptr first(operator_dispatcher::create(l, l));
Ptr second;
ref first(operator_dispatcher::create(l, l));
ref second;
if(r->ob_type == &operator_dispatcher::type_object)
if(r->ob_type == &operator_dispatcher::type_obj)
{
second = r;
}
else
{
second = Ptr(operator_dispatcher::create(r, Ptr()));
second = ref(operator_dispatcher::create(r, ref()));
}
return py::Tuple(first, second);
return python::tuple(first, second);
}
enum { unwrap_exception_code = -1000 };
int unwrap_args(PyObject* left, PyObject* right, PyObject*& self, PyObject*& other)
{
if (left->ob_type != &operator_dispatcher::type_object ||
right->ob_type != &operator_dispatcher::type_object)
if (left->ob_type != &operator_dispatcher::type_obj ||
right->ob_type != &operator_dispatcher::type_obj)
{
PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_args(): expecting operator_dispatcher arguments only!");
return unwrap_exception_code;
}
typedef PyPtr<operator_dispatcher> DPtr;
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::new_ref);
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::new_ref);
typedef reference<operator_dispatcher> DPtr;
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::increment_count);
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::increment_count);
if (lwrapper->m_self.get() != 0)
{
@@ -97,18 +97,18 @@ namespace detail {
int unwrap_pow_args(PyObject* left, PyObject* right, PyObject* m,
PyObject*& self, PyObject*& first, PyObject*& second)
{
if (left->ob_type != &operator_dispatcher::type_object ||
right->ob_type != &operator_dispatcher::type_object ||
m->ob_type != &operator_dispatcher::type_object)
if (left->ob_type != &operator_dispatcher::type_obj ||
right->ob_type != &operator_dispatcher::type_obj ||
m->ob_type != &operator_dispatcher::type_obj)
{
PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_pow_args(): expecting operator_dispatcher arguments only!");
return unwrap_exception_code;
}
typedef PyPtr<operator_dispatcher> DPtr;
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::new_ref);
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::new_ref);
DPtr mwrapper(static_cast<operator_dispatcher*>(m), DPtr::new_ref);
typedef reference<operator_dispatcher> DPtr;
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::increment_count);
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::increment_count);
DPtr mwrapper(static_cast<operator_dispatcher*>(m), DPtr::increment_count);
if (lwrapper->m_self.get() != 0)
{
@@ -133,41 +133,41 @@ namespace detail {
}
}
ExtensionInstance* get_extension_instance(PyObject* p)
extension_instance* get_extension_instance(PyObject* p)
{
// The object's type will just be some Class<ExtensionInstance> object,
// but if its meta-type is right, then it is an ExtensionInstance.
// The object's type will just be some class_t<extension_instance> object,
// but if its meta-type is right, then it is an extension_instance.
if (p->ob_type->ob_type != extension_meta_class())
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw py::ArgumentError();
throw python::argument_error();
}
return static_cast<ExtensionInstance*>(p);
return static_cast<extension_instance*>(p);
}
void
ExtensionInstance::add_implementation(std::auto_ptr<InstanceHolderBase> holder)
extension_instance::add_implementation(std::auto_ptr<instance_holder_base> holder)
{
for (WrappedObjects::const_iterator p = m_wrapped_objects.begin();
for (held_objects::const_iterator p = m_wrapped_objects.begin();
p != m_wrapped_objects.end(); ++p)
{
if (typeid(*holder) == typeid(**p))
{
PyErr_SetString(PyExc_RuntimeError, "Base class already initialized");
throw ErrorAlreadySet();
throw error_already_set();
}
}
m_wrapped_objects.push_back(holder.release());
}
ExtensionInstance::ExtensionInstance(PyTypeObject* class_)
: Instance(class_)
extension_instance::extension_instance(PyTypeObject* class_)
: instance(class_)
{
}
ExtensionInstance::~ExtensionInstance()
extension_instance::~extension_instance()
{
for (WrappedObjects::const_iterator p = m_wrapped_objects.begin(),
for (held_objects::const_iterator p = m_wrapped_objects.begin(),
finish = m_wrapped_objects.end();
p != finish; ++p)
{
@@ -175,19 +175,19 @@ ExtensionInstance::~ExtensionInstance()
}
}
MetaClass<ExtensionInstance>* extension_meta_class()
meta_class<extension_instance>* extension_meta_class()
{
static MetaClass<ExtensionInstance> result;
static meta_class<extension_instance> result;
return &result;
}
typedef Class<ExtensionInstance> ExtClass;
typedef class_t<extension_instance> extension_class_t;
bool is_subclass(const ExtClass* derived,
bool is_subclass(const extension_class_t* derived,
const PyObject* possible_base)
{
Tuple bases = derived->bases();
tuple bases = derived->bases();
for (std::size_t i = 0, size = bases.size(); i < size; ++i)
{
@@ -198,7 +198,7 @@ bool is_subclass(const ExtClass* derived,
if (base->ob_type == extension_meta_class())
{
const ExtClass* base_class = Downcast<const ExtClass>(base);
const extension_class_t* base_class = downcast<const extension_class_t>(base);
if (is_subclass(base_class, possible_base))
return true;
}
@@ -206,16 +206,16 @@ bool is_subclass(const ExtClass* derived,
return false;
}
// Return true iff instance is an instance of target_class
bool is_instance(ExtensionInstance* instance,
Class<ExtensionInstance>* target_class)
// Return true iff obj is an obj of target_class
bool is_instance(extension_instance* obj,
class_t<extension_instance>* target_class)
{
if (instance->ob_type == target_class)
if (obj->ob_type == target_class)
return true;
else
{
return is_subclass(
Downcast<Class<ExtensionInstance> >(instance->ob_type).get(),
downcast<class_t<extension_instance> >(obj->ob_type).get(),
as_object(target_class));
}
}
@@ -223,9 +223,9 @@ bool is_instance(ExtensionInstance* instance,
void two_string_error(PyObject* exception_object, const char* format, const char* s1, const char* s2)
{
char buffer[256];
std::size_t format_length = PY_CSTD_::strlen(format);
std::size_t length1 = PY_CSTD_::strlen(s1);
std::size_t length2 = PY_CSTD_::strlen(s2);
std::size_t format_length = BOOST_CSTD_::strlen(format);
std::size_t length1 = BOOST_CSTD_::strlen(s1);
std::size_t length2 = BOOST_CSTD_::strlen(s2);
std::size_t additional_length = length1 + length2;
if (additional_length + format_length > format_length - 1)
@@ -239,29 +239,29 @@ void two_string_error(PyObject* exception_object, const char* format, const char
PyErr_SetString(exception_object, buffer);
if (exception_object == PyExc_TypeError)
throw ArgumentError();
throw argument_error();
else
throw ErrorAlreadySet();
throw error_already_set();
}
// This is called when an attempt has been made to convert the given instance to
// a C++ type for which it doesn't have any instance data. In that case, either
// the instance was not derived from the target_class, or the appropriate
// __init__ function wasn't called to initialize the instance data of the target class.
// This is called when an attempt has been made to convert the given obj to
// a C++ type for which it doesn't have any obj data. In that case, either
// the obj was not derived from the target_class, or the appropriate
// __init__ function wasn't called to initialize the obj data of the target class.
void report_missing_instance_data(
ExtensionInstance* instance, // The object being converted
Class<ExtensionInstance>* target_class, // the extension class of the C++ type
extension_instance* obj, // The object being converted
class_t<extension_instance>* target_class, // the extension class of the C++ type
const std::type_info& target_typeid, // The typeid of the C++ type
bool target_is_ptr)
{
char buffer[256];
if (is_instance(instance, target_class))
if (is_instance(obj, target_class))
{
if (target_is_ptr)
{
two_string_error(PyExc_RuntimeError,
"Object of extension class '%.*s' does not wrap <%.*s>.",
instance->ob_type->tp_name, target_typeid.name());
obj->ob_type->tp_name, target_typeid.name());
}
else
{
@@ -280,24 +280,24 @@ void report_missing_instance_data(
else
{
two_string_error(PyExc_TypeError, "extension class '%.*s' is not convertible into '%.*s'.",
instance->ob_type->tp_name, target_class->tp_name);
obj->ob_type->tp_name, target_class->tp_name);
}
}
void report_missing_instance_data(
ExtensionInstance* instance, // The object being converted
Class<ExtensionInstance>* target_class, // the extension class of the C++ type
extension_instance* obj, // The object being converted
class_t<extension_instance>* target_class, // the extension class of the C++ type
const std::type_info& target_typeid) // The typeid of the C++ type
{
report_missing_instance_data(instance, target_class, target_typeid, false);
report_missing_instance_data(obj, target_class, target_typeid, false);
}
void report_missing_ptr_data(
ExtensionInstance* instance, // The object being converted
Class<ExtensionInstance>* target_class, // the extension class of the C++ type
extension_instance* obj, // The object being converted
class_t<extension_instance>* target_class, // the extension class of the C++ type
const std::type_info& target_typeid) // The typeid of the C++ type
{
report_missing_instance_data(instance, target_class, target_typeid, true);
report_missing_instance_data(obj, target_class, target_typeid, true);
}
void report_missing_class_object(const std::type_info& info)
@@ -306,7 +306,7 @@ void report_missing_class_object(const std::type_info& info)
const char message[] = "Cannot convert <%.*s> to python; its Python class was never created or has been deleted.";
sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name());
PyErr_SetString(PyExc_RuntimeError, buffer);
throw ErrorAlreadySet();
throw error_already_set();
}
void report_released_smart_pointer(const std::type_info& info)
@@ -315,28 +315,28 @@ void report_released_smart_pointer(const std::type_info& info)
const char message[] = "Converting from python, pointer or smart pointer to <%.*s> is NULL.";
sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name());
PyErr_SetString(PyExc_RuntimeError, buffer);
throw ArgumentError();
throw argument_error();
}
ReadOnlySetattrFunction::ReadOnlySetattrFunction(const char* name)
read_only_setattr_function::read_only_setattr_function(const char* name)
: m_name(name)
{
}
PyObject* ReadOnlySetattrFunction::do_call(PyObject* /*args*/, PyObject* /*keywords*/) const
PyObject* read_only_setattr_function::do_call(PyObject* /*args*/, PyObject* /*keywords*/) const
{
PyErr_SetObject(PyExc_AttributeError, ("'" + m_name + "' attribute is read-only").get());
return 0;
}
const char* ReadOnlySetattrFunction::description() const
const char* read_only_setattr_function::description() const
{
return "uncallable";
}
ExtensionClassBase::ExtensionClassBase(const char* name)
: Class<ExtensionInstance>(
extension_meta_class(), String(name), Tuple(), Dict())
extension_class_base::extension_class_base(const char* name)
: class_t<extension_instance>(
extension_meta_class(), string(name), tuple(), dictionary())
{
}
@@ -356,10 +356,10 @@ ExtensionClassBase::ExtensionClassBase(const char* name)
// conversion functions will return a NULL pointer.
// The function extract_object_from_holder() attempts to actually extract the pointer
// to the contained object from an InstanceHolderBase (a wrapper class). A conversion
// to the contained object from an instance_holder_base (a wrapper class). A conversion
// of the held object to 'T *' is allowed when the conversion
// 'dynamic_cast<InstanceHolder<T> *>(an_instance_holder_base)' succeeds.
void* ExtensionClassBase::try_class_conversions(InstanceHolderBase* object) const
// 'dynamic_cast<instance_holder<T> *>(an_instance_holder_base)' succeeds.
void* extension_class_base::try_class_conversions(instance_holder_base* object) const
{
void* result = try_derived_class_conversions(object);
if (result)
@@ -371,7 +371,7 @@ void* ExtensionClassBase::try_class_conversions(InstanceHolderBase* object) cons
return 0;
}
void* ExtensionClassBase::try_base_class_conversions(InstanceHolderBase* object) const
void* extension_class_base::try_base_class_conversions(instance_holder_base* object) const
{
for (std::size_t i = 0; i < base_classes().size(); ++i)
{
@@ -388,7 +388,7 @@ void* ExtensionClassBase::try_base_class_conversions(InstanceHolderBase* object)
return 0;
}
void* ExtensionClassBase::try_derived_class_conversions(InstanceHolderBase* object) const
void* extension_class_base::try_derived_class_conversions(instance_holder_base* object) const
{
for (std::size_t i = 0; i < derived_classes().size(); ++i)
{
@@ -403,60 +403,60 @@ void* ExtensionClassBase::try_derived_class_conversions(InstanceHolderBase* obje
return 0;
}
void ExtensionClassBase::add_method(Function* method, const char* name)
void extension_class_base::add_method(function* method, const char* name)
{
add_method(PyPtr<Function>(method), name);
add_method(reference<function>(method), name);
}
void ExtensionClassBase::add_method(PyPtr<Function> method, const char* name)
void extension_class_base::add_method(reference<function> method, const char* name)
{
// Add the attribute to the computed target
Function::add_to_namespace(method, name, this->dict().get());
function::add_to_namespace(method, name, this->dict().get());
// If it is a special member function it should be enabled both here and there.
detail::enable_named_method(this, name);
}
void ExtensionClassBase::add_constructor_object(Function* init_function)
void extension_class_base::add_constructor_object(function* init_fn)
{
add_method(init_function, "__init__");
add_method(init_fn, "__init__");
}
void ExtensionClassBase::add_setter_method(Function* setter_, const char* name)
void extension_class_base::add_setter_method(function* setter_, const char* name)
{
PyPtr<Function> setter(setter_);
reference<function> setter(setter_);
add_method(setter, (detail::setattr_string() + name + "__").c_str());
}
void ExtensionClassBase::add_getter_method(Function* getter_, const char* name)
void extension_class_base::add_getter_method(function* getter_, const char* name)
{
PyPtr<Function> getter(getter_);
reference<function> getter(getter_);
add_method(getter, (detail::getattr_string() + name + "__").c_str());
}
void ExtensionClassBase::set_attribute(const char* name, PyObject* x_)
void extension_class_base::set_attribute(const char* name, PyObject* x_)
{
Ptr x(x_);
ref x(x_);
set_attribute(name, x);
}
void ExtensionClassBase::set_attribute(const char* name, Ptr x)
void extension_class_base::set_attribute(const char* name, ref x)
{
dict().set_item(String(name), x);
dict().set_item(string(name), x);
if (PyCallable_Check(x.get()))
detail::enable_named_method(this, name);
}
operator_dispatcher::operator_dispatcher(const Ptr& o, const Ptr& s)
operator_dispatcher::operator_dispatcher(const ref& o, const ref& s)
: m_object(o), m_self(s), m_free_list_link(0)
{
ob_refcnt = 1;
ob_type = &type_object;
ob_type = &type_obj;
}
operator_dispatcher*
operator_dispatcher::create(const Ptr& object, const Ptr& self)
operator_dispatcher::create(const ref& object, const ref& self)
{
operator_dispatcher* const result = free_list;
if (result == 0)
@@ -474,11 +474,11 @@ extern "C"
void operator_dispatcher_dealloc(PyObject* self)
{
operator_dispatcher* instance = static_cast<operator_dispatcher*>(self);
instance->m_free_list_link = operator_dispatcher::free_list;
operator_dispatcher::free_list = instance;
instance->m_object.reset();
instance->m_self.reset();
operator_dispatcher* obj = static_cast<operator_dispatcher*>(self);
obj->m_free_list_link = operator_dispatcher::free_list;
operator_dispatcher::free_list = obj;
obj->m_object.reset();
obj->m_self.reset();
}
int operator_dispatcher_coerce(PyObject** l, PyObject** r)
@@ -486,7 +486,7 @@ int operator_dispatcher_coerce(PyObject** l, PyObject** r)
Py_INCREF(*l);
try
{
*r = operator_dispatcher::create(Ptr(*r, Ptr::new_ref), Ptr());
*r = operator_dispatcher::create(ref(*r, ref::increment_count), ref());
}
catch(...)
{
@@ -608,7 +608,7 @@ int operator_dispatcher_call_cmp(PyObject* left, PyObject* right)
{
try
{
return PY_CONVERSION::from_python(result, Type<int>());
return BOOST_PYTHON_CONVERSION::from_python(result, type<int>());
}
catch(...)
{
@@ -621,7 +621,7 @@ int operator_dispatcher_call_cmp(PyObject* left, PyObject* right)
} // extern "C"
PyTypeObject operator_dispatcher::type_object =
PyTypeObject operator_dispatcher::type_obj =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -680,4 +680,4 @@ PyNumberMethods operator_dispatcher::number_methods =
} // namespace detail
} // namespace py
} // namespace python

View File

@@ -7,7 +7,7 @@
// producing this work.
//
// This file automatically generated for 10-argument constructors by
// gen_extclass.py
// gen_extclass.python
#ifndef EXTENSION_CLASS_DWA052000_H_
# define EXTENSION_CLASS_DWA052000_H_
@@ -23,33 +23,33 @@
# include <typeinfo>
# include <boost/smart_ptr.hpp>
namespace py {
namespace python {
// 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 };
enum without_downcast_t { 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;
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
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);
void report_missing_instance_data(ExtensionInstance*, Class<ExtensionInstance>*, const std::type_info&);
void report_missing_ptr_data(ExtensionInstance*, Class<ExtensionInstance>*, const std::type_info&);
meta_class<extension_instance>* extension_meta_class();
extension_instance* get_extension_instance(PyObject* p);
void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_class_object(const std::type_info&);
void report_released_smart_pointer(const std::type_info&);
@@ -61,87 +61,87 @@ T* check_non_null(T* p)
return p;
}
template <class T> class HeldInstance;
template <class T> class held_instance;
typedef void* (*ConversionFunction)(void*);
struct BaseClassInfo
{
BaseClassInfo(ExtensionClassBase* t, ConversionFunction f)
BaseClassInfo(extension_class_base* t, ConversionFunction f)
:class_object(t), convert(f)
{}
ExtensionClassBase* class_object;
extension_class_base* class_object;
ConversionFunction convert;
};
typedef BaseClassInfo DerivedClassInfo;
typedef BaseClassInfo derived_class_info;
struct add_operator_base;
class ExtensionClassBase : public Class<ExtensionInstance>
class extension_class_base : public class_t<extension_instance>
{
public:
ExtensionClassBase(const char* name);
extension_class_base(const char* name);
public:
// the purpose of try_class_conversions() and its related functions
// is explained in extclass.cpp
void* try_class_conversions(InstanceHolderBase*) const;
void* try_base_class_conversions(InstanceHolderBase*) const;
void* try_derived_class_conversions(InstanceHolderBase*) const;
void* try_class_conversions(instance_holder_base*) const;
void* try_base_class_conversions(instance_holder_base*) const;
void* try_derived_class_conversions(instance_holder_base*) const;
void set_attribute(const char* name, PyObject* x);
void set_attribute(const char* name, Ptr x);
void set_attribute(const char* name, ref x);
private:
virtual void* extract_object_from_holder(InstanceHolderBase* v) const = 0;
virtual void* extract_object_from_holder(instance_holder_base* v) const = 0;
virtual std::vector<BaseClassInfo> const& base_classes() const = 0;
virtual std::vector<DerivedClassInfo> const& derived_classes() const = 0;
virtual std::vector<derived_class_info> const& derived_classes() const = 0;
protected:
friend struct add_operator_base;
void add_method(PyPtr<Function> method, const char* name);
void add_method(Function* method, const char* name);
void add_method(reference<function> method, const char* name);
void add_method(function* method, const char* name);
void add_constructor_object(Function*);
void add_setter_method(Function*, const char* name);
void add_getter_method(Function*, const char* name);
void add_constructor_object(function*);
void add_setter_method(function*, const char* name);
void add_getter_method(function*, const char* name);
};
template <class T>
class ClassRegistry
class class_registry
{
public:
static ExtensionClassBase* class_object()
static extension_class_base* class_object()
{ return static_class_object; }
// Register/unregister the Python class object corresponding to T
static void register_class(ExtensionClassBase*);
static void unregister_class(ExtensionClassBase*);
static void register_class(extension_class_base*);
static void unregister_class(extension_class_base*);
// Establish C++ inheritance relationships
static void register_base_class(BaseClassInfo const&);
static void register_derived_class(DerivedClassInfo const&);
static void register_derived_class(derived_class_info const&);
// Query the C++ inheritance relationships
static std::vector<BaseClassInfo> const& base_classes();
static std::vector<DerivedClassInfo> const& derived_classes();
static std::vector<derived_class_info> const& derived_classes();
private:
static ExtensionClassBase* static_class_object;
static extension_class_base* static_class_object;
static std::vector<BaseClassInfo> static_base_class_info;
static std::vector<DerivedClassInfo> static_derived_class_info;
static std::vector<derived_class_info> static_derived_class_info;
};
}} // namespace py::detail
}} // namespace python::detail
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
// This class' only job is to define from_python and to_python converters for T
// 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::detail::HeldInstance<T> >
// virtual functions, U = held_instance<T>.
template <class T, class U = python::detail::held_instance<T> >
class PyExtensionClassConverters
{
public:
@@ -154,7 +154,7 @@ class PyExtensionClassConverters
// pop up. Now, if T hasn't been wrapped as an extension class, the user
// will see an error message about the lack of an eligible
// py_extension_class_converters() function.
friend PyExtensionClassConverters py_extension_class_converters(py::Type<T>)
friend PyExtensionClassConverters py_extension_class_converters(python::type<T>)
{
return PyExtensionClassConverters();
}
@@ -172,118 +172,118 @@ class PyExtensionClassConverters
// writes code which causes us to try to copy a T.
PyObject* to_python(const T& x) const
{
py::PyPtr<py::detail::ExtensionInstance> result(create_instance());
python::reference<python::detail::extension_instance> result(create_instance());
result->add_implementation(
std::auto_ptr<py::detail::InstanceHolderBase>(
new py::detail::InstanceValueHolder<T,U>(result.get(), x)));
std::auto_ptr<python::detail::instance_holder_base>(
new python::detail::instance_value_holder<T,U>(result.get(), x)));
return result.release();
}
// Convert to T*
friend T* from_python(PyObject* obj, py::Type<T*>)
friend T* from_python(PyObject* obj, python::type<T*>)
{
// Downcast to an ExtensionInstance, then find the actual T
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();
// downcast to an extension_instance, then find the actual T
python::detail::extension_instance* self = python::detail::get_extension_instance(obj);
typedef std::vector<python::detail::instance_holder_base*>::const_iterator iterator;
for (iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
py::detail::InstanceHolder<T>* held = dynamic_cast<py::detail::InstanceHolder<T>*>(*p);
python::detail::instance_holder<T>* held = dynamic_cast<python::detail::instance_holder<T>*>(*p);
if (held != 0)
return held->target();
// see extclass.cpp for an explanation of try_class_conversions()
void* target = py::detail::ClassRegistry<T>::class_object()->try_class_conversions(*p);
void* target = python::detail::class_registry<T>::class_object()->try_class_conversions(*p);
if(target)
return static_cast<T*>(target);
}
py::detail::report_missing_instance_data(self, py::detail::ClassRegistry<T>::class_object(), typeid(T));
throw py::ArgumentError();
python::detail::report_missing_instance_data(self, python::detail::class_registry<T>::class_object(), typeid(T));
throw python::argument_error();
}
// Convert to PtrType, where PtrType can be dereferenced to obtain a T.
template <class PtrType>
static PtrType& ptr_from_python(PyObject* obj, py::Type<PtrType>)
static PtrType& ptr_from_python(PyObject* obj, python::type<PtrType>)
{
// Downcast to an ExtensionInstance, then find the actual T
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();
// downcast to an extension_instance, then find the actual T
python::detail::extension_instance* self = python::detail::get_extension_instance(obj);
typedef std::vector<python::detail::instance_holder_base*>::const_iterator iterator;
for (iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
py::detail::InstancePtrHolder<PtrType, T>* held =
dynamic_cast<py::detail::InstancePtrHolder<PtrType, T>*>(*p);
python::detail::instance_ptr_holder<PtrType, T>* held =
dynamic_cast<python::detail::instance_ptr_holder<PtrType, T>*>(*p);
if (held != 0)
return held->ptr();
}
py::detail::report_missing_ptr_data(self, py::detail::ClassRegistry<T>::class_object(), typeid(T));
throw py::ArgumentError();
python::detail::report_missing_ptr_data(self, python::detail::class_registry<T>::class_object(), typeid(T));
throw python::argument_error();
}
template <class PtrType>
static PyObject* ptr_to_python(PtrType x)
{
py::PyPtr<py::detail::ExtensionInstance> result(create_instance());
python::reference<python::detail::extension_instance> result(create_instance());
result->add_implementation(
std::auto_ptr<py::detail::InstanceHolderBase>(
new py::detail::InstancePtrHolder<PtrType,T>(x)));
std::auto_ptr<python::detail::instance_holder_base>(
new python::detail::instance_ptr_holder<PtrType,T>(x)));
return result.release();
}
static py::PyPtr<py::detail::ExtensionInstance> create_instance()
static python::reference<python::detail::extension_instance> create_instance()
{
PyTypeObject* class_object = py::detail::ClassRegistry<T>::class_object();
PyTypeObject* class_object = python::detail::class_registry<T>::class_object();
if (class_object == 0)
py::detail::report_missing_class_object(typeid(T));
python::detail::report_missing_class_object(typeid(T));
return py::PyPtr<py::detail::ExtensionInstance>(
new py::detail::ExtensionInstance(class_object));
return python::reference<python::detail::extension_instance>(
new python::detail::extension_instance(class_object));
}
// Convert to const T*
friend const T* from_python(PyObject* p, py::Type<const T*>)
{ return from_python(p, py::Type<T*>()); }
friend const T* from_python(PyObject* p, python::type<const T*>)
{ return from_python(p, python::type<T*>()); }
// Convert to const T* const&
friend const T* from_python(PyObject* p, py::Type<const T*const&>)
{ return from_python(p, py::Type<const T*>()); }
friend const T* from_python(PyObject* p, python::type<const T*const&>)
{ return from_python(p, python::type<const T*>()); }
// Convert to T* const&
friend T* from_python(PyObject* p, py::Type<T* const&>)
{ return from_python(p, py::Type<T*>()); }
friend T* from_python(PyObject* p, python::type<T* const&>)
{ return from_python(p, python::type<T*>()); }
// Convert to T&
friend T& from_python(PyObject* p, py::Type<T&>)
{ return *py::detail::check_non_null(from_python(p, py::Type<T*>())); }
friend T& from_python(PyObject* p, python::type<T&>)
{ return *python::detail::check_non_null(from_python(p, python::type<T*>())); }
// Convert to const T&
friend const T& from_python(PyObject* p, py::Type<const T&>)
{ return from_python(p, py::Type<T&>()); }
friend const T& from_python(PyObject* p, python::type<const T&>)
{ return from_python(p, python::type<T&>()); }
// Convert to T
friend const T& from_python(PyObject* p, py::Type<T>)
{ return from_python(p, py::Type<T&>()); }
friend const T& from_python(PyObject* p, python::type<T>)
{ return from_python(p, python::type<T&>()); }
friend std::auto_ptr<T>& from_python(PyObject* p, py::Type<std::auto_ptr<T>&>)
{ return ptr_from_python(p, py::Type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, python::type<std::auto_ptr<T>&>)
{ return ptr_from_python(p, python::type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, py::Type<std::auto_ptr<T> >)
{ return ptr_from_python(p, py::Type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, python::type<std::auto_ptr<T> >)
{ return ptr_from_python(p, python::type<std::auto_ptr<T> >()); }
friend const std::auto_ptr<T>& from_python(PyObject* p, py::Type<const std::auto_ptr<T>&>)
{ return ptr_from_python(p, py::Type<std::auto_ptr<T> >()); }
friend const std::auto_ptr<T>& from_python(PyObject* p, python::type<const std::auto_ptr<T>&>)
{ return ptr_from_python(p, python::type<std::auto_ptr<T> >()); }
friend PyObject* to_python(std::auto_ptr<T> x)
{ return ptr_to_python(x); }
friend boost::shared_ptr<T>& from_python(PyObject* p, py::Type<boost::shared_ptr<T>&>)
{ return ptr_from_python(p, py::Type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, python::type<boost::shared_ptr<T>&>)
{ return ptr_from_python(p, python::type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, py::Type<boost::shared_ptr<T> >)
{ return ptr_from_python(p, py::Type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, python::type<boost::shared_ptr<T> >)
{ return ptr_from_python(p, python::type<boost::shared_ptr<T> >()); }
friend const boost::shared_ptr<T>& from_python(PyObject* p, py::Type<const boost::shared_ptr<T>&>)
{ return ptr_from_python(p, py::Type<boost::shared_ptr<T> >()); }
friend const boost::shared_ptr<T>& from_python(PyObject* p, python::type<const boost::shared_ptr<T>&>)
{ return ptr_from_python(p, python::type<boost::shared_ptr<T> >()); }
friend PyObject* to_python(boost::shared_ptr<T> x)
{ return ptr_to_python(x); }
@@ -296,31 +296,31 @@ class PyExtensionClassConverters
template <class T>
PyObject* to_python(const T& x)
{
return py_extension_class_converters(py::Type<T>()).to_python(x);
return py_extension_class_converters(python::type<T>()).to_python(x);
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace py {
namespace python {
PY_IMPORT_CONVERSION(PyExtensionClassConverters);
BOOST_PYTHON_IMPORT_CONVERSION(PyExtensionClassConverters);
namespace detail {
template <class T> class InstanceHolder;
template <class T> class instance_holder;
class ReadOnlySetattrFunction : public Function
class read_only_setattr_function : public function
{
public:
ReadOnlySetattrFunction(const char* name);
read_only_setattr_function(const char* name);
PyObject* do_call(PyObject* args, PyObject* keywords) const;
const char* description() const;
private:
String m_name;
string m_name;
};
template <class From, class To>
struct DefineConversion
struct define_conversion
{
static void* upcast_ptr(void* v)
{
@@ -334,7 +334,7 @@ class ReadOnlySetattrFunction : public Function
};
// 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.
// subclasses of this class will simply be class_t<extension_instance> objects.
//
// U should be a class derived from T which overrides virtual functions with
// boilerplate code to call back into Python. See extclass_demo.h for examples.
@@ -343,50 +343,50 @@ class ReadOnlySetattrFunction : public Function
// Python which are called from C++ if you don't supply it. If you just want to
// be able to use T in python without overriding member functions, you can omit
// U.
template <class T, class U = HeldInstance<T> >
class ExtensionClass
template <class T, class U = held_instance<T> >
class extension_class
: public PyExtensionClassConverters<T, U>, // This generates the to_python/from_python functions
public ExtensionClassBase
public extension_class_base
{
public:
typedef T WrappedType;
typedef U CallbackType;
typedef T wrapped_type;
typedef U callback_type;
// Construct with a name that comes from typeid(T).name(). The name only
// affects the objects of this class are represented through repr()
ExtensionClass();
extension_class();
// Construct with the given name. The name only affects the objects of this
// class are represented through repr()
ExtensionClass(const char* name);
extension_class(const char* name);
~ExtensionClass();
~extension_class();
// define constructors
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
inline void def(Constructor<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>)
// The following incantation builds a Signature1, Signature2,... object. It
inline void def(constructor<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>)
// The following incantation builds a signature1, signature2,... object. It
// should _all_ get optimized away.
{ add_constructor(
prepend(Type<A1>::Id(),
prepend(Type<A2>::Id(),
prepend(Type<A3>::Id(),
prepend(Type<A4>::Id(),
prepend(Type<A5>::Id(),
prepend(Type<A6>::Id(),
prepend(Type<A7>::Id(),
prepend(Type<A8>::Id(),
prepend(Type<A9>::Id(),
prepend(Type<A10>::Id(),
Signature0())))))))))));
prepend(type<A1>::id(),
prepend(type<A2>::id(),
prepend(type<A3>::id(),
prepend(type<A4>::id(),
prepend(type<A5>::id(),
prepend(type<A6>::id(),
prepend(type<A7>::id(),
prepend(type<A8>::id(),
prepend(type<A9>::id(),
prepend(type<A10>::id(),
signature0())))))))))));
}
// export homogeneous operators (type of both lhs and rhs is 'operator')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>());
// export homogeneous operators (type of both lhs and rhs is 'T const&')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub)>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub)>());
template <long which, class Operand>
inline void def(operators<which,Operand>)
{
@@ -395,12 +395,12 @@ class ExtensionClass
}
// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>(),
// py::right_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>(),
// python::right_operand<int const&>());
// export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub)>(),
// py::right_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub)>(),
// python::right_operand<int const&>());
template <long which, class Left, class Right>
inline void def(operators<which,Left>, right_operand<Right> r)
{
@@ -410,13 +410,13 @@ class ExtensionClass
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>(),
// py::left_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>(),
// python::left_operand<int const&>());
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'T const&')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub)>(),
// py::left_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub)>(),
// python::left_operand<int const&>());
template <long which, class Left, class Right>
inline void def(operators<which,Right>, left_operand<Left> l)
{
@@ -425,7 +425,7 @@ class ExtensionClass
}
// define a function that passes Python arguments and keywords
// to C++ verbatim (as a 'Tuple const&' and 'Dict const&'
// to C++ verbatim (as a 'tuple const&' and 'dictionary const&'
// respectively). This is useful for manual argument passing.
// It's also the only possibility to pass keyword arguments to C++.
// Fn must have a signatur that is compatible to
@@ -452,34 +452,34 @@ class ExtensionClass
template <class Fn, class DefaultFn>
inline void def(Fn fn, const char* name, DefaultFn default_fn)
{
this->add_method(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
// member (pm) of the T instance
// member (pm) of the T obj
template <class MemberType>
inline void def_getter(MemberType T::*pm, const char* name)
{
this->add_getter_method(new GetterFunction<T, MemberType>(pm), name);
this->add_getter_method(new getter_function<T, MemberType>(pm), name);
}
// Provide a function which implements assignment to x.<name>, writing to
// the given member (pm) of the T instance
// the given member (pm) of the T obj
template <class MemberType>
inline void def_setter(MemberType T::*pm, const char* name)
{
this->add_setter_method(new SetterFunction<T, MemberType>(pm), name);
this->add_setter_method(new setter_function<T, MemberType>(pm), name);
}
// Expose the given member (pm) of the T instance as a read-only attribute
// Expose the given member (pm) of the T obj as a read-only attribute
template <class MemberType>
inline void def_readonly(MemberType T::*pm, const char* name)
{
this->add_setter_method(new ReadOnlySetattrFunction(name), name);
this->add_setter_method(new read_only_setattr_function(name), name);
this->def_getter(pm, name);
}
// Expose the given member (pm) of the T instance as a read/write attribute
// Expose the given member (pm) of the T obj as a read/write attribute
template <class MemberType>
inline void def_read_write(MemberType T::*pm, const char* name)
{
@@ -493,43 +493,43 @@ class ExtensionClass
// declare the given class a base class of this one and register
// up and down conversion functions
template <class S, class V>
void declare_base(ExtensionClass<S, V>* base)
void declare_base(extension_class<S, V>* base)
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
BaseClassInfo baseInfo(base,
&DefineConversion<S, T>::downcast_ptr);
ClassRegistry<T>::register_base_class(baseInfo);
add_base(Ptr(as_object(base), Ptr::new_ref));
&define_conversion<S, T>::downcast_ptr);
class_registry<T>::register_base_class(baseInfo);
add_base(ref(as_object(base), ref::increment_count));
DerivedClassInfo derivedInfo(this,
&DefineConversion<T, S>::upcast_ptr);
ClassRegistry<S>::register_derived_class(derivedInfo);
derived_class_info derivedInfo(this,
&define_conversion<T, S>::upcast_ptr);
class_registry<S>::register_derived_class(derivedInfo);
}
// declare the given class a base class of this one and register
// only up conversion function
template <class S, class V>
void declare_base(ExtensionClass<S, V>* base, WithoutDowncast)
void declare_base(extension_class<S, V>* base, without_downcast_t)
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
BaseClassInfo baseInfo(base, 0);
ClassRegistry<T>::register_base_class(baseInfo);
add_base(Ptr(as_object(base), Ptr::new_ref));
class_registry<T>::register_base_class(baseInfo);
add_base(ref(as_object(base), ref::increment_count));
DerivedClassInfo derivedInfo(this,
&DefineConversion<T, S>::upcast_ptr);
ClassRegistry<S>::register_derived_class(derivedInfo);
derived_class_info derivedInfo(this,
&define_conversion<T, S>::upcast_ptr);
class_registry<S>::register_derived_class(derivedInfo);
}
private: // types
typedef InstanceValueHolder<T,U> Holder;
typedef instance_value_holder<T,U> holder;
private: // ExtensionClassBase virtual function implementations
private: // extension_class_base virtual function implementations
std::vector<BaseClassInfo> const& base_classes() const;
std::vector<DerivedClassInfo> const& derived_classes() const;
void* extract_object_from_holder(InstanceHolderBase* v) const;
std::vector<derived_class_info> const& derived_classes() const;
void* extract_object_from_holder(instance_holder_base* v) const;
private: // Utility functions
template <long which, class Operand>
@@ -604,57 +604,57 @@ class ExtensionClass
choose_rop<(which & op_cmp)>::template args<Left,Right>::add(this);
}
template <class Signature>
void add_constructor(Signature sig)
template <class signature>
void add_constructor(signature sig)
{
this->add_constructor_object(InitFunction<Holder>::create(sig));
this->add_constructor_object(init_function<holder>::create(sig));
}
};
// A simple wrapper over a T which allows us to use ExtensionClass<T> with a
// single template parameter only. See ExtensionClass<T>, above.
// A simple wrapper over a T which allows us to use extension_class<T> with a
// single template parameter only. See extension_class<T>, above.
template <class T>
class HeldInstance : public T
class held_instance : public T
{
// There are no member functions: we want to avoid inadvertently overriding
// any virtual functions in T.
public:
HeldInstance(PyObject*) : T() {}
held_instance(PyObject*) : T() {}
template <class A1>
HeldInstance(PyObject*, A1 a1) : T(a1) {}
held_instance(PyObject*, A1 a1) : T(a1) {}
template <class A1, class A2>
HeldInstance(PyObject*, A1 a1, A2 a2) : T(a1, a2) {}
held_instance(PyObject*, A1 a1, A2 a2) : T(a1, a2) {}
template <class A1, class A2, class A3>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3) : T(a1, a2, a3) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : T(a1, a2, a3) {}
template <class A1, class A2, class A3, class A4>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : T(a1, a2, a3, a4) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : T(a1, a2, a3, a4) {}
template <class A1, class A2, class A3, class A4, class A5>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : T(a1, a2, a3, a4, a5) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : T(a1, a2, a3, a4, a5) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : T(a1, a2, a3, a4, a5, a6) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : T(a1, a2, a3, a4, a5, a6) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : T(a1, a2, a3, a4, a5, a6, a7) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : T(a1, a2, a3, a4, a5, a6, a7) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : T(a1, a2, a3, a4, a5, a6, a7, a8) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : T(a1, a2, a3, a4, a5, a6, a7, a8) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
HeldInstance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
};
// Abstract base class for all instance holders. Base for template class
// InstanceHolder<>, below.
class InstanceHolderBase
// Abstract base class for all obj holders. Base for template class
// instance_holder<>, below.
class instance_holder_base
{
public:
virtual ~InstanceHolderBase() {}
virtual ~instance_holder_base() {}
virtual bool held_by_value() = 0;
};
// Abstract base class which holds a Held, somehow. Provides a uniform way to
// get a pointer to the held object
template <class Held>
class InstanceHolder : public InstanceHolderBase
class instance_holder : public instance_holder_base
{
public:
virtual Held*target() = 0;
@@ -665,49 +665,49 @@ public:
// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is
// neccessary to implement virtual function callbacks (there must be a
// back-pointer to the actual Python object so that we can call any
// overrides). HeldInstance (above) is used as a default Wrapper class when
// overrides). held_instance (above) is used as a default Wrapper class when
// there are no virtual functions.
template <class Held, class Wrapper>
class InstanceValueHolder : public InstanceHolder<Held>
class instance_value_holder : public instance_holder<Held>
{
public:
Held* target() { return &m_held; }
Wrapper* value_target() { return &m_held; }
InstanceValueHolder(ExtensionInstance* p) :
instance_value_holder(extension_instance* p) :
m_held(p) {}
template <class A1>
InstanceValueHolder(ExtensionInstance* p, A1 a1) :
instance_value_holder(extension_instance* p, A1 a1) :
m_held(p, a1) {}
template <class A1, class A2>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2) :
m_held(p, a1, a2) {}
template <class A1, class A2, class A3>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) :
m_held(p, a1, a2, a3) {}
template <class A1, class A2, class A3, class A4>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) :
m_held(p, a1, a2, a3, a4) {}
template <class A1, class A2, class A3, class A4, class A5>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
m_held(p, a1, a2, a3, a4, a5) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
m_held(p, a1, a2, a3, a4, a5, a6) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
m_held(p, a1, a2, a3, a4, a5, a6, a7) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
InstanceValueHolder(ExtensionInstance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
public: // implementation of InstanceHolderBase required interface
public: // implementation of instance_holder_base required interface
bool held_by_value() { return true; }
private:
@@ -718,59 +718,59 @@ public:
// PtrType. By default, these are only generated for PtrType ==
// std::auto_ptr<HeldType> and PtrType == boost::shared_ptr<HeldType>.
template <class PtrType, class HeldType>
class InstancePtrHolder : public InstanceHolder<HeldType>
class instance_ptr_holder : public instance_holder<HeldType>
{
public:
HeldType* target() { return &*m_ptr; }
PtrType& ptr() { return m_ptr; }
InstancePtrHolder(PtrType ptr) : m_ptr(ptr) {}
instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {}
public: // implementation of InstanceHolderBase required interface
public: // implementation of instance_holder_base required interface
bool held_by_value() { return false; }
private:
PtrType m_ptr;
};
class ExtensionInstance : public Instance
class extension_instance : public instance
{
public:
ExtensionInstance(PyTypeObject* class_);
~ExtensionInstance();
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<InstanceHolderBase> holder);
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<InstanceHolderBase*> WrappedObjects;
const WrappedObjects& wrapped_objects() const
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
WrappedObjects m_wrapped_objects;
held_objects m_wrapped_objects;
};
//
// Template function implementations
//
Tuple extension_class_coerce(Ptr l, Ptr r);
tuple extension_class_coerce(ref l, ref r);
template <class T, class U>
ExtensionClass<T, U>::ExtensionClass()
: ExtensionClassBase(typeid(T).name())
extension_class<T, U>::extension_class()
: extension_class_base(typeid(T).name())
{
ClassRegistry<T>::register_class(this);
class_registry<T>::register_class(this);
}
template <class T, class U>
ExtensionClass<T, U>::ExtensionClass(const char* name)
: ExtensionClassBase(name)
extension_class<T, U>::extension_class(const char* name)
: extension_class_base(name)
{
ClassRegistry<T>::register_class(this);
class_registry<T>::register_class(this);
}
template <class T, class U>
void ExtensionClass<T, U>::def_standard_coerce()
void extension_class<T, U>::def_standard_coerce()
{
Ptr coerce_fct = dict().get_item(String("__coerce__"));
ref coerce_fct = dict().get_item(string("__coerce__"));
if(coerce_fct.get() == 0) // not yet defined
this->def(&extension_class_coerce, "__coerce__");
@@ -779,36 +779,36 @@ void ExtensionClass<T, U>::def_standard_coerce()
template <class T, class U>
inline
std::vector<BaseClassInfo> const&
ExtensionClass<T, U>::base_classes() const
extension_class<T, U>::base_classes() const
{
return ClassRegistry<T>::base_classes();
return class_registry<T>::base_classes();
}
template <class T, class U>
inline
std::vector<DerivedClassInfo> const&
ExtensionClass<T, U>::derived_classes() const
std::vector<derived_class_info> const&
extension_class<T, U>::derived_classes() const
{
return ClassRegistry<T>::derived_classes();
return class_registry<T>::derived_classes();
}
template <class T, class U>
void* ExtensionClass<T, U>::extract_object_from_holder(InstanceHolderBase* v) const
void* extension_class<T, U>::extract_object_from_holder(instance_holder_base* v) const
{
InstanceHolder<T>* held = dynamic_cast<InstanceHolder<T>*>(v);
instance_holder<T>* held = dynamic_cast<instance_holder<T>*>(v);
if(held)
return held->target();
return 0;
}
template <class T, class U>
ExtensionClass<T, U>::~ExtensionClass()
extension_class<T, U>::~extension_class()
{
ClassRegistry<T>::unregister_class(this);
class_registry<T>::unregister_class(this);
}
template <class T>
inline void ClassRegistry<T>::register_class(ExtensionClassBase* p)
inline void class_registry<T>::register_class(extension_class_base* p)
{
// You're not expected to create more than one of these!
assert(static_class_object == 0);
@@ -816,7 +816,7 @@ inline void ClassRegistry<T>::register_class(ExtensionClassBase* p)
}
template <class T>
inline void ClassRegistry<T>::unregister_class(ExtensionClassBase* p)
inline void class_registry<T>::unregister_class(extension_class_base* p)
{
// The user should be destroying the same object they created.
assert(static_class_object == p);
@@ -825,25 +825,25 @@ inline void ClassRegistry<T>::unregister_class(ExtensionClassBase* p)
}
template <class T>
void ClassRegistry<T>::register_base_class(BaseClassInfo const& i)
void class_registry<T>::register_base_class(BaseClassInfo const& i)
{
static_base_class_info.push_back(i);
}
template <class T>
void ClassRegistry<T>::register_derived_class(DerivedClassInfo const& i)
void class_registry<T>::register_derived_class(derived_class_info const& i)
{
static_derived_class_info.push_back(i);
}
template <class T>
std::vector<BaseClassInfo> const& ClassRegistry<T>::base_classes()
std::vector<BaseClassInfo> const& class_registry<T>::base_classes()
{
return static_base_class_info;
}
template <class T>
std::vector<DerivedClassInfo> const& ClassRegistry<T>::derived_classes()
std::vector<derived_class_info> const& class_registry<T>::derived_classes()
{
return static_derived_class_info;
}
@@ -852,12 +852,12 @@ std::vector<DerivedClassInfo> const& ClassRegistry<T>::derived_classes()
// Static data member declaration.
//
template <class T>
ExtensionClassBase* ClassRegistry<T>::static_class_object;
extension_class_base* class_registry<T>::static_class_object;
template <class T>
std::vector<BaseClassInfo> ClassRegistry<T>::static_base_class_info;
std::vector<BaseClassInfo> class_registry<T>::static_base_class_info;
template <class T>
std::vector<DerivedClassInfo> ClassRegistry<T>::static_derived_class_info;
std::vector<derived_class_info> class_registry<T>::static_derived_class_info;
}} // namespace py::detail
}} // namespace python::detail
#endif // EXTENSION_CLASS_DWA052000_H_

View File

@@ -21,7 +21,7 @@ FooCallback::FooCallback(PyObject* self, int x)
int FooCallback::add_len(const char* x) const
{
// Try to call the "add_len" method on the corresponding Python object.
return py::Callback<int>::call_method(m_self, "add_len", x);
return python::callback<int>::call_method(m_self, "add_len", x);
}
// A function which Python can call in case bar is not overridden from
@@ -41,13 +41,13 @@ int FooCallback::default_add_len(const Foo* self, const char* x)
// exception at runtime when pure() is called.
std::string FooCallback::pure() const
{
return py::Callback<std::string>::call_method(m_self, "pure");
return python::callback<std::string>::call_method(m_self, "pure");
}
Foo::PythonClass::PythonClass(py::Module& m)
: py::ClassWrapper<Foo,FooCallback>(m, "Foo")
Foo::PythonClass::PythonClass(python::module_builder& m)
: python::class_builder<Foo,FooCallback>(m, "Foo")
{
def(py::Constructor<int>());
def(python::constructor<int>());
def(&Foo::mumble, "mumble");
def(&Foo::set, "set");
def(&Foo::call_pure, "call_pure");
@@ -59,19 +59,19 @@ Foo::PythonClass::PythonClass(py::Module& m)
// Since pure() is pure virtual, we are leaving it undefined.
}
BarPythonClass::BarPythonClass(py::Module& m)
: py::ClassWrapper<Bar>(m, "Bar")
BarPythonClass::BarPythonClass(python::module_builder& m)
: python::class_builder<Bar>(m, "Bar")
{
def(py::Constructor<int, int>());
def(python::constructor<int, int>());
def(&Bar::first, "first");
def(&Bar::second, "second");
def(&Bar::pass_baz, "pass_baz");
}
BazPythonClass::BazPythonClass(py::Module& m)
: py::ClassWrapper<Baz>(m, "Baz") // optional
BazPythonClass::BazPythonClass(python::module_builder& m)
: python::class_builder<Baz>(m, "Baz") // optional
{
def(py::Constructor<>());
def(python::constructor<>());
def(&Baz::pass_bar, "pass_bar");
def(&Baz::clone, "clone");
def(&Baz::create_foo, "create_foo");
@@ -79,10 +79,10 @@ BazPythonClass::BazPythonClass(py::Module& m)
def(&Baz::eat_baz, "eat_baz");
}
StringMapPythonClass::StringMapPythonClass(py::Module& m)
: py::ClassWrapper<StringMap >(m, "StringMap")
StringMapPythonClass::StringMapPythonClass(python::module_builder& m)
: python::class_builder<StringMap >(m, "StringMap")
{
def(py::Constructor<>());
def(python::constructor<>());
def(&StringMap::size, "__len__");
def(&get_item, "__getitem__");
def(&set_item, "__setitem__");
@@ -102,13 +102,13 @@ void set_first(IntPair& p, int value)
void del_first(const IntPair&)
{
PyErr_SetString(PyExc_AttributeError, "first can't be deleted!");
throw py::ErrorAlreadySet();
throw python::error_already_set();
}
IntPairPythonClass::IntPairPythonClass(py::Module& m)
: py::ClassWrapper<IntPair>(m, "IntPair")
IntPairPythonClass::IntPairPythonClass(python::module_builder& m)
: python::class_builder<IntPair>(m, "IntPair")
{
def(py::Constructor<int, int>());
def(python::constructor<int, int>());
def(&getattr, "__getattr__");
def(&setattr, "__setattr__");
def(&delattr, "__delattr__");
@@ -126,14 +126,14 @@ void IntPairPythonClass::setattr(IntPair& x, const std::string& name, int value)
else
{
PyErr_SetString(PyExc_AttributeError, name.c_str());
throw py::ErrorAlreadySet();
throw python::error_already_set();
}
}
void IntPairPythonClass::delattr(IntPair&, const char*)
{
PyErr_SetString(PyExc_AttributeError, "Attributes can't be deleted!");
throw py::ErrorAlreadySet();
throw python::error_already_set();
}
int IntPairPythonClass::getattr(const IntPair& p, const std::string& s)
@@ -145,7 +145,7 @@ int IntPairPythonClass::getattr(const IntPair& p, const std::string& s)
else
{
PyErr_SetString(PyExc_AttributeError, s.c_str());
throw py::ErrorAlreadySet();
throw python::error_already_set();
}
#if defined(__MWERKS__) && __MWERKS__ <= 0x2400
return 0;
@@ -157,8 +157,8 @@ void throw_key_error_if_end(const StringMap& m, StringMap::const_iterator p, std
{
if (p == m.end())
{
PyErr_SetObject(PyExc_KeyError, PY_CONVERSION::to_python(key));
throw py::ErrorAlreadySet();
PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(key));
throw python::error_already_set();
}
}
}} // namespace <anonymous>::file_local
@@ -230,7 +230,7 @@ int Foo::call_add_len(const char* s) const
int Foo::add_len(const char* s) const // sum the held value and the length of s
{
return PY_CSTD_::strlen(s) + static_cast<int>(m_x);
return BOOST_CSTD_::strlen(s) + static_cast<int>(m_x);
}
boost::shared_ptr<Foo> Baz::create_foo()
@@ -265,11 +265,11 @@ int stringpair_compare(const StringPair& sp1, const StringPair& sp2)
return sp1 < sp2 ? -1 : sp2 < sp1 ? 1 : 0;
}
py::String range_str(const Range& r)
python::string range_str(const Range& r)
{
char buf[200];
sprintf(buf, "(%d, %d)", r.m_start, r.m_finish);
return py::String(buf);
return python::string(buf);
}
int range_compare(const Range& r1, const Range& r2)
@@ -450,11 +450,11 @@ struct CallbackTestCallback : public CallbackTest
int callback(int x)
{
return py::Callback<int>::call_method(m_self, "callback", x);
return python::callback<int>::call_method(m_self, "callback", x);
}
std::string callbackString(std::string const & x)
{
return py::Callback<std::string>::call_method(m_self, "callback", x);
return python::callback<std::string>::call_method(m_self, "callback", x);
}
static int default_callback(CallbackTest* self, int x)
@@ -522,8 +522,8 @@ std::auto_ptr<B1> factoryCasB1() { return std::auto_ptr<B1>(new C); }
struct B_callback : B1 {
B_callback(PyObject* self) : m_self(self) {}
std::string overrideA1() const { return py::Callback<std::string>::call_method(m_self, "overrideA1"); }
std::string overrideB1() const { return py::Callback<std::string>::call_method(m_self, "overrideB1"); }
std::string overrideA1() const { return python::callback<std::string>::call_method(m_self, "overrideA1"); }
std::string overrideB1() const { return python::callback<std::string>::call_method(m_self, "overrideB1"); }
static std::string default_overrideA1(B1& x) { return x.B1::overrideA1(); }
static std::string default_overrideB1(B1& x) { return x.B1::overrideB1(); }
@@ -534,8 +534,8 @@ struct B_callback : B1 {
struct A_callback : A1 {
A_callback(PyObject* self) : m_self(self) {}
std::string overrideA1() const { return py::Callback<std::string>::call_method(m_self, "overrideA1"); }
std::string inheritA1() const { return py::Callback<std::string>::call_method(m_self, "inheritA1"); }
std::string overrideA1() const { return python::callback<std::string>::call_method(m_self, "overrideA1"); }
std::string inheritA1() const { return python::callback<std::string>::call_method(m_self, "inheritA1"); }
static std::string default_overrideA1(A1& x) { return x.A1::overrideA1(); }
static std::string default_inheritA1(A1& x) { return x.A1::inheritA1(); }
@@ -557,14 +557,14 @@ struct RawTest
int i_;
};
PyObject* raw(py::Tuple const & args, py::Dict const & keywords);
PyObject* raw(python::tuple const & args, python::dictionary const & keywords);
int raw1(PyObject* args, PyObject* keywords)
{
return PyTuple_Size(args) + PyDict_Size(keywords);
}
int raw2(py::Ptr args, py::Ptr keywords)
int raw2(python::ref args, python::ref keywords)
{
return PyTuple_Size(args.get()) + PyDict_Size(keywords.get());
}
@@ -579,7 +579,7 @@ int raw2(py::Ptr args, py::Ptr keywords)
typedef boost::rational<int> Ratio;
py::String ratio_str(const Ratio& r)
python::string ratio_str(const Ratio& r)
{
char buf[200];
@@ -588,19 +588,19 @@ py::String ratio_str(const Ratio& r)
else
sprintf(buf, "%d/%d", r.numerator(), r.denominator());
return py::String(buf);
return python::string(buf);
}
py::String ratio_repr(const Ratio& r)
python::string ratio_repr(const Ratio& r)
{
char buf[200];
sprintf(buf, "Rational(%d, %d)", r.numerator(), r.denominator());
return py::String(buf);
return python::string(buf);
}
py::Tuple ratio_coerce(const Ratio& r1, int r2)
python::tuple ratio_coerce(const Ratio& r1, int r2)
{
return py::Tuple(r1, Ratio(r2));
return python::tuple(r1, Ratio(r2));
}
// The most reliable way, across compilers, to grab the particular abs function
@@ -688,7 +688,7 @@ std::ostream & operator<<(std::ostream & o, Int const & r) { return (o << r.i_);
/* double tests from Mark Evans(<mark.evans@clarisay.com>) */
/* */
/************************************************************/
double sizelist(py::List list) { return list.size(); }
double sizelist(python::list list) { return list.size(); }
void vd_push_back(std::vector<double>& vd, const double& x)
{
vd.push_back(x);
@@ -714,16 +714,16 @@ const Record* get_record()
return &v;
}
template class py::ClassWrapper<Record>; // explicitly instantiate
template class python::class_builder<Record>; // explicitly instantiate
} // namespace extclass_demo
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
inline PyObject* to_python(const extclass_demo::Record* p)
{
return to_python(*p);
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
/************************************************************/
/* */
@@ -752,14 +752,14 @@ struct EnumOwner
}
namespace py {
namespace python {
template class enum_as_int_converters<extclass_demo::EnumOwner::enum_type>;
using extclass_demo::pow;
}
// This is just a way of getting the converters instantiated
//struct EnumOwner_enum_type_Converters
// : py::py_enum_as_int_converters<EnumOwner::enum_type>
// : python::py_enum_as_int_converters<EnumOwner::enum_type>
//{
//};
@@ -786,29 +786,29 @@ namespace extclass_demo {
};
// Support for pickle.
py::Tuple world_getinitargs(const world& w)
python::tuple world_getinitargs(const world& w)
{
py::Tuple result(1);
python::tuple result(1);
result.set_item(0, w.get_country());
return result;
}
py::Tuple world_getstate(const world& w)
python::tuple world_getstate(const world& w)
{
py::Tuple result(1);
python::tuple result(1);
result.set_item(0, w.get_secret_number());
return result;
}
void world_setstate(world& w, py::Tuple state)
void world_setstate(world& w, python::tuple state)
{
if (state.size() != 1) {
PyErr_SetString(PyExc_ValueError,
"Unexpected argument in call to __setstate__.");
throw py::ErrorAlreadySet();
throw python::error_already_set();
}
const int number = PY_CONVERSION::from_python(state[0].get(), py::Type<int>());
const int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(), python::type<int>());
if (number != 42)
w.set_secret_number(number);
}
@@ -819,21 +819,21 @@ namespace extclass_demo {
/* */
/************************************************************/
void init_module(py::Module& m)
void init_module(python::module_builder& m)
{
m.def(get_record, "get_record");
py::ClassWrapper<Record> record_class(m, "Record");
python::class_builder<Record> record_class(m, "Record");
record_class.def_readonly(&Record::value, "value");
m.def(sizelist, "sizelist");
py::ClassWrapper<std::vector<double> > vector_double(m, "vector_double");
vector_double.def(py::Constructor<>());
python::class_builder<std::vector<double> > vector_double(m, "vector_double");
vector_double.def(python::constructor<>());
vector_double.def(vd_push_back, "push_back");
py::ClassWrapper<Fubar> fubar(m, "Fubar");
fubar.def(py::Constructor<Foo&>());
fubar.def(py::Constructor<int>());
python::class_builder<Fubar> fubar(m, "Fubar");
fubar.def(python::constructor<Foo&>());
fubar.def(python::constructor<int>());
Foo::PythonClass foo(m);
BarPythonClass bar(m);
@@ -843,8 +843,8 @@ void init_module(py::Module& m)
m.def(make_pair, "make_pair");
CompareIntPairPythonClass compare_int_pair(m);
py::ClassWrapper<StringPair> string_pair(m, "StringPair");
string_pair.def(py::Constructor<std::string, std::string>());
python::class_builder<StringPair> string_pair(m, "StringPair");
string_pair.def(python::constructor<std::string, std::string>());
string_pair.def_readonly(&StringPair::first, "first");
string_pair.def_read_write(&StringPair::second, "second");
string_pair.def(&stringpair_repr, "__repr__");
@@ -853,10 +853,10 @@ void init_module(py::Module& m)
m.def(second_string, "second_string");
// This shows the wrapping of a 3rd-party numeric type.
py::ClassWrapper<boost::rational<int> > rational(m, "Rational");
rational.def(py::Constructor<int, int>());
rational.def(py::Constructor<int>());
rational.def(py::Constructor<>());
python::class_builder<boost::rational<int> > rational(m, "Rational");
rational.def(python::constructor<int, int>());
rational.def(python::constructor<int>());
rational.def(python::constructor<>());
rational.def(StandardOps<Ratio>::add, "__add__");
rational.def(StandardOps<Ratio>::sub, "__sub__");
rational.def(StandardOps<Ratio>::mul, "__mul__");
@@ -867,9 +867,9 @@ void init_module(py::Module& m)
rational.def(ratio_repr, "__repr__");
rational.def(ratio_abs, "__abs__");
py::ClassWrapper<Range> range(m, "Range");
range.def(py::Constructor<int>());
range.def(py::Constructor<int, int>());
python::class_builder<Range> range(m, "Range");
range.def(python::constructor<int>());
range.def(python::constructor<int, int>());
range.def((void (Range::*)(std::size_t))&Range::length, "__len__");
range.def((std::size_t (Range::*)() const)&Range::length, "__len__");
range.def(&Range::operator[], "__getitem__");
@@ -888,14 +888,14 @@ void init_module(py::Module& m)
m.def(&test4, "overloaded");
m.def(&test5, "overloaded");
py::ClassWrapper<OverloadTest> over(m, "OverloadTest");
over.def(py::Constructor<>());
over.def(py::Constructor<OverloadTest const &>());
over.def(py::Constructor<int>());
over.def(py::Constructor<int, int>());
over.def(py::Constructor<int, int, int>());
over.def(py::Constructor<int, int, int, int>());
over.def(py::Constructor<int, int, int, int, int>());
python::class_builder<OverloadTest> over(m, "OverloadTest");
over.def(python::constructor<>());
over.def(python::constructor<OverloadTest const &>());
over.def(python::constructor<int>());
over.def(python::constructor<int, int>());
over.def(python::constructor<int, int, int>());
over.def(python::constructor<int, int, int, int>());
over.def(python::constructor<int, int, int, int, int>());
over.def(&getX, "getX");
over.def(&OverloadTest::setX, "setX");
over.def(&OverloadTest::x, "overloaded");
@@ -905,19 +905,19 @@ void init_module(py::Module& m)
over.def(&OverloadTest::p4, "overloaded");
over.def(&OverloadTest::p5, "overloaded");
py::ClassWrapper<Base> base(m, "Base");
python::class_builder<Base> base(m, "Base");
base.def(&Base::x, "x");
py::ClassWrapper<Derived1> derived1(m, "Derived1");
python::class_builder<Derived1> derived1(m, "Derived1");
// this enables conversions between Base and Derived1
// and makes wrapped methods of Base available
derived1.declare_base(base);
derived1.def(py::Constructor<int>());
derived1.def(python::constructor<int>());
py::ClassWrapper<Derived2> derived2(m, "Derived2");
python::class_builder<Derived2> derived2(m, "Derived2");
// don't enable downcast from Base to Derived2
derived2.declare_base(base, py::without_downcast);
derived2.def(py::Constructor<int>());
derived2.declare_base(base, python::without_downcast);
derived2.def(python::constructor<int>());
m.def(&testUpcast, "testUpcast");
m.def(&derived1Factory, "derived1Factory");
@@ -925,12 +925,12 @@ void init_module(py::Module& m)
m.def(&testDowncast1, "testDowncast1");
m.def(&testDowncast2, "testDowncast2");
py::ClassWrapper<CallbackTestBase> callbackTestBase(m, "CallbackTestBase");
python::class_builder<CallbackTestBase> callbackTestBase(m, "CallbackTestBase");
callbackTestBase.def(&CallbackTestBase::testCallback, "testCallback");
m.def(&testCallback, "testCallback");
py::ClassWrapper<CallbackTest, CallbackTestCallback> callbackTest(m, "CallbackTest");
callbackTest.def(py::Constructor<>());
python::class_builder<CallbackTest, CallbackTestCallback> callbackTest(m, "CallbackTest");
callbackTest.def(python::constructor<>());
callbackTest.def(&CallbackTest::callback, "callback",
&CallbackTestCallback::default_callback);
callbackTest.def(&CallbackTest::callbackString, "callback",
@@ -938,28 +938,28 @@ void init_module(py::Module& m)
callbackTest.declare_base(callbackTestBase);
py::ClassWrapper<A1, A_callback> a1_class(m, "A1");
a1_class.def(py::Constructor<>());
python::class_builder<A1, A_callback> a1_class(m, "A1");
a1_class.def(python::constructor<>());
a1_class.def(&A1::overrideA1, "overrideA1", &A_callback::default_overrideA1);
a1_class.def(&A1::inheritA1, "inheritA1", &A_callback::default_inheritA1);
py::ClassWrapper<A2> a2_class(m, "A2");
a2_class.def(py::Constructor<>());
python::class_builder<A2> a2_class(m, "A2");
a2_class.def(python::constructor<>());
a2_class.def(&A2::inheritA2, "inheritA2");
py::ClassWrapper<B1, B_callback> b1_class(m, "B1");
python::class_builder<B1, B_callback> b1_class(m, "B1");
b1_class.declare_base(a1_class);
b1_class.declare_base(a2_class);
b1_class.def(py::Constructor<>());
b1_class.def(python::constructor<>());
b1_class.def(&B1::overrideA1, "overrideA1", &B_callback::default_overrideA1);
b1_class.def(&B1::overrideB1, "overrideB1", &B_callback::default_overrideB1);
py::ClassWrapper<B2> b2_class(m, "B2");
python::class_builder<B2> b2_class(m, "B2");
b2_class.declare_base(a1_class);
b2_class.declare_base(a2_class);
b2_class.def(py::Constructor<>());
b2_class.def(python::constructor<>());
b2_class.def(&B2::overrideA1, "overrideA1");
b2_class.def(&B2::inheritB2, "inheritB2");
@@ -976,40 +976,40 @@ void init_module(py::Module& m)
m.def(factoryB1asB1, "factoryB1asB1");
m.def(factoryCasB1, "factoryCasB1");
py::ClassWrapper<RawTest> rawtest_class(m, "RawTest");
rawtest_class.def(py::Constructor<int>());
python::class_builder<RawTest> rawtest_class(m, "RawTest");
rawtest_class.def(python::constructor<int>());
rawtest_class.def_raw(&raw, "raw");
m.def_raw(&raw, "raw");
m.def_raw(&raw1, "raw1");
m.def_raw(&raw2, "raw2");
py::ClassWrapper<Int> int_class(m, "Int");
int_class.def(py::Constructor<int>());
python::class_builder<Int> int_class(m, "Int");
int_class.def(python::constructor<int>());
int_class.def(&Int::i, "i");
// wrap homogeneous operators
int_class.def(py::operators<(py::op_add | py::op_sub | py::op_neg |
py::op_cmp | py::op_str | py::op_divmod | py::op_pow )>());
int_class.def(python::operators<(python::op_add | python::op_sub | python::op_neg |
python::op_cmp | python::op_str | python::op_divmod | python::op_pow )>());
// export non-operator functions as homogeneous operators
int_class.def(&mul, "__mul__");
int_class.def(&powmod, "__pow__");
// wrap heterogeneous operators (lhs: Int const &, rhs: int const &)
int_class.def(py::operators<(py::op_add | py::op_sub | py::op_cmp | py::op_pow)>(),
py::right_operand<int const & >());
int_class.def(python::operators<(python::op_add | python::op_sub | python::op_cmp | python::op_pow)>(),
python::right_operand<int const & >());
// export non-operator function as heterogeneous operator
int_class.def(&imul, "__mul__");
// wrap heterogeneous operators (lhs: int const &, rhs: Int const &)
int_class.def(py::operators<(py::op_add | py::op_sub | py::op_cmp)>(),
py::left_operand<int const & >());
int_class.def(python::operators<(python::op_add | python::op_sub | python::op_cmp)>(),
python::left_operand<int const & >());
// export non-operator function as heterogeneous reverse-argument operator
int_class.def(&rmul, "__rmul__");
py::ClassWrapper<EnumOwner> enum_owner(m, "EnumOwner");
enum_owner.def(py::Constructor<EnumOwner::enum_type, const EnumOwner::enum_type&>());
python::class_builder<EnumOwner> enum_owner(m, "EnumOwner");
enum_owner.def(python::constructor<EnumOwner::enum_type, const EnumOwner::enum_type&>());
enum_owner.def(&EnumOwner::set_first, "__setattr__first__");
enum_owner.def(&EnumOwner::set_second, "__setattr__second__");
enum_owner.def(&EnumOwner::first, "__getattr__first__");
@@ -1021,10 +1021,10 @@ void init_module(py::Module& m)
// pickling support
// Create the Python type object for our extension class.
py::ClassWrapper<world> world_class(m, "world");
python::class_builder<world> world_class(m, "world");
// Add the __init__ function.
world_class.def(py::Constructor<std::string>());
world_class.def(python::constructor<std::string>());
// Add a regular member function.
world_class.def(&world::greet, "greet");
world_class.def(&world::get_secret_number, "get_secret_number");
@@ -1036,30 +1036,30 @@ void init_module(py::Module& m)
world_class.def(world_setstate, "__setstate__");
}
PyObject* raw(py::Tuple const& args, py::Dict const& keywords)
PyObject* raw(python::tuple const& args, python::dictionary const& keywords)
{
if(args.size() != 2 || keywords.size() != 2)
{
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
throw py::ArgumentError();
throw python::argument_error();
}
RawTest* first = PY_CONVERSION::from_python(args[0].get(), py::Type<RawTest*>());
int second = PY_CONVERSION::from_python(args[1].get(), py::Type<int>());
RawTest* first = BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<RawTest*>());
int second = BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<int>());
int third = PY_CONVERSION::from_python(keywords[py::String("third")].get(), py::Type<int>());
int fourth = PY_CONVERSION::from_python(keywords[py::String("fourth")].get(), py::Type<int>());
int third = BOOST_PYTHON_CONVERSION::from_python(keywords[python::string("third")].get(), python::type<int>());
int fourth = BOOST_PYTHON_CONVERSION::from_python(keywords[python::string("fourth")].get(), python::type<int>());
return PY_CONVERSION::to_python(first->i_ + second + third + fourth);
return BOOST_PYTHON_CONVERSION::to_python(first->i_ + second + third + fourth);
}
void init_module()
{
py::Module demo("demo");
python::module_builder demo("demo");
init_module(demo);
// Just for giggles, add a raw metaclass.
demo.add(new py::MetaClass<py::Instance>);
demo.add(new python::meta_class<python::instance>);
}
extern "C"
@@ -1072,14 +1072,14 @@ void initdemo()
extclass_demo::init_module();
}
catch(...) {
py::handle_exception();
python::handle_exception();
} // Need a way to report other errors here
}
CompareIntPairPythonClass::CompareIntPairPythonClass(py::Module& m)
: py::ClassWrapper<CompareIntPair>(m, "CompareIntPair")
CompareIntPairPythonClass::CompareIntPairPythonClass(python::module_builder& m)
: python::class_builder<CompareIntPair>(m, "CompareIntPair")
{
def(py::Constructor<>());
def(python::constructor<>());
def(&CompareIntPair::operator(), "__call__");
}
@@ -1096,7 +1096,7 @@ CompareIntPairPythonClass::CompareIntPairPythonClass(py::Module& m)
# endif
extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved );
# ifdef PY_COMPILER_IS_MSVC
# ifdef BOOST_MSVC
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
{
throw;
@@ -1104,7 +1104,7 @@ extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS
# endif
#ifndef NDEBUG
namespace py { namespace detail { extern int total_Dispatchers; }}
namespace python { namespace detail { extern int total_Dispatchers; }}
#endif
BOOL WINAPI DllMain(
@@ -1113,7 +1113,7 @@ BOOL WINAPI DllMain(
LPVOID // lpvReserved
)
{
# ifdef PY_COMPILER_IS_MSVC
# ifdef BOOST_MSVC
_set_se_translator(structured_exception_translator);
#endif
(void)fdwReason; // warning suppression.

View File

@@ -52,7 +52,7 @@ class Foo // prohibit copying, proving that it doesn't choke
public: // friend declarations
// If you have private virtual functions such as add_len which you want to
// override in Python and have default implementations, they must be
// accessible by the thing making the def() call on the ExtensionClass (in
// accessible by the thing making the def() call on the extension_class (in
// this case, the nested PythonClass itself), and by the C++ derived class
// which is used to cause the Python callbacks (in this case,
// FooCallback). See the definition of FooCallback::add_len()
@@ -180,25 +180,25 @@ class FooCallback : public Foo
std::string pure() const;
private: // Required boilerplate if functions will be overridden
PyObject* m_self; // No, we don't want a py::Ptr here, or we'd get an ownership cycle.
PyObject* m_self; // No, we don't want a python::ref here, or we'd get an ownership cycle.
};
// Define the Python base class
struct Foo::PythonClass : py::ClassWrapper<Foo, FooCallback> { PythonClass(py::Module&); };
struct Foo::PythonClass : python::class_builder<Foo, FooCallback> { PythonClass(python::module_builder&); };
// 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
// us. Even so, Python class_t 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::ClassWrapper<> that
// definitions, since it is the definition of the python::class_builder<> that
// causes to_python/from_python conversion functions to be generated.
struct BarPythonClass : py::ClassWrapper<Bar> { BarPythonClass(py::Module&); };
struct BazPythonClass : py::ClassWrapper<Baz> { BazPythonClass(py::Module&); };
struct BarPythonClass : python::class_builder<Bar> { BarPythonClass(python::module_builder&); };
struct BazPythonClass : python::class_builder<Baz> { BazPythonClass(python::module_builder&); };
struct StringMapPythonClass
: py::ClassWrapper<StringMap>
: python::class_builder<StringMap>
{
StringMapPythonClass(py::Module&);
StringMapPythonClass(python::module_builder&);
// 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::ClassWrapper<IntPair>
: python::class_builder<IntPair>
{
IntPairPythonClass(py::Module&);
IntPairPythonClass(python::module_builder&);
// 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::ClassWrapper<CompareIntPair>
: python::class_builder<CompareIntPair>
{
CompareIntPairPythonClass(py::Module&);
CompareIntPairPythonClass(python::module_builder&);
};
} // namespace extclass_demo

View File

@@ -12,30 +12,30 @@
#include "objects.h"
#include "errors.h"
namespace py { namespace detail {
namespace python { namespace detail {
struct Function::TypeObject :
Singleton<Function::TypeObject, Callable<py::detail::TypeObject<Function> > >
struct function::type_object :
singleton<function::type_object, callable<python::detail::type_object<function> > >
{
TypeObject() : SingletonBase(&PyType_Type) {}
type_object() : singleton_base(&PyType_Type) {}
};
void Function::add_to_namespace(PyPtr<Function> new_function, const char* name, PyObject* dict)
void function::add_to_namespace(reference<function> new_function, const char* name, PyObject* dict)
{
Dict d(Ptr(dict, Ptr::borrowed));
String key(name);
dictionary d(ref(dict, ref::increment_count));
string key(name);
Ptr existing_object = d.get_item(key.reference());
ref existing_object = d.get_item(key.reference());
if (existing_object.get() == 0)
{
d[key] = Ptr(new_function.get(), Ptr::borrowed);
d[key] = ref(new_function.get(), ref::increment_count);
}
else
{
if (existing_object->ob_type == TypeObject::singleton())
if (existing_object->ob_type == type_object::instance())
{
Function* f = static_cast<Function*>(existing_object.get());
function* f = static_cast<function*>(existing_object.get());
while (f->m_overloads.get() != 0)
f = f->m_overloads.get();
f->m_overloads = new_function;
@@ -43,22 +43,22 @@ void Function::add_to_namespace(PyPtr<Function> new_function, const char* name,
else
{
PyErr_SetObject(PyExc_RuntimeError,
(String("Attempt to overload ") + name
(string("Attempt to overload ") + name
+ " failed. The existing attribute has type "
+ existing_object->ob_type->tp_name).get());
throw ErrorAlreadySet();
throw error_already_set();
}
}
}
Function::Function()
: PythonObject(TypeObject::singleton())
function::function()
: python_object(type_object::instance())
{
}
PyObject* Function::call(PyObject* args, PyObject* keywords) const
PyObject* function::call(PyObject* args, PyObject* keywords) const
{
for (const Function* f = this; f != 0; f = f->m_overloads.get())
for (const function* f = this; f != 0; f = f->m_overloads.get())
{
PyErr_Clear();
try
@@ -67,7 +67,7 @@ PyObject* Function::call(PyObject* args, PyObject* keywords) const
if (result != 0)
return result;
}
catch(const ArgumentError&)
catch(const argument_error&)
{
}
}
@@ -76,8 +76,8 @@ PyObject* Function::call(PyObject* args, PyObject* keywords) const
return 0;
PyErr_Clear();
String message("No overloaded functions match (");
Tuple arguments(Ptr(args, Ptr::borrowed));
string message("No overloaded functions match (");
tuple arguments(ref(args, ref::increment_count));
for (std::size_t i = 0; i < arguments.size(); ++i)
{
if (i != 0)
@@ -86,7 +86,7 @@ PyObject* Function::call(PyObject* args, PyObject* keywords) const
}
message += "). Candidates are:\n";
for (const Function* f1 = this; f1 != 0; f1 = f1->m_overloads.get())
for (const function* f1 = this; f1 != 0; f1 = f1->m_overloads.get())
{
if (f1 != this)
message += "\n";
@@ -97,11 +97,11 @@ PyObject* Function::call(PyObject* args, PyObject* keywords) const
return 0;
}
BoundFunction* BoundFunction::create(const Ptr& target, const Ptr& fn)
bound_function* bound_function::create(const ref& target, const ref& fn)
{
BoundFunction* const result = free_list;
bound_function* const result = free_list;
if (result == 0)
return new BoundFunction(target, fn);
return new bound_function(target, fn);
free_list = result->m_free_list_link;
result->m_target = target;
@@ -110,21 +110,21 @@ BoundFunction* BoundFunction::create(const Ptr& target, const Ptr& fn)
return result;
}
// The singleton class whose instance represents the type of BoundFunction
// objects in Python. BoundFunctions must be GetAttrable so the __doc__
// The instance class whose obj represents the type of bound_function
// objects in Python. bound_functions must be GetAttrable so the __doc__
// attribute of built-in Python functions can be accessed when bound.
struct BoundFunction::TypeObject :
Singleton<BoundFunction::TypeObject,
Getattrable<Callable<py::detail::TypeObject<BoundFunction> > > >
struct bound_function::type_object :
singleton<bound_function::type_object,
getattrable<callable<python::detail::type_object<bound_function> > > >
{
TypeObject() : SingletonBase(&PyType_Type) {}
type_object() : singleton_base(&PyType_Type) {}
private: // TypeObject<BoundFunction> hook override
void dealloc(BoundFunction*) const;
private: // type_object<bound_function> hook override
void dealloc(bound_function*) const;
};
BoundFunction::BoundFunction(const Ptr& target, const Ptr& fn)
: PythonObject(TypeObject::singleton()),
bound_function::bound_function(const ref& target, const ref& fn)
: python_object(type_object::instance()),
m_target(target),
m_unbound_function(fn),
m_free_list_link(0)
@@ -132,11 +132,11 @@ BoundFunction::BoundFunction(const Ptr& target, const Ptr& fn)
}
PyObject*
BoundFunction::call(PyObject* args, PyObject* keywords) const
bound_function::call(PyObject* args, PyObject* keywords) const
{
// Build a new tuple which prepends the target to the arguments
Tuple tail_arguments(Ptr(args, Ptr::borrowed));
Ptr all_arguments(PyTuple_New(tail_arguments.size() + 1));
tuple tail_arguments(ref(args, ref::increment_count));
ref all_arguments(PyTuple_New(tail_arguments.size() + 1));
PyTuple_SET_ITEM(all_arguments.get(), 0, m_target.get());
Py_INCREF(m_target.get());
@@ -149,19 +149,19 @@ BoundFunction::call(PyObject* args, PyObject* keywords) const
return PyEval_CallObjectWithKeywords(m_unbound_function.get(), all_arguments.get(), keywords);
}
PyObject* BoundFunction::getattr(const char* name) const
PyObject* bound_function::getattr(const char* name) const
{
return PyObject_GetAttrString(m_unbound_function.get(), const_cast<char*>(name));
}
void BoundFunction::TypeObject::dealloc(BoundFunction* instance) const
void bound_function::type_object::dealloc(bound_function* obj) const
{
instance->m_free_list_link = free_list;
free_list = instance;
instance->m_target.reset();
instance->m_unbound_function.reset();
obj->m_free_list_link = free_list;
free_list = obj;
obj->m_target.reset();
obj->m_unbound_function.reset();
}
BoundFunction* BoundFunction::free_list;
bound_function* bound_function::free_list;
}} // namespace py::detail
}} // namespace python::detail

View File

@@ -20,36 +20,36 @@
# include <typeinfo>
# include <vector>
namespace py { namespace detail {
namespace python { namespace detail {
// forward declaration
class ExtensionInstance;
class extension_instance;
// Function --
// function --
// the common base class for all overloadable function and method objects
// supplied by the library.
class Function : public PythonObject
class function : public python_object
{
public:
Function();
// Function objects are reasonably rare, so we guess we can afford a virtual table.
function();
// function objects are reasonably rare, so we guess we can afford a virtual table.
// This cuts down on the number of distinct type objects which need to be defined.
virtual ~Function() {}
virtual ~function() {}
PyObject* call(PyObject* args, PyObject* keywords) const;
static void add_to_namespace(PyPtr<Function> f, const char* name, PyObject* dict);
static void add_to_namespace(reference<function> f, const char* name, PyObject* dict);
private:
virtual PyObject* do_call(PyObject* args, PyObject* keywords) const = 0;
virtual const char* description() const = 0;
private:
struct TypeObject;
struct type_object;
private:
PyPtr<Function> m_overloads;
reference<function> m_overloads;
};
// WrappedFunctionPointer<> --
// wrapped_function_pointer<> --
// A single function or member function pointer wrapped and presented to
// Python as a callable object.
//
@@ -57,22 +57,22 @@ class Function : public PythonObject
// R - the return type of the function pointer
// F - the complete type of the wrapped function pointer
template <class R, class F>
struct WrappedFunctionPointer : Function
struct wrapped_function_pointer : function
{
typedef F PtrFun; // pointer-to--function or pointer-to-member-function
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
WrappedFunctionPointer(PtrFun pf)
wrapped_function_pointer(ptr_fun pf)
: m_pf(pf) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const
{ return Caller<R>::call(m_pf, args, keywords); }
{ return caller<R>::call(m_pf, args, keywords); }
const char* description() const
{ return typeid(F).name(); }
private:
const PtrFun m_pf;
const ptr_fun m_pf;
};
// raw_arguments_function
@@ -80,30 +80,30 @@ struct WrappedFunctionPointer : Function
// verbatim to C++ (useful for customized argument parsing and variable
// argument lists)
template <class Ret, class Args, class Keywords>
struct raw_arguments_function : Function
struct raw_arguments_function : function
{
typedef Ret (*PtrFun)(Args, Keywords);
typedef Ret (*ptr_fun)(Args, Keywords);
raw_arguments_function(PtrFun pf)
raw_arguments_function(ptr_fun pf)
: m_pf(pf) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const
{
Ptr dict(keywords ?
Ptr(keywords, Ptr::new_ref) :
Ptr(PyDict_New()));
ref dict(keywords ?
ref(keywords, ref::increment_count) :
ref(PyDict_New()));
return to_python(
(*m_pf)(from_python(args, py::Type<Args>()),
from_python(dict.get(), py::Type<Keywords>())));
(*m_pf)(from_python(args, python::type<Args>()),
from_python(dict.get(), python::type<Keywords>())));
}
const char* description() const
{ return typeid(PtrFun).name(); }
{ return typeid(ptr_fun).name(); }
private:
const PtrFun m_pf;
const ptr_fun m_pf;
};
// virtual_function<> --
@@ -119,7 +119,7 @@ struct raw_arguments_function : Function
// parameter and calls T::f on it /non-virtually/, where V
// approximates &T::f.
template <class T, class R, class V, class D>
class virtual_function : public Function
class virtual_function : public function
{
public:
virtual_function(V virtual_function_ptr, D default_implementation)
@@ -140,92 +140,92 @@ class virtual_function : public Function
// A helper function for new_member_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 pmf.
// be type<X>, where X is the actual return type of pmf.
template <class F, class R>
Function* new_wrapped_function_aux(R, F pmf)
function* new_wrapped_function_aux(R, F pmf)
{
// We can't just use "typename R::Type" below because MSVC (incorrectly) pukes.
typedef typename R::Type ReturnType;
return new WrappedFunctionPointer<ReturnType, F>(pmf);
typedef typename R::type return_type;
return new wrapped_function_pointer<return_type, F>(pmf);
}
// Create and return a new member function object wrapping the given
// pointer-to-member function
template <class F>
inline Function* new_wrapped_function(F pmf)
inline function* new_wrapped_function(F pmf)
{
// Deduce the return type and pass it off to the helper function above
return new_wrapped_function_aux(return_value(pmf), pmf);
}
template <class R, class Args, class Keywords>
Function* new_raw_arguments_function(R (*pmf)(Args, Keywords))
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);
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.
// 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
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>(
typedef typename R::type return_type;
return new virtual_function<T, return_type, 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
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),
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
// is a callable object not found in the instance namespace but on its class or
// the expression a.b where a is an instance or extension_instance object and b
// is a callable object not found in the obj namespace but on its class or
// a base class.
class BoundFunction : public PythonObject
class bound_function : public python_object
{
public:
static BoundFunction* create(const Ptr& target, const Ptr& fn);
static bound_function* create(const ref& target, const ref& fn);
BoundFunction(const Ptr& target, const Ptr& fn);
bound_function(const ref& target, const ref& fn);
PyObject* call(PyObject*args, PyObject* keywords) const;
PyObject* getattr(const char* name) const;
private:
struct TypeObject;
friend struct TypeObject;
struct type_object;
friend struct type_object;
Ptr m_target;
Ptr m_unbound_function;
ref m_target;
ref m_unbound_function;
private: // data members for allocation/deallocation optimization
BoundFunction* m_free_list_link;
bound_function* m_free_list_link;
static BoundFunction* free_list;
static bound_function* free_list;
};
// Special functions designed to access data members of a wrapped C++ object.
template <class ClassType, class MemberType>
class GetterFunction : public Function
class getter_function : public function
{
public:
typedef MemberType ClassType::* PointerToMember;
typedef MemberType ClassType::* pointer_to_member;
GetterFunction(PointerToMember pm)
getter_function(pointer_to_member pm)
: m_pm(pm) {}
private:
@@ -234,16 +234,16 @@ class GetterFunction : public Function
const char* description() const
{ return typeid(MemberType (*)(const ClassType&)).name(); }
private:
PointerToMember m_pm;
pointer_to_member m_pm;
};
template <class ClassType, class MemberType>
class SetterFunction : public Function
class setter_function : public function
{
public:
typedef MemberType ClassType::* PointerToMember;
typedef MemberType ClassType::* pointer_to_member;
SetterFunction(PointerToMember pm)
setter_function(pointer_to_member pm)
: m_pm(pm) {}
private:
@@ -252,11 +252,11 @@ class SetterFunction : public Function
const char* description() const
{ return typeid(void (*)(const ClassType&, const MemberType&)).name(); }
private:
PointerToMember m_pm;
pointer_to_member m_pm;
};
template <class ClassType, class MemberType>
PyObject* GetterFunction<ClassType, MemberType>::do_call(
PyObject* getter_function<ClassType, MemberType>::do_call(
PyObject* args, PyObject* /* keywords */) const
{
PyObject* self;
@@ -264,11 +264,11 @@ PyObject* GetterFunction<ClassType, MemberType>::do_call(
return 0;
return to_python(
from_python(self, Type<const ClassType*>())->*m_pm);
from_python(self, type<const ClassType*>())->*m_pm);
}
template <class ClassType, class MemberType>
PyObject* SetterFunction<ClassType, MemberType>::do_call(
PyObject* setter_function<ClassType, MemberType>::do_call(
PyObject* args, PyObject* /* keywords */) const
{
PyObject* self;
@@ -276,9 +276,9 @@ PyObject* SetterFunction<ClassType, MemberType>::do_call(
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &self, &value))
return 0;
typedef typename boost::call_traits<MemberType>::const_reference ExtractType;
from_python(self, Type<ClassType*>())->*m_pm
= from_python(value, Type<ExtractType>());
typedef typename boost::call_traits<MemberType>::const_reference extract_type;
from_python(self, type<ClassType*>())->*m_pm
= from_python(value, type<extract_type>());
return none();
}
@@ -291,16 +291,16 @@ PyObject* virtual_function<T,R,V,D>::do_call(PyObject* args, PyObject* keywords)
PyObject* target = PyTuple_GetItem(args, 0);
if (target != 0)
{
ExtensionInstance* self = get_extension_instance(target);
extension_instance* self = get_extension_instance(target);
if (self->wrapped_objects().size() == 1
&& !self->wrapped_objects()[0]->held_by_value())
{
return Caller<R>::call(m_virtual_function_ptr, args, keywords);
return caller<R>::call(m_virtual_function_ptr, args, keywords);
}
}
return Caller<R>::call(m_default_implementation, args, keywords);
return caller<R>::call(m_default_implementation, args, keywords);
}
}} // namespace py::detail
}} // namespace python::detail
#endif // FUNCTIONS_DWA051400_H_

View File

@@ -10,7 +10,7 @@ def gen_all(args):
open('caller.h', 'w').write(gen_caller(args))
open('init_function.h', 'w').write(gen_init_function(args))
open('signatures.h', 'w').write(gen_signatures(args))
open('singleton.h', 'w').write(gen_singleton(args))
open('instance.h', 'w').write(gen_singleton(args))
open('extclass.h', 'w').write(gen_extclass(args))
if __name__ == '__main__':

View File

@@ -11,7 +11,7 @@ def gen_callback(args):
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file was generated for %d-argument python callbacks by gen_callback.py
// This file was generated for %d-argument python callbacks by gen_callback.python
#ifndef CALLBACK_DWA_052100_H_
# define CALLBACK_DWA_052100_H_
@@ -19,41 +19,41 @@ def gen_callback(args):
# include "pyconfig.h"
# include "py.h"
namespace py {
namespace python {
namespace detail {
template <class T>
inline void callback_adjust_refcount(PyObject*, Type<T>) {}
inline void callback_adjust_refcount(PyObject*, type<T>) {}
inline void callback_adjust_refcount(PyObject* p, Type<PyObject*>)
inline void callback_adjust_refcount(PyObject* p, type<PyObject*>)
{ Py_INCREF(p); }
}
// Calling Python from C++
template <class R>
struct Callback
struct callback
{""" % args
+ gen_functions('''
%{ template <%(class A%n%:, %)>
%} static R call_method(PyObject* self, const char* name%(, const A%n& a%n%))
{%(
Ptr p%n(to_python(a%n));%)
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
ref p%n(to_python(a%n));%)
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
const_cast<char*>("(%(O%))")%(,
p%n.get()%)));
detail::callback_adjust_refcount(result.get(), Type<R>());
return from_python(result.get(), Type<R>());
detail::callback_adjust_refcount(result.get(), type<R>());
return from_python(result.get(), type<R>());
}
%{ template <%(class A%n%:, %)>
%} static R call(PyObject* self%(, const A%n& a%n%))
{%(
Ptr p%n(to_python(a%n));%)
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
ref p%n(to_python(a%n));%)
ref result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
p%n.get()%)));
detail::callback_adjust_refcount(result.get(), Type<R>());
return from_python(result.get(), Type<R>());
detail::callback_adjust_refcount(result.get(), type<R>());
return from_python(result.get(), type<R>());
}
''', args)
+
@@ -63,15 +63,15 @@ struct Callback
// void g();
// void f() { return g(); }
template <>
struct Callback<void>
struct callback<void>
{
"""
+ gen_functions('''
%{ template <%(class A%n%:, %)>
%} static void call_method(PyObject* self, const char* name%(, const A%n& a%n%))
{%(
Ptr p%n(to_python(a%n));%)
Ptr result(PyEval_CallMethod(self, const_cast<char*>(name),
ref p%n(to_python(a%n));%)
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
const_cast<char*>("(%(O%))")%(,
p%n.get()%)));
}
@@ -79,8 +79,8 @@ struct Callback<void>
%{ template <%(class A%n%:, %)>
%} static void call(PyObject* self%(, const A%n& a%n%))
{%(
Ptr p%n(to_python(a%n));%)
Ptr result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
ref p%n(to_python(a%n));%)
ref result(PyEval_CallFunction(self, const_cast<char*>("(%(O%))")%(,
p%n.get()%)));
}
''', args)
@@ -90,25 +90,25 @@ struct Callback<void>
// Make it a compile-time error to try to return a const char* from a virtual
// function. The standard conversion
//
// from_python(PyObject* string, py::Type<const char*>)
// from_python(PyObject* string, python::type<const char*>)
//
// returns a pointer to the character array which is internal to string. The
// problem with trying to do this in a standard callback function is that the
// Python string would likely be destroyed upon return from the calling function
// (py::Callback<const char*>::call[_method]) when its reference count is
// (python::callback<const char*>::call[_method]) when its reference count is
// decremented. If you absolutely need to do this and you're sure it's safe (it
// usually isn't), you can use
//
// py::String result(py::Callback<py::String>::call[_method](...args...));
// python::string result(python::callback<python::string>::call[_method](...args...));
// ...result.c_str()... // access the char* array
template <>
struct Callback<const char*>
struct callback<const char*>
{
// Try hard to generate a readable error message
typedef struct unsafe_since_python_string_may_be_destroyed {} call, call_method;
};
} // namespace py
} // namespace python
#endif // CALLBACK_DWA_052100_H_
""")

View File

@@ -18,7 +18,7 @@ header = '''// (C) Copyright David Abrahams 2000. Permission to copy, use, modi
// producing this work.
//
// This file generated for %d-argument member functions and %d-argument free
// functions by gen_caller.py
// functions by gen_caller.python
'''
body_sections = (
@@ -32,11 +32,11 @@ body_sections = (
# include "signatures.h"
# include "none.h"
namespace py {
namespace python {
// Calling C++ from Python
template <class R>
struct Caller
struct caller
{
''',
'''
@@ -46,7 +46,7 @@ struct Caller
'''};
template <>
struct Caller<void>
struct caller<void>
{
''',
'''
@@ -69,8 +69,8 @@ member_function = ''' template <class T%(, class A%n%)>
%( PyObject* a%n;
%) if (!PyArg_ParseTuple(args, const_cast<char*>("O%(O%)"), &self%(, &a%n%)))
return 0;
T& target = from_python(self, Type<T&>());
%3(target.*pmf)(%(from_python(a%n, Type<A%n>())%:,
T& target = from_python(self, type<T&>());
%3(target.*pmf)(%(from_python(a%n, type<A%n>())%:,
%))%4
}
@@ -81,7 +81,7 @@ free_function = '''%{ template <%(class A%n%:, %)>
%( PyObject* a%n;
%) if (!PyArg_ParseTuple(args, const_cast<char*>("%(O%)")%(, &a%n%)))
return 0;
%2f(%(from_python(a%n, Type<A%n>())%:,
%2f(%(from_python(a%n, type<A%n>())%:,
%))%3
}

View File

@@ -12,7 +12,7 @@ def gen_extclass(args):
// producing this work.
//
// This file automatically generated for %d-argument constructors by
// gen_extclass.py
// gen_extclass.python
#ifndef EXTENSION_CLASS_DWA052000_H_
# define EXTENSION_CLASS_DWA052000_H_
@@ -28,33 +28,33 @@ def gen_extclass(args):
# include <typeinfo>
# include <boost/smart_ptr.hpp>
namespace py {
namespace python {
// 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 };
enum without_downcast_t { 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;
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
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);
void report_missing_instance_data(ExtensionInstance*, Class<ExtensionInstance>*, const std::type_info&);
void report_missing_ptr_data(ExtensionInstance*, Class<ExtensionInstance>*, const std::type_info&);
meta_class<extension_instance>* extension_meta_class();
extension_instance* get_extension_instance(PyObject* p);
void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_class_object(const std::type_info&);
void report_released_smart_pointer(const std::type_info&);
@@ -66,87 +66,87 @@ T* check_non_null(T* p)
return p;
}
template <class T> class HeldInstance;
template <class T> class held_instance;
typedef void* (*ConversionFunction)(void*);
struct BaseClassInfo
{
BaseClassInfo(ExtensionClassBase* t, ConversionFunction f)
BaseClassInfo(extension_class_base* t, ConversionFunction f)
:class_object(t), convert(f)
{}
ExtensionClassBase* class_object;
extension_class_base* class_object;
ConversionFunction convert;
};
typedef BaseClassInfo DerivedClassInfo;
typedef BaseClassInfo derived_class_info;
struct add_operator_base;
class ExtensionClassBase : public Class<ExtensionInstance>
class extension_class_base : public class_t<extension_instance>
{
public:
ExtensionClassBase(const char* name);
extension_class_base(const char* name);
public:
// the purpose of try_class_conversions() and its related functions
// is explained in extclass.cpp
void* try_class_conversions(InstanceHolderBase*) const;
void* try_base_class_conversions(InstanceHolderBase*) const;
void* try_derived_class_conversions(InstanceHolderBase*) const;
void* try_class_conversions(instance_holder_base*) const;
void* try_base_class_conversions(instance_holder_base*) const;
void* try_derived_class_conversions(instance_holder_base*) const;
void set_attribute(const char* name, PyObject* x);
void set_attribute(const char* name, Ptr x);
void set_attribute(const char* name, ref x);
private:
virtual void* extract_object_from_holder(InstanceHolderBase* v) const = 0;
virtual void* extract_object_from_holder(instance_holder_base* v) const = 0;
virtual std::vector<BaseClassInfo> const& base_classes() const = 0;
virtual std::vector<DerivedClassInfo> const& derived_classes() const = 0;
virtual std::vector<derived_class_info> const& derived_classes() const = 0;
protected:
friend struct add_operator_base;
void add_method(PyPtr<Function> method, const char* name);
void add_method(Function* method, const char* name);
void add_method(reference<function> method, const char* name);
void add_method(function* method, const char* name);
void add_constructor_object(Function*);
void add_setter_method(Function*, const char* name);
void add_getter_method(Function*, const char* name);
void add_constructor_object(function*);
void add_setter_method(function*, const char* name);
void add_getter_method(function*, const char* name);
};
template <class T>
class ClassRegistry
class class_registry
{
public:
static ExtensionClassBase* class_object()
static extension_class_base* class_object()
{ return static_class_object; }
// Register/unregister the Python class object corresponding to T
static void register_class(ExtensionClassBase*);
static void unregister_class(ExtensionClassBase*);
static void register_class(extension_class_base*);
static void unregister_class(extension_class_base*);
// Establish C++ inheritance relationships
static void register_base_class(BaseClassInfo const&);
static void register_derived_class(DerivedClassInfo const&);
static void register_derived_class(derived_class_info const&);
// Query the C++ inheritance relationships
static std::vector<BaseClassInfo> const& base_classes();
static std::vector<DerivedClassInfo> const& derived_classes();
static std::vector<derived_class_info> const& derived_classes();
private:
static ExtensionClassBase* static_class_object;
static extension_class_base* static_class_object;
static std::vector<BaseClassInfo> static_base_class_info;
static std::vector<DerivedClassInfo> static_derived_class_info;
static std::vector<derived_class_info> static_derived_class_info;
};
}} // namespace py::detail
}} // namespace python::detail
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
// This class' only job is to define from_python and to_python converters for T
// 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::detail::HeldInstance<T> >
// virtual functions, U = held_instance<T>.
template <class T, class U = python::detail::held_instance<T> >
class PyExtensionClassConverters
{
public:
@@ -159,7 +159,7 @@ class PyExtensionClassConverters
// pop up. Now, if T hasn't been wrapped as an extension class, the user
// will see an error message about the lack of an eligible
// py_extension_class_converters() function.
friend PyExtensionClassConverters py_extension_class_converters(py::Type<T>)
friend PyExtensionClassConverters py_extension_class_converters(python::type<T>)
{
return PyExtensionClassConverters();
}
@@ -177,118 +177,118 @@ class PyExtensionClassConverters
// writes code which causes us to try to copy a T.
PyObject* to_python(const T& x) const
{
py::PyPtr<py::detail::ExtensionInstance> result(create_instance());
python::reference<python::detail::extension_instance> result(create_instance());
result->add_implementation(
std::auto_ptr<py::detail::InstanceHolderBase>(
new py::detail::InstanceValueHolder<T,U>(result.get(), x)));
std::auto_ptr<python::detail::instance_holder_base>(
new python::detail::instance_value_holder<T,U>(result.get(), x)));
return result.release();
}
// Convert to T*
friend T* from_python(PyObject* obj, py::Type<T*>)
friend T* from_python(PyObject* obj, python::type<T*>)
{
// Downcast to an ExtensionInstance, then find the actual T
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();
// downcast to an extension_instance, then find the actual T
python::detail::extension_instance* self = python::detail::get_extension_instance(obj);
typedef std::vector<python::detail::instance_holder_base*>::const_iterator iterator;
for (iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
py::detail::InstanceHolder<T>* held = dynamic_cast<py::detail::InstanceHolder<T>*>(*p);
python::detail::instance_holder<T>* held = dynamic_cast<python::detail::instance_holder<T>*>(*p);
if (held != 0)
return held->target();
// see extclass.cpp for an explanation of try_class_conversions()
void* target = py::detail::ClassRegistry<T>::class_object()->try_class_conversions(*p);
void* target = python::detail::class_registry<T>::class_object()->try_class_conversions(*p);
if(target)
return static_cast<T*>(target);
}
py::detail::report_missing_instance_data(self, py::detail::ClassRegistry<T>::class_object(), typeid(T));
throw py::ArgumentError();
python::detail::report_missing_instance_data(self, python::detail::class_registry<T>::class_object(), typeid(T));
throw python::argument_error();
}
// Convert to PtrType, where PtrType can be dereferenced to obtain a T.
template <class PtrType>
static PtrType& ptr_from_python(PyObject* obj, py::Type<PtrType>)
static PtrType& ptr_from_python(PyObject* obj, python::type<PtrType>)
{
// Downcast to an ExtensionInstance, then find the actual T
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();
// downcast to an extension_instance, then find the actual T
python::detail::extension_instance* self = python::detail::get_extension_instance(obj);
typedef std::vector<python::detail::instance_holder_base*>::const_iterator iterator;
for (iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
py::detail::InstancePtrHolder<PtrType, T>* held =
dynamic_cast<py::detail::InstancePtrHolder<PtrType, T>*>(*p);
python::detail::instance_ptr_holder<PtrType, T>* held =
dynamic_cast<python::detail::instance_ptr_holder<PtrType, T>*>(*p);
if (held != 0)
return held->ptr();
}
py::detail::report_missing_ptr_data(self, py::detail::ClassRegistry<T>::class_object(), typeid(T));
throw py::ArgumentError();
python::detail::report_missing_ptr_data(self, python::detail::class_registry<T>::class_object(), typeid(T));
throw python::argument_error();
}
template <class PtrType>
static PyObject* ptr_to_python(PtrType x)
{
py::PyPtr<py::detail::ExtensionInstance> result(create_instance());
python::reference<python::detail::extension_instance> result(create_instance());
result->add_implementation(
std::auto_ptr<py::detail::InstanceHolderBase>(
new py::detail::InstancePtrHolder<PtrType,T>(x)));
std::auto_ptr<python::detail::instance_holder_base>(
new python::detail::instance_ptr_holder<PtrType,T>(x)));
return result.release();
}
static py::PyPtr<py::detail::ExtensionInstance> create_instance()
static python::reference<python::detail::extension_instance> create_instance()
{
PyTypeObject* class_object = py::detail::ClassRegistry<T>::class_object();
PyTypeObject* class_object = python::detail::class_registry<T>::class_object();
if (class_object == 0)
py::detail::report_missing_class_object(typeid(T));
python::detail::report_missing_class_object(typeid(T));
return py::PyPtr<py::detail::ExtensionInstance>(
new py::detail::ExtensionInstance(class_object));
return python::reference<python::detail::extension_instance>(
new python::detail::extension_instance(class_object));
}
// Convert to const T*
friend const T* from_python(PyObject* p, py::Type<const T*>)
{ return from_python(p, py::Type<T*>()); }
friend const T* from_python(PyObject* p, python::type<const T*>)
{ return from_python(p, python::type<T*>()); }
// Convert to const T* const&
friend const T* from_python(PyObject* p, py::Type<const T*const&>)
{ return from_python(p, py::Type<const T*>()); }
friend const T* from_python(PyObject* p, python::type<const T*const&>)
{ return from_python(p, python::type<const T*>()); }
// Convert to T* const&
friend T* from_python(PyObject* p, py::Type<T* const&>)
{ return from_python(p, py::Type<T*>()); }
friend T* from_python(PyObject* p, python::type<T* const&>)
{ return from_python(p, python::type<T*>()); }
// Convert to T&
friend T& from_python(PyObject* p, py::Type<T&>)
{ return *py::detail::check_non_null(from_python(p, py::Type<T*>())); }
friend T& from_python(PyObject* p, python::type<T&>)
{ return *python::detail::check_non_null(from_python(p, python::type<T*>())); }
// Convert to const T&
friend const T& from_python(PyObject* p, py::Type<const T&>)
{ return from_python(p, py::Type<T&>()); }
friend const T& from_python(PyObject* p, python::type<const T&>)
{ return from_python(p, python::type<T&>()); }
// Convert to T
friend const T& from_python(PyObject* p, py::Type<T>)
{ return from_python(p, py::Type<T&>()); }
friend const T& from_python(PyObject* p, python::type<T>)
{ return from_python(p, python::type<T&>()); }
friend std::auto_ptr<T>& from_python(PyObject* p, py::Type<std::auto_ptr<T>&>)
{ return ptr_from_python(p, py::Type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, python::type<std::auto_ptr<T>&>)
{ return ptr_from_python(p, python::type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, py::Type<std::auto_ptr<T> >)
{ return ptr_from_python(p, py::Type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, python::type<std::auto_ptr<T> >)
{ return ptr_from_python(p, python::type<std::auto_ptr<T> >()); }
friend const std::auto_ptr<T>& from_python(PyObject* p, py::Type<const std::auto_ptr<T>&>)
{ return ptr_from_python(p, py::Type<std::auto_ptr<T> >()); }
friend const std::auto_ptr<T>& from_python(PyObject* p, python::type<const std::auto_ptr<T>&>)
{ return ptr_from_python(p, python::type<std::auto_ptr<T> >()); }
friend PyObject* to_python(std::auto_ptr<T> x)
{ return ptr_to_python(x); }
friend boost::shared_ptr<T>& from_python(PyObject* p, py::Type<boost::shared_ptr<T>&>)
{ return ptr_from_python(p, py::Type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, python::type<boost::shared_ptr<T>&>)
{ return ptr_from_python(p, python::type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, py::Type<boost::shared_ptr<T> >)
{ return ptr_from_python(p, py::Type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, python::type<boost::shared_ptr<T> >)
{ return ptr_from_python(p, python::type<boost::shared_ptr<T> >()); }
friend const boost::shared_ptr<T>& from_python(PyObject* p, py::Type<const boost::shared_ptr<T>&>)
{ return ptr_from_python(p, py::Type<boost::shared_ptr<T> >()); }
friend const boost::shared_ptr<T>& from_python(PyObject* p, python::type<const boost::shared_ptr<T>&>)
{ return ptr_from_python(p, python::type<boost::shared_ptr<T> >()); }
friend PyObject* to_python(boost::shared_ptr<T> x)
{ return ptr_to_python(x); }
@@ -301,31 +301,31 @@ class PyExtensionClassConverters
template <class T>
PyObject* to_python(const T& x)
{
return py_extension_class_converters(py::Type<T>()).to_python(x);
return py_extension_class_converters(python::type<T>()).to_python(x);
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace py {
namespace python {
PY_IMPORT_CONVERSION(PyExtensionClassConverters);
BOOST_PYTHON_IMPORT_CONVERSION(PyExtensionClassConverters);
namespace detail {
template <class T> class InstanceHolder;
template <class T> class instance_holder;
class ReadOnlySetattrFunction : public Function
class read_only_setattr_function : public function
{
public:
ReadOnlySetattrFunction(const char* name);
read_only_setattr_function(const char* name);
PyObject* do_call(PyObject* args, PyObject* keywords) const;
const char* description() const;
private:
String m_name;
string m_name;
};
template <class From, class To>
struct DefineConversion
struct define_conversion
{
static void* upcast_ptr(void* v)
{
@@ -339,7 +339,7 @@ class ReadOnlySetattrFunction : public Function
};
// 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.
// subclasses of this class will simply be class_t<extension_instance> objects.
//
// U should be a class derived from T which overrides virtual functions with
// boilerplate code to call back into Python. See extclass_demo.h for examples.
@@ -348,45 +348,45 @@ class ReadOnlySetattrFunction : public Function
// Python which are called from C++ if you don't supply it. If you just want to
// be able to use T in python without overriding member functions, you can omit
// U.
template <class T, class U = HeldInstance<T> >
class ExtensionClass
template <class T, class U = held_instance<T> >
class extension_class
: public PyExtensionClassConverters<T, U>, // This generates the to_python/from_python functions
public ExtensionClassBase
public extension_class_base
{
public:
typedef T WrappedType;
typedef U CallbackType;
typedef T wrapped_type;
typedef U callback_type;
// Construct with a name that comes from typeid(T).name(). The name only
// affects the objects of this class are represented through repr()
ExtensionClass();
extension_class();
// Construct with the given name. The name only affects the objects of this
// class are represented through repr()
ExtensionClass(const char* name);
extension_class(const char* name);
~ExtensionClass();
~extension_class();
// define constructors
""" % args
+ gen_function(
""" template <%(class A%n%:, %)>
inline void def(Constructor<%(A%n%:, %)>)
// The following incantation builds a Signature1, Signature2,... object. It
inline void def(constructor<%(A%n%:, %)>)
// The following incantation builds a signature1, signature2,... object. It
// should _all_ get optimized away.
{ add_constructor(
%(prepend(Type<A%n>::Id(),
%) Signature0()%()%));
%(prepend(type<A%n>::id(),
%) signature0()%()%));
}
""", args)
+
"""
// export homogeneous operators (type of both lhs and rhs is 'operator')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>());
// export homogeneous operators (type of both lhs and rhs is 'T const&')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub)>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub)>());
template <long which, class Operand>
inline void def(operators<which,Operand>)
{
@@ -395,12 +395,12 @@ class ExtensionClass
}
// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>(),
// py::right_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>(),
// python::right_operand<int const&>());
// export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub)>(),
// py::right_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub)>(),
// python::right_operand<int const&>());
template <long which, class Left, class Right>
inline void def(operators<which,Left>, right_operand<Right> r)
{
@@ -410,13 +410,13 @@ class ExtensionClass
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub), Foo>(),
// py::left_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub), Foo>(),
// python::left_operand<int const&>());
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'T const&')
// usage: foo_class.def(py::operators<(py::op_add | py::op_sub)>(),
// py::left_operand<int const&>());
// usage: foo_class.def(python::operators<(python::op_add | python::op_sub)>(),
// python::left_operand<int const&>());
template <long which, class Left, class Right>
inline void def(operators<which,Right>, left_operand<Left> l)
{
@@ -425,7 +425,7 @@ class ExtensionClass
}
// define a function that passes Python arguments and keywords
// to C++ verbatim (as a 'Tuple const&' and 'Dict const&'
// to C++ verbatim (as a 'tuple const&' and 'dictionary const&'
// respectively). This is useful for manual argument passing.
// It's also the only possibility to pass keyword arguments to C++.
// Fn must have a signatur that is compatible to
@@ -452,34 +452,34 @@ class ExtensionClass
template <class Fn, class DefaultFn>
inline void def(Fn fn, const char* name, DefaultFn default_fn)
{
this->add_method(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
// member (pm) of the T instance
// member (pm) of the T obj
template <class MemberType>
inline void def_getter(MemberType T::*pm, const char* name)
{
this->add_getter_method(new GetterFunction<T, MemberType>(pm), name);
this->add_getter_method(new getter_function<T, MemberType>(pm), name);
}
// Provide a function which implements assignment to x.<name>, writing to
// the given member (pm) of the T instance
// the given member (pm) of the T obj
template <class MemberType>
inline void def_setter(MemberType T::*pm, const char* name)
{
this->add_setter_method(new SetterFunction<T, MemberType>(pm), name);
this->add_setter_method(new setter_function<T, MemberType>(pm), name);
}
// Expose the given member (pm) of the T instance as a read-only attribute
// Expose the given member (pm) of the T obj as a read-only attribute
template <class MemberType>
inline void def_readonly(MemberType T::*pm, const char* name)
{
this->add_setter_method(new ReadOnlySetattrFunction(name), name);
this->add_setter_method(new read_only_setattr_function(name), name);
this->def_getter(pm, name);
}
// Expose the given member (pm) of the T instance as a read/write attribute
// Expose the given member (pm) of the T obj as a read/write attribute
template <class MemberType>
inline void def_read_write(MemberType T::*pm, const char* name)
{
@@ -493,43 +493,43 @@ class ExtensionClass
// declare the given class a base class of this one and register
// up and down conversion functions
template <class S, class V>
void declare_base(ExtensionClass<S, V>* base)
void declare_base(extension_class<S, V>* base)
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
BaseClassInfo baseInfo(base,
&DefineConversion<S, T>::downcast_ptr);
ClassRegistry<T>::register_base_class(baseInfo);
add_base(Ptr(as_object(base), Ptr::new_ref));
&define_conversion<S, T>::downcast_ptr);
class_registry<T>::register_base_class(baseInfo);
add_base(ref(as_object(base), ref::increment_count));
DerivedClassInfo derivedInfo(this,
&DefineConversion<T, S>::upcast_ptr);
ClassRegistry<S>::register_derived_class(derivedInfo);
derived_class_info derivedInfo(this,
&define_conversion<T, S>::upcast_ptr);
class_registry<S>::register_derived_class(derivedInfo);
}
// declare the given class a base class of this one and register
// only up conversion function
template <class S, class V>
void declare_base(ExtensionClass<S, V>* base, WithoutDowncast)
void declare_base(extension_class<S, V>* base, without_downcast_t)
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
BaseClassInfo baseInfo(base, 0);
ClassRegistry<T>::register_base_class(baseInfo);
add_base(Ptr(as_object(base), Ptr::new_ref));
class_registry<T>::register_base_class(baseInfo);
add_base(ref(as_object(base), ref::increment_count));
DerivedClassInfo derivedInfo(this,
&DefineConversion<T, S>::upcast_ptr);
ClassRegistry<S>::register_derived_class(derivedInfo);
derived_class_info derivedInfo(this,
&define_conversion<T, S>::upcast_ptr);
class_registry<S>::register_derived_class(derivedInfo);
}
private: // types
typedef InstanceValueHolder<T,U> Holder;
typedef instance_value_holder<T,U> holder;
private: // ExtensionClassBase virtual function implementations
private: // extension_class_base virtual function implementations
std::vector<BaseClassInfo> const& base_classes() const;
std::vector<DerivedClassInfo> const& derived_classes() const;
void* extract_object_from_holder(InstanceHolderBase* v) const;
std::vector<derived_class_info> const& derived_classes() const;
void* extract_object_from_holder(instance_holder_base* v) const;
private: // Utility functions
template <long which, class Operand>
@@ -604,40 +604,40 @@ class ExtensionClass
choose_rop<(which & op_cmp)>::template args<Left,Right>::add(this);
}
template <class Signature>
void add_constructor(Signature sig)
template <class signature>
void add_constructor(signature sig)
{
this->add_constructor_object(InitFunction<Holder>::create(sig));
this->add_constructor_object(init_function<holder>::create(sig));
}
};
// A simple wrapper over a T which allows us to use ExtensionClass<T> with a
// single template parameter only. See ExtensionClass<T>, above.
// A simple wrapper over a T which allows us to use extension_class<T> with a
// single template parameter only. See extension_class<T>, above.
template <class T>
class HeldInstance : public T
class held_instance : public T
{
// There are no member functions: we want to avoid inadvertently overriding
// any virtual functions in T.
public:"""
+ gen_functions("""%{
template <%(class A%n%:, %)>%}
HeldInstance(PyObject*%(, A%n% a%n%)) : T(%(a%n%:, %)) {}""", args)
held_instance(PyObject*%(, A%n% a%n%)) : T(%(a%n%:, %)) {}""", args)
+ """
};
// Abstract base class for all instance holders. Base for template class
// InstanceHolder<>, below.
class InstanceHolderBase
// Abstract base class for all obj holders. Base for template class
// instance_holder<>, below.
class instance_holder_base
{
public:
virtual ~InstanceHolderBase() {}
virtual ~instance_holder_base() {}
virtual bool held_by_value() = 0;
};
// Abstract base class which holds a Held, somehow. Provides a uniform way to
// get a pointer to the held object
template <class Held>
class InstanceHolder : public InstanceHolderBase
class instance_holder : public instance_holder_base
{
public:
virtual Held*target() = 0;
@@ -648,10 +648,10 @@ public:
// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is
// neccessary to implement virtual function callbacks (there must be a
// back-pointer to the actual Python object so that we can call any
// overrides). HeldInstance (above) is used as a default Wrapper class when
// overrides). held_instance (above) is used as a default Wrapper class when
// there are no virtual functions.
template <class Held, class Wrapper>
class InstanceValueHolder : public InstanceHolder<Held>
class instance_value_holder : public instance_holder<Held>
{
public:
Held* target() { return &m_held; }
@@ -659,11 +659,11 @@ public:
"""
+ gen_functions("""%{
template <%(class A%n%:, %)>%}
InstanceValueHolder(ExtensionInstance* p%(, A%n a%n%)) :
instance_value_holder(extension_instance* p%(, A%n a%n%)) :
m_held(p%(, a%n%)) {}""", args)
+ """
public: // implementation of InstanceHolderBase required interface
public: // implementation of instance_holder_base required interface
bool held_by_value() { return true; }
private:
@@ -674,59 +674,59 @@ public:
// PtrType. By default, these are only generated for PtrType ==
// std::auto_ptr<HeldType> and PtrType == boost::shared_ptr<HeldType>.
template <class PtrType, class HeldType>
class InstancePtrHolder : public InstanceHolder<HeldType>
class instance_ptr_holder : public instance_holder<HeldType>
{
public:
HeldType* target() { return &*m_ptr; }
PtrType& ptr() { return m_ptr; }
InstancePtrHolder(PtrType ptr) : m_ptr(ptr) {}
instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {}
public: // implementation of InstanceHolderBase required interface
public: // implementation of instance_holder_base required interface
bool held_by_value() { return false; }
private:
PtrType m_ptr;
};
class ExtensionInstance : public Instance
class extension_instance : public instance
{
public:
ExtensionInstance(PyTypeObject* class_);
~ExtensionInstance();
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<InstanceHolderBase> holder);
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<InstanceHolderBase*> WrappedObjects;
const WrappedObjects& wrapped_objects() const
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
WrappedObjects m_wrapped_objects;
held_objects m_wrapped_objects;
};
//
// Template function implementations
//
Tuple extension_class_coerce(Ptr l, Ptr r);
tuple extension_class_coerce(ref l, ref r);
template <class T, class U>
ExtensionClass<T, U>::ExtensionClass()
: ExtensionClassBase(typeid(T).name())
extension_class<T, U>::extension_class()
: extension_class_base(typeid(T).name())
{
ClassRegistry<T>::register_class(this);
class_registry<T>::register_class(this);
}
template <class T, class U>
ExtensionClass<T, U>::ExtensionClass(const char* name)
: ExtensionClassBase(name)
extension_class<T, U>::extension_class(const char* name)
: extension_class_base(name)
{
ClassRegistry<T>::register_class(this);
class_registry<T>::register_class(this);
}
template <class T, class U>
void ExtensionClass<T, U>::def_standard_coerce()
void extension_class<T, U>::def_standard_coerce()
{
Ptr coerce_fct = dict().get_item(String("__coerce__"));
ref coerce_fct = dict().get_item(string("__coerce__"));
if(coerce_fct.get() == 0) // not yet defined
this->def(&extension_class_coerce, "__coerce__");
@@ -735,36 +735,36 @@ void ExtensionClass<T, U>::def_standard_coerce()
template <class T, class U>
inline
std::vector<BaseClassInfo> const&
ExtensionClass<T, U>::base_classes() const
extension_class<T, U>::base_classes() const
{
return ClassRegistry<T>::base_classes();
return class_registry<T>::base_classes();
}
template <class T, class U>
inline
std::vector<DerivedClassInfo> const&
ExtensionClass<T, U>::derived_classes() const
std::vector<derived_class_info> const&
extension_class<T, U>::derived_classes() const
{
return ClassRegistry<T>::derived_classes();
return class_registry<T>::derived_classes();
}
template <class T, class U>
void* ExtensionClass<T, U>::extract_object_from_holder(InstanceHolderBase* v) const
void* extension_class<T, U>::extract_object_from_holder(instance_holder_base* v) const
{
InstanceHolder<T>* held = dynamic_cast<InstanceHolder<T>*>(v);
instance_holder<T>* held = dynamic_cast<instance_holder<T>*>(v);
if(held)
return held->target();
return 0;
}
template <class T, class U>
ExtensionClass<T, U>::~ExtensionClass()
extension_class<T, U>::~extension_class()
{
ClassRegistry<T>::unregister_class(this);
class_registry<T>::unregister_class(this);
}
template <class T>
inline void ClassRegistry<T>::register_class(ExtensionClassBase* p)
inline void class_registry<T>::register_class(extension_class_base* p)
{
// You're not expected to create more than one of these!
assert(static_class_object == 0);
@@ -772,7 +772,7 @@ inline void ClassRegistry<T>::register_class(ExtensionClassBase* p)
}
template <class T>
inline void ClassRegistry<T>::unregister_class(ExtensionClassBase* p)
inline void class_registry<T>::unregister_class(extension_class_base* p)
{
// The user should be destroying the same object they created.
assert(static_class_object == p);
@@ -781,25 +781,25 @@ inline void ClassRegistry<T>::unregister_class(ExtensionClassBase* p)
}
template <class T>
void ClassRegistry<T>::register_base_class(BaseClassInfo const& i)
void class_registry<T>::register_base_class(BaseClassInfo const& i)
{
static_base_class_info.push_back(i);
}
template <class T>
void ClassRegistry<T>::register_derived_class(DerivedClassInfo const& i)
void class_registry<T>::register_derived_class(derived_class_info const& i)
{
static_derived_class_info.push_back(i);
}
template <class T>
std::vector<BaseClassInfo> const& ClassRegistry<T>::base_classes()
std::vector<BaseClassInfo> const& class_registry<T>::base_classes()
{
return static_base_class_info;
}
template <class T>
std::vector<DerivedClassInfo> const& ClassRegistry<T>::derived_classes()
std::vector<derived_class_info> const& class_registry<T>::derived_classes()
{
return static_derived_class_info;
}
@@ -808,13 +808,13 @@ std::vector<DerivedClassInfo> const& ClassRegistry<T>::derived_classes()
// Static data member declaration.
//
template <class T>
ExtensionClassBase* ClassRegistry<T>::static_class_object;
extension_class_base* class_registry<T>::static_class_object;
template <class T>
std::vector<BaseClassInfo> ClassRegistry<T>::static_base_class_info;
std::vector<BaseClassInfo> class_registry<T>::static_base_class_info;
template <class T>
std::vector<DerivedClassInfo> ClassRegistry<T>::static_derived_class_info;
std::vector<derived_class_info> class_registry<T>::static_derived_class_info;
}} // namespace py::detail
}} // namespace python::detail
#endif // EXTENSION_CLASS_DWA052000_H_
""")

View File

@@ -72,9 +72,9 @@ def gen_function(template, n, *args, **keywords):
... %( PyObject* a%n;
... %) if (!PyArg_ParseTuple(args, const_cast<char*>("O%(O%)"), &self%(, &a%n%)))
... return 0;
... T& target = from_python(self, Type<T&>());
... T& target = from_python(self, type<T&>());
... %3to_python((target.*pmf)(%(
... from_python(a%n, Type<A%n>())%:,%)
... from_python(a%n, type<A%n>())%:,%)
... ));%4
... }'''
@@ -84,7 +84,7 @@ def gen_function(template, n, *args, **keywords):
PyObject* self;
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &self))
return 0;
T& target = from_python(self, Type<T&>());
T& target = from_python(self, type<T&>());
return to_python((target.*pmf)(
));
}
@@ -97,10 +97,10 @@ def gen_function(template, n, *args, **keywords):
PyObject* a2;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOO"), &self, &a1, &a2))
return 0;
T& target = from_python(self, Type<T&>());
T& target = from_python(self, type<T&>());
return to_python((target.*pmf)(
from_python(a1, Type<A1>()),
from_python(a2, Type<A2>())
from_python(a1, type<A1>()),
from_python(a2, type<A2>())
));
}
@@ -113,11 +113,11 @@ def gen_function(template, n, *args, **keywords):
PyObject* a3;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOO"), &self, &a1, &a2, &a3))
return 0;
T& target = from_python(self, Type<T&>());
T& target = from_python(self, type<T&>());
to_python((target.*pmf)(
from_python(a1, Type<A1>()),
from_python(a2, Type<A2>()),
from_python(a3, Type<A3>())
from_python(a1, type<A1>()),
from_python(a2, type<A2>()),
from_python(a3, type<A3>())
));
return none();
}

View File

@@ -12,7 +12,7 @@ def gen_init_function(args):
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file was generated for %d-argument constructors by gen_init_function.py
// This file was generated for %d-argument constructors by gen_init_function.python
#ifndef INIT_FUNCTION_DWA052000_H_
# define INIT_FUNCTION_DWA052000_H_
@@ -22,7 +22,7 @@ def gen_init_function(args):
# include "signatures.h"
# include <typeinfo>
namespace py {
namespace python {
namespace detail {
@@ -106,50 +106,50 @@ namespace detail {
const_reference value;
};
class ExtensionInstance;
class InstanceHolderBase;
class extension_instance;
class instance_holder_base;
class Init;
class init;
"""
+ gen_functions('template <class T%(, class A%n%)> struct Init%x;\n', args)
+ gen_functions('template <class T%(, class A%n%)> struct init%x;\n', args)
+ """
template <class T>
struct InitFunction
struct init_function
{
""" + gen_functions("""%{
template <%(class A%n%:, %)>
%} static Init* create(Signature%x%{<%(A%n%:, %)>%}) {
return new Init%x<T%(,
%} static init* create(signature%x%{<%(A%n%:, %)>%}) {
return new init%x<T%(,
detail::parameter_traits<A%n>::const_reference%)>;
}
""", args)+"""};
class Init : public Function
class init : public function
{
private: // override Function hook
private: // override function hook
PyObject* do_call(PyObject* args, PyObject* keywords) const;
private:
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* tail_args, PyObject* keywords) const = 0;
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
};
""" + gen_functions("""
template <class T%(, class A%n%)>
struct Init%x : Init
struct init%x : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
%(PyObject* a%n;
%)if (!PyArg_ParseTuple(args, const_cast<char*>("%(O%)")%(, &a%n%)))
throw ArgumentError();
throw argument_error();
return new T(self%(,
py::detail::reference_parameter<A%n>(from_python(a%n, Type<A%n>()))%)
python::detail::reference_parameter<A%n>(from_python(a%n, type<A%n>()))%)
);
}
const char* description() const
{ return typeid(void (*)(T&%(, A%n%%))).name(); }
};""", args) + """
}} // namespace py::detail
}} // namespace python::detail
#endif // INIT_FUNCTION_DWA052000_H_
""")

View File

@@ -6,23 +6,23 @@ def gen_struct_signatures(args):
for n in range(args, -1, -1):
result = (
result + gen_function("""%{template <%(class T%n%:, %)>
%}struct Signature%x {};
%}struct signature%x {};
""", n)
# + ((n == args) and [""] or
# [gen_function("""
# template <class X>
# static inline Signature%1<X%(, T%n%)> prepend(Type<X>)
# { return Signature%1<X%(, T%n%)>(); }""",
# static inline signature%1<X%(, T%n%)> prepend(type<X>)
# { return signature%1<X%(, T%n%)>(); }""",
# n, (str(n+1),))
# ]
# )[0]
#
# + ((n != 0) and [""] or
# ["""
# // This one terminates the chain. Prepending Void to the head of a Void
# // signature results in a Void signature again.
# static inline Signature0 prepend(Void) { return Signature0(); }"""]
# // This one terminates the chain. Prepending void_t to the head of a void_t
# // signature results in a void_t signature again.
# static inline signature0 prepend(void_t) { return signature0(); }"""]
# )[0]
# + """
#};
@@ -31,8 +31,8 @@ def gen_struct_signatures(args):
+ ((n == args) and [""] or
[gen_function(
"""template <%(class T%n%, %)class X>
inline Signature%1<X%(, T%n%)> prepend(Type<X>, Signature%x%{<%(T%n%:, %)>%})
{ return Signature%1<X%(, T%n%)>(); }
inline signature%1<X%(, T%n%)> prepend(type<X>, signature%x%{<%(T%n%:, %)>%})
{ return signature%1<X%(, T%n%)>(); }
""", n, str(n+1))
]
@@ -50,62 +50,62 @@ def gen_signatures(args):
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file automatically generated by gen_signatures.py for %d arguments.
// This file automatically generated by gen_signatures.python for %d arguments.
#ifndef SIGNATURES_DWA050900_H_
# define SIGNATURES_DWA050900_H_
# include "pyconfig.h"
namespace py {
namespace python {
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 {};
struct void_t {};
}
// An envelope in which type information can be delivered for the purposes
// of selecting an overloaded from_python() function. This is needed to work
// around MSVC's lack of partial specialiation/ordering. Where normally we'd
// want to form a function call like void f<const T&>(), We instead pass
// Type<const T&> as one of the function parameters to select a particular
// type<const T&> as one of the function parameters to select a particular
// overload.
//
// The Id typedef helps us deal with the lack of partial ordering by generating
// unique types for constructor signatures. In general, Type<T>::Id is Type<T>,
// but Type<Void>::Id is just Void.
// The id typedef helps us deal with the lack of partial ordering by generating
// unique types for constructor signatures. In general, type<T>::id is type<T>,
// but type<void_t>::id is just void_t.
template <class T>
struct Type
struct type
{
typedef Type Id;
typedef type id;
};
template <>
struct Type<py::detail::Void>
struct type<python::detail::void_t>
{
typedef py::detail::Void Id;
typedef python::detail::void_t 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
// 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
// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs
// that involve recursive template nesting.
//
// Signature chaining
// signature chaining
""" % args
+ gen_struct_signatures(args)
+ """
// This one terminates the chain. Prepending Void to the head of a Void
// signature results in a Void signature again.
inline Signature0 prepend(Void, Signature0) { return Signature0(); }
// This one terminates the chain. Prepending void_t to the head of a void_t
// signature results in a void_t signature again.
inline signature0 prepend(void_t, signature0) { return signature0(); }
} // namespace detail
"""
+ gen_function("""
template <%(class A%n% = detail::Void%:, %)>
struct Constructor
template <%(class A%n% = detail::void_t%:, %)>
struct constructor
{
};
""", args)
@@ -113,16 +113,16 @@ struct Constructor
namespace detail {
// Return value extraction:
// This is just another little envelope for carrying a typedef (see Type,
// above). I could have re-used Type, but that has a very specific purpose. I
// This is just another little envelope for carrying a typedef (see type,
// above). I could have re-used type, but that has a very specific purpose. I
// thought this would be clearer.
template <class T>
struct ReturnValue { typedef T Type; };
struct return_value_select { typedef T type; };
// free functions"""
+ gen_functions("""
template <class R%(, class A%n%)>
ReturnValue<R> return_value(R (*)(%(A%n%:, %))) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(%(A%n%:, %))) { return return_value_select<R>(); }
""", args)
+
@@ -132,16 +132,16 @@ ReturnValue<R> return_value(R (*)(%(A%n%:, %))) { return ReturnValue<R>(); }
// member functions"""
+ gen_functions("""
template <class R, class T%(, class A%n%)>
ReturnValue<R> return_value(R (T::*)(%(A%n%:, %))) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(%(A%n%:, %))) { return return_value_select<R>(); }
""", args)
+ gen_functions("""
template <class R, class T%(, class A%n%)>
ReturnValue<R> return_value(R (T::*)(%(A%n%:, %)) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(%(A%n%:, %)) const) { return return_value_select<R>(); }
""", args)
+ """
}} // namespace py::detail
}} // namespace python::detail
#endif
""")

View File

@@ -16,33 +16,33 @@ def gen_singleton(args):
# include "pyconfig.h"
namespace py { namespace detail {
namespace python { namespace detail {
struct Empty {};
template <class Derived, class Base = Empty>
struct Singleton : Base
struct empty {};
template <class Derived, class Base = empty>
struct singleton : Base
{
typedef Singleton SingletonBase; // Convenience type for derived class constructors
typedef singleton singleton_base; // Convenience type for derived class constructors
static Derived* singleton();
static Derived* instance();
// Pass-through constructors
"""
+ gen_functions("""%{
template <%(class A%n%:, %)>
%} Singleton(%(const A%n& a%n%:, %)) : Base(%(a%n%:, %)) {}
%} singleton(%(const A%n& a%n%:, %)) : Base(%(a%n%:, %)) {}
""", args)
+ """
};
template <class Derived, class Base>
Derived* Singleton<Derived,Base>::singleton()
Derived* singleton<Derived,Base>::instance()
{
static Derived x;
return &x;
}
}} // namespace py::detail
}} // namespace python::detail
#endif
""")

View File

@@ -41,7 +41,7 @@
wrapped derived classes may be passed where values, pointers, or
references to a base class are expected as arguments. The
<code>declare_base</code> member function of
<code>ClassWrapper&lt;&gt;</code> is used to establish the relationship
<code>class_builder&lt;&gt;</code> is used to establish the relationship
between base and derived classes:
<blockquote>
@@ -80,13 +80,13 @@ void initmy_module()
{
    try
    {
       py::Module my_module("my_module");
       python::module_builder my_module("my_module");
       py::ClassWrapper&lt;Base&gt; base_class(my_module, "Base");
       base_class.def(py::Constructor&lt;void&gt;());
       python::class_builder&lt;Base&gt; base_class(my_module, "Base");
       base_class.def(python::constructor&lt;void&gt;());
       py::ClassWrapper&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(py::Constructor&lt;void&gt;());
       python::class_builder&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(python::constructor&lt;void&gt;());
<b>// Establish the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);</b>
@@ -96,7 +96,7 @@ void initmy_module()
    }
    catch(...)
    {
       py::handle_exception();    // Deal with the exception for Python
       python::handle_exception();    // Deal with the exception for Python
    }
}
</pre>
@@ -126,7 +126,7 @@ expected but where type information has been lost.</i><pre>
<p>
If for some reason your base class has no virtual functions but you still want
to represent the inheritance relationship between base and derived classes,
pass the special symbol <code>py::without_downcast</code> as the 2nd parameter
pass the special symbol <code>python::without_downcast</code> as the 2nd parameter
to <code>declare_base</code>:
<blockquote>
@@ -135,12 +135,12 @@ struct Base2 {};
struct Derived2 { int f(); };
<hr>
...
   py::ClassWrapper&lt;Base&gt; base2_class(my_module, "Base2");
   base2_class.def(py::Constructor&lt;void&gt;());
   python::class_builder&lt;Base&gt; base2_class(my_module, "Base2");
   base2_class.def(python::constructor&lt;void&gt;());
   py::ClassWrapper&lt;Derived2&gt; derived2_class(my_module, "Derived2");
   derived2_class.def(py::Constructor&lt;void&gt;());
derived_class.declare_base(base_class, <b>py::without_downcast</b>);
   python::class_builder&lt;Derived2&gt; derived2_class(my_module, "Derived2");
   derived2_class.def(python::constructor&lt;void&gt;());
derived_class.declare_base(base_class, <b>python::without_downcast</b>);
</pre>
</blockquote>

View File

@@ -11,26 +11,26 @@
#include "extclass.h"
#include <utility>
namespace py { namespace detail {
namespace python { namespace detail {
PyObject* Init::do_call(PyObject* args_, PyObject* keywords) const
PyObject* init::do_call(PyObject* args_, PyObject* keywords) const
{
Tuple args(Ptr(args_, Ptr::borrowed));
tuple args(ref(args_, ref::increment_count));
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());
extension_instance *self = static_cast<extension_instance*>(args[0].get());
Tuple ctor_args = args.slice(1, args.size());
tuple ctor_args = args.slice(1, args.size());
std::auto_ptr<InstanceHolderBase> result(
std::auto_ptr<instance_holder_base> result(
create_holder(self, ctor_args.get(), keywords));
self->add_implementation(result);
return none();
}
}} // namespace py::detail
}} // namespace python::detail

View File

@@ -6,7 +6,7 @@
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file was generated for %d-argument constructors by gen_init_function.py
// This file was generated for %d-argument constructors by gen_init_function.python
#ifndef INIT_FUNCTION_DWA052000_H_
# define INIT_FUNCTION_DWA052000_H_
@@ -16,7 +16,7 @@
# include "signatures.h"
# include <typeinfo>
namespace py {
namespace python {
namespace detail {
@@ -100,16 +100,16 @@ namespace detail {
const_reference value;
};
class ExtensionInstance;
class InstanceHolderBase;
class extension_instance;
class instance_holder_base;
class Init;
template <class T> struct Init0;
template <class T, class A1> struct Init1;
template <class T, class A1, class A2> struct Init2;
template <class T, class A1, class A2, class A3> struct Init3;
template <class T, class A1, class A2, class A3, class A4> struct Init4;
template <class T, class A1, class A2, class A3, class A4, class A5> struct Init5;
class init;
template <class T> struct init0;
template <class T, class A1> struct init1;
template <class T, class A1, class A2> struct init2;
template <class T, class A1, class A2, class A3> struct init3;
template <class T, class A1, class A2, class A3, class A4> struct init4;
template <class T, class A1, class A2, class A3, class A4, class A5> struct init5;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6> struct Init6;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct Init7;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> struct Init8;
@@ -117,36 +117,36 @@ template <class T, class A1, class A2, class A3, class A4, class A5, class A6, c
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> struct Init10;
template <class T>
struct InitFunction
struct init_function
{
static Init* create(Signature0) {
return new Init0<T>;
static init* create(signature0) {
return new init0<T>;
}
template <class A1>
static Init* create(Signature1<A1>) {
return new Init1<T,
static init* create(signature1<A1>) {
return new init1<T,
detail::parameter_traits<A1>::const_reference>;
}
template <class A1, class A2>
static Init* create(Signature2<A1, A2>) {
return new Init2<T,
static init* create(signature2<A1, A2>) {
return new init2<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference>;
}
template <class A1, class A2, class A3>
static Init* create(Signature3<A1, A2, A3>) {
return new Init3<T,
static init* create(signature3<A1, A2, A3>) {
return new init3<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference>;
}
template <class A1, class A2, class A3, class A4>
static Init* create(Signature4<A1, A2, A3, A4>) {
return new Init4<T,
static init* create(signature4<A1, A2, A3, A4>) {
return new init4<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -154,8 +154,8 @@ struct InitFunction
}
template <class A1, class A2, class A3, class A4, class A5>
static Init* create(Signature5<A1, A2, A3, A4, A5>) {
return new Init5<T,
static init* create(signature5<A1, A2, A3, A4, A5>) {
return new init5<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -164,7 +164,7 @@ struct InitFunction
}
template <class A1, class A2, class A3, class A4, class A5, class A6>
static Init* create(Signature6<A1, A2, A3, A4, A5, A6>) {
static init* create(Signature6<A1, A2, A3, A4, A5, A6>) {
return new Init6<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
@@ -175,7 +175,7 @@ struct InitFunction
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Init* create(Signature7<A1, A2, A3, A4, A5, A6, A7>) {
static init* create(Signature7<A1, A2, A3, A4, A5, A6, A7>) {
return new Init7<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
@@ -187,7 +187,7 @@ struct InitFunction
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Init* create(Signature8<A1, A2, A3, A4, A5, A6, A7, A8>) {
static init* create(Signature8<A1, A2, A3, A4, A5, A6, A7, A8>) {
return new Init8<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
@@ -200,7 +200,7 @@ struct InitFunction
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
static Init* create(Signature9<A1, A2, A3, A4, A5, A6, A7, A8, A9>) {
static init* create(Signature9<A1, A2, A3, A4, A5, A6, A7, A8, A9>) {
return new Init9<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
@@ -214,7 +214,7 @@ struct InitFunction
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
static Init* create(Signature10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>) {
static init* create(Signature10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>) {
return new Init10<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
@@ -229,22 +229,22 @@ struct InitFunction
}
};
class Init : public Function
class init : public function
{
private: // override Function hook
private: // override function hook
PyObject* do_call(PyObject* args, PyObject* keywords) const;
private:
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* tail_args, PyObject* keywords) const = 0;
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
};
template <class T>
struct Init0 : Init
struct init0 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
if (!PyArg_ParseTuple(args, const_cast<char*>("")))
throw ArgumentError();
throw argument_error();
return new T(self
);
}
@@ -253,15 +253,15 @@ struct Init0 : Init
};
template <class T, class A1>
struct Init1 : Init
struct init1 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &a1))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>()))
);
}
const char* description() const
@@ -269,17 +269,17 @@ struct Init1 : Init
};
template <class T, class A1, class A2>
struct Init2 : Init
struct init2 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>()))
);
}
const char* description() const
@@ -287,19 +287,19 @@ struct Init2 : Init
};
template <class T, class A1, class A2, class A3>
struct Init3 : Init
struct init3 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOO"), &a1, &a2, &a3))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>()))
);
}
const char* description() const
@@ -307,21 +307,21 @@ struct Init3 : Init
};
template <class T, class A1, class A2, class A3, class A4>
struct Init4 : Init
struct init4 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
PyObject* a4;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOO"), &a1, &a2, &a3, &a4))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>()))
);
}
const char* description() const
@@ -329,9 +329,9 @@ struct Init4 : Init
};
template <class T, class A1, class A2, class A3, class A4, class A5>
struct Init5 : Init
struct init5 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
@@ -339,13 +339,13 @@ struct Init5 : Init
PyObject* a4;
PyObject* a5;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOO"), &a1, &a2, &a3, &a4, &a5))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>()))
);
}
const char* description() const
@@ -353,9 +353,9 @@ struct Init5 : Init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6>
struct Init6 : Init
struct Init6 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
@@ -364,14 +364,14 @@ struct Init6 : Init
PyObject* a5;
PyObject* a6;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>())),
py::detail::reference_parameter<A6>(from_python(a6, Type<A6>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>()))
);
}
const char* description() const
@@ -379,9 +379,9 @@ struct Init6 : Init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct Init7 : Init
struct Init7 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
@@ -391,15 +391,15 @@ struct Init7 : Init
PyObject* a6;
PyObject* a7;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>())),
py::detail::reference_parameter<A6>(from_python(a6, Type<A6>())),
py::detail::reference_parameter<A7>(from_python(a7, Type<A7>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>()))
);
}
const char* description() const
@@ -407,9 +407,9 @@ struct Init7 : Init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct Init8 : Init
struct Init8 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
@@ -420,16 +420,16 @@ struct Init8 : Init
PyObject* a7;
PyObject* a8;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>())),
py::detail::reference_parameter<A6>(from_python(a6, Type<A6>())),
py::detail::reference_parameter<A7>(from_python(a7, Type<A7>())),
py::detail::reference_parameter<A8>(from_python(a8, Type<A8>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
python::detail::reference_parameter<A8>(from_python(a8, type<A8>()))
);
}
const char* description() const
@@ -437,9 +437,9 @@ struct Init8 : Init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct Init9 : Init
struct Init9 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
@@ -451,17 +451,17 @@ struct Init9 : Init
PyObject* a8;
PyObject* a9;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>())),
py::detail::reference_parameter<A6>(from_python(a6, Type<A6>())),
py::detail::reference_parameter<A7>(from_python(a7, Type<A7>())),
py::detail::reference_parameter<A8>(from_python(a8, Type<A8>())),
py::detail::reference_parameter<A9>(from_python(a9, Type<A9>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
python::detail::reference_parameter<A8>(from_python(a8, type<A8>())),
python::detail::reference_parameter<A9>(from_python(a9, type<A9>()))
);
}
const char* description() const
@@ -469,9 +469,9 @@ struct Init9 : Init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
struct Init10 : Init
struct Init10 : init
{
virtual InstanceHolderBase* create_holder(ExtensionInstance* self, PyObject* args, PyObject* /*keywords*/) const
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
@@ -484,24 +484,24 @@ struct Init10 : Init
PyObject* a9;
PyObject* a10;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10))
throw ArgumentError();
throw argument_error();
return new T(self,
py::detail::reference_parameter<A1>(from_python(a1, Type<A1>())),
py::detail::reference_parameter<A2>(from_python(a2, Type<A2>())),
py::detail::reference_parameter<A3>(from_python(a3, Type<A3>())),
py::detail::reference_parameter<A4>(from_python(a4, Type<A4>())),
py::detail::reference_parameter<A5>(from_python(a5, Type<A5>())),
py::detail::reference_parameter<A6>(from_python(a6, Type<A6>())),
py::detail::reference_parameter<A7>(from_python(a7, Type<A7>())),
py::detail::reference_parameter<A8>(from_python(a8, Type<A8>())),
py::detail::reference_parameter<A9>(from_python(a9, Type<A9>())),
py::detail::reference_parameter<A10>(from_python(a10, Type<A10>()))
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
python::detail::reference_parameter<A8>(from_python(a8, type<A8>())),
python::detail::reference_parameter<A9>(from_python(a9, type<A9>())),
python::detail::reference_parameter<A10>(from_python(a10, type<A10>()))
);
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)).name(); }
};
}} // namespace py::detail
}} // namespace python::detail
#endif // INIT_FUNCTION_DWA052000_H_

View File

@@ -8,45 +8,45 @@
#include "module.h"
namespace py {
namespace python {
namespace {
Ptr name_holder;
ref name_holder;
}
String Module::name()
string module_builder::name()
{
// If this fails, you haven't created a Module object
// If this fails, you haven't created a module_builder object
assert(name_holder.get() != 0);
return String(name_holder);
return string(name_holder);
}
Module::Module(const char* name)
module_builder::module_builder(const char* name)
: m_module(Py_InitModule(const_cast<char*>(name), initial_methods))
{
// If this fails, you've created more than 1 Module object in your module
// If this fails, you've created more than 1 module_builder object in your module
assert(name_holder.get() == 0);
name_holder = Ptr(PyObject_GetAttrString(m_module, const_cast<char*>("__name__")));
name_holder = ref(PyObject_GetAttrString(m_module, const_cast<char*>("__name__")));
}
void
Module::add(detail::Function* x, const char* name)
module_builder::add(detail::function* x, const char* name)
{
PyPtr<detail::Function> f(x); // First take possession of the object.
detail::Function::add_to_namespace(f, name, PyModule_GetDict(m_module));
reference<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)
void module_builder::add(ref x, const char* name)
{
PyObject* dictionary = PyModule_GetDict(m_module);
PyDict_SetItemString(dictionary, const_cast<char*>(name), x.get());
}
void Module::add(PyTypeObject* x, const char* name /*= 0*/)
void module_builder::add(PyTypeObject* x, const char* name /*= 0*/)
{
this->add(Ptr(as_object(x)), name ? name : x->tp_name);
this->add(ref(as_object(x)), name ? name : x->tp_name);
}
PyMethodDef Module::initial_methods[] = { { 0, 0, 0, 0 } };
PyMethodDef module_builder::initial_methods[] = { { 0, 0, 0, 0 } };
}

View File

@@ -14,20 +14,20 @@
# include "objects.h"
# include "functions.h"
namespace py {
namespace python {
class Module
class module_builder
{
typedef PyObject * (*RawFunctionPtr)(py::Tuple const &, py::Dict const &);
typedef PyObject * (*raw_function_ptr)(python::tuple const &, python::dictionary const &);
public:
// Create a module. REQUIRES: only one Module is created per module.
Module(const char* name);
// Create a module. REQUIRES: only one module_builder is created per module.
module_builder(const char* name);
// Add elements to the module
void add(detail::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);
void add(ref x, const char*name);
template <class Fn>
void def_raw(Fn fn, const char* name)
@@ -41,7 +41,7 @@ class Module
add(detail::new_wrapped_function(fn), name);
}
static String name();
static string name();
private:
PyObject* m_module;

File diff suppressed because it is too large Load Diff

View File

@@ -11,40 +11,40 @@
// Usage:
// class X : public
// py::Callable<
// py::Getattrable <
// py::Setattrable<PythonObject, X> > >
// python::callable<
// python::getattrable <
// python::setattrable<python_object, X> > >
// {
// public:
// Ptr call(args, kw);
// Ptr getattr(args, kw);
// Ptr setattr(args, kw);
// ref call(args, kw);
// ref getattr(args, kw);
// ref setattr(args, kw);
// };
# include "pyconfig.h"
# include "signatures.h" // really just for Type<>
# include "signatures.h" // really just for type<>
# include "cast.h"
# include "base_object.h"
# include <typeinfo>
# include <vector>
# include <cassert>
namespace py {
namespace python {
class String;
class string;
namespace detail {
class InstanceHolderBase;
class instance_holder_base;
class TypeObjectBase : public PythonType
class type_object_base : public python_type
{
public:
explicit TypeObjectBase(PyTypeObject* type_type);
virtual ~TypeObjectBase();
explicit type_object_base(PyTypeObject* type_type);
virtual ~type_object_base();
public:
enum Capability {
enum capability {
hash, call, str, getattr, setattr, compare, repr,
mapping_length, mapping_subscript, mapping_ass_subscript,
@@ -60,19 +60,19 @@ class TypeObjectBase : public PythonType
number_hex
};
void enable(Capability);
void enable(capability);
//
// Type behaviors
// type behaviors
//
public: // Callbacks for basic type functionality.
virtual PyObject* instance_repr(PyObject*) const;
virtual int instance_compare(PyObject*, PyObject* other) const;
virtual PyObject* instance_str(PyObject*) const;
virtual long instance_hash(PyObject*) const;
virtual PyObject* instance_call(PyObject* instance, PyObject* args, PyObject* kw) const;
virtual PyObject* instance_getattr(PyObject* instance, const char* name) const;
virtual int instance_setattr(PyObject* instance, const char* name, PyObject* value) const;
virtual PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const;
virtual PyObject* instance_getattr(PyObject* obj, const char* name) const;
virtual int instance_setattr(PyObject* obj, const char* name, PyObject* value) const;
// Dealloc is a special case, since every type needs a nonzero tp_dealloc slot.
virtual void instance_dealloc(PyObject*) const = 0;
@@ -83,13 +83,13 @@ class TypeObjectBase : public PythonType
virtual int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const;
public: // Callbacks for sequence methods
virtual int instance_sequence_length(PyObject* instance) const;
virtual PyObject* instance_sequence_concat(PyObject* instance, PyObject* other) const;
virtual PyObject* instance_sequence_repeat(PyObject* instance, int n) const;
virtual PyObject* instance_sequence_item(PyObject* instance, int n) const;
virtual PyObject* instance_sequence_slice(PyObject* instance, int start, int finish) const;
virtual int instance_sequence_ass_item(PyObject* instance, int n, PyObject* value) const;
virtual int instance_sequence_ass_slice(PyObject* instance, int start, int finish, PyObject* value) const;
virtual int instance_sequence_length(PyObject* obj) const;
virtual PyObject* instance_sequence_concat(PyObject* obj, PyObject* other) const;
virtual PyObject* instance_sequence_repeat(PyObject* obj, int n) const;
virtual PyObject* instance_sequence_item(PyObject* obj, int n) const;
virtual PyObject* instance_sequence_slice(PyObject* obj, int start, int finish) const;
virtual int instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const;
virtual int instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const;
public: // Callbacks for number methods
virtual PyObject* instance_number_add(PyObject*, PyObject*) const;
@@ -118,22 +118,22 @@ class TypeObjectBase : public PythonType
};
template <class T>
class TypeObject : public TypeObjectBase
class type_object : public type_object_base
{
public:
typedef T Instance;
typedef T instance;
TypeObject(PyTypeObject* type_type, const char* name)
: TypeObjectBase(type_type)
type_object(PyTypeObject* type_type, const char* name)
: type_object_base(type_type)
{
assert(name != 0);
this->tp_name = const_cast<char*>(name);
}
TypeObject(PyTypeObject* type_type)
: TypeObjectBase(type_type)
type_object(PyTypeObject* type_type)
: type_object_base(type_type)
{
this->tp_name = const_cast<char*>(typeid(Instance).name());
this->tp_name = const_cast<char*>(typeid(instance).name());
}
private: // Overridable behaviors.
@@ -142,193 +142,193 @@ class TypeObject : public TypeObjectBase
// you have other constraints, you'll need to override this
virtual void dealloc(T* p) const;
private: // Implementation of TypeObjectBase hooks. Do not reimplement in derived classes.
private: // Implementation of type_object_base hooks. Do not reimplement in derived classes.
void instance_dealloc(PyObject*) const;
};
//
// Type objects
// type objects
//
template <class Base>
class Callable : public Base
class callable : public Base
{
public:
typedef Callable Properties; // Convenience for derived class construction
typedef typename Base::Instance Instance;
Callable(PyTypeObject* type_type, const char* name);
Callable(PyTypeObject* type_type);
typedef callable properties; // Convenience for derived class construction
typedef typename Base::instance instance;
callable(PyTypeObject* type_type, const char* name);
callable(PyTypeObject* type_type);
private:
PyObject* instance_call(PyObject* instance, PyObject* args, PyObject* kw) const;
PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const;
};
template <class Base>
class Getattrable : public Base
class getattrable : public Base
{
public:
typedef Getattrable Properties; // Convenience for derived class construction
typedef typename Base::Instance Instance;
Getattrable(PyTypeObject* type_type, const char* name);
Getattrable(PyTypeObject* type_type);
typedef getattrable properties; // Convenience for derived class construction
typedef typename Base::instance instance;
getattrable(PyTypeObject* type_type, const char* name);
getattrable(PyTypeObject* type_type);
private:
PyObject* instance_getattr(PyObject* instance, const char* name) const;
PyObject* instance_getattr(PyObject* obj, const char* name) const;
};
template <class Base>
class Setattrable : public Base
class setattrable : public Base
{
public:
typedef Setattrable Properties; // Convenience for derived class construction
typedef typename Base::Instance Instance;
Setattrable(PyTypeObject* type_type, const char* name);
Setattrable(PyTypeObject* type_type);
typedef setattrable properties; // Convenience for derived class construction
typedef typename Base::instance instance;
setattrable(PyTypeObject* type_type, const char* name);
setattrable(PyTypeObject* type_type);
private:
int instance_setattr(PyObject* instance, const char* name, PyObject* value) const;
int instance_setattr(PyObject* obj, const char* name, PyObject* value) const;
};
template <class Base>
class Reprable : public Base
class reprable : public Base
{
public:
typedef Reprable Properties; // Convenience for derived class construction
typedef typename Base::Instance Instance;
Reprable(PyTypeObject* type_type, const char* name);
Reprable(PyTypeObject* type_type);
typedef reprable properties; // Convenience for derived class construction
typedef typename Base::instance instance;
reprable(PyTypeObject* type_type, const char* name);
reprable(PyTypeObject* type_type);
private:
PyObject* instance_repr(PyObject* instance) const;
PyObject* instance_repr(PyObject* obj) const;
};
//
// Member function definitions
//
// TypeObject<>
// type_object<>
template <class T>
void TypeObject<T>::instance_dealloc(PyObject* instance) const
void type_object<T>::instance_dealloc(PyObject* obj) const
{
this->dealloc(Downcast<Instance>(instance).get());
this->dealloc(downcast<instance>(obj).get());
}
template <class T>
void TypeObject<T>::dealloc(T* instance) const
void type_object<T>::dealloc(T* obj) const
{
delete instance;
delete obj;
}
// Callable
// callable
template <class Base>
Callable<Base>::Callable(PyTypeObject* type_type, const char* name)
callable<Base>::callable(PyTypeObject* type_type, const char* name)
: Base(type_type, name)
{
this->enable(call);
}
template <class Base>
Callable<Base>::Callable(PyTypeObject* type_type)
callable<Base>::callable(PyTypeObject* type_type)
: Base(type_type)
{
this->enable(call);
}
template <class Base>
PyObject* Callable<Base>::instance_call(PyObject* instance, PyObject* args, PyObject* kw) const
PyObject* callable<Base>::instance_call(PyObject* obj, PyObject* args, PyObject* kw) const
{
return Downcast<Instance>(instance)->call(args, kw);
return downcast<instance>(obj)->call(args, kw);
}
// Getattrable
// getattrable
template <class Base>
Getattrable<Base>::Getattrable(PyTypeObject* type_type, const char* name)
getattrable<Base>::getattrable(PyTypeObject* type_type, const char* name)
: Base(type_type, name)
{
this->enable(getattr);
}
template <class Base>
Getattrable<Base>::Getattrable(PyTypeObject* type_type)
getattrable<Base>::getattrable(PyTypeObject* type_type)
: Base(type_type)
{
this->enable(getattr);
}
template <class Base>
PyObject* Getattrable<Base>::instance_getattr(PyObject* instance, const char* name) const
PyObject* getattrable<Base>::instance_getattr(PyObject* obj, const char* name) const
{
return Downcast<Instance>(instance)->getattr(name);
return downcast<instance>(obj)->getattr(name);
}
// Setattrable
// setattrable
template <class Base>
Setattrable<Base>::Setattrable(PyTypeObject* type_type, const char* name)
setattrable<Base>::setattrable(PyTypeObject* type_type, const char* name)
: Base(type_type, name)
{
this->enable(setattr);
}
template <class Base>
Setattrable<Base>::Setattrable(PyTypeObject* type_type)
setattrable<Base>::setattrable(PyTypeObject* type_type)
: Base(type_type)
{
this->enable(setattr);
}
template <class Base>
int Setattrable<Base>::instance_setattr(PyObject* instance, const char* name, PyObject* value) const
int setattrable<Base>::instance_setattr(PyObject* obj, const char* name, PyObject* value) const
{
return Downcast<Instance>(instance)->setattr(name, value);
return downcast<instance>(obj)->setattr(name, value);
}
// Reprable
// reprable
template <class Base>
Reprable<Base>::Reprable(PyTypeObject* type_type, const char* name)
reprable<Base>::reprable(PyTypeObject* type_type, const char* name)
: Base(type_type, name)
{
this->enable(repr);
}
template <class Base>
Reprable<Base>::Reprable(PyTypeObject* type_type)
reprable<Base>::reprable(PyTypeObject* type_type)
: Base(type_type)
{
this->enable(repr);
}
template <class Base>
PyObject* Reprable<Base>::instance_repr(PyObject* instance) const
PyObject* reprable<Base>::instance_repr(PyObject* obj) const
{
return Downcast<Instance>(instance)->repr();
return downcast<instance>(obj)->repr();
}
class shared_pod_manager
{
typedef std::pair<char*, std::size_t> Holder;
typedef std::vector<Holder> Storage;
typedef std::pair<char*, std::size_t> holder;
typedef std::vector<holder> storage;
public:
static shared_pod_manager& instance();
static shared_pod_manager& obj();
~shared_pod_manager();
template <class T>
static void replace_if_equal(T*& t)
{
t = reinterpret_cast<T*>(instance().replace_if_equal(t, sizeof(T)));
t = reinterpret_cast<T*>(obj().replace_if_equal(t, sizeof(T)));
}
template <class T>
static void make_unique_copy(T*& t)
{
t = reinterpret_cast<T*>(instance().make_unique_copy(t, sizeof(T)));
t = reinterpret_cast<T*>(obj().make_unique_copy(t, sizeof(T)));
}
template <class T>
static void create(T*& t)
{
t = reinterpret_cast<T*>(instance().create(sizeof(T)));
t = reinterpret_cast<T*>(obj().create(sizeof(T)));
}
template <class T>
static void dispose(T* t)
{
instance().dec_ref(t, sizeof(T));
obj().dec_ref(t, sizeof(T));
}
private:
@@ -338,26 +338,26 @@ PyObject* Reprable<Base>::instance_repr(PyObject* instance) const
void dec_ref(void* pod, std::size_t size);
void erase_from_list(void* pod);
struct Compare;
struct compare;
struct identical;
private:
shared_pod_manager() {} // singleton
shared_pod_manager() {} // instance
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
public:
#endif
Storage m_storage;
storage m_storage;
};
void add_capability(TypeObjectBase::Capability capability,
void add_capability(type_object_base::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)
(sizeof(::python::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0)
template<typename T>
inline void countof_validate(T* const, T* const*);
@@ -365,6 +365,6 @@ PyObject* Reprable<Base>::instance_repr(PyObject* instance) const
template<typename T>
inline int countof_validate(const void*, T);
}} // namespace py::detail
}} // namespace python::detail
#endif // TYPES_DWA051800_H_

4
none.h
View File

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

View File

@@ -11,141 +11,141 @@
#include "objects.h"
#include "none.h"
namespace py {
namespace python {
template <class T>
T object_from_python(PyObject* p, Type<T>)
T object_from_python(PyObject* p, type<T>)
{
Ptr x(p, Ptr::new_ref);
ref x(p, ref::increment_count);
if (!T::accepts(x))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw ErrorAlreadySet();
throw error_already_set();
}
return T(x);
}
inline PyObject* object_to_python(const Object& x)
inline PyObject* object_to_python(const object& x)
{
return x.reference().release();
}
Object::Object(Ptr p)
object::object(ref p)
: m_p(p) {}
// Return a reference to the held object
Ptr Object::reference() const
ref object::reference() const
{
return m_p;
}
// Return a raw pointer to the held object
PyObject* Object::get() const
PyObject* object::get() const
{
return m_p.get();
}
} // namespace py
} // namespace python
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
PyObject* to_python(const py::Tuple& x)
PyObject* to_python(const python::tuple& x)
{
return object_to_python(x);
}
py::Tuple from_python(PyObject* p, py::Type<py::Tuple> type)
python::tuple from_python(PyObject* p, python::type<python::tuple> type)
{
return py::object_from_python(p, type);
return python::object_from_python(p, type);
}
PyObject* to_python(const py::List& x)
PyObject* to_python(const python::list& x)
{
return object_to_python(x);
}
py::List from_python(PyObject* p, py::Type<py::List> type)
python::list from_python(PyObject* p, python::type<python::list> type)
{
return py::object_from_python(p, type);
return python::object_from_python(p, type);
}
PyObject* to_python(const py::Dict& x)
PyObject* to_python(const python::dictionary& x)
{
return object_to_python(x);
}
py::Dict from_python(PyObject* p, py::Type<py::Dict> type)
python::dictionary from_python(PyObject* p, python::type<python::dictionary> type)
{
return py::object_from_python(p, type);
return python::object_from_python(p, type);
}
PyObject* to_python(const py::String& x)
PyObject* to_python(const python::string& x)
{
return object_to_python(x);
}
py::String from_python(PyObject* p, py::Type<py::String> type)
python::string from_python(PyObject* p, python::type<python::string> type)
{
return py::object_from_python(p, type);
return python::object_from_python(p, type);
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace py {
namespace python {
Tuple::Tuple(std::size_t n)
: Object(Ptr(PyTuple_New(n)))
tuple::tuple(std::size_t n)
: object(ref(PyTuple_New(n)))
{
for (std::size_t i = 0; i < n; ++i)
PyTuple_SET_ITEM(get(), i, detail::none());
}
Tuple::Tuple(Ptr p)
: Object(p)
tuple::tuple(ref p)
: object(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw ErrorAlreadySet();
throw error_already_set();
}
}
PyTypeObject* Tuple::type_object()
PyTypeObject* tuple::type_obj()
{
return &PyTuple_Type;
}
bool Tuple::accepts(Ptr p)
bool tuple::accepts(ref p)
{
return PyTuple_Check(p.get());
}
std::size_t Tuple::size() const
std::size_t tuple::size() const
{
return PyTuple_Size(get());
}
Ptr Tuple::operator[](std::size_t pos) const
ref tuple::operator[](std::size_t pos) const
{
return Ptr(PyTuple_GetItem(get(), static_cast<int>(pos)),
Ptr::new_ref);
return ref(PyTuple_GetItem(get(), static_cast<int>(pos)),
ref::increment_count);
}
void Tuple::set_item(std::size_t pos, const Ptr& rhs)
void tuple::set_item(std::size_t pos, const ref& rhs)
{
int failed = PyTuple_SetItem(
get(), static_cast<int>(pos), Ptr(rhs).release()); // A reference is stolen here.
get(), static_cast<int>(pos), ref(rhs).release()); // A reference is stolen here.
(void)failed;
assert(failed == 0);
}
Tuple Tuple::slice(int low, int high) const
tuple tuple::slice(int low, int high) const
{
return Tuple(Ptr(PyTuple_GetSlice(get(), low, high)));
return tuple(ref(PyTuple_GetSlice(get(), low, high)));
}
Tuple& Tuple::operator+=(const Tuple& rhs)
tuple& tuple::operator+=(const tuple& rhs)
{
return *this = *this + rhs;
}
@@ -153,44 +153,44 @@ Tuple& Tuple::operator+=(const Tuple& rhs)
// Construct from an owned PyObject*.
// Precondition: p must point to a python string.
String::String(Ptr p)
: Object(p)
string::string(ref p)
: object(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw ErrorAlreadySet();
throw error_already_set();
}
}
String::String(const char* s)
: Object(Ptr(PyString_FromString(s))) {}
string::string(const char* s)
: object(ref(PyString_FromString(s))) {}
String::String(const char* s, std::size_t length)
: Object(Ptr(PyString_FromStringAndSize(s, length))) {}
string::string(const char* s, std::size_t length)
: object(ref(PyString_FromStringAndSize(s, length))) {}
String::String(const char* s, Interned)
: Object(Ptr(PyString_InternFromString(s))) {}
string::string(const char* s, interned_t)
: object(ref(PyString_InternFromString(s))) {}
#if 0
String::String(const char* s, std::size_t length, Interned)
: Object(Ptr(PyString_InternFromStringAndSize(s, length))) {}
string::string(const char* s, std::size_t length, interned_t)
: object(ref(PyString_InternFromStringAndSize(s, length))) {}
#endif
String::String(const String& rhs)
: Object(rhs.reference()) {}
string::string(const string& rhs)
: object(rhs.reference()) {}
// Get the type object for Strings
PyTypeObject* String::type_object()
PyTypeObject* string::type_obj()
{ return &PyString_Type; }
// Return true if the given object is a python String
bool String::accepts(Ptr o)
// Return true if the given object is a python string
bool string::accepts(ref o)
{ return PyString_Check(o.get()); }
// Return the length of the string.
std::size_t String::size() const
std::size_t string::size() const
{
int size = PyString_GET_SIZE(get());
assert(size >= 0);
@@ -200,134 +200,134 @@ std::size_t String::size() const
// Returns a null-terminated representation of the contents of string.
// The pointer refers to the internal buffer of string, not a copy.
// The data must not be modified in any way. It must not be de-allocated.
const char* String::c_str() const
const char* string::c_str() const
{ return PyString_AS_STRING(get()); }
void String::intern()
void string::intern()
{ // UNTESTED!!
*this = String(Ptr(PyString_InternFromString(c_str()), Ptr::borrowed));
*this = string(ref(PyString_InternFromString(c_str()), ref::increment_count));
}
String& String::operator*=(unsigned int repeat_count)
string& string::operator*=(unsigned int repeat_count)
{
*this = String(Ptr(PySequence_Repeat(get(), repeat_count)));
*this = string(ref(PySequence_Repeat(get(), repeat_count)));
return *this;
}
Dict::Dict(Ptr p)
: Object(p)
dictionary::dictionary(ref p)
: object(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw ErrorAlreadySet();
throw error_already_set();
}
}
Dict::Dict()
: Object(Ptr(PyDict_New())) {}
dictionary::dictionary()
: object(ref(PyDict_New())) {}
PyTypeObject* Dict::type_object()
PyTypeObject* dictionary::type_obj()
{ return &PyDict_Type; }
bool Dict::accepts(Ptr p)
bool dictionary::accepts(ref p)
{ return PyDict_Check(p.get()); }
void Dict::clear()
void dictionary::clear()
{ PyDict_Clear(get()); }
const Ptr& Dict::Proxy::operator=(const Ptr& rhs)
const ref& dictionary::proxy::operator=(const ref& rhs)
{
if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
return rhs;
}
Dict::Proxy::operator Ptr() const
dictionary::proxy::operator ref() const
{
return Ptr(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()),
Ptr::borrowed);
return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()),
ref::increment_count);
}
Dict::Proxy::Proxy(const Ptr& dict, const Ptr& key)
dictionary::proxy::proxy(const ref& dict, const ref& key)
: m_dict(dict), m_key(key) {}
Dict::Proxy Dict::operator[](Ptr key)
{ return Proxy(reference(), key); }
dictionary::proxy dictionary::operator[](ref key)
{ return proxy(reference(), key); }
Ptr Dict::operator[](Ptr key) const {
ref dictionary::operator[](ref key) const {
// An odd MSVC bug causes the ".operator Ptr()" to be needed
return Proxy(reference(), key).operator Ptr();
return proxy(reference(), key).operator ref();
}
Ptr Dict::get_item(const Ptr& key) const
ref dictionary::get_item(const ref& key) const
{
return get_item(key, Ptr());
return get_item(key, ref());
}
Ptr Dict::get_item(const Ptr& key, const Ptr& default_) const
ref dictionary::get_item(const ref& key, const ref& default_) const
{
PyObject* value_or_null = PyDict_GetItem(get(), key.get());
if (value_or_null == 0 && !PyErr_Occurred())
return default_;
else
return Ptr(value_or_null, Ptr::borrowed); // Will throw if there was another error
return ref(value_or_null, ref::increment_count); // Will throw if there was another error
}
void Dict::set_item(const Ptr& key, const Ptr& value)
void dictionary::set_item(const ref& key, const ref& value)
{
if (PyDict_SetItem(get(), key.get(), value.get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
}
void Dict::erase(Ptr key) {
void dictionary::erase(ref key) {
if (PyDict_DelItem(get(), key.get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
}
List Dict::items() const { return List(Ptr(PyDict_Items(get()))); }
List Dict::keys() const { return List(Ptr(PyDict_Keys(get()))); }
List Dict::values() const { return List(Ptr(PyDict_Values(get()))); }
list dictionary::items() const { return list(ref(PyDict_Items(get()))); }
list dictionary::keys() const { return list(ref(PyDict_Keys(get()))); }
list dictionary::values() const { return list(ref(PyDict_Values(get()))); }
std::size_t Dict::size() const { return static_cast<std::size_t>(PyDict_Size(get())); }
std::size_t dictionary::size() const { return static_cast<std::size_t>(PyDict_Size(get())); }
String operator+(String x, String y)
string operator+(string x, string y)
{
PyObject* io_string = x.reference().release();
PyString_Concat(&io_string, y.get());
return String(Ptr(io_string));
return string(ref(io_string));
}
String& String::operator+=(const String& rhs)
string& string::operator+=(const string& rhs)
{
return *this = *this + rhs;
}
String& String::operator+=(const char* y)
string& string::operator+=(const char* y)
{
return *this += String(y);
return *this += string(y);
}
String operator%(const String& format, const Tuple& args)
string operator%(const string& format, const tuple& args)
{
return String(Ptr(PyString_Format(format.get(), args.reference().get())));
return string(ref(PyString_Format(format.get(), args.reference().get())));
}
String operator+(String x, const char* y)
string operator+(string x, const char* y)
{
return x + String(y);
return x + string(y);
}
String operator+(const char* x, String y)
string operator+(const char* x, string y)
{
return String(x) + y;
return string(x) + y;
}
Tuple operator+(const Tuple& x, const Tuple& y)
tuple operator+(const tuple& x, const tuple& y)
{
Tuple result(x.size() + y.size());
tuple result(x.size() + y.size());
for (std::size_t xi = 0; xi < x.size(); ++xi)
result.set_item(xi, x[xi]);
for (std::size_t yi = 0; yi < y.size(); ++yi)
@@ -336,148 +336,148 @@ Tuple operator+(const Tuple& x, const Tuple& y)
}
List::List(Ptr p)
: Object(p)
list::list(ref p)
: object(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw ErrorAlreadySet();
throw error_already_set();
}
}
List::List(std::size_t sz)
: Object(Ptr(PyList_New(sz)))
list::list(std::size_t sz)
: object(ref(PyList_New(sz)))
{
}
PyTypeObject* List::type_object()
PyTypeObject* list::type_obj()
{
return &PyList_Type;
}
bool List::accepts(Ptr p)
bool list::accepts(ref p)
{
return PyList_Check(p.get());
}
std::size_t List::size()
std::size_t list::size()
{
return PyList_Size(get());
}
Ptr List::operator[](std::size_t pos) const
ref list::operator[](std::size_t pos) const
{
return Ptr(PyList_GetItem(get(), pos), Ptr::borrowed);
return ref(PyList_GetItem(get(), pos), ref::increment_count);
}
List::Proxy List::operator[](std::size_t pos)
list::proxy list::operator[](std::size_t pos)
{
return Proxy(reference(), pos);
return proxy(reference(), pos);
}
void List::insert(std::size_t index, const Ptr& item)
void list::insert(std::size_t index, const ref& item)
{
if (PyList_Insert(get(), index, item.get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
}
void List::push_back(const Ptr& item)
void list::push_back(const ref& item)
{
if (PyList_Append(get(), item.get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
}
void List::append(const Ptr& item)
void list::append(const ref& item)
{
this->push_back(item);
}
List List::slice(int low, int high) const
list list::slice(int low, int high) const
{
return List(Ptr(PyList_GetSlice(get(), low, high)));
return list(ref(PyList_GetSlice(get(), low, high)));
}
List::SliceProxy List::slice(int low, int high)
list::slice_proxy list::slice(int low, int high)
{
return SliceProxy(reference(), low, high);
return slice_proxy(reference(), low, high);
}
void List::sort()
void list::sort()
{
if (PyList_Sort(get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
}
void List::reverse()
void list::reverse()
{
if (PyList_Reverse(get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
}
Tuple List::as_tuple() const
tuple list::as_tuple() const
{
return Tuple(Ptr(PyList_AsTuple(get())));
return tuple(ref(PyList_AsTuple(get())));
}
const Ptr& List::Proxy::operator=(const Ptr& rhs)
const ref& list::proxy::operator=(const ref& rhs)
{
m_list.set_item(m_index, rhs);
return rhs;
}
List::Proxy::operator Ptr() const
list::proxy::operator ref() const
{
return Ptr(PyList_GetItem(m_list.get(), m_index), Ptr::borrowed);
return ref(PyList_GetItem(m_list.get(), m_index), ref::increment_count);
}
Ptr List::get_item(std::size_t pos) const
ref list::get_item(std::size_t pos) const
{
return Ptr(PyList_GetItem(this->get(), pos), Ptr::borrowed);
return ref(PyList_GetItem(this->get(), pos), ref::increment_count);
}
void List::set_item(std::size_t pos, const Ptr& rhs)
void list::set_item(std::size_t pos, const ref& rhs)
{
int result = PyList_SetItem(this->get(), pos, rhs.get());
if (result == -1)
throw ErrorAlreadySet();
throw error_already_set();
Py_INCREF(rhs.get());
}
List::Proxy::Proxy(const Ptr& list, std::size_t index)
list::proxy::proxy(const ref& list, std::size_t index)
: m_list(list), m_index(index)
{
}
const List& List::SliceProxy::operator=(const List& rhs)
const list& list::slice_proxy::operator=(const list& rhs)
{
if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1)
throw ErrorAlreadySet();
throw error_already_set();
return rhs;
}
List::SliceProxy::operator Ptr() const
list::slice_proxy::operator ref() const
{
return Ptr(PyList_GetSlice(m_list.get(), m_low, m_high));
return ref(PyList_GetSlice(m_list.get(), m_low, m_high));
}
List::SliceProxy::operator List() const
list::slice_proxy::operator list() const
{
return List(this->operator Ptr());
return list(this->operator ref());
}
std::size_t List::SliceProxy::size()
std::size_t list::slice_proxy::size()
{
return this->operator List().size();
return this->operator list().size();
}
Ptr List::SliceProxy::operator[](std::size_t pos) const
ref list::slice_proxy::operator[](std::size_t pos) const
{
return this->operator List()[pos].operator Ptr();
return this->operator list()[pos].operator ref();
}
List::SliceProxy::SliceProxy(const Ptr& list, int low, int high)
list::slice_proxy::slice_proxy(const ref& list, int low, int high)
: m_list(list), m_low(low), m_high(high)
{
}

254
objects.h
View File

@@ -15,48 +15,48 @@
# include "boost/operators.hpp"
# include <utility>
namespace py {
namespace python {
class Object
class object
{
public:
explicit Object(Ptr p);
explicit object(ref p);
// Return a reference to the held object
Ptr reference() const;
ref reference() const;
// Return a raw pointer to the held object
PyObject* get() const;
private:
Ptr m_p;
ref m_p;
};
class Tuple : public Object
class tuple : public object
{
public:
explicit Tuple(std::size_t n = 0);
explicit Tuple(Ptr p);
explicit tuple(std::size_t n = 0);
explicit tuple(ref p);
template <class First, class Second>
Tuple(const std::pair<First,Second>& x)
: Object(Ptr(PyTuple_New(2)))
tuple(const std::pair<First,Second>& x)
: object(ref(PyTuple_New(2)))
{
set_item(0, x.first);
set_item(1, x.second);
}
template <class First, class Second>
Tuple(const First& first, const Second& second)
: Object(Ptr(PyTuple_New(2)))
tuple(const First& first, const Second& second)
: object(ref(PyTuple_New(2)))
{
set_item(0, first);
set_item(1, second);
}
template <class First, class Second, class Third>
Tuple(const First& first, const Second& second, const Third& third)
: Object(Ptr(PyTuple_New(3)))
tuple(const First& first, const Second& second, const Third& third)
: object(ref(PyTuple_New(3)))
{
set_item(0, first);
set_item(1, second);
@@ -64,8 +64,8 @@ class Tuple : public Object
}
template <class First, class Second, class Third, class Fourth>
Tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth)
: Object(Ptr(PyTuple_New(4)))
tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth)
: object(ref(PyTuple_New(4)))
{
set_item(0, first);
set_item(1, second);
@@ -73,10 +73,10 @@ class Tuple : public Object
set_item(3, fourth);
}
static PyTypeObject* type_object();
static bool accepts(Ptr p);
static PyTypeObject* type_obj();
static bool accepts(ref p);
std::size_t size() const;
Ptr operator[](std::size_t pos) const;
ref operator[](std::size_t pos) const;
template <class T>
void set_item(std::size_t pos, const T& rhs)
@@ -84,76 +84,76 @@ class Tuple : public Object
this->set_item(pos, make_ptr(rhs));
}
void set_item(std::size_t pos, const Ptr& rhs);
void set_item(std::size_t pos, const ref& rhs);
Tuple slice(int low, int high) const;
tuple slice(int low, int high) const;
friend Tuple operator+(const Tuple&, const Tuple&);
Tuple& operator+=(const Tuple& rhs);
friend tuple operator+(const tuple&, const tuple&);
tuple& operator+=(const tuple& rhs);
};
class List : public Object
class list : public object
{
struct Proxy;
struct SliceProxy;
struct proxy;
struct slice_proxy;
public:
explicit List(Ptr p);
explicit List(std::size_t sz = 0);
static PyTypeObject* type_object();
static bool accepts(Ptr p);
explicit list(ref p);
explicit list(std::size_t sz = 0);
static PyTypeObject* type_obj();
static bool accepts(ref p);
std::size_t size();
Ptr operator[](std::size_t pos) const;
Proxy operator[](std::size_t pos);
Ptr get_item(std::size_t pos) const;
ref operator[](std::size_t pos) const;
proxy operator[](std::size_t pos);
ref get_item(std::size_t pos) const;
template <class T>
void set_item(std::size_t pos, const T& x)
{ this->set_item(pos, make_ptr(x)); }
void set_item(std::size_t pos, const Ptr& );
void set_item(std::size_t pos, const ref& );
// void set_item(std::size_t pos, const Object& );
// void set_item(std::size_t pos, const object& );
template <class T>
void insert(std::size_t index, const T& x)
{ this->insert(index, make_ptr(x)); }
void insert(std::size_t index, const Ptr& item);
void insert(std::size_t index, const ref& item);
template <class T>
void push_back(const T& item)
{ this->push_back(make_ptr(item)); }
void push_back(const Ptr& item);
void push_back(const ref& item);
template <class T>
void append(const T& item)
{ this->append(make_ptr(item)); }
void append(const Ptr& item);
void append(const ref& item);
List slice(int low, int high) const;
SliceProxy slice(int low, int high);
list slice(int low, int high) const;
slice_proxy slice(int low, int high);
void sort();
void reverse();
Tuple as_tuple() const;
tuple as_tuple() const;
};
class String
: public Object, public boost::multipliable2<String, unsigned int>
class string
: public object, public boost::multipliable2<string, unsigned int>
{
public:
// Construct from an owned PyObject*.
// Precondition: p must point to a python string.
explicit String(Ptr p);
explicit String(const char* s);
String(const char* s, std::size_t length);
String(const String& rhs);
explicit string(ref p);
explicit string(const char* s);
string(const char* s, std::size_t length);
string(const string& rhs);
enum Interned { interned };
String(const char* s, Interned);
enum interned_t { interned };
string(const char* s, interned_t);
// Get the type object for Strings
static PyTypeObject* type_object();
static PyTypeObject* type_obj();
// Return true if the given object is a python String
static bool accepts(Ptr o);
// Return true if the given object is a python string
static bool accepts(ref o);
// Return the length of the string.
std::size_t size() const;
@@ -163,172 +163,172 @@ class String
// The data must not be modified in any way. It must not be de-allocated.
const char* c_str() const;
String& operator*=(unsigned int repeat_count);
String& operator+=(const String& rhs);
friend String operator+(String x, String y);
String& operator+=(const char* rhs);
friend String operator+(String x, const char* y);
friend String operator+(const char* x, String y);
string& operator*=(unsigned int repeat_count);
string& operator+=(const string& rhs);
friend string operator+(string x, string y);
string& operator+=(const char* rhs);
friend string operator+(string x, const char* y);
friend string operator+(const char* x, string y);
void intern();
friend String operator%(const String& format, const Tuple& args);
friend string operator%(const string& format, const tuple& args);
};
class Dict : public Object
class dictionary : public object
{
private:
struct Proxy;
struct proxy;
public:
explicit Dict(Ptr p);
Dict();
explicit dictionary(ref p);
dictionary();
void clear();
static PyTypeObject* type_object();
static bool accepts(Ptr p);
static PyTypeObject* type_obj();
static bool accepts(ref p);
public:
template <class Key>
Proxy operator[](const Key& key)
proxy operator[](const Key& key)
{ return this->operator[](make_ptr(key)); }
Proxy operator[](Ptr key);
proxy operator[](ref key);
template <class Key>
Ptr operator[](const Key& key) const
ref operator[](const Key& key) const
{ return this->operator[](make_ptr(key)); }
Ptr operator[](Ptr key) const;
ref operator[](ref key) const;
template <class Key>
Ptr get_item(const Key& key) const
ref get_item(const Key& key) const
{ return this->get_item(make_ptr(key)); }
Ptr get_item(const Ptr& key) const;
ref get_item(const ref& key) const;
template <class Key, class Default>
Ptr get_item(const Key& key, const Default& default_) const
ref get_item(const Key& key, const Default& default_) const
{ return this->get_item(make_ptr(key), make_ptr(default_)); }
Ptr get_item(const Ptr& key, const Ptr& default_) const;
ref get_item(const ref& key, const ref& default_) const;
template <class Key, class Value>
void set_item(const Key& key, const Value& value)
{ this->set_item(make_ptr(key), make_ptr(value)); }
void set_item(const Ptr& key, const Ptr& value);
void set_item(const ref& key, const ref& value);
template <class Key>
void erase(const Key& key)
{ this->erase(make_ptr(key)); }
void erase(Ptr key);
void erase(ref key);
// Proxy operator[](const Object& key);
// Ptr operator[](const Object& key) const;
// proxy operator[](const object& key);
// ref operator[](const object& key) const;
// Ptr get_item(const Object& key, Ptr default_ = Ptr()) const;
// void set_item(const Object& key, const Ptr& value);
// ref get_item(const object& key, ref default_ = ref()) const;
// void set_item(const object& key, const ref& value);
// void erase(const Object& key);
// void erase(const object& key);
List items() const;
List keys() const;
List values() const;
list items() const;
list keys() const;
list values() const;
std::size_t size() const;
// TODO: iterator support
};
struct Dict::Proxy
struct dictionary::proxy
{
template <class T>
const Ptr& operator=(const T& rhs)
const ref& operator=(const T& rhs)
{ return (*this) = make_ptr(rhs); }
const Ptr& operator=(const Ptr& rhs);
const ref& operator=(const ref& rhs);
operator Ptr() const;
operator ref() const;
private:
friend class Dict;
Proxy(const Ptr& dict, const Ptr& key);
friend class dictionary;
proxy(const ref& dict, const ref& key);
// This is needed to work around the very strange MSVC error report that the
// return type of the built-in operator= differs from that of the ones
// defined above. Couldn't hurt to make these un-assignable anyway, though.
const Ptr& operator=(const Proxy&); // Not actually implemented
const ref& operator=(const proxy&); // Not actually implemented
private:
Ptr m_dict;
Ptr m_key;
ref m_dict;
ref m_key;
};
struct List::Proxy
struct list::proxy
{
template <class T>
const Ptr& operator=(const T& rhs)
const ref& operator=(const T& rhs)
{ return (*this) = make_ptr(rhs); }
const Ptr& operator=(const Ptr& rhs);
const ref& operator=(const ref& rhs);
operator Ptr() const;
operator ref() const;
private:
friend class List;
Proxy(const Ptr& list, std::size_t index);
friend class list;
proxy(const ref& list, std::size_t index);
// This is needed to work around the very strange MSVC error report that the
// return type of the built-in operator= differs from that of the ones
// defined above. Couldn't hurt to make these un-assignable anyway, though.
const Ptr& operator=(const Proxy&); // Not actually implemented
const ref& operator=(const proxy&); // Not actually implemented
private:
List m_list;
list m_list;
std::size_t m_index;
};
struct List::SliceProxy
struct list::slice_proxy
{
const List& operator=(const List& rhs);
operator Ptr() const;
operator List() const;
const list& operator=(const list& rhs);
operator ref() const;
operator list() const;
std::size_t size();
Ptr operator[](std::size_t pos) const;
ref operator[](std::size_t pos) const;
private:
friend class List;
SliceProxy(const Ptr& list, int low, int high);
friend class list;
slice_proxy(const ref& list, int low, int high);
private:
Ptr m_list;
ref m_list;
int m_low, m_high;
};
} // namespace py
} // namespace python
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
PyObject* to_python(const py::Tuple&);
py::Tuple from_python(PyObject* p, py::Type<py::Tuple>);
PyObject* to_python(const python::tuple&);
python::tuple from_python(PyObject* p, python::type<python::tuple>);
inline py::Tuple from_python(PyObject* p, py::Type<const py::Tuple&>)
inline python::tuple from_python(PyObject* p, python::type<const python::tuple&>)
{
return from_python(p, py::Type<py::Tuple>());
return from_python(p, python::type<python::tuple>());
}
PyObject* to_python(const py::List&);
py::List from_python(PyObject* p, py::Type<py::List>);
PyObject* to_python(const python::list&);
python::list from_python(PyObject* p, python::type<python::list>);
inline py::List from_python(PyObject* p, py::Type<const py::List&>)
inline python::list from_python(PyObject* p, python::type<const python::list&>)
{
return from_python(p, py::Type<py::List>());
return from_python(p, python::type<python::list>());
}
PyObject* to_python(const py::String&);
py::String from_python(PyObject* p, py::Type<py::String>);
PyObject* to_python(const python::string&);
python::string from_python(PyObject* p, python::type<python::string>);
inline py::String from_python(PyObject* p, py::Type<const py::String&>)
inline python::string from_python(PyObject* p, python::type<const python::string&>)
{
return from_python(p, py::Type<py::String>());
return from_python(p, python::type<python::string>());
}
PyObject* to_python(const py::Dict&);
py::Dict from_python(PyObject* p, py::Type<py::Dict>);
PyObject* to_python(const python::dictionary&);
python::dictionary from_python(PyObject* p, python::type<python::dictionary>);
inline py::Dict from_python(PyObject* p, py::Type<const py::Dict&>)
inline python::dictionary from_python(PyObject* p, python::type<const python::dictionary&>)
{
return from_python(p, py::Type<py::Dict>());
return from_python(p, python::type<python::dictionary>());
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
#endif // OBJECTS_DWA051100_H_

View File

@@ -8,7 +8,7 @@
# include <strstream>
#endif
namespace py {
namespace python {
namespace detail {
struct auto_operand {};
@@ -39,7 +39,7 @@ enum operator_id
op_cmp = 0x100000
};
template <long which, class operand = py::detail::auto_operand>
template <long which, class operand = python::detail::auto_operand>
struct operators {};
template <class T>
@@ -53,7 +53,7 @@ namespace detail
template <class Specified>
struct operand_select
{
template <class WrappedType>
template <class wrapped_type>
struct wrapped
{
typedef Specified type;
@@ -63,20 +63,20 @@ namespace detail
template <>
struct operand_select<auto_operand>
{
template <class WrappedType>
template <class wrapped_type>
struct wrapped
{
typedef const WrappedType& type;
typedef const wrapped_type& type;
};
};
template <long> struct define_operator;
// Base class which grants access to ExtensionClassBase::add_method() to its derived classes
// Base class which grants access to extension_class_base::add_method() to its derived classes
struct add_operator_base
{
protected:
static inline void add_method(ExtensionClassBase* target, Function* method, const char* name)
static inline void add_method(extension_class_base* target, function* method, const char* name)
{ target->add_method(method, name); }
};
@@ -89,7 +89,7 @@ namespace detail
// Usage:
// choose_op<(which & op_add)>::template args<left_t,right_t>::add(ext_class);
//
// (see ExtensionClass<>::def_operators() for more examples).
// (see extension_class<>::def_operators() for more examples).
//
template <long op_selector>
struct choose_op
@@ -97,7 +97,7 @@ namespace detail
template <class Left, class Right = Left>
struct args : add_operator_base
{
static inline void add(ExtensionClassBase* target)
static inline void add(extension_class_base* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
@@ -115,7 +115,7 @@ namespace detail
template <class Left, class Right = Left>
struct args
{
static inline void add(ExtensionClassBase*)
static inline void add(extension_class_base*)
{
}
@@ -128,7 +128,7 @@ namespace detail
template <class Operand>
struct args : add_operator_base
{
static inline void add(ExtensionClassBase* target)
static inline void add(extension_class_base* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
@@ -146,7 +146,7 @@ namespace detail
template <class Operand>
struct args
{
static inline void add(ExtensionClassBase*)
static inline void add(extension_class_base*)
{
}
@@ -159,7 +159,7 @@ namespace detail
template <class Left, class Right = Left>
struct args : add_operator_base
{
static inline void add(ExtensionClassBase* target)
static inline void add(extension_class_base* target)
{
typedef define_operator<op_selector> def_op;
add_method(target,
@@ -177,7 +177,7 @@ namespace detail
template <class Left, class Right = Left>
struct args
{
static inline void add(ExtensionClassBase*)
static inline void add(extension_class_base*)
{
}
@@ -189,15 +189,15 @@ namespace detail
struct define_operator<op_##id> \
{ \
template <class Left, class Right = Left> \
struct operator_function : Function \
struct operator_function : function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
tuple args(ref(arguments, ref::increment_count)); \
\
return PY_CONVERSION::to_python( \
PY_CONVERSION::from_python(args[0].get(), py::Type<Left>()) oper \
PY_CONVERSION::from_python(args[1].get(), py::Type<Right>())); \
return BOOST_PYTHON_CONVERSION::to_python( \
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>()) oper \
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())); \
} \
\
const char* description() const \
@@ -205,15 +205,15 @@ namespace detail
}; \
\
template <class Right, class Left> \
struct roperator_function : Function \
struct roperator_function : function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
tuple args(ref(arguments, ref::increment_count)); \
\
return PY_CONVERSION::to_python( \
PY_CONVERSION::from_python(args[1].get(), py::Type<Left>()) oper \
PY_CONVERSION::from_python(args[0].get(), py::Type<Right>())); \
return BOOST_PYTHON_CONVERSION::to_python( \
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>()) oper \
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())); \
} \
\
const char* description() const \
@@ -230,14 +230,14 @@ namespace detail
struct define_operator<op_##id> \
{ \
template <class operand> \
struct operator_function : Function \
struct operator_function : function \
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
Tuple args(Ptr(arguments, Ptr::new_ref)); \
tuple args(ref(arguments, ref::increment_count)); \
\
return PY_CONVERSION::to_python( \
oper(PY_CONVERSION::from_python(args[0].get(), py::Type<operand>()))); \
return BOOST_PYTHON_CONVERSION::to_python( \
oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<operand>()))); \
} \
\
const char* description() const \
@@ -273,21 +273,21 @@ namespace detail
struct define_operator<op_pow>
{
template <class Left, class Right = Left>
struct operator_function : Function
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3");
throw ArgumentError();
throw argument_error();
}
return PY_CONVERSION::to_python(
pow(PY_CONVERSION::from_python(args[0].get(), py::Type<Left>()),
PY_CONVERSION::from_python(args[1].get(), py::Type<Right>())));
return BOOST_PYTHON_CONVERSION::to_python(
pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>()),
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())));
}
const char* description() const
@@ -296,21 +296,21 @@ namespace detail
};
template <class Right, class Left>
struct roperator_function : Function
struct roperator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()");
throw ArgumentError();
throw argument_error();
}
return PY_CONVERSION::to_python(
pow(PY_CONVERSION::from_python(args[1].get(), py::Type<Left>()),
PY_CONVERSION::from_python(args[0].get(), py::Type<Right>())));
return BOOST_PYTHON_CONVERSION::to_python(
pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>()),
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())));
}
const char* description() const
@@ -326,21 +326,21 @@ namespace detail
struct define_operator<op_divmod>
{
template <class Left, class Right = Left>
struct operator_function : Function
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
PyObject * res = PyTuple_New(2);
PyTuple_SET_ITEM(res, 0,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[0].get(), py::Type<Left>()) /
PY_CONVERSION::from_python(args[1].get(), py::Type<Right>())));
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>()) /
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())));
PyTuple_SET_ITEM(res, 1,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[0].get(), py::Type<Left>()) %
PY_CONVERSION::from_python(args[1].get(), py::Type<Right>())));
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>()) %
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())));
return res;
}
@@ -351,21 +351,21 @@ namespace detail
};
template <class Right, class Left>
struct roperator_function : Function
struct roperator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
PyObject * res = PyTuple_New(2);
PyTuple_SET_ITEM(res, 0,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[1].get(), py::Type<Left>()) /
PY_CONVERSION::from_python(args[0].get(), py::Type<Right>())));
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>()) /
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())));
PyTuple_SET_ITEM(res, 1,
PY_CONVERSION::to_python(
PY_CONVERSION::from_python(args[1].get(), py::Type<Left>()) %
PY_CONVERSION::from_python(args[0].get(), py::Type<Right>())));
BOOST_PYTHON_CONVERSION::to_python(
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>()) %
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())));
return res;
}
@@ -383,18 +383,18 @@ namespace detail
struct define_operator<op_cmp>
{
template <class Left, class Right = Left>
struct operator_function : Function
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
return PY_CONVERSION::to_python(
(PY_CONVERSION::from_python(args[0].get(), py::Type<Left>()) <
PY_CONVERSION::from_python(args[1].get(), py::Type<Right>())) ?
return BOOST_PYTHON_CONVERSION::to_python(
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>()) <
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())) ?
- 1 :
(PY_CONVERSION::from_python(args[1].get(), py::Type<Right>()) <
PY_CONVERSION::from_python(args[0].get(), py::Type<Left>())) ?
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>()) <
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>())) ?
1 :
0) ;
}
@@ -405,18 +405,18 @@ namespace detail
};
template <class Right, class Left>
struct roperator_function : Function
struct roperator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
return PY_CONVERSION::to_python(
(PY_CONVERSION::from_python(args[1].get(), py::Type<Left>()) <
PY_CONVERSION::from_python(args[0].get(), py::Type<Right>())) ?
return BOOST_PYTHON_CONVERSION::to_python(
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>()) <
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())) ?
- 1 :
(PY_CONVERSION::from_python(args[0].get(), py::Type<Right>()) <
PY_CONVERSION::from_python(args[1].get(), py::Type<Left>())) ?
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>()) <
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>())) ?
1 :
0) ;
}
@@ -434,24 +434,24 @@ namespace detail
struct define_operator<op_str>
{
template <class operand>
struct operator_function : Function
struct operator_function : function
{
PyObject* do_call(PyObject* arguments, PyObject*) const
{
Tuple args(Ptr(arguments, Ptr::new_ref));
tuple args(ref(arguments, ref::increment_count));
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
std::ostringstream s;
s << PY_CONVERSION::from_python(args[0].get(), py::Type<operand>());
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<operand>());
#else
std::ostrstream s;
s << PY_CONVERSION::from_python(args[0].get(), py::Type<operand>()) << char();
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<operand>()) << char();
#endif
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
return PY_CONVERSION::to_python(s.str());
return BOOST_PYTHON_CONVERSION::to_python(s.str());
#else
return PY_CONVERSION::to_python(const_cast<char const *>(s.str()));
return BOOST_PYTHON_CONVERSION::to_python(const_cast<char const *>(s.str()));
#endif
}
@@ -466,6 +466,6 @@ namespace detail
} // namespace detail
} // namespace py
} // namespace python
#endif /* OPERATORS_UK112000_H_ */

View File

@@ -33,15 +33,15 @@ void initoverload_demo()
{
    try
    {
py::Module overload_demo("overload_demo");
python::module_builder overload_demo("overload_demo");
// Overloaded functions at module scope
overload_demo.def(f1, "f");
overload_demo.def(f2, "f");
py::ClassWrapper&lt;X&gt; x_class(overload_demo, "X");
python::class_builder&lt;X&gt; x_class(overload_demo, "X");
// Overloaded constructors
x_class.def(py::Constructor&lt;&gt;());
x_class.def(py::Constructor&lt;int&gt;());
x_class.def(python::constructor&lt;&gt;());
x_class.def(python::constructor&lt;int&gt;());
// Overloaded member functions
x_class.def((int (X::*)() const)&amp;X::value, "value");

View File

@@ -46,7 +46,7 @@ class world
<li><a name="derived_3">An</a> implementation of each virtual function you may wish to override in
Python which uses
<code>py::Callback&lt<i>return-type</i>&gt;::call_method()</code> to call the
<code>python::callback&lt<i>return-type</i>&gt;::call_method()</code> to call the
Python override.
<li><a name="derived_4">For</a> each non-pure virtual function meant to be overridable from Python, a
@@ -65,7 +65,7 @@ struct world_callback : world
m_self(self) {}
const char* get() const // <a href="#derived_3">3</a>
{ return py::Callback&lt;const char*&gt;::call_method(m_self, "get"); }
{ return python::callback&lt;const char*&gt;::call_method(m_self, "get"); }
static const char* <a name= "default_implementation">default_get</a>(const hello::world& self) const // <a href="#derived_4">4</a>
{ return self.world::get(); }
@@ -76,14 +76,14 @@ struct world_callback : world
<p>
Finally, we add <code>world_callback</code> to the <code>
ClassWrapper&lt;&gt;</code> declaration in our module initialization
class_builder&lt;&gt;</code> declaration in our module initialization
function, and when we define the function, we must tell py_cpp about the default
implementation:
<blockquote><pre>
// Create the <a name=
"world_class">Python type object</a> for our extension class
py::ClassWrapper&lt;hello::world<strong>,world_callback&gt;</strong> world_class(hello, "world");
python::class_builder&lt;hello::world<strong>,world_callback&gt;</strong> world_class(hello, "world");
// Add a virtual member function
world_class.def(&amp;world::get, "get", &amp;<b>world_callback::default_get</b>);
</pre></blockquote>
@@ -116,7 +116,7 @@ world_class.def(&amp;world::get, "get", &amp;<b>world_callback::default_get</b>)
to deal with than a virtual function with a default implementation. First
of all, you obviously don't need to <a href="#default_implementation">
supply a default implementation</a>. Secondly, you don't need to call
<code>def()</code> on the <code>ExtensionClass&lt;&gt;</code> instance
<code>def()</code> on the <code>extension_class&lt;&gt;</code> instance
for the virtual function. In fact, you wouldn't <em>want</em> to: if the
corresponding attribute on the Python class stays undefined, you'll get
an <code>AttributeError</code> in Python when you try to call the
@@ -128,7 +128,7 @@ struct baz {
};
struct baz_callback {
int pure(int x) { py::Callback&lt;int&gt;::call_method(m_self, "pure", x); }
int pure(int x) { python::callback&lt;int&gt;::call_method(m_self, "pure", x); }
};
extern "C"
@@ -139,13 +139,13 @@ initfoobar()
{
try
{
py::Module foobar("foobar");
py::ClassWrapper&lt;baz,baz_callback&gt; baz_class("baz");
python::module_builder foobar("foobar");
python::class_builder&lt;baz,baz_callback&gt; baz_class("baz");
baz_class.def(&amp;baz::pure, "pure");
}
catch(...)
{
py::handle_exception(); // Deal with the exception for Python
python::handle_exception(); // Deal with the exception for Python
}
}
</pre>

View File

@@ -61,11 +61,11 @@ wrapped <code>T</code>, you may want to provide an automatic
thin wrappers. You can do this simply as follows:
<blockquote><pre>
PY_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
PyObject* to_python(const Foo* p) {
return to_python(*p); // convert const Foo* in terms of const Foo&
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
</pre></blockquote>
<h4>If you can't (afford to) copy the referent, or the pointer is non-const</h4>
@@ -78,17 +78,17 @@ can not control the lifetime of the referent, so it may be destroyed by your C++
code before the last Python reference to it disappears:
<blockquote><pre>
PY_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
PyObject* to_python(Foo* p)
{
return py::PyExtensionClassConverters<Foo>::ptr_to_python(p);
return python::PyExtensionClassConverters<Foo>::ptr_to_python(p);
}
PyObject* to_python(const Foo* p)
{
return to_python(const_cast<Foo*>(p));
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
</pre></blockquote>
This will cause the Foo* to be treated as though it were an owning smart
@@ -117,9 +117,9 @@ typedef unsigned ErrorCode;
const char* f(int* in_out_x); // original function
...
#include &lt;py_cpp/objects.h&gt;
const py::Tuple f_wrapper(int in_x) {
const python::tuple f_wrapper(int in_x) {
const char* s = f(in_x);
return py::Tuple(s, in_x);
return python::tuple(s, in_x);
}
...
my_module.def(f_wrapper, "f");

64
py.cpp
View File

@@ -13,7 +13,7 @@
# include <boost/cast.hpp>
#endif
namespace py {
namespace python {
// IMPORTANT: this function may only be called from within a catch block!
void handle_exception()
@@ -26,7 +26,7 @@ void handle_exception()
// Codewarrior doesn't suffer from this problem.
throw;
}
catch(const py::ErrorAlreadySet&)
catch(const python::error_already_set&)
{
// The python error reporting has already been handled.
}
@@ -44,37 +44,37 @@ void handle_exception()
}
}
} // namespace py
} // namespace python
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
long from_python(PyObject* p, py::Type<long>)
long from_python(PyObject* p, python::type<long>)
{
// Why am I clearing the error here before trying to convert? I know there's a reason...
long result;
{
result = PyInt_AsLong(p);
if (PyErr_Occurred())
throw py::ArgumentError();
throw python::argument_error();
}
return result;
}
double from_python(PyObject* p, py::Type<double>)
double from_python(PyObject* p, python::type<double>)
{
double result;
{
result = PyFloat_AsDouble(p);
if (PyErr_Occurred())
throw py::ArgumentError();
throw python::argument_error();
}
return result;
}
template <class T>
T integer_from_python(PyObject* p, py::Type<T>)
T integer_from_python(PyObject* p, python::type<T>)
{
const long long_result = from_python(p, py::Type<long>());
const long long_result = from_python(p, python::type<long>());
#ifndef BOOST_NO_LIMITS
try
@@ -94,7 +94,7 @@ T integer_from_python(PyObject* p, py::Type<T>)
const char message[] = "%ld out of range for %s";
sprintf(buffer, message, long_result, typeid(T).name());
PyErr_SetString(PyExc_ValueError, buffer);
throw py::ArgumentError();
throw python::argument_error();
}
#if defined(__MWERKS__) && __MWERKS__ <= 0x2400
return 0; // Not smart enough to know that the catch clause always rethrows
@@ -119,13 +119,13 @@ PyObject* integer_to_python(T value)
{
const char message[] = "value out of range for Python int";
PyErr_SetString(PyExc_ValueError, message);
throw py::ErrorAlreadySet();
throw python::error_already_set();
}
return to_python(value_as_long);
}
int from_python(PyObject* p, py::Type<int> type)
int from_python(PyObject* p, python::type<int> type)
{
return integer_from_python(p, type);
}
@@ -135,19 +135,19 @@ PyObject* to_python(unsigned int i)
return integer_to_python(i);
}
unsigned int from_python(PyObject* p, py::Type<unsigned int> type)
unsigned int from_python(PyObject* p, python::type<unsigned int> type)
{
return integer_from_python(p, type);
}
short from_python(PyObject* p, py::Type<short> type)
short from_python(PyObject* p, python::type<short> type)
{
return integer_from_python(p, type);
}
float from_python(PyObject* p, py::Type<float>)
float from_python(PyObject* p, python::type<float>)
{
return static_cast<float>(from_python(p, py::Type<double>()));
return static_cast<float>(from_python(p, python::type<double>()));
}
PyObject* to_python(unsigned short i)
@@ -155,7 +155,7 @@ PyObject* to_python(unsigned short i)
return integer_to_python(i);
}
unsigned short from_python(PyObject* p, py::Type<unsigned short> type)
unsigned short from_python(PyObject* p, python::type<unsigned short> type)
{
return integer_from_python(p, type);
}
@@ -165,7 +165,7 @@ PyObject* to_python(unsigned char i)
return integer_to_python(i);
}
unsigned char from_python(PyObject* p, py::Type<unsigned char> type)
unsigned char from_python(PyObject* p, python::type<unsigned char> type)
{
return integer_from_python(p, type);
}
@@ -175,7 +175,7 @@ PyObject* to_python(signed char i)
return integer_to_python(i);
}
signed char from_python(PyObject* p, py::Type<signed char> type)
signed char from_python(PyObject* p, python::type<signed char> type)
{
return integer_from_python(p, type);
}
@@ -185,24 +185,24 @@ PyObject* to_python(unsigned long x)
return integer_to_python(x);
}
unsigned long from_python(PyObject* p, py::Type<unsigned long> type)
unsigned long from_python(PyObject* p, python::type<unsigned long> type)
{
return integer_from_python(p, type);
}
void from_python(PyObject* p, py::Type<void>)
void from_python(PyObject* p, python::type<void>)
{
if (p != Py_None) {
PyErr_SetString(PyExc_TypeError, "expected argument of type None");
throw py::ArgumentError();
throw python::argument_error();
}
}
const char* from_python(PyObject* p, py::Type<const char*>)
const char* from_python(PyObject* p, python::type<const char*>)
{
const char* s = PyString_AsString(p);
if (!s)
throw py::ArgumentError();
throw python::argument_error();
return s;
}
@@ -211,20 +211,20 @@ PyObject* to_python(const std::string& s)
return PyString_FromString(s.c_str());
}
std::string from_python(PyObject* p, py::Type<std::string>)
std::string from_python(PyObject* p, python::type<std::string>)
{
return std::string(from_python(p, py::Type<const char*>()));
return std::string(from_python(p, python::type<const char*>()));
}
bool from_python(PyObject* p, py::Type<bool>)
bool from_python(PyObject* p, python::type<bool>)
{
int value = from_python(p, py::Type<int>());
int value = from_python(p, python::type<int>());
if (value == 0)
return false;
return true;
}
#ifdef PY_MSVC6_OR_EARLIER
#ifdef BOOST_MSVC6_OR_EARLIER
// An optimizer bug prevents these from being inlined.
PyObject* to_python(double d)
{
@@ -235,7 +235,7 @@ PyObject* to_python(float f)
{
return PyFloat_FromDouble(f);
}
#endif // PY_MSVC6_OR_EARLIER
#endif // BOOST_MSVC6_OR_EARLIER
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE

166
py.h
View File

@@ -17,23 +17,23 @@
# include "errors.h"
# include <string>
PY_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
// This can be instantiated on an enum to provide the to_python/from_python
// conversions, provided the values can fit in a long.
template <class EnumType>
class py_enum_as_int_converters
{
friend EnumType from_python(PyObject* x, py::Type<EnumType>)
friend EnumType from_python(PyObject* x, python::type<EnumType>)
{
return static_cast<EnumType>(
from_python(x, py::Type<long>()));
from_python(x, python::type<long>()));
}
friend EnumType from_python(PyObject* x, py::Type<const EnumType&>)
friend EnumType from_python(PyObject* x, python::type<const EnumType&>)
{
return static_cast<EnumType>(
from_python(x, py::Type<long>()));
from_python(x, python::type<long>()));
}
friend PyObject* to_python(EnumType x)
@@ -41,13 +41,13 @@ class py_enum_as_int_converters
return to_python(static_cast<long>(x));
}
};
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace py {
namespace python {
template <class EnumType> class enum_as_int_converters
: public PY_CONVERSION::py_enum_as_int_converters<EnumType> {};
: public BOOST_PYTHON_CONVERSION::py_enum_as_int_converters<EnumType> {};
template <class P, class T> class WrappedPointer;
template <class P, class T> class wrapped_pointer;
//#pragma warn_possunwant off
inline void decref_impl(PyObject* p) { Py_DECREF(p); }
@@ -70,80 +70,80 @@ inline void xdecref(T* p)
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
}
} // namespace py
} // namespace python
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
//
// Converters
//
PyObject* to_python(long);
long from_python(PyObject* p, py::Type<long>);
long from_python(PyObject* p, py::Type<const long&>);
long from_python(PyObject* p, python::type<long>);
long from_python(PyObject* p, python::type<const long&>);
PyObject* to_python(unsigned long);
unsigned long from_python(PyObject* p, py::Type<unsigned long>);
unsigned long from_python(PyObject* p, py::Type<const unsigned long&>);
unsigned long from_python(PyObject* p, python::type<unsigned long>);
unsigned long from_python(PyObject* p, python::type<const unsigned long&>);
PyObject* to_python(int);
int from_python(PyObject*, py::Type<int>);
int from_python(PyObject*, py::Type<const int&>);
int from_python(PyObject*, python::type<int>);
int from_python(PyObject*, python::type<const int&>);
PyObject* to_python(unsigned int);
unsigned int from_python(PyObject*, py::Type<unsigned int>);
unsigned int from_python(PyObject*, py::Type<const unsigned int&>);
unsigned int from_python(PyObject*, python::type<unsigned int>);
unsigned int from_python(PyObject*, python::type<const unsigned int&>);
PyObject* to_python(short);
short from_python(PyObject*, py::Type<short>);
short from_python(PyObject*, py::Type<const short&>);
short from_python(PyObject*, python::type<short>);
short from_python(PyObject*, python::type<const short&>);
PyObject* to_python(unsigned short);
unsigned short from_python(PyObject*, py::Type<unsigned short>);
unsigned short from_python(PyObject*, py::Type<const unsigned short&>);
unsigned short from_python(PyObject*, python::type<unsigned short>);
unsigned short from_python(PyObject*, python::type<const unsigned short&>);
PyObject* to_python(signed char);
signed char from_python(PyObject*, py::Type<signed char>);
signed char from_python(PyObject*, py::Type<const signed char&>);
signed char from_python(PyObject*, python::type<signed char>);
signed char from_python(PyObject*, python::type<const signed char&>);
PyObject* to_python(unsigned char);
unsigned char from_python(PyObject*, py::Type<unsigned char>);
unsigned char from_python(PyObject*, py::Type<const unsigned char&>);
unsigned char from_python(PyObject*, python::type<unsigned char>);
unsigned char from_python(PyObject*, python::type<const unsigned char&>);
PyObject* to_python(float);
float from_python(PyObject*, py::Type<float>);
float from_python(PyObject*, py::Type<const float&>);
float from_python(PyObject*, python::type<float>);
float from_python(PyObject*, python::type<const float&>);
PyObject* to_python(double);
double from_python(PyObject*, py::Type<double>);
double from_python(PyObject*, py::Type<const double&>);
double from_python(PyObject*, python::type<double>);
double from_python(PyObject*, python::type<const double&>);
PyObject* to_python(bool);
bool from_python(PyObject*, py::Type<bool>);
bool from_python(PyObject*, py::Type<const bool&>);
bool from_python(PyObject*, python::type<bool>);
bool from_python(PyObject*, python::type<const bool&>);
PyObject* to_python(void);
void from_python(PyObject*, py::Type<void>);
void from_python(PyObject*, python::type<void>);
PyObject* to_python(const char* s);
const char* from_python(PyObject*, py::Type<const char*>);
const char* from_python(PyObject*, python::type<const char*>);
PyObject* to_python(const std::string& s);
std::string from_python(PyObject*, py::Type<std::string>);
std::string from_python(PyObject*, py::Type<const std::string&>);
std::string from_python(PyObject*, python::type<std::string>);
std::string from_python(PyObject*, python::type<const std::string&>);
// For when your C++ function really wants to pass/return a PyObject*
PyObject* to_python(PyObject*);
PyObject* from_python(PyObject*, py::Type<PyObject*>);
PyObject* from_python(PyObject*, python::type<PyObject*>);
// Some standard conversions to/from smart pointer types. You can add your own
// from these examples. These are not generated using the friend technique from
// WrappedPointer because:
// wrapped_pointer because:
//
// 1. We want to be able to extend conversion to/from WrappedPointers using
// arbitrary smart pointer types.
//
// 2. It helps with compilation independence. This way, code which creates
// wrappers for functions accepting and returning smart_ptr<T> does not
// have to have already seen the invocation of WrappedType<T>.
// have to have already seen the invocation of wrapped_type<T>.
//
// Unfortunately, MSVC6 is so incredibly lame that we have to rely on the friend
@@ -151,15 +151,15 @@ PyObject* from_python(PyObject*, py::Type<PyObject*>);
// types. This means that you need to write a non-templated function for each
// specific smart_ptr<T> which you want to convert from_python. For example,
//
// namespace py {
// namespace python {
// #ifdef MUST_SUPPORT_MSVC
//
// MyPtr<Foo> from_python(PyObject*p, Type<MyPtr<Foo> >)
// { return smart_ptr_from_python(p, Type<MyPtr<Foo> >(), Type<Foo>());}
// MyPtr<Foo> from_python(PyObject*p, type<MyPtr<Foo> >)
// { return smart_ptr_from_python(p, type<MyPtr<Foo> >(), type<Foo>());}
// }
//
// MyPtr<Bar> from_python(PyObject*p, Type<MyPtr<Bar> >)
// { return smart_ptr_from_python(p, Type<MyPtr<Bar> >(), Type<Bar>());}
// MyPtr<Bar> from_python(PyObject*p, type<MyPtr<Bar> >)
// { return smart_ptr_from_python(p, type<MyPtr<Bar> >(), type<Bar>());}
//
// ... // definitions for MyPtr<Baz>, MyPtr<Mumble>, etc.
//
@@ -167,19 +167,19 @@ PyObject* from_python(PyObject*, py::Type<PyObject*>);
//
// // Just once for all MyPtr<T>
// template <class T>
// MyPtr<T> from_python(PyObject*p, Type<MyPtr<T> >)
// MyPtr<T> from_python(PyObject*p, type<MyPtr<T> >)
// {
// return smart_ptr_from_python(p, Type<MyPtr<T> >(), Type<T>());
// return smart_ptr_from_python(p, type<MyPtr<T> >(), type<T>());
// }
//
// #endif
// }
#if !defined(PY_MSVC6_OR_EARLIER)
#if !defined(BOOST_MSVC6_OR_EARLIER)
template <class T>
boost::shared_ptr<T> from_python(PyObject*p, py::Type<boost::shared_ptr<T> >)
boost::shared_ptr<T> from_python(PyObject*p, python::type<boost::shared_ptr<T> >)
{
return smart_ptr_from_python(p, py::Type<boost::shared_ptr<T> >(), py::Type<T>());
return smart_ptr_from_python(p, python::type<boost::shared_ptr<T> >(), python::type<T>());
}
#endif
@@ -187,13 +187,13 @@ boost::shared_ptr<T> from_python(PyObject*p, py::Type<boost::shared_ptr<T> >)
template <class T>
PyObject* to_python(std::auto_ptr<T> p)
{
return new py::WrappedPointer<std::auto_ptr<T>, T>(p);
return new python::wrapped_pointer<std::auto_ptr<T>, T>(p);
}
template <class T>
PyObject* to_python(boost::shared_ptr<T> p)
{
return new py::WrappedPointer<boost::shared_ptr<T>, T>(p);
return new python::wrapped_pointer<boost::shared_ptr<T>, T>(p);
}
#endif
@@ -201,7 +201,7 @@ PyObject* to_python(boost::shared_ptr<T> p)
// inline implementations
//
#ifndef PY_MSVC6_OR_EARLIER
#ifndef BOOST_MSVC6_OR_EARLIER
inline PyObject* to_python(double d)
{
return PyFloat_FromDouble(d);
@@ -211,7 +211,7 @@ inline PyObject* to_python(float f)
{
return PyFloat_FromDouble(f);
}
#endif // PY_MSVC6_OR_EARLIER
#endif // BOOST_MSVC6_OR_EARLIER
inline PyObject* to_python(long l)
{
@@ -235,7 +235,7 @@ inline PyObject* to_python(bool b)
inline PyObject* to_python(void)
{
return py::detail::none();
return python::detail::none();
}
inline PyObject* to_python(const char* s)
@@ -243,9 +243,9 @@ inline PyObject* to_python(const char* s)
return PyString_FromString(s);
}
inline std::string from_python(PyObject* p, py::Type<const std::string&>)
inline std::string from_python(PyObject* p, python::type<const std::string&>)
{
return from_python(p, py::Type<std::string>());
return from_python(p, python::type<std::string>());
}
inline PyObject* to_python(PyObject* p)
@@ -254,72 +254,72 @@ inline PyObject* to_python(PyObject* p)
return p;
}
inline PyObject* from_python(PyObject* p, py::Type<PyObject*>)
inline PyObject* from_python(PyObject* p, python::type<PyObject*>)
{
return p;
}
inline const char* from_python(PyObject* p, py::Type<const char* const&>)
inline const char* from_python(PyObject* p, python::type<const char* const&>)
{
return from_python(p, py::Type<const char*>());
return from_python(p, python::type<const char*>());
}
inline double from_python(PyObject* p, py::Type<const double&>)
inline double from_python(PyObject* p, python::type<const double&>)
{
return from_python(p, py::Type<double>());
return from_python(p, python::type<double>());
}
inline float from_python(PyObject* p, py::Type<const float&>)
inline float from_python(PyObject* p, python::type<const float&>)
{
return from_python(p, py::Type<float>());
return from_python(p, python::type<float>());
}
inline int from_python(PyObject* p, py::Type<const int&>)
inline int from_python(PyObject* p, python::type<const int&>)
{
return from_python(p, py::Type<int>());
return from_python(p, python::type<int>());
}
inline short from_python(PyObject* p, py::Type<const short&>)
inline short from_python(PyObject* p, python::type<const short&>)
{
return from_python(p, py::Type<short>());
return from_python(p, python::type<short>());
}
inline long from_python(PyObject* p, py::Type<const long&>)
inline long from_python(PyObject* p, python::type<const long&>)
{
return from_python(p, py::Type<long>());
return from_python(p, python::type<long>());
}
inline bool from_python(PyObject* p, py::Type<const bool&>)
inline bool from_python(PyObject* p, python::type<const bool&>)
{
return from_python(p, py::Type<bool>());
return from_python(p, python::type<bool>());
}
inline unsigned int from_python(PyObject* p, py::Type<const unsigned int&>)
inline unsigned int from_python(PyObject* p, python::type<const unsigned int&>)
{
return from_python(p, py::Type<unsigned int>());
return from_python(p, python::type<unsigned int>());
}
inline unsigned short from_python(PyObject* p, py::Type<const unsigned short&>)
inline unsigned short from_python(PyObject* p, python::type<const unsigned short&>)
{
return from_python(p, py::Type<unsigned short>());
return from_python(p, python::type<unsigned short>());
}
inline signed char from_python(PyObject* p, py::Type<const signed char&>)
inline signed char from_python(PyObject* p, python::type<const signed char&>)
{
return from_python(p, py::Type<signed char>());
return from_python(p, python::type<signed char>());
}
inline unsigned char from_python(PyObject* p, py::Type<const unsigned char&>)
inline unsigned char from_python(PyObject* p, python::type<const unsigned char&>)
{
return from_python(p, py::Type<unsigned char>());
return from_python(p, python::type<unsigned char>());
}
inline unsigned long from_python(PyObject* p, py::Type<const unsigned long&>)
inline unsigned long from_python(PyObject* p, python::type<const unsigned long&>)
{
return from_python(p, py::Type<unsigned long>());
return from_python(p, python::type<unsigned long>());
}
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
#endif // METHOD_DWA122899_H_

View File

@@ -77,9 +77,9 @@
href="overloading.html">function overloading</a> and wrote the support for
<a href="inheritance.html#implicit_conversion">reflecting C++ inheritance
relationships</a>. He has helped to improve error-reporting from both
Python and C++, and has designed an extremely easy-to-use approach to
export <a href="special.html#numeric">numeric operators</a> including
the possibility to avoid explicit coercion by means of overloading.
Python and C++, and has designed an extremely easy-to-use way of
exposing <a href="special.html#numeric">numeric operators</a>, including
a way to avoid explicit coercion by means of overloading.
<li>The members of the boost mailing list and the Python community supplied
invaluable early feedback. In particular, Ron Clarke, Mark Evans, Anton
@@ -118,7 +118,7 @@
<li>Advanced Topics
<ol>
<li>ClassWrapper&lt;&gt;
<li>class_builder&lt;&gt;
<li><a href="enums.html">enums</a>

View File

@@ -14,21 +14,20 @@
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
// A gcc bug forces some symbols into the global namespace
# define PY_BEGIN_CONVERSION_NAMESPACE
# define PY_END_CONVERSION_NAMESPACE
# define PY_CONVERSION
# define PY_IMPORT_CONVERSION(x) using ::x
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE
# define BOOST_PYTHON_CONVERSION
# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x
# else
# define PY_BEGIN_CONVERSION_NAMESPACE namespace py {
# define PY_END_CONVERSION_NAMESPACE }
# define PY_CONVERSION py
# define PY_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace python {
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }
# define BOOST_PYTHON_CONVERSION python
# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
# endif
# if defined(BOOST_MSVC)
# define PY_COMPILER_IS_MSVC 1
# if _MSC_VER <= 1200
# define PY_MSVC6_OR_EARLIER 1
# define BOOST_MSVC6_OR_EARLIER 1
# endif
# pragma warning (disable : 4786)
@@ -39,19 +38,19 @@
// EDG-based compilers (e.g. alpha), which incorrectly warn that the result of
// offsetof() is not an integer constant expression.
# if defined(__DECCXX_VER) && __DECCXX_VER <= 60290024
# define PY_OFFSETOF(s_name, s_member) \
# define BOOST_OFFSETOF(s_name, s_member) \
((size_t)__INTADDR__(&(((s_name *)0)->s_member)))
# else
# define PY_OFFSETOF(s_name, s_member) \
# define BOOST_OFFSETOF(s_name, s_member) \
offsetof(s_name, s_member)
# endif
// The STLport puts all of the standard 'C' library names in std (as far as the
// user is concerned), but without it you need a fix if you're using MSVC.
# if defined(PY_MSVC6_OR_EARLIER) && !defined(__STLPORT)
# define PY_CSTD_
# if defined(BOOST_MSVC6_OR_EARLIER) && !defined(__STLPORT)
# define BOOST_CSTD_
# else
# define PY_CSTD_ std
# define BOOST_CSTD_ std
# endif
#endif // CONFIG_DWA052200_H_

70
pyptr.h
View File

@@ -18,82 +18,82 @@
# include "errors.h"
# include "py.h"
PY_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
template <class T, class Value, class Base>
struct PyPtrConversions : Base
struct py_ptr_conversions : Base
{
inline friend T from_python(PyObject* x, py::Type<const T&>)
{ return T(py::Downcast<Value>(x).get(), T::new_ref); }
inline friend T from_python(PyObject* x, python::type<const T&>)
{ return T(python::downcast<Value>(x).get(), T::increment_count); }
inline friend T from_python(PyObject* x, py::Type<T>)
{ return T(py::Downcast<Value>(x).get(), T::new_ref); }
inline friend T from_python(PyObject* x, python::type<T>)
{ return T(python::downcast<Value>(x).get(), T::increment_count); }
inline friend PyObject* to_python(T x)
{ return py::as_object(x.release()); }
{ return python::as_object(x.release()); }
};
PY_END_CONVERSION_NAMESPACE
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace py {
namespace python {
PY_IMPORT_CONVERSION(PyPtrConversions);
BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions);
template <class T>
class PyPtr
: public PyPtrConversions<PyPtr<T>, T,
boost::dereferenceable<PyPtr<T>, T*> > // supplies op->
class reference
: public py_ptr_conversions<reference<T>, T,
boost::dereferenceable<reference<T>, T*> > // supplies op->
{
public:
typedef T value_type;
PyPtr(const PyPtr& rhs)
reference(const reference& rhs)
: m_p(rhs.m_p)
{
Py_XINCREF(object());
}
#if !defined(PY_MSVC6_OR_EARLIER)
#if !defined(BOOST_MSVC6_OR_EARLIER)
template <class T2>
PyPtr(const PyPtr<T2>& rhs)
reference(const reference<T2>& rhs)
: m_p(rhs.object())
{
Py_XINCREF(object());
}
#endif
PyPtr() : m_p(0) {}
reference() : m_p(0) {}
// These are two ways of spelling the same thing, that we need to increment
// the reference count on the pointer when we're initialized.
enum NewRef { new_ref, borrowed = new_ref };
enum increment_count_t { increment_count };
enum AllowNull { null_ok };
enum allow_null { null_ok };
template <class T2>
explicit PyPtr(T2* x)
explicit reference(T2* x)
: m_p(expect_non_null(x)) {}
template <class T2>
PyPtr(T2* x, NewRef)
reference(T2* x, increment_count_t)
: m_p(expect_non_null(x)) { Py_INCREF(object()); }
template <class T2>
PyPtr(T2* x, AllowNull)
reference(T2* x, allow_null)
: m_p(x) {}
template <class T2>
PyPtr(T2* x, AllowNull, NewRef)
reference(T2* x, allow_null, increment_count_t)
: m_p(x) { Py_XINCREF(object()); }
template <class T2>
PyPtr(T2* x, NewRef, AllowNull)
reference(T2* x, increment_count_t, allow_null)
: m_p(x) { Py_XINCREF(object()); }
#if !defined(PY_MSVC6_OR_EARLIER)
#if !defined(BOOST_MSVC6_OR_EARLIER)
template <class T2>
PyPtr& operator=(const PyPtr<T2>& rhs)
reference& operator=(const reference<T2>& rhs)
{
Py_XDECREF(object());
m_p = rhs.m_p;
@@ -102,7 +102,7 @@ public:
}
#endif
PyPtr& operator=(const PyPtr& rhs)
reference& operator=(const reference& rhs)
{
Py_XINCREF(static_cast<PyObject*>(rhs.m_p));
Py_XDECREF(object());
@@ -110,7 +110,7 @@ public:
return *this;
}
~PyPtr()
~reference()
{
Py_XDECREF(m_p);
}
@@ -134,19 +134,19 @@ public:
{ Py_XDECREF(m_p); m_p = expect_non_null(x);}
template <class T2>
void reset(T2* x, NewRef)
void reset(T2* x, increment_count_t)
{ Py_XDECREF(m_p); m_p = expect_non_null(x); Py_INCREF(object()); }
template <class T2>
void reset(T2* x, AllowNull)
void reset(T2* x, allow_null)
{ Py_XDECREF(m_p); m_p = x;}
template <class T2>
void reset(T2* x, AllowNull, NewRef)
void reset(T2* x, allow_null, increment_count_t)
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
template <class T2>
void reset(T2* x, NewRef, AllowNull)
void reset(T2* x, increment_count_t, allow_null)
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
@@ -160,12 +160,12 @@ private:
T* m_p;
};
typedef PyPtr<PyObject> Ptr;
typedef reference<PyObject> ref;
template <class T>
Ptr make_ptr(const T& x)
ref make_ptr(const T& x)
{
return Ptr(to_python(x));
return ref(to_python(x));
}
}

View File

@@ -6,50 +6,50 @@
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file automatically generated by gen_signatures.py for 10 arguments.
// This file automatically generated by gen_signatures.python for 10 arguments.
#ifndef SIGNATURES_DWA050900_H_
# define SIGNATURES_DWA050900_H_
# include "pyconfig.h"
namespace py {
namespace python {
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 {};
struct void_t {};
}
// An envelope in which type information can be delivered for the purposes
// of selecting an overloaded from_python() function. This is needed to work
// around MSVC's lack of partial specialiation/ordering. Where normally we'd
// want to form a function call like void f<const T&>(), We instead pass
// Type<const T&> as one of the function parameters to select a particular
// type<const T&> as one of the function parameters to select a particular
// overload.
//
// The Id typedef helps us deal with the lack of partial ordering by generating
// unique types for constructor signatures. In general, Type<T>::Id is Type<T>,
// but Type<Void>::Id is just Void.
// The id typedef helps us deal with the lack of partial ordering by generating
// unique types for constructor signatures. In general, type<T>::id is type<T>,
// but type<void_t>::id is just void_t.
template <class T>
struct Type
struct type
{
typedef Type Id;
typedef type id;
};
template <>
struct Type<py::detail::Void>
struct type<python::detail::void_t>
{
typedef py::detail::Void Id;
typedef python::detail::void_t 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
// 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
// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs
// that involve recursive template nesting.
//
// Signature chaining
// signature chaining
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10>
struct Signature10 {};
@@ -57,195 +57,195 @@ template <class T1, class T2, class T3, class T4, class T5, class T6, class T7,
struct Signature9 {};
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class X>
inline Signature10<X, T1, T2, T3, T4, T5, T6, T7, T8, T9> prepend(Type<X>, Signature9<T1, T2, T3, T4, T5, T6, T7, T8, T9>)
inline Signature10<X, T1, T2, T3, T4, T5, T6, T7, T8, T9> prepend(type<X>, Signature9<T1, T2, T3, T4, T5, T6, T7, T8, T9>)
{ return Signature10<X, T1, T2, T3, T4, T5, T6, T7, T8, T9>(); }
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
struct Signature8 {};
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class X>
inline Signature9<X, T1, T2, T3, T4, T5, T6, T7, T8> prepend(Type<X>, Signature8<T1, T2, T3, T4, T5, T6, T7, T8>)
inline Signature9<X, T1, T2, T3, T4, T5, T6, T7, T8> prepend(type<X>, Signature8<T1, T2, T3, T4, T5, T6, T7, T8>)
{ return Signature9<X, T1, T2, T3, T4, T5, T6, T7, T8>(); }
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
struct Signature7 {};
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class X>
inline Signature8<X, T1, T2, T3, T4, T5, T6, T7> prepend(Type<X>, Signature7<T1, T2, T3, T4, T5, T6, T7>)
inline Signature8<X, T1, T2, T3, T4, T5, T6, T7> prepend(type<X>, Signature7<T1, T2, T3, T4, T5, T6, T7>)
{ return Signature8<X, T1, T2, T3, T4, T5, T6, T7>(); }
template <class T1, class T2, class T3, class T4, class T5, class T6>
struct Signature6 {};
template <class T1, class T2, class T3, class T4, class T5, class T6, class X>
inline Signature7<X, T1, T2, T3, T4, T5, T6> prepend(Type<X>, Signature6<T1, T2, T3, T4, T5, T6>)
inline Signature7<X, T1, T2, T3, T4, T5, T6> prepend(type<X>, Signature6<T1, T2, T3, T4, T5, T6>)
{ return Signature7<X, T1, T2, T3, T4, T5, T6>(); }
template <class T1, class T2, class T3, class T4, class T5>
struct Signature5 {};
struct signature5 {};
template <class T1, class T2, class T3, class T4, class T5, class X>
inline Signature6<X, T1, T2, T3, T4, T5> prepend(Type<X>, Signature5<T1, T2, T3, T4, T5>)
inline Signature6<X, T1, T2, T3, T4, T5> prepend(type<X>, signature5<T1, T2, T3, T4, T5>)
{ return Signature6<X, T1, T2, T3, T4, T5>(); }
template <class T1, class T2, class T3, class T4>
struct Signature4 {};
struct signature4 {};
template <class T1, class T2, class T3, class T4, class X>
inline Signature5<X, T1, T2, T3, T4> prepend(Type<X>, Signature4<T1, T2, T3, T4>)
{ return Signature5<X, T1, T2, T3, T4>(); }
inline signature5<X, T1, T2, T3, T4> prepend(type<X>, signature4<T1, T2, T3, T4>)
{ return signature5<X, T1, T2, T3, T4>(); }
template <class T1, class T2, class T3>
struct Signature3 {};
struct signature3 {};
template <class T1, class T2, class T3, class X>
inline Signature4<X, T1, T2, T3> prepend(Type<X>, Signature3<T1, T2, T3>)
{ return Signature4<X, T1, T2, T3>(); }
inline signature4<X, T1, T2, T3> prepend(type<X>, signature3<T1, T2, T3>)
{ return signature4<X, T1, T2, T3>(); }
template <class T1, class T2>
struct Signature2 {};
struct signature2 {};
template <class T1, class T2, class X>
inline Signature3<X, T1, T2> prepend(Type<X>, Signature2<T1, T2>)
{ return Signature3<X, T1, T2>(); }
inline signature3<X, T1, T2> prepend(type<X>, signature2<T1, T2>)
{ return signature3<X, T1, T2>(); }
template <class T1>
struct Signature1 {};
struct signature1 {};
template <class T1, class X>
inline Signature2<X, T1> prepend(Type<X>, Signature1<T1>)
{ return Signature2<X, T1>(); }
inline signature2<X, T1> prepend(type<X>, signature1<T1>)
{ return signature2<X, T1>(); }
struct Signature0 {};
struct signature0 {};
template <class X>
inline Signature1<X> prepend(Type<X>, Signature0)
{ return Signature1<X>(); }
inline signature1<X> prepend(type<X>, signature0)
{ return signature1<X>(); }
// This one terminates the chain. Prepending Void to the head of a Void
// signature results in a Void signature again.
inline Signature0 prepend(Void, Signature0) { return Signature0(); }
// This one terminates the chain. Prepending void_t to the head of a void_t
// signature results in a void_t signature again.
inline signature0 prepend(void_t, signature0) { return signature0(); }
} // namespace detail
template <class A1 = detail::Void, class A2 = detail::Void, class A3 = detail::Void, class A4 = detail::Void, class A5 = detail::Void, class A6 = detail::Void, class A7 = detail::Void, class A8 = detail::Void, class A9 = detail::Void, class A10 = detail::Void>
struct Constructor
template <class A1 = detail::void_t, class A2 = detail::void_t, class A3 = detail::void_t, class A4 = detail::void_t, class A5 = detail::void_t, class A6 = detail::void_t, class A7 = detail::void_t, class A8 = detail::void_t, class A9 = detail::void_t, class A10 = detail::void_t>
struct constructor
{
};
namespace detail {
// Return value extraction:
// This is just another little envelope for carrying a typedef (see Type,
// above). I could have re-used Type, but that has a very specific purpose. I
// This is just another little envelope for carrying a typedef (see type,
// above). I could have re-used type, but that has a very specific purpose. I
// thought this would be clearer.
template <class T>
struct ReturnValue { typedef T Type; };
struct return_value_select { typedef T type; };
// free functions
template <class R>
ReturnValue<R> return_value(R (*)()) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)()) { return return_value_select<R>(); }
template <class R, class A1>
ReturnValue<R> return_value(R (*)(A1)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1)) { return return_value_select<R>(); }
template <class R, class A1, class A2>
ReturnValue<R> return_value(R (*)(A1, A2)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3>
ReturnValue<R> return_value(R (*)(A1, A2, A3)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4, class A5>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4, A5)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4, A5)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4, A5, A6)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4, A5, A6)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return return_value_select<R>(); }
template <class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
ReturnValue<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return return_value_select<R>(); }
// TODO(?): handle 'const void'
// member functions
template <class R, class T>
ReturnValue<R> return_value(R (T::*)()) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)()) { return return_value_select<R>(); }
template <class R, class T, class A1>
ReturnValue<R> return_value(R (T::*)(A1)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2>
ReturnValue<R> return_value(R (T::*)(A1, A2)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4)) { return return_value_select<R>(); }
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)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return return_value_select<R>(); }
template <class R, class T>
ReturnValue<R> return_value(R (T::*)() const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)() const) { return return_value_select<R>(); }
template <class R, class T, class A1>
ReturnValue<R> return_value(R (T::*)(A1) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2>
ReturnValue<R> return_value(R (T::*)(A1, A2) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4) const) { return return_value_select<R>(); }
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>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { return return_value_select<R>(); }
template <class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
ReturnValue<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { return ReturnValue<R>(); }
return_value_select<R> return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { return return_value_select<R>(); }
}} // namespace py::detail
}} // namespace python::detail
#endif

View File

@@ -11,58 +11,58 @@
# include "pyconfig.h"
namespace py { namespace detail {
namespace python { namespace detail {
struct Empty {};
template <class Derived, class Base = Empty>
struct Singleton : Base
struct empty {};
template <class Derived, class Base = empty>
struct singleton : Base
{
typedef Singleton SingletonBase; // Convenience type for derived class constructors
typedef singleton singleton_base; // Convenience type for derived class constructors
static Derived* singleton();
static Derived* instance();
// Pass-through constructors
Singleton() : Base() {}
singleton() : Base() {}
template <class A1>
Singleton(const A1& a1) : Base(a1) {}
singleton(const A1& a1) : Base(a1) {}
template <class A1, class A2>
Singleton(const A1& a1, const A2& a2) : Base(a1, a2) {}
singleton(const A1& a1, const A2& a2) : Base(a1, a2) {}
template <class A1, class A2, class A3>
Singleton(const A1& a1, const A2& a2, const A3& a3) : Base(a1, a2, a3) {}
singleton(const A1& a1, const A2& a2, const A3& a3) : Base(a1, a2, a3) {}
template <class A1, class A2, class A3, class A4>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4) : Base(a1, a2, a3, a4) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4) : Base(a1, a2, a3, a4) {}
template <class A1, class A2, class A3, class A4, class A5>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) : Base(a1, a2, a3, a4, a5) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) : Base(a1, a2, a3, a4, a5) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) : Base(a1, a2, a3, a4, a5, a6) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) : Base(a1, a2, a3, a4, a5, a6) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) : Base(a1, a2, a3, a4, a5, a6, a7) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) : Base(a1, a2, a3, a4, a5, a6, a7) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : Base(a1, a2, a3, a4, a5, a6, a7, a8) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : Base(a1, a2, a3, a4, a5, a6, a7, a8) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
Singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
};
template <class Derived, class Base>
Derived* Singleton<Derived,Base>::singleton()
Derived* singleton<Derived,Base>::instance()
{
static Derived x;
return &x;
}
}} // namespace py::detail
}} // namespace python::detail
#endif

View File

@@ -52,7 +52,9 @@ Python provides a number of special operatos for basic customization of a class:
<p>
</dl>
If we have a suitable C++ function that supports any of these features, we can export it like any other function, using its Python special name. For example, suppose that class <code>Foo</code> provides a string conversion function:
If we have a suitable C++ function that supports any of these features, we can
export it like any other function, using its Python special name. For example,
suppose that class <code>Foo</code> provides a string conversion function:
<pre>
std::string to_string(Foo const &amp; f)
@@ -66,17 +68,23 @@ If we have a suitable C++ function that supports any of these features, we can e
This function would be wrapped like this:
<pre>
py::ClassWrapper&lt:Foo&gt; foo_class(my_module, "Foo");
python::class_builder&lt:Foo&gt; foo_class(my_module, "Foo");
foo_class.def(&amp;to_string, "__str__");
</pre>
Note that py_cpp also supports <em>automatic wrapping</em> in case of __str__ and __cmp__. This is explained in the <a href="#numeric">next section</a> and the <a href="#numeric_table">table of numeric operators</a>.
Note that py_cpp also supports <em>automatic wrapping</em> in case of __str__
and __cmp__. This is explained in the <a href="#numeric">next section</a> and
the <a href="#numeric_table">table of numeric operators</a>.
<a name="numeric">
<h2>Numeric Operators</h2>
</a>
There are two fundamental ways to define numeric operators within py_cpp: manual wrapping (as is done with <a href="#general">general operators</a>) and automatic wrapping. Lets start with the second possibility. Suppose, C++ defines a class <code>Int</code> (which might represent an infinite-precision integer) which support addition, so that we can write (in C++):
There are two fundamental ways to define numeric operators within py_cpp: manual
wrapping (as is done with <a href="#general">general operators</a>) and
automatic wrapping. Lets start with the second possibility. Suppose, C++ defines
a class <code>Int</code> (which might represent an infinite-precision integer)
which support addition, so that we can write (in C++):
<pre>
Int a, b, c;
@@ -87,24 +95,30 @@ There are two fundamental ways to define numeric operators within py_cpp: manual
To enable the same functionality in Python, we first wrap the <code>Int</code> class as usual:
<pre>
py::ClassWrapper&lt;Int&gt; int_class(my_module, "Int");
int_class.def(py::Constructor&lt;&gt;());
python::class_builder&lt;Int&gt; int_class(my_module, "Int");
int_class.def(python::constructor&lt;&gt;());
...
</pre>
Then we export the addition operator like this:
<pre>
int_class.def(py::operators&lt;py::op_add&gt;());
int_class.def(python::operators&lt;python::op_add&gt;());
</pre>
Since Int also supports subtraction, multiplication, adn division, we want to export those also. This can be done in a single command by 'or'ing the operator identifiers together (a complete list of these identifiers and the corresponding operators can be found in the <a href="#numeric_table">table</a>):
Since Int also supports subtraction, multiplication, adn division, we want to
export those also. This can be done in a single command by 'or'ing the operator
identifiers together (a complete list of these identifiers and the corresponding
operators can be found in the <a href="#numeric_table">table</a>):
<pre>
int_class.def(py::operators&lt;(py::op_sub | py::op_mul | py::op_div)&gt;());
int_class.def(python::operators&lt;(python::op_sub | python::op_mul | python::op_div)&gt;());
</pre>
Note that the or-expression must be enclosed in parentheses. This form of operator definition will wrap homogeneous operators, i.e. operators whose left and right operand have the same type. Now, suppose that our C++ library also supports addition of Ints and plain integers:
Note that the or-expression must be enclosed in parentheses. This form of
operator definition will wrap homogeneous operators, i.e. operators whose left
and right operand have the same type. Now, suppose that our C++ library also
supports addition of Ints and plain integers:
<pre>
Int a, b;
@@ -114,37 +128,56 @@ Note that the or-expression must be enclosed in parentheses. This form of operat
a = i + b;
</pre>
To wrap these heterogeneous operators (left and right hand side have different types), we need a possibility to specify a different type for one of the operands. This is done using the <code>right_operand</code> and <code>left_operand</code> templates:
To wrap these heterogeneous operators (left and right hand side have different
types), we need a possibility to specify a different type for one of the
operands. This is done using the <code>right_operand</code> and
<code>left_operand</code> templates:
<pre>
int_class.def(py::operators&lt;py::op_add&gt;(), py::right_operand&lt;int&gt;());
int_class.def(py::operators&lt;py::op_add&gt;(), py::left_operand&lt;int&gt;());
int_class.def(python::operators&lt;python::op_add&gt;(), python::right_operand&lt;int&gt;());
int_class.def(python::operators&lt;python::op_add&gt;(), python::left_operand&lt;int&gt;());
</pre>
Py_cpp uses overloading to register several variants of the same operation (more on this in the context of <a href="#coercion">coercion</a>). Again, several operators can be exported at once:
Py_cpp uses overloading to register several variants of the same operation (more
on this in the context of <a href="#coercion">coercion</a>). Again, several
operators can be exported at once:
<pre>
int_class.def(py::operators&lt;(py::op_sub | py::op_mul | py::op_div)&gt;(),
py::right_operand&lt;int&gt;());
int_class.def(py::operators&lt;(py::op_sub | py::op_mul | py::op_div)&gt;(),
py::left_operand&lt;int&gt;());
int_class.def(python::operators&lt;(python::op_sub | python::op_mul | python::op_div)&gt;(),
python::right_operand&lt;int&gt;());
int_class.def(python::operators&lt;(python::op_sub | python::op_mul | python::op_div)&gt;(),
python::left_operand&lt;int&gt;());
</pre>
The type of the operand not mentioned is taken from the class object. In our example, the class object is <code>int_class</code>, and thus the other operand's type is `<code>Int const &amp;</code>'. You can override this default by explicitly specifying a type in the <code>operators</code> template:
The type of the operand not mentioned is taken from the class object. In our
example, the class object is <code>int_class</code>, and thus the other
operand's type is `<code>Int const &amp;</code>'. You can override this default
by explicitly specifying a type in the <code>operators</code> template:
<pre>
int_class.def(py::operators&lt;py::op_add, Int&gt;(), py::right_operand&lt;int&gt;());
int_class.def(python::operators&lt;python::op_add, Int&gt;(), python::right_operand&lt;int&gt;());
</pre>
Here, `<code>Int</code>' would be used instead of `<code>Int const &amp;</code>'.
<p>
Note that automatic wrapping doesn't need any specific form of <code>operator+()</code> (or one of the other operators), but rather wraps the <em>expression</em> `<code>left + right</code>'. That is, this mechanism can be used for any definition of <code>operator+()</code>, such as a free function `<code>Int operator+(Int, Int)</code>' or a member function `<code>Int Int::operator+(Int)</code>'.
Note that automatic wrapping doesn't need any specific form of
<code>operator+()</code> (or one of the other operators), but rather wraps the
<em>expression</em> `<code>left + right</code>'. That is, this mechanism can be
used for any definition of <code>operator+()</code>, such as a free function
`<code>Int operator+(Int, Int)</code>' or a member function `<code>Int
Int::operator+(Int)</code>'.
<p>
For the Python operators <code>pow()</code> and <code>abs()</code>, there is no corresponding C++ operator. Instead, automatic wrapping attempts to wrap C++ functions of the same name. This only works if those functions are known in namespace <code>py::detail</code>. Thus it might be necessary to add a using declaration prior to wrapping:
For the Python operators <code>pow()</code> and <code>abs()</code>, there is no
corresponding C++ operator. Instead, automatic wrapping attempts to wrap C++
functions of the same name. This only works if those functions are known in
namespace <code>python::detail</code>. Thus it might be necessary to add a using
declaration prior to wrapping:
<pre>
namespace py {
namespace python {
namespace detail {
using my_namespace::pow;
using my_namespace::abs;
@@ -153,7 +186,10 @@ For the Python operators <code>pow()</code> and <code>abs()</code>, there is no
<p>
In some cases, automatic wrapping of operators is not possible or not desirable. Suppose, for example, that the modulo operation for Ints is defined by a set of functions <code>mod()</code> (for automatic wrapping, we would need <code>operator%()</code>):
In some cases, automatic wrapping of operators is not possible or not
desirable. Suppose, for example, that the modulo operation for Ints is defined
by a set of functions <code>mod()</code> (for automatic wrapping, we would need
<code>operator%()</code>):
<pre>
Int mod(Int const &amp; left, Int const &amp; right);
@@ -168,7 +204,9 @@ In order to create the Python operator "__mod__" from these functions, we have t
int_class.def((Int (*)(Int const &amp;, int))&amp;mod, "__mod__");
</pre>
The third form (with <code>int</code> as left operand) cannot be wrapped this way. We must first create a function <code>rmod()</code> with the operands reversed:
The third form (with <code>int</code> as left operand) cannot be wrapped this
way. We must first create a function <code>rmod()</code> with the operands
reversed:
<pre>
Int rmod(Int const &amp; right, int left)
@@ -186,41 +224,70 @@ This function must be wrapped under the name "__rmod__":
A list of the possible operator names is also found in the <a href="#numeric_table">table</a>.
Special treatment is necessary to export the <a href="#ternary_pow">ternary pow</a> operator.
<p>
Automatic and manual wrapping can be mixed arbitrarily. Note that you cannot overload the same operator for a given extension class on both `<code>int</code>' and `<code>float</code>', because Python implicitly converts these types into each other. Thus, the overloaded variant found first (be it `<code>int</code>' or `<code>float</code>') will be used for either of the two types.
Automatic and manual wrapping can be mixed arbitrarily. Note that you cannot
overload the same operator for a given extension class on both
`<code>int</code>' and `<code>float</code>', because Python implicitly converts
these types into each other. Thus, the overloaded variant found first (be it
`<code>int</code>' or `<code>float</code>') will be used for either of the two
types.
<a name="coercion">
<h4>Coercion</h4></a>
Plain Python can only execute operators with identical types on the left and right hand side. If it encounters an expression where the types of the left and right operand differ, it tries to coerce these type to a common type before invoking the actual operator. Implementing good coercion functions can be difficult if many type combinations must be supported.
Plain Python can only execute operators with identical types on the left and
right hand side. If it encounters an expression where the types of the left and
right operand differ, it tries to coerce these type to a common type before
invoking the actual operator. Implementing good coercion functions can be
difficult if many type combinations must be supported.
<p>
In contrast, py_cpp provides <em><a href="overloading.html">overloading</a></em>. By means of overloading, operator calling can be simplyfied drastically: you just register operators for all desired type combinations, and py_cpp automatically ensures that the correct function is called in each case. User defined coercion functions are <em>not necessary</em>. To enable operator overloading, py_cpp provides a standard coercion which is <em>implicitly registered</em> whenever automatic operator wrapping is used.
In contrast, py_cpp provides <em><a
href="overloading.html">overloading</a></em>. By means of overloading, operator
calling can be simplyfied drastically: you just register operators for all
desired type combinations, and py_cpp automatically ensures that the correct
function is called in each case. User defined coercion functions are <em>not
necessary</em>. To enable operator overloading, py_cpp provides a standard
coercion which is <em>implicitly registered</em> whenever automatic operator
wrapping is used.
<p>
If you wrap all operator functions manually, but still want to use operator overloading, you have to register the standard coercion function explicitly:
If you wrap all operator functions manually, but still want to use operator
overloading, you have to register the standard coercion function explicitly:
<pre>
// this is not necessary if automatic operator wrapping is used
int_class.def_standard_coerce();
</pre>
In case you encounter a situation where you absolutely need a customized coercion, you can overload the "__coerce__" operator itself. The signature of a coercion function must look like this:
In case you encounter a situation where you absolutely need a customized
coercion, you can overload the "__coerce__" operator itself. The signature of a
coercion function must look like this:
<pre>
py::Tuple custom_coerce(PyObject * left, PyObject * right);
python::tuple custom_coerce(PyObject * left, PyObject * right);
</pre>
The resulting <code>Tuple</code> must contain two elements which represent the values of <code>left</code> and <code>right</code> converted to the same type. Such a function is wrapped as usual:
The resulting <code>tuple</code> must contain two elements which represent the
values of <code>left</code> and <code>right</code> converted to the same
type. Such a function is wrapped as usual:
<pre>
some_class.def(&amp;custom_coerce, "__coerce__");
</pre>
Note that the custom coercion function is only used if it is defined <em>before</em> any automatic operator wrapping on the given class or a call to `<code>some_class.def_standard_coerce()</code>'.
Note that the custom coercion function is only used if it is defined
<em>before</em> any automatic operator wrapping on the given class or a call to
`<code>some_class.def_standard_coerce()</code>'.
<a name="ternary_pow">
<h4>The Ternary <code>pow()</code> Operator</h4></a>
In addition to the usual binary <code>pow()</code>-operator (meaning <code>x^y</code>), Python also provides a ternary variant that implements <code>(x^y) % z</code> (presumably using a more efficient algorithm than concatenation of power and modulo operators). Automatic operator wrapping can only be used with the binary variant. Ternary <code>pow()</code> must always be wrapped manually. For a homgeneous ternary <code>pow()</code>, this is done as usual:
In addition to the usual binary <code>pow()</code>-operator (meaning
<code>x^y</code>), Python also provides a ternary variant that implements
<code>(x^y) % z</code> (presumably using a more efficient algorithm than
concatenation of power and modulo operators). Automatic operator wrapping can
only be used with the binary variant. Ternary <code>pow()</code> must always be
wrapped manually. For a homgeneous ternary <code>pow()</code>, this is done as
usual:
<pre>
Int power(Int const &amp; first, Int const &amp; second, Int const &amp; module);
@@ -229,7 +296,8 @@ In addition to the usual binary <code>pow()</code>-operator (meaning <code>x^y</
int_class.def((ternary_function1)&amp;power, "__pow__");
</pre>
In case you want to support this function with non-uniform argument types, wrapping is a little more involved. Suppose, you have to wrap:
In case you want to support this function with non-uniform argument types,
wrapping is a little more involved. Suppose, you have to wrap:
<pre>
Int power(Int const &amp; first, int second, int module);
@@ -244,7 +312,10 @@ The first variant can be wrapped as usual:
int_class.def((ternary_function2)&amp;power, "__pow__");
</pre>
In the second variant, however, <code>Int</code> appears only as second argument, and in the last one it is the third argument. Therefor we must first provide functions where the argumant order is changed so that <code>Int</code> appears in first place:
In the second variant, however, <code>Int</code> appears only as second
argument, and in the last one it is the third argument. Therefor we must first
provide functions where the argumant order is changed so that <code>Int</code>
appears in first place:
<pre>
Int rpower(Int const &amp; second, int first, int module)
@@ -286,16 +357,16 @@ Note that "__rrpow__" is an extension not present in plain Python.
<b>C++ Operator Id</b>
<td align=center>
<b>C++ Expression Used For Automatic Wrapping</b><br>
with <code>cpp_left = from_python(left, Type&lt;Left&gt;())</code>,<br>
<code>cpp_right = from_python(right, Type&lt;Right&gt;())</code>,<br>
and <code>cpp_oper = from_python(oper, Type&lt;Oper&gt;())</code>
with <code>cpp_left = from_python(left, type&lt;Left&gt;())</code>,<br>
<code>cpp_right = from_python(right, type&lt;Right&gt;())</code>,<br>
and <code>cpp_oper = from_python(oper, type&lt;Oper&gt;())</code>
<tr>
<td>
<code>__add__, __radd__</code>
<td>
<code>left + right</code>
<td>
<code>py::op_add</code>
<code>python::op_add</code>
<td>
<code>cpp_left + cpp_right</code>
<tr>
@@ -304,7 +375,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left - right</code>
<td>
<code>py::op_sub</code>
<code>python::op_sub</code>
<td>
<code>cpp_left - cpp_right</code>
<tr>
@@ -313,7 +384,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left * right</code>
<td>
<code>py::op_mul</code>
<code>python::op_mul</code>
<td>
<code>cpp_left * cpp_right</code>
<tr>
@@ -322,7 +393,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left / right</code>
<td>
<code>py::op_div</code>
<code>python::op_div</code>
<td>
<code>cpp_left / cpp_right</code>
<tr>
@@ -331,7 +402,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left % right</code>
<td>
<code>py::op_mod</code>
<code>python::op_mod</code>
<td>
<code>cpp_left % cpp_right</code>
<tr>
@@ -340,7 +411,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>(quotient, remainder) <br>= divmod(left, right)</code>
<td>
<code>py::op_divmod</code>
<code>python::op_divmod</code>
<td>
<code>cpp_left / cpp_right&nbsp;</code> and
<code>&nbsp;cpp_left % cpp_right</code>
@@ -351,7 +422,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<code>pow(left, right)</code><br>
(binary power)
<td>
<code>py::op_pow</code>
<code>python::op_pow</code>
<td>
<code>pow(cpp_left, cpp_right)</code>
<tr>
@@ -368,7 +439,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left &lt;&lt; right</code>
<td>
<code>py::op_lshift</code>
<code>python::op_lshift</code>
<td>
<code>cpp_left &lt;&lt; cpp_right</code>
<tr>
@@ -377,7 +448,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left &gt;&gt; right</code>
<td>
<code>py::op_rshift</code>
<code>python::op_rshift</code>
<td>
<code>cpp_left &gt;&gt; cpp_right</code>
<tr>
@@ -386,7 +457,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left &amp; right</code>
<td>
<code>py::op_and</code>
<code>python::op_and</code>
<td>
<code>cpp_left &amp; cpp_right</code>
<tr>
@@ -395,7 +466,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left ^ right</code>
<td>
<code>py::op_xor</code>
<code>python::op_xor</code>
<td>
<code>cpp_left ^ cpp_right</code>
<tr>
@@ -404,7 +475,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>left | right</code>
<td>
<code>py::op_or</code>
<code>python::op_or</code>
<td>
<code>cpp_left | cpp_right</code>
<tr>
@@ -418,7 +489,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<code>left &gt;= right</code><br>
<code>left == right</code>
<td>
<code>py::op_cmp</code>
<code>python::op_cmp</code>
<td>
<code>cpp_left &lt; cpp_right&nbsp</code> and <code>&nbsp;cpp_right &lt; cpp_left</code>
<tr>
@@ -427,7 +498,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>-oper&nbsp</code> (unary negation)
<td>
<code>py::op_neg</code>
<code>python::op_neg</code>
<td>
<code>-cpp_oper</code>
<tr>
@@ -436,7 +507,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>+oper&nbsp</code> (identity)
<td>
<code>py::op_pos</code>
<code>python::op_pos</code>
<td>
<code>+cpp_oper</code>
<tr>
@@ -445,7 +516,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>abs(oper)&nbsp</code> (absolute value)
<td>
<code>py::op_abs</code>
<code>python::op_abs</code>
<td>
<code>abs(cpp_oper)</code>
<tr>
@@ -454,7 +525,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>~oper&nbsp</code> (bitwise inversion)
<td>
<code>py::op_invert</code>
<code>python::op_invert</code>
<td>
<code>~cpp_oper</code>
<tr>
@@ -463,7 +534,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>int(oper)&nbsp</code> (integer conversion)
<td>
<code>py::op_int</code>
<code>python::op_int</code>
<td>
<code>long(cpp_oper)</code>
<tr>
@@ -472,7 +543,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>long(oper)&nbsp</code><br> (infinite precision integer conversion)
<td>
<code>py::op_long</code>
<code>python::op_long</code>
<td>
<code>PyLong_FromLong(cpp_oper)</code>
<tr>
@@ -481,7 +552,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>float(oper)&nbsp</code> (float conversion)
<td>
<code>py::op_float</code>
<code>python::op_float</code>
<td>
<code>double(cpp_oper)</code>
<tr>
@@ -504,7 +575,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
<td>
<code>str(oper)&nbsp</code> (string conversion)
<td>
<code>py::op_str</code>
<code>python::op_str</code>
<td>
<code>std::ostringstream s; s &lt;&lt; oper;</code>
<tr>
@@ -521,11 +592,31 @@ Note that "__rrpow__" is an extension not present in plain Python.
<h2>Sequence and Mapping Operators</h2>
</a>
Sequence and mapping operators let wrapped objects behave in accordance to Python's iteration and access protocols. These protocols differ considerably from the ones found in C++. For example, Python's typically iteration idiom looks like &nbsp;"<code>for i in S:</code>"&nbsp;, while in C++ one uses &nbsp;"<code>for(iterator i = S.begin(); i != S.end(); ++i)</code>". One could try to wrap C++ iterators in order to carry the C++ idiom into Python. However, this does not work very well because (1) it leads to non-uniform Python code (wrapped types must be used in a different way than Python built-in types) and (2) iterators are often implemented as plain C++ pointers which cannot be wrapped easily because py_cpp is designed to handle objects only.
Sequence and mapping operators let wrapped objects behave in accordance to
Python's iteration and access protocols. These protocols differ considerably
from the ones found in C++. For example, Python's typically iteration idiom
looks like &nbsp;"<code>for i in S:</code>"&nbsp;, while in C++ one uses
&nbsp;"<code>for(iterator i = S.begin(); i != S.end(); ++i)</code>". One could
try to wrap C++ iterators in order to carry the C++ idiom into Python. However,
this does not work very well because (1) it leads to non-uniform Python code
(wrapped types must be used in a different way than Python built-in types) and
(2) iterators are often implemented as plain C++ pointers which cannot be
wrapped easily because py_cpp is designed to handle objects only.
<p>
Thus, it is a good idea to provide sequence and mapping operators for your wrapped containers. These operators have to be wrapped manually because there are no corresponding C++ operators that could be used for automatic wrapping. The Python documentation lists the relevant <a href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/sequence-types.html">container operators</a>. In particular, expose __getitem__, __setitem__ and remember to throw the <code>PyExc_IndexError</code> when the index is out-of-range in order to enable the &nbsp;"<code>for i in S:</code>"&nbsp; idiom.
Thus, it is a good idea to provide sequence and mapping operators for your
wrapped containers. These operators have to be wrapped manually because there
are no corresponding C++ operators that could be used for automatic
wrapping. The Python documentation lists the relevant <a
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/sequence-types.html">container
operators</a>. In particular, expose __getitem__, __setitem__ and remember to
throw the <code>PyExc_IndexError</code> when the index is out-of-range in order
to enable the &nbsp;"<code>for i in S:</code>"&nbsp; idiom.
<p>
Here is an example. Suppose you, we want to wrap a <code>std::map&lt;std::size_t,std::string&gt;</code>. This is done as follows as follows:
Here is an example. Suppose you, we want to wrap a
<code>std::map&lt;std::size_t,std::string&gt;</code>. This is done as follows as
follows:
<blockquote>
<pre>
@@ -540,8 +631,8 @@ void throw_key_error_if_end(
{
if (p == m.end())
{
PyErr_SetObject(PyExc_KeyError, py::converters::to_python(key));
throw py::ErrorAlreadySet();
PyErr_SetObject(PyExc_KeyError, python::converters::to_python(key));
throw python::error_already_set();
}
}
@@ -570,8 +661,8 @@ void StringMapPythonClass::del_item(StringMap&amp; self, std::size_t key)
self.erase(p);
}
ClassWrapper&lt;StringMap&gt; string_map(my_module, "StringMap");
string_map.def(py::Constructor&lt;&gt;());
class_builder&lt;StringMap&gt; string_map(my_module, "StringMap");
string_map.def(python::constructor&lt;&gt;());
string_map.def(&amp;StringMap::size, "__len__");
string_map.def(get_item, "__getitem__");
string_map.def(set_item, "__setitem__");
@@ -658,8 +749,8 @@ three
Py_cpp uses the special <code>
__xxxattr__<em>&lt;name&gt;</em>__</code> functionality described above
to allow direct access to data members through the following special
functions on <code>ClassWrapper&lt;&gt;</code> and <code>
ExtensionClass&lt;&gt;</code>:
functions on <code>class_builder&lt;&gt;</code> and <code>
extension_class&lt;&gt;</code>:
<ul>
<li>
<code>def_getter(<em>pointer-to-member</em>, <em>name</em>)</code> //
@@ -680,7 +771,7 @@ three
behavior. For example, when <code>def_getter()</code> is used, the
default functionality for <code>setattr()</code> and <code>
delattr()</code> remains in effect, operating on items in the extension
instance's name-space (i.e., its <code>__dict__</code>). For that
obj's name-space (i.e., its <code>__dict__</code>). For that
reason, you'll usually want to stick with <code>def_readonly</code> and
<code>def_read_write</code>.
<p>
@@ -695,9 +786,9 @@ long second(const Pil&amp; x) { return x.second; }
my_module.def(first, "first");
my_module.def(second, "second");
ClassWrapper&lt;Pil&gt; pair_int_long(my_module, "Pair");
pair_int_long.def(py::Constructor&lt;&gt;());
pair_int_long.def(py::Constructor&lt;int,long&gt;());
class_builder&lt;Pil&gt; pair_int_long(my_module, "Pair");
pair_int_long.def(python::constructor&lt;&gt;());
pair_int_long.def(python::constructor&lt;int,long&gt;());
pair_int_long.def_read_write(&amp;Pil::first, "first");
pair_int_long.def_read_write(&amp;Pil::second, "second");
</pre>
@@ -717,7 +808,7 @@ pair_int_long.def_read_write(&amp;Pil::second, "second");
&gt;&gt;&gt; x.second = 8
&gt;&gt;&gt; x.second
8
&gt;&gt;&gt; second(x) # Prove that we're not just changing the instance __dict__
&gt;&gt;&gt; second(x) # Prove that we're not just changing the obj __dict__
8
</pre>
</blockquote>

View File

@@ -14,22 +14,22 @@
#include <cstring>
#include "module.h"
namespace py {
namespace python {
namespace detail {
void enable_named_method(py::detail::ClassBase* type_object, const char* name);
void enable_named_method(python::detail::class_base* type_obj, const char* name);
}
namespace {
// Add the name of the module currently being loaded to the name_space with the
// key "__module__". If no module is being loaded, or if name_space already has
// a key "__module", has no effect. This is not really a useful public
// interface; it's just used for Class<>::Class() below.
void add_current_module_name(Dict&);
// interface; it's just used for class_t<>::class_t() below.
void add_current_module_name(dictionary&);
bool is_prefix(const char* s1, const char* s2);
bool is_special_name(const char* name);
void enable_special_methods(py::detail::ClassBase* derived, const Tuple& bases, const Dict& name_space);
void enable_special_methods(python::detail::class_base* derived, const tuple& bases, const dictionary& name_space);
void report_ignored_exception(PyObject* source)
{
@@ -65,53 +65,53 @@ namespace {
return PyObject_GetAttrString(klass, const_cast<char*>("__name__"));
}
Ptr global_class_reduce()
ref global_class_reduce()
{
static Ptr result(detail::new_wrapped_function(class_reduce));
static ref result(detail::new_wrapped_function(class_reduce));
return result;
}
Tuple instance_reduce(PyObject* instance)
tuple instance_reduce(PyObject* obj)
{
Ptr instance_class(PyObject_GetAttrString(instance, const_cast<char*>("__class__")));
ref instance_class(PyObject_GetAttrString(obj, const_cast<char*>("__class__")));
Ptr getinitargs(PyObject_GetAttrString(instance, const_cast<char*>("__getinitargs__")),
Ptr::null_ok);
ref getinitargs(PyObject_GetAttrString(obj, const_cast<char*>("__getinitargs__")),
ref::null_ok);
PyErr_Clear();
Ptr initargs;
ref initargs;
if (getinitargs.get() != 0)
{
initargs = Ptr(PyEval_CallObject(getinitargs.get(), NULL));
initargs = Ptr(PySequence_Tuple(initargs.get()));
initargs = ref(PyEval_CallObject(getinitargs.get(), NULL));
initargs = ref(PySequence_Tuple(initargs.get()));
}
else
{
initargs = Ptr(PyTuple_New(0));
initargs = ref(PyTuple_New(0));
}
Ptr getstate(PyObject_GetAttrString(instance, const_cast<char*>("__getstate__")),
Ptr::null_ok);
ref getstate(PyObject_GetAttrString(obj, const_cast<char*>("__getstate__")),
ref::null_ok);
PyErr_Clear();
if (getstate.get() != 0)
{
Ptr state = Ptr(PyEval_CallObject(getstate.get(), NULL));
return Tuple(instance_class, initargs, state);
ref state = ref(PyEval_CallObject(getstate.get(), NULL));
return tuple(instance_class, initargs, state);
}
Ptr state(PyObject_GetAttrString(instance, const_cast<char*>("__dict__")), Ptr::null_ok);
ref state(PyObject_GetAttrString(obj, const_cast<char*>("__dict__")), ref::null_ok);
PyErr_Clear();
if (state.get() != 0 && Dict(state).size() > 0)
if (state.get() != 0 && dictionary(state).size() > 0)
{
return Tuple(instance_class, initargs, state);
return tuple(instance_class, initargs, state);
}
return Tuple(instance_class, initargs);
return tuple(instance_class, initargs);
}
Ptr global_instance_reduce()
ref global_instance_reduce()
{
static Ptr result(detail::new_wrapped_function(instance_reduce));
static ref result(detail::new_wrapped_function(instance_reduce));
return result;
}
}
@@ -119,17 +119,17 @@ namespace {
namespace detail {
ClassBase::ClassBase(PyTypeObject* meta_class, String name, Tuple bases, const Dict& name_space)
: TypeObjectBase(meta_class),
class_base::class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space)
: type_object_base(meta_class_obj),
m_name(name),
m_bases(bases),
m_name_space(name_space)
{
this->tp_name = const_cast<char*>(name.c_str());
enable(TypeObjectBase::getattr);
enable(TypeObjectBase::setattr);
enable(type_object_base::getattr);
enable(type_object_base::setattr);
add_current_module_name(m_name_space);
static const py::String docstr("__doc__", py::String::interned);
static const python::string docstr("__doc__", python::string::interned);
if (PyDict_GetItem(m_name_space.get(), docstr.get())== 0)
{
PyDict_SetItem(m_name_space.get(), docstr.get(), Py_None);
@@ -137,32 +137,32 @@ namespace detail {
enable_special_methods(this, bases, name_space);
}
void ClassBase::add_base(Ptr base)
void class_base::add_base(ref base)
{
Tuple new_bases(m_bases.size() + 1);
tuple new_bases(m_bases.size() + 1);
for (std::size_t i = 0; i < m_bases.size(); ++i)
new_bases.set_item(i, m_bases[i]);
new_bases.set_item(m_bases.size(), base);
m_bases = new_bases;
}
PyObject* ClassBase::getattr(const char* name)
PyObject* class_base::getattr(const char* name)
{
if (!PY_CSTD_::strcmp(name, "__dict__"))
if (!BOOST_CSTD_::strcmp(name, "__dict__"))
{
PyObject* result = m_name_space.get();
Py_INCREF(result);
return result;
}
if (!PY_CSTD_::strcmp(name, "__bases__"))
if (!BOOST_CSTD_::strcmp(name, "__bases__"))
{
PyObject* result = m_bases.get();
Py_INCREF(result);
return result;
}
if (!PY_CSTD_::strcmp(name, "__name__"))
if (!BOOST_CSTD_::strcmp(name, "__name__"))
{
PyObject* result = m_name.get();
Py_INCREF(result);
@@ -170,17 +170,17 @@ namespace detail {
}
// pickle support courtesy of "Ralf W. Grosse-Kunstleve" <rwgk@cci.lbl.gov>
if (!PY_CSTD_::strcmp(name, "__safe_for_unpickling__"))
if (!BOOST_CSTD_::strcmp(name, "__safe_for_unpickling__"))
{
return PyInt_FromLong(1);
}
if (!PY_CSTD_::strcmp(name, "__reduce__"))
if (!BOOST_CSTD_::strcmp(name, "__reduce__"))
{
Ptr target(as_object(this), Ptr::new_ref);
return new BoundFunction(target, global_class_reduce());
ref target(as_object(this), ref::increment_count);
return new bound_function(target, global_class_reduce());
}
Ptr local_attribute = m_name_space.get_item(String(name).reference());
ref local_attribute = m_name_space.get_item(string(name).reference());
if (local_attribute.get())
return local_attribute.release();
@@ -203,7 +203,7 @@ namespace detail {
// Unwind the actual underlying function from unbound Python class
// methods in case of multiple inheritance from real Python
// classes. Python stubbornly insists that the first argument to a
// method must be a true Python Instance object otherwise. Do not
// method must be a true Python instance object otherwise. Do not
// unwrap bound methods; that would interfere with intended semantics.
if (PyMethod_Check(base_attribute)
&& reinterpret_cast<PyMethodObject*>(base_attribute)->im_self == 0)
@@ -224,27 +224,27 @@ namespace detail {
}
// Mostly copied wholesale from Python's classobject.c
PyObject* ClassBase::repr() const
PyObject* class_base::repr() const
{
PyObject *mod = PyDict_GetItemString(
m_name_space.get(), const_cast<char*>("__module__"));
unsigned long address = reinterpret_cast<unsigned long>(this);
String result = (mod == NULL || !PyString_Check(mod))
? String("<extension class %s at %lx>") % Tuple(m_name, address)
: String("<extension class %s.%s at %lx>") % Tuple(Ptr(mod, Ptr::borrowed), m_name, address);
string result = (mod == NULL || !PyString_Check(mod))
? string("<extension class %s at %lx>") % tuple(m_name, address)
: string("<extension class %s.%s at %lx>") % tuple(ref(mod, ref::increment_count), m_name, address);
return result.reference().release();
}
int ClassBase::setattr(const char* name, PyObject* value)
int class_base::setattr(const char* name, PyObject* value)
{
if (is_special_name(name)
&& PY_CSTD_::strcmp(name, "__doc__") != 0
&& PY_CSTD_::strcmp(name, "__name__") != 0)
&& BOOST_CSTD_::strcmp(name, "__doc__") != 0
&& BOOST_CSTD_::strcmp(name, "__name__") != 0)
{
py::String message("Special attribute names other than '__doc__' and '__name__' are read-only, in particular: ");
python::string message("Special attribute names other than '__doc__' and '__name__' are read-only, in particular: ");
PyErr_SetObject(PyExc_TypeError, (message + name).get());
throw ErrorAlreadySet();
throw error_already_set();
}
if (PyCallable_Check(value))
@@ -254,11 +254,11 @@ namespace detail {
m_name_space.reference().get(), const_cast<char*>(name), value);
}
bool ClassBase::initialize_instance(Instance* instance, PyObject* args, PyObject* keywords)
bool class_base::initialize_instance(instance* obj, PyObject* args, PyObject* keywords)
{
// Getting the init function off the instance should result in a
// Getting the init function off the obj should result in a
// bound method.
PyObject* const init_function = instance->getattr("__init__", false);
PyObject* const init_function = obj->getattr("__init__", false);
if (init_function == 0)
{
@@ -272,18 +272,18 @@ namespace detail {
else
{
// Manage the reference to the bound function
Ptr init_function_holder(init_function);
ref init_function_holder(init_function);
// Declare a Ptr to manage the result of calling __init__ (which should be None).
Ptr init_result(
// Declare a ref to manage the result of calling __init__ (which should be None).
ref init_result(
PyEval_CallObjectWithKeywords(init_function, args, keywords));
}
return true;
}
void ClassBase::instance_dealloc(PyObject* instance) const
void class_base::instance_dealloc(PyObject* obj) const
{
Py_INCREF(instance); // This allows a __del__ function to revive the instance
Py_INCREF(obj); // This allows a __del__ function to revive the obj
PyObject* exc_type;
PyObject* exc_value;
@@ -293,17 +293,17 @@ namespace detail {
// This scope ensures that the reference held by del_function doesn't release
// the last reference and delete the object recursively (infinitely).
{
Ptr del_function;
ref del_function;
try {
Instance* const target = py::Downcast<py::Instance>(instance);
del_function = Ptr(target->getattr("__del__", false), Ptr::null_ok);
instance* const target = python::downcast<python::instance>(obj);
del_function = ref(target->getattr("__del__", false), ref::null_ok);
}
catch(...) {
}
if (del_function.get() != 0)
{
Ptr result(PyEval_CallObject(del_function.get(), (PyObject *)NULL), Ptr::null_ok);
ref result(PyEval_CallObject(del_function.get(), (PyObject *)NULL), ref::null_ok);
if (result.get() == NULL)
report_ignored_exception(del_function.get());
@@ -311,25 +311,25 @@ namespace detail {
}
PyErr_Restore(exc_type, exc_value, exc_traceback);
if (--instance->ob_refcnt <= 0)
delete_instance(instance);
if (--obj->ob_refcnt <= 0)
delete_instance(obj);
}
}
Instance::Instance(PyTypeObject* class_)
: py::detail::BaseObject<PyObject>(class_)
instance::instance(PyTypeObject* class_)
: python::detail::base_object<PyObject>(class_)
{
}
Instance::~Instance()
instance::~instance()
{
}
PyObject* Instance::getattr(const char* name, bool use_special_function)
PyObject* instance::getattr(const char* name, bool use_special_function)
{
if (!PY_CSTD_::strcmp(name, "__dict__"))
if (!BOOST_CSTD_::strcmp(name, "__dict__"))
{
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
@@ -340,18 +340,18 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
return m_name_space.get();
}
if (!PY_CSTD_::strcmp(name, "__class__"))
if (!BOOST_CSTD_::strcmp(name, "__class__"))
{
Py_INCREF(this->ob_type);
return as_object(this->ob_type);
}
if (!PY_CSTD_::strcmp(name, "__reduce__"))
if (!BOOST_CSTD_::strcmp(name, "__reduce__"))
{
return new detail::BoundFunction(Ptr(this, Ptr::new_ref), global_instance_reduce());
return new detail::bound_function(ref(this, ref::increment_count), global_instance_reduce());
}
Ptr local_attribute = m_name_space.get_item(String(name).reference());
ref local_attribute = m_name_space.get_item(string(name).reference());
if (local_attribute.get())
return local_attribute.release();
@@ -365,11 +365,11 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
return 0;
}
Ptr class_attribute;
ref class_attribute;
if (function != 0)
{
// This will throw if the attribute wasn't found
class_attribute = Ptr(function);
class_attribute = ref(function);
}
else
{
@@ -379,7 +379,7 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
// First we try the special method that comes from concatenating
// "__getattr__" and <name> and 2 trailing underscores. This is an
// extension to regular Python class functionality.
const String specific_getattr_name(detail::getattr_string() + name + "__");
const string specific_getattr_name(detail::getattr_string() + name + "__");
PyObject* getattr_method = PyObject_GetAttr(
as_object(this->ob_type), specific_getattr_name.get());
@@ -405,7 +405,7 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
}
// Take ownership of the method
Ptr owner(getattr_method);
ref owner(getattr_method);
// Call it to get the attribute.
return PyEval_CallFunction(getattr_method, arg_format, this, name);
@@ -418,15 +418,15 @@ PyObject* Instance::getattr(const char* name, bool use_special_function)
}
else
{
return detail::BoundFunction::create(Ptr(this, Ptr::borrowed), class_attribute);
return detail::bound_function::create(ref(this, ref::increment_count), class_attribute);
}
}
// Instance::setattr_dict
// instance::setattr_dict
//
// Implements setattr() functionality for the "__dict__" attribute
//
int Instance::setattr_dict(PyObject* value)
int instance::setattr_dict(PyObject* value)
{
if (PyEval_GetRestricted())
{
@@ -441,35 +441,35 @@ int Instance::setattr_dict(PyObject* value)
"__dict__ must be set to a dictionary");
return -1;
}
m_name_space = Dict(Ptr(value, Ptr::borrowed));
m_name_space = dictionary(ref(value, ref::increment_count));
return 0;
}
// Instance::setattr -
// instance::setattr -
//
// Implements the setattr() and delattr() functionality for our own Instance
// Implements the setattr() and delattr() functionality for our own instance
// objects, using the standard Python interface: if value == 0, we are deleting
// the attribute, and returns 0 unless an error occurred.
int Instance::setattr(const char* name, PyObject* value)
int instance::setattr(const char* name, PyObject* value)
{
if (PY_CSTD_::strcmp(name, "__class__") == 0)
if (BOOST_CSTD_::strcmp(name, "__class__") == 0)
{
PyErr_SetString(PyExc_TypeError, "__class__ attribute is read-only");
throw ErrorAlreadySet();
throw error_already_set();
}
if (PY_CSTD_::strcmp(name, "__dict__") == 0)
if (BOOST_CSTD_::strcmp(name, "__dict__") == 0)
return setattr_dict(value);
// Try to find an appropriate "specific" setter or getter method, either
// __setattr__<name>__(value) or __delattr__<name>__(). This is an extension
// to regular Python class functionality.
const String& base_name = value ? detail::setattr_string() : detail::delattr_string();
const String specific_method_name(base_name + name + "__");
const string& base_name = value ? detail::setattr_string() : detail::delattr_string();
const string specific_method_name(base_name + name + "__");
Ptr special_method(
ref special_method(
PyObject_GetAttr(as_object(this->ob_type), specific_method_name.get()),
Ptr::null_ok);
ref::null_ok);
PyObject* result_object = 0;
if (special_method.get() != 0)
@@ -486,7 +486,7 @@ int Instance::setattr(const char* name, PyObject* value)
PyErr_Clear();
special_method.reset(
PyObject_GetAttr(as_object(this->ob_type), base_name.get()),
Ptr::null_ok);
ref::null_ok);
if (special_method.get() != 0)
{
@@ -501,7 +501,7 @@ int Instance::setattr(const char* name, PyObject* value)
// If we found an appropriate special method, handle the return value.
if (special_method.get() != 0)
{
Ptr manage_result(result_object);
ref manage_result(result_object);
return 0;
}
@@ -525,239 +525,239 @@ int Instance::setattr(const char* name, PyObject* value)
}
}
PyObject* Instance::call(PyObject* args, PyObject* keywords)
PyObject* instance::call(PyObject* args, PyObject* keywords)
{
return PyEval_CallObjectWithKeywords(
Ptr(getattr("__call__")).get(), // take possession of the result from getattr()
ref(getattr("__call__")).get(), // take possession of the result from getattr()
args, keywords);
}
PyObject* Instance::repr()
PyObject* instance::repr()
{
return Callback<PyObject*>::call_method(this, "__repr__");
return callback<PyObject*>::call_method(this, "__repr__");
}
int Instance::compare(PyObject* other)
int instance::compare(PyObject* other)
{
return Callback<int>::call_method(this, "__cmp__", other);
return callback<int>::call_method(this, "__cmp__", other);
}
PyObject* Instance::str()
PyObject* instance::str()
{
return Callback<PyObject*>::call_method(this, "__str__");
return callback<PyObject*>::call_method(this, "__str__");
}
long Instance::hash()
long instance::hash()
{
return Callback<long>::call_method(this, "__hash__");
return callback<long>::call_method(this, "__hash__");
}
int Instance::length()
int instance::length()
{
return Callback<int>::call_method(this, "__len__");
return callback<int>::call_method(this, "__len__");
}
PyObject* Instance::get_subscript(PyObject* key)
PyObject* instance::get_subscript(PyObject* key)
{
return Callback<PyObject*>::call_method(this, "__getitem__", key);
return callback<PyObject*>::call_method(this, "__getitem__", key);
}
void Instance::set_subscript(PyObject* key, PyObject* value)
void instance::set_subscript(PyObject* key, PyObject* value)
{
if (value == 0)
Callback<void>::call_method(this, "__delitem__", key);
callback<void>::call_method(this, "__delitem__", key);
else
Callback<void>::call_method(this, "__setitem__", key, value);
callback<void>::call_method(this, "__setitem__", key, value);
}
PyObject* Instance::get_slice(int start, int finish)
PyObject* instance::get_slice(int start, int finish)
{
return Callback<PyObject*>::call_method(this, "__getslice__", start, finish);
return callback<PyObject*>::call_method(this, "__getslice__", start, finish);
}
void Instance::set_slice(int start, int finish, PyObject* value)
void instance::set_slice(int start, int finish, PyObject* value)
{
if (value == 0)
Callback<void>::call_method(this, "__delslice__", start, finish);
callback<void>::call_method(this, "__delslice__", start, finish);
else
Callback<void>::call_method(this, "__setslice__", start, finish, value);
callback<void>::call_method(this, "__setslice__", start, finish, value);
}
PyObject* Instance::add(PyObject* other)
PyObject* instance::add(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__add__", other);
return callback<PyObject*>::call_method(this, "__add__", other);
}
PyObject* Instance::subtract(PyObject* other)
PyObject* instance::subtract(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__sub__", other);
return callback<PyObject*>::call_method(this, "__sub__", other);
}
PyObject* Instance::multiply(PyObject* other)
PyObject* instance::multiply(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__mul__", other);
return callback<PyObject*>::call_method(this, "__mul__", other);
}
PyObject* Instance::divide(PyObject* other)
PyObject* instance::divide(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__div__", other);
return callback<PyObject*>::call_method(this, "__div__", other);
}
PyObject* Instance::remainder(PyObject* other)
PyObject* instance::remainder(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__mod__", other);
return callback<PyObject*>::call_method(this, "__mod__", other);
}
PyObject* Instance::divmod(PyObject* other)
PyObject* instance::divmod(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__divmod__", other);
return callback<PyObject*>::call_method(this, "__divmod__", other);
}
PyObject* Instance::power(PyObject* exponent, PyObject* modulus)
PyObject* instance::power(PyObject* exponent, PyObject* modulus)
{
if (as_object(modulus->ob_type) == Py_None)
return Callback<PyObject*>::call_method(this, "__pow__", exponent);
return callback<PyObject*>::call_method(this, "__pow__", exponent);
else
return Callback<PyObject*>::call_method(this, "__pow__", exponent, modulus);
return callback<PyObject*>::call_method(this, "__pow__", exponent, modulus);
}
PyObject* Instance::negative()
PyObject* instance::negative()
{
return Callback<PyObject*>::call_method(this, "__neg__");
return callback<PyObject*>::call_method(this, "__neg__");
}
PyObject* Instance::positive()
PyObject* instance::positive()
{
return Callback<PyObject*>::call_method(this, "__pos__");
return callback<PyObject*>::call_method(this, "__pos__");
}
PyObject* Instance::absolute()
PyObject* instance::absolute()
{
return Callback<PyObject*>::call_method(this, "__abs__");
return callback<PyObject*>::call_method(this, "__abs__");
}
int Instance::nonzero()
int instance::nonzero()
{
return Callback<bool>::call_method(this, "__nonzero__");
return callback<bool>::call_method(this, "__nonzero__");
}
PyObject* Instance::invert()
PyObject* instance::invert()
{
return Callback<PyObject*>::call_method(this, "__invert__");
return callback<PyObject*>::call_method(this, "__invert__");
}
PyObject* Instance::lshift(PyObject* other)
PyObject* instance::lshift(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__lshift__", other);
return callback<PyObject*>::call_method(this, "__lshift__", other);
}
PyObject* Instance::rshift(PyObject* other)
PyObject* instance::rshift(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__rshift__", other);
return callback<PyObject*>::call_method(this, "__rshift__", other);
}
PyObject* Instance::do_and(PyObject* other)
PyObject* instance::do_and(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__and__", other);
return callback<PyObject*>::call_method(this, "__and__", other);
}
PyObject* Instance::do_xor(PyObject* other)
PyObject* instance::do_xor(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__xor__", other);
return callback<PyObject*>::call_method(this, "__xor__", other);
}
PyObject* Instance::do_or(PyObject* other)
PyObject* instance::do_or(PyObject* other)
{
return Callback<PyObject*>::call_method(this, "__or__", other);
return callback<PyObject*>::call_method(this, "__or__", other);
}
int Instance::coerce(PyObject** x, PyObject** y)
int instance::coerce(PyObject** x, PyObject** y)
{
assert(this == *x);
// Coerce must return a tuple
Tuple result(Callback<Tuple>::call_method(this, "__coerce__", *y));
tuple result(callback<tuple>::call_method(this, "__coerce__", *y));
*x = result[0].release();
*y = result[1].release();
return 0;
}
PyObject* Instance::as_int()
PyObject* instance::as_int()
{
return Callback<PyObject*>::call_method(this, "__int__");
return callback<PyObject*>::call_method(this, "__int__");
}
PyObject* Instance::as_long()
PyObject* instance::as_long()
{
return Callback<PyObject*>::call_method(this, "__long__");
return callback<PyObject*>::call_method(this, "__long__");
}
PyObject* Instance::as_float()
PyObject* instance::as_float()
{
return Callback<PyObject*>::call_method(this, "__float__");
return callback<PyObject*>::call_method(this, "__float__");
}
PyObject* Instance::oct()
PyObject* instance::oct()
{
return Callback<PyObject*>::call_method(this, "__oct__");
return callback<PyObject*>::call_method(this, "__oct__");
}
PyObject* Instance::hex()
PyObject* instance::hex()
{
return Callback<PyObject*>::call_method(this, "__hex__");
return callback<PyObject*>::call_method(this, "__hex__");
}
namespace {
struct NamedCapability
struct named_capability
{
const char* name;
detail::TypeObjectBase::Capability capability;
detail::type_object_base::capability capability;
};
const NamedCapability enablers[] =
const named_capability enablers[] =
{
{ "__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 }
{ "__hash__", detail::type_object_base::hash },
{ "__cmp__", detail::type_object_base::compare },
{ "__repr__", detail::type_object_base::repr },
{ "__str__", detail::type_object_base::str },
{ "__call__", detail::type_object_base::call },
{ "__getattr__", detail::type_object_base::getattr },
{ "__setattr__", detail::type_object_base::setattr },
{ "__len__", detail::type_object_base::mapping_length },
{ "__len__", detail::type_object_base::sequence_length },
{ "__getitem__", detail::type_object_base::mapping_subscript },
{ "__getitem__", detail::type_object_base::sequence_item },
{ "__setitem__", detail::type_object_base::mapping_ass_subscript },
{ "__setitem__", detail::type_object_base::sequence_ass_item },
{ "__delitem__", detail::type_object_base::mapping_ass_subscript },
{ "__delitem__", detail::type_object_base::sequence_ass_item },
{ "__getslice__", detail::type_object_base::sequence_slice },
{ "__setslice__", detail::type_object_base::sequence_ass_slice },
{ "__delslice__", detail::type_object_base::sequence_ass_slice },
{ "__add__", detail::type_object_base::number_add },
{ "__sub__", detail::type_object_base::number_subtract },
{ "__mul__", detail::type_object_base::number_multiply },
{ "__div__", detail::type_object_base::number_divide },
{ "__mod__", detail::type_object_base::number_remainder },
{ "__divmod__", detail::type_object_base::number_divmod },
{ "__pow__", detail::type_object_base::number_power },
{ "__neg__", detail::type_object_base::number_negative },
{ "__pos__", detail::type_object_base::number_positive },
{ "__abs__", detail::type_object_base::number_absolute },
{ "__nonzero__", detail::type_object_base::number_nonzero },
{ "__invert__", detail::type_object_base::number_invert },
{ "__lshift__", detail::type_object_base::number_lshift },
{ "__rshift__", detail::type_object_base::number_rshift },
{ "__and__", detail::type_object_base::number_and },
{ "__xor__", detail::type_object_base::number_xor },
{ "__or__", detail::type_object_base::number_or },
{ "__coerce__", detail::type_object_base::number_coerce },
{ "__int__", detail::type_object_base::number_int },
{ "__long__", detail::type_object_base::number_long },
{ "__float__", detail::type_object_base::number_float },
{ "__oct__", detail::type_object_base::number_oct },
{ "__hex__", detail::type_object_base::number_hex }
};
bool is_prefix(const char* s1, const char* s2)
@@ -772,14 +772,14 @@ namespace {
if (name[0] != '_' || name[1] != '_' || name[2] == 0 || name[3] == 0)
return false;
std::size_t name_length = PY_CSTD_::strlen(name);
std::size_t name_length = BOOST_CSTD_::strlen(name);
return name[name_length - 1] == '_' && name[name_length - 2] == '_';
}
}
namespace detail {
// Enable the special handler for methods of the given name, if any.
void enable_named_method(py::detail::ClassBase* type_object, const char* name)
void enable_named_method(python::detail::class_base* type_obj, const char* name)
{
const std::size_t num_enablers = sizeof(enablers) / sizeof(enablers[0]);
@@ -793,7 +793,7 @@ namespace detail {
{
if (is_prefix(enablers[i].name + 2, name + 2))
{
type_object->enable(enablers[i].capability);
type_obj->enable(enablers[i].capability);
}
}
}
@@ -801,7 +801,7 @@ namespace detail {
namespace {
// Enable any special methods which are enabled in the base class.
void enable_special_methods(py::detail::ClassBase* derived, const Tuple& bases, const Dict& name_space)
void enable_special_methods(python::detail::class_base* derived, const tuple& bases, const dictionary& name_space)
{
for (std::size_t i = 0; i < bases.size(); ++i)
{
@@ -809,19 +809,19 @@ namespace {
for (std::size_t n = 0; n < PY_ARRAY_LENGTH(enablers); ++n)
{
Ptr attribute(
ref attribute(
PyObject_GetAttrString(base, const_cast<char*>(enablers[n].name)),
Ptr::null_ok);
ref::null_ok);
PyErr_Clear();
if (attribute.get() != 0 && PyCallable_Check(attribute.get()))
detail::add_capability(enablers[n].capability, derived);
}
}
List keys(name_space.keys());
list keys(name_space.keys());
for (std::size_t j = 0, len = keys.size(); j < len; ++j)
{
String name_obj(keys.get_item(j));
string name_obj(keys.get_item(j));
const char* name = name_obj.c_str();
if (!is_special_name(name))
@@ -837,16 +837,16 @@ namespace {
}
}
void add_current_module_name(Dict& name_space)
void add_current_module_name(dictionary& name_space)
{
static String module_key("__module__", String::interned);
name_space.set_item(module_key, Module::name());
static string module_key("__module__", string::interned);
name_space.set_item(module_key, module_builder::name());
}
}
void adjust_slice_indices(PyObject* instance, int& start, int& finish)
void adjust_slice_indices(PyObject* obj, int& start, int& finish)
{
int length = Callback<int>::call_method(instance, "__len__");
int length = callback<int>::call_method(obj, "__len__");
// This is standard Python class behavior.
if (start < 0)
@@ -862,23 +862,23 @@ void adjust_slice_indices(PyObject* instance, int& start, int& finish)
}
namespace detail {
const String& setattr_string()
const string& setattr_string()
{
static String x("__setattr__", String::interned);
static string x("__setattr__", string::interned);
return x;
}
const String& getattr_string()
const string& getattr_string()
{
static String x("__getattr__", String::interned);
static string x("__getattr__", string::interned);
return x;
}
const String& delattr_string()
const string& delattr_string()
{
static String x("__delattr__", String::interned);
static string x("__delattr__", string::interned);
return x;
}
}
} // namespace py
} // namespace python

View File

@@ -17,15 +17,15 @@
# include "py.h"
# include "callback.h"
namespace py {
namespace python {
// A simple type which acts something like a built-in Python class instance.
class Instance
: public py::detail::PythonObject
// A simple type which acts something like a built-in Python class obj.
class instance
: public python::detail::python_object
{
public:
Instance(PyTypeObject* class_);
~Instance();
instance(PyTypeObject* class_);
~instance();
// Standard Python functions.
PyObject* repr();
@@ -71,60 +71,60 @@ class Instance
PyObject* hex();
private: // noncopyable, without the size bloat
Instance(const Instance&);
void operator=(const Instance&);
instance(const instance&);
void operator=(const instance&);
private: // helper functions
int setattr_dict(PyObject* value);
private:
Dict m_name_space;
dictionary m_name_space;
};
template <class T> class MetaClass;
template <class T> class meta_class;
namespace detail {
class ClassBase : public TypeObjectBase
class class_base : public type_object_base
{
public:
ClassBase(PyTypeObject* meta_class, String name, Tuple bases, const Dict& name_space);
Tuple bases() const;
String name() const;
Dict& dict();
class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space);
tuple bases() const;
string name() const;
dictionary& dict();
// Standard Python functions.
PyObject* getattr(const char* name);
int setattr(const char* name, PyObject* value);
PyObject* repr() const;
void add_base(Ptr base);
void add_base(ref base);
protected:
bool initialize_instance(Instance* instance, PyObject* args, PyObject* keywords);
bool initialize_instance(instance* obj, PyObject* args, PyObject* keywords);
private: // virtual functions
// Subclasses should override this to delete the particular instance type
// Subclasses should override this to delete the particular obj type
virtual void delete_instance(PyObject*) const = 0;
private: // py::TypeObjectBase required interface implementation
private: // python::type_object_base required interface implementation
void instance_dealloc(PyObject*) const; // subclasses should not override this
private:
String m_name;
Tuple m_bases;
Dict m_name_space;
string m_name;
tuple m_bases;
dictionary m_name_space;
};
void enable_named_method(ClassBase* type_object, const char* name);
void enable_named_method(class_base* type_obj, const char* name);
}
// A type which acts a lot like a built-in Python class. T is the instance type,
// so Class<Instance> is a very simple "class-alike".
// A type which acts a lot like a built-in Python class. T is the obj type,
// so class_t<instance> is a very simple "class-alike".
template <class T>
class Class
: public py::detail::ClassBase
class class_t
: public python::detail::class_base
{
public:
Class(MetaClass<T>* meta_class, String name, Tuple bases, const Dict& name_space);
class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space);
// Standard Python functions.
PyObject* call(PyObject* args, PyObject* keywords);
@@ -140,8 +140,8 @@ class Class
private: // Implement sequence methods on instances
int instance_sequence_length(PyObject*) const;
PyObject* instance_sequence_item(PyObject* instance, int n) const;
int instance_sequence_ass_item(PyObject* instance, int n, PyObject* value) const;
PyObject* instance_sequence_item(PyObject* obj, int n) const;
int instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const;
PyObject* instance_sequence_slice(PyObject*, int start, int finish) const;
int instance_sequence_ass_slice(PyObject*, int start, int finish, PyObject* value) const;
@@ -171,40 +171,40 @@ class Class
PyObject* instance_number_hex(PyObject*) const;
private: // Miscellaneous "special" methods
PyObject* instance_call(PyObject* instance, PyObject* args, PyObject* keywords) const;
PyObject* instance_getattr(PyObject* instance, const char* name) const;
int instance_setattr(PyObject* instance, const char* name, PyObject* value) const;
PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const;
PyObject* instance_getattr(PyObject* obj, const char* name) const;
int instance_setattr(PyObject* obj, const char* name, PyObject* value) const;
private: // Implementation of py::detail::ClassBase required interface
private: // Implementation of python::detail::class_base required interface
void delete_instance(PyObject*) const;
private: // noncopyable, without the size bloat
Class(const Class<T>&);
void operator=(const Class&);
class_t(const class_t<T>&);
void operator=(const class_t&);
};
// The type of a Class<T> object.
// The type of a class_t<T> object.
template <class T>
class MetaClass
: public py::detail::Reprable<
py::detail::Callable<
py::detail::Getattrable<
py::detail::Setattrable<
py::detail::TypeObject<Class<T> > > > > >,
class meta_class
: public python::detail::reprable<
python::detail::callable<
python::detail::getattrable<
python::detail::setattrable<
python::detail::type_object<class_t<T> > > > > >,
boost::noncopyable
{
public:
MetaClass();
meta_class();
// Standard Python functions.
PyObject* call(PyObject* args, PyObject* keywords);
struct TypeObject
: py::detail::Singleton<TypeObject,
py::detail::Callable<
py::detail::TypeObject<MetaClass> > >
struct type_object
: python::detail::singleton<type_object,
python::detail::callable<
python::detail::type_object<meta_class> > >
{
TypeObject() : SingletonBase(&PyType_Type) {}
type_object() : singleton_base(&PyType_Type) {}
};
};
@@ -212,27 +212,27 @@ class MetaClass
// Member function implementations.
//
template <class T>
MetaClass<T>::MetaClass()
: Properties(TypeObject::singleton())
meta_class<T>::meta_class()
: properties(type_object::instance())
{
}
template <class T>
Class<T>::Class(MetaClass<T>* meta_class, String name, Tuple bases, const Dict& name_space)
: py::detail::ClassBase(meta_class, name, bases, name_space)
class_t<T>::class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space)
: python::detail::class_base(meta_class_obj, name, bases, name_space)
{
}
template <class T>
void Class<T>::delete_instance(PyObject* instance) const
void class_t<T>::delete_instance(PyObject* obj) const
{
delete Downcast<T>(instance);
delete downcast<T>(obj);
}
template <class T>
PyObject* Class<T>::call(PyObject* args, PyObject* keywords)
PyObject* class_t<T>::call(PyObject* args, PyObject* keywords)
{
PyPtr<T> result(new T(this));
reference<T> result(new T(this));
if (!this->initialize_instance(result.get(), args, keywords))
return 0;
else
@@ -240,257 +240,257 @@ PyObject* Class<T>::call(PyObject* args, PyObject* keywords)
}
template <class T>
PyObject* Class<T>::instance_repr(PyObject* instance) const
PyObject* class_t<T>::instance_repr(PyObject* obj) const
{
return Downcast<T>(instance)->repr();
return downcast<T>(obj)->repr();
}
template <class T>
int Class<T>::instance_compare(PyObject* instance, PyObject* other) const
int class_t<T>::instance_compare(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->compare(other);
return downcast<T>(obj)->compare(other);
}
template <class T>
PyObject* Class<T>::instance_str(PyObject* instance) const
PyObject* class_t<T>::instance_str(PyObject* obj) const
{
return Downcast<T>(instance)->str();
return downcast<T>(obj)->str();
}
template <class T>
long Class<T>::instance_hash(PyObject* instance) const
long class_t<T>::instance_hash(PyObject* obj) const
{
return Downcast<T>(instance)->hash();
return downcast<T>(obj)->hash();
}
template <class T>
int Class<T>::instance_mapping_length(PyObject* instance) const
int class_t<T>::instance_mapping_length(PyObject* obj) const
{
return Downcast<T>(instance)->length();
return downcast<T>(obj)->length();
}
template <class T>
int Class<T>::instance_sequence_length(PyObject* instance) const
int class_t<T>::instance_sequence_length(PyObject* obj) const
{
return Downcast<T>(instance)->length();
return downcast<T>(obj)->length();
}
template <class T>
PyObject* Class<T>::instance_mapping_subscript(PyObject* instance, PyObject* key) const
PyObject* class_t<T>::instance_mapping_subscript(PyObject* obj, PyObject* key) const
{
return Downcast<T>(instance)->get_subscript(key);
return downcast<T>(obj)->get_subscript(key);
}
template <class T>
PyObject* Class<T>::instance_sequence_item(PyObject* instance, int n) const
PyObject* class_t<T>::instance_sequence_item(PyObject* obj, int n) const
{
Ptr key(to_python(n));
return Downcast<T>(instance)->get_subscript(key.get());
ref key(to_python(n));
return downcast<T>(obj)->get_subscript(key.get());
}
template <class T>
int Class<T>::instance_sequence_ass_item(PyObject* instance, int n, PyObject* value) const
int class_t<T>::instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const
{
Ptr key(to_python(n));
Downcast<T>(instance)->set_subscript(key.get(), value);
ref key(to_python(n));
downcast<T>(obj)->set_subscript(key.get(), value);
return 0;
}
template <class T>
int Class<T>::instance_mapping_ass_subscript(PyObject* instance, PyObject* key, PyObject* value) const
int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyObject* value) const
{
Downcast<T>(instance)->set_subscript(key, value);
downcast<T>(obj)->set_subscript(key, value);
return 0;
}
void adjust_slice_indices(PyObject* instance, int& start, int& finish);
void adjust_slice_indices(PyObject* obj, int& start, int& finish);
template <class T>
PyObject* Class<T>::instance_sequence_slice(PyObject* instance, int start, int finish) const
PyObject* class_t<T>::instance_sequence_slice(PyObject* obj, int start, int finish) const
{
adjust_slice_indices(instance, start, finish);
return Downcast<T>(instance)->get_slice(start, finish);
adjust_slice_indices(obj, start, finish);
return downcast<T>(obj)->get_slice(start, finish);
}
template <class T>
int Class<T>::instance_sequence_ass_slice(PyObject* instance, int start, int finish, PyObject* value) const
int class_t<T>::instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const
{
adjust_slice_indices(instance, start, finish);
Downcast<T>(instance)->set_slice(start, finish, value);
adjust_slice_indices(obj, start, finish);
downcast<T>(obj)->set_slice(start, finish, value);
return 0;
}
template <class T>
PyObject* Class<T>::instance_call(PyObject* instance, PyObject* args, PyObject* keywords) const
PyObject* class_t<T>::instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const
{
return Downcast<T>(instance)->call(args, keywords);
return downcast<T>(obj)->call(args, keywords);
}
template <class T>
PyObject* Class<T>::instance_getattr(PyObject* instance, const char* name) const
PyObject* class_t<T>::instance_getattr(PyObject* obj, const char* name) const
{
return Downcast<T>(instance)->getattr(name);
return downcast<T>(obj)->getattr(name);
}
template <class T>
int Class<T>::instance_setattr(PyObject* instance, const char* name, PyObject* value) const
int class_t<T>::instance_setattr(PyObject* obj, const char* name, PyObject* value) const
{
return Downcast<T>(instance)->setattr(name, value);
return downcast<T>(obj)->setattr(name, value);
}
template <class T>
PyObject* Class<T>::instance_number_add(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_add(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->add(other);
return downcast<T>(obj)->add(other);
}
template <class T>
PyObject* Class<T>::instance_number_subtract(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_subtract(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->subtract(other);
return downcast<T>(obj)->subtract(other);
}
template <class T>
PyObject* Class<T>::instance_number_multiply(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_multiply(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->multiply(other);
return downcast<T>(obj)->multiply(other);
}
template <class T>
PyObject* Class<T>::instance_number_divide(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_divide(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->divide(other);
return downcast<T>(obj)->divide(other);
}
template <class T>
PyObject* Class<T>::instance_number_remainder(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_remainder(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->remainder(other);
return downcast<T>(obj)->remainder(other);
}
template <class T>
PyObject* Class<T>::instance_number_divmod(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_divmod(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->divmod(other);
return downcast<T>(obj)->divmod(other);
}
template <class T>
PyObject* Class<T>::instance_number_power(PyObject* instance, PyObject* exponent, PyObject* modulus) const
PyObject* class_t<T>::instance_number_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const
{
return Downcast<T>(instance)->power(exponent, modulus);
return downcast<T>(obj)->power(exponent, modulus);
}
template <class T>
PyObject* Class<T>::instance_number_negative(PyObject* instance) const
PyObject* class_t<T>::instance_number_negative(PyObject* obj) const
{
return Downcast<T>(instance)->negative();
return downcast<T>(obj)->negative();
}
template <class T>
PyObject* Class<T>::instance_number_positive(PyObject* instance) const
PyObject* class_t<T>::instance_number_positive(PyObject* obj) const
{
return Downcast<T>(instance)->positive();
return downcast<T>(obj)->positive();
}
template <class T>
PyObject* Class<T>::instance_number_absolute(PyObject* instance) const
PyObject* class_t<T>::instance_number_absolute(PyObject* obj) const
{
return Downcast<T>(instance)->absolute();
return downcast<T>(obj)->absolute();
}
template <class T>
int Class<T>::instance_number_nonzero(PyObject* instance) const
int class_t<T>::instance_number_nonzero(PyObject* obj) const
{
return Downcast<T>(instance)->nonzero();
return downcast<T>(obj)->nonzero();
}
template <class T>
PyObject* Class<T>::instance_number_invert(PyObject* instance) const
PyObject* class_t<T>::instance_number_invert(PyObject* obj) const
{
return Downcast<T>(instance)->invert();
return downcast<T>(obj)->invert();
}
template <class T>
PyObject* Class<T>::instance_number_lshift(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_lshift(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->lshift(other);
return downcast<T>(obj)->lshift(other);
}
template <class T>
PyObject* Class<T>::instance_number_rshift(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_rshift(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->rshift(other);
return downcast<T>(obj)->rshift(other);
}
template <class T>
PyObject* Class<T>::instance_number_and(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_and(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->do_and(other);
return downcast<T>(obj)->do_and(other);
}
template <class T>
PyObject* Class<T>::instance_number_xor(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_xor(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->do_xor(other);
return downcast<T>(obj)->do_xor(other);
}
template <class T>
PyObject* Class<T>::instance_number_or(PyObject* instance, PyObject* other) const
PyObject* class_t<T>::instance_number_or(PyObject* obj, PyObject* other) const
{
return Downcast<T>(instance)->do_or(other);
return downcast<T>(obj)->do_or(other);
}
template <class T>
int Class<T>::instance_number_coerce(PyObject* instance, PyObject** x, PyObject** y) const
int class_t<T>::instance_number_coerce(PyObject* obj, PyObject** x, PyObject** y) const
{
return Downcast<T>(instance)->coerce(x, y);
return downcast<T>(obj)->coerce(x, y);
}
template <class T>
PyObject* Class<T>::instance_number_int(PyObject* instance) const
PyObject* class_t<T>::instance_number_int(PyObject* obj) const
{
return Downcast<T>(instance)->as_int();
return downcast<T>(obj)->as_int();
}
template <class T>
PyObject* Class<T>::instance_number_long(PyObject* instance) const
PyObject* class_t<T>::instance_number_long(PyObject* obj) const
{
return Downcast<T>(instance)->as_long();
return downcast<T>(obj)->as_long();
}
template <class T>
PyObject* Class<T>::instance_number_float(PyObject* instance) const
PyObject* class_t<T>::instance_number_float(PyObject* obj) const
{
return Downcast<T>(instance)->as_float();
return downcast<T>(obj)->as_float();
}
template <class T>
PyObject* Class<T>::instance_number_oct(PyObject* instance) const
PyObject* class_t<T>::instance_number_oct(PyObject* obj) const
{
return Downcast<T>(instance)->oct();
return downcast<T>(obj)->oct();
}
template <class T>
PyObject* Class<T>::instance_number_hex(PyObject* instance) const
PyObject* class_t<T>::instance_number_hex(PyObject* obj) const
{
return Downcast<T>(instance)->hex();
return downcast<T>(obj)->hex();
}
namespace detail {
inline Dict& ClassBase::dict()
inline dictionary& class_base::dict()
{
return m_name_space;
}
inline Tuple ClassBase::bases() const
inline tuple class_base::bases() const
{
return m_bases;
}
}
template <class T>
PyObject* MetaClass<T>::call(PyObject* args, PyObject* /*keywords*/)
PyObject* meta_class<T>::call(PyObject* args, PyObject* /*keywords*/)
{
PyObject* name;
PyObject* bases;
@@ -505,23 +505,23 @@ PyObject* MetaClass<T>::call(PyObject* args, PyObject* /*keywords*/)
}
return as_object(
new Class<T>(this, String(Ptr(name, Ptr::borrowed)),
Tuple(Ptr(bases, Ptr::borrowed)),
Dict(Ptr(name_space, Ptr::borrowed)))
new class_t<T>(this, string(ref(name, ref::increment_count)),
tuple(ref(bases, ref::increment_count)),
dictionary(ref(name_space, ref::increment_count)))
);
}
namespace detail {
const String& setattr_string();
const String& getattr_string();
const String& delattr_string();
const string& setattr_string();
const string& getattr_string();
const string& delattr_string();
inline String ClassBase::name() const
inline string class_base::name() const
{
return m_name;
}
}
} // namespace py
} // namespace python
#endif

View File

@@ -166,7 +166,7 @@ But objects not derived from Bar cannot:
TypeError: extension class 'Baz' is not convertible into 'Bar'.
The clone function on Baz returns a smart pointer; we wrap it into an
ExtensionInstance and make it look just like any other Baz instance.
extension_instance and make it look just like any other Baz obj.
>>> baz_clone = baz.clone()
>>> baz_clone.pass_bar(mi).first()
@@ -403,7 +403,7 @@ delete non-existent attribute:
del m.foobar
Traceback (innermost last):
File "<stdin>", line 1, in ?
AttributeError: delete non-existing instance attribute
AttributeError: delete non-existing obj attribute
Testing __getattr__ and __getattr__<name>:

View File

@@ -11,10 +11,10 @@
A Peek Under the Hood
</h1>
<p>
<code> ExtensionClass&lt;T&gt;</code> is a subclass of <code>
<code> extension_class&lt;T&gt;</code> is a subclass of <code>
PyTypeObject</code>, the <code> struct</code> which Python's 'C' API uses
to describe a type. <a href="example1.html#world_class">An instance of
the <code>ExtensionClass&lt;&gt;</code></a> becomes the Python type
to describe a type. <a href="example1.html#world_class">An obj of
the <code>extension_class&lt;&gt;</code></a> becomes the Python type
object corresponding to <code>hello::world</code>. When we <a href=
"example1.html#add_world_class">add it to the module</a> it goes into the
module's dictionary to be looked up under the name "world".
@@ -26,10 +26,10 @@
overloaded functions <code>PyObject*
to_python(</code><em>S</em><code>)</code> and <em>
S'</em><code>from_python(PyObject*,
Type&lt;</code><em>S</em><code>&gt;)</code> which convert between any C++
type&lt;</code><em>S</em><code>&gt;)</code> which convert between any C++
type <em>S</em> and a <code>PyObject*</code>, the type which represents a
reference to any Python object in its 'C' API. The <a href=
"example1.html#world_class"><code>ExtensionClass&lt;T&gt;</code></a>
"example1.html#world_class"><code>extension_class&lt;T&gt;</code></a>
template defines a whole raft of these conversions (for <code>T, T*,
T&amp;, std::auto_ptr&lt;T&gt;</code>, etc.), using the same inline
friend function technique employed by <a href=
@@ -38,15 +38,15 @@
<p>
Because the <code>to_python</code> and <code>from_python</code> functions
for a user-defined class are defined by <code>
ExtensionClass&lt;T&gt;</code>, it is important that an instantiation of
<code> ExtensionClass&lt;T&gt;</code> is visible to any code which wraps
extension_class&lt;T&gt;</code>, it is important that an instantiation of
<code> extension_class&lt;T&gt;</code> is visible to any code which wraps
a C++ function with a <code>T, T*, const T&amp;</code>, etc. parameter or
return value. In particular, you may want to create all of the classes at
the top of your module's init function, then <code>def</code> the member
functions later to avoid problems with inter-class dependencies.
<p>
Previous: <a href="overriding.html">Function Overloading</a>
Next: <a href="building.html">Building a Module with Py_cpp</a>
Previous: <a href="overriding.html">function Overloading</a>
Next: <a href="building.html">Building a module_builder with Py_cpp</a>
Up: <a href="py_cpp.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,