mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
Compare commits
6 Commits
svn-branch
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2a7dfef5a | ||
|
|
a49bc99b94 | ||
|
|
56287c49ca | ||
|
|
e5ec0d0c71 | ||
|
|
3dcb1c7e98 | ||
|
|
8fc12312b3 |
@@ -1,44 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Building an Extension Module
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Building an Extension Module
|
||||
</h1>
|
||||
<p>
|
||||
Right now, the only supported configuration is one in which the BPL
|
||||
source files are statically linked with the source for your extension
|
||||
module. You may first build them into a library and link it with your
|
||||
extension module source, but the effect is the same as compiling all
|
||||
the source files together. Some users have successfully built the
|
||||
sources into a shared library, and support for a shared library
|
||||
build is planned, but not yet implemented. The BPL source files are:
|
||||
<blockquote>
|
||||
<pre>
|
||||
<a href="../../../libs/python/src/extension_class.cpp">extclass.cpp</a>
|
||||
<a href="../../../libs/python/src/functions.cpp">functions.cpp</a>
|
||||
<a href="../../../libs/python/src/init_function.cpp">init_function.cpp</a>
|
||||
<a href="../../../libs/python/src/module_builder.cpp">module.cpp</a>
|
||||
<a href="../../../libs/python/src/types.cpp">newtypes.cpp</a>
|
||||
<a href="../../../libs/python/src/objects.cpp">objects.cpp</a>
|
||||
<a href="../../../libs/python/src/conversions.cpp">py.cpp</a>
|
||||
<a href="../../../libs/python/src/classes.cpp">subclass.cpp</a>
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Next: <a href="enums.html">Enums</a>
|
||||
Previous: <a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as
|
||||
is'' without express or implied warranty, and with no claim as to
|
||||
its suitability for any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
</div>
|
||||
|
||||
@@ -1,829 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
//
|
||||
// This file was generated for 10-argument python callbacks by gen_callback.python
|
||||
|
||||
#ifndef CALLBACK_DWA_052100_H_
|
||||
# define CALLBACK_DWA_052100_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/conversions.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail {
|
||||
template <class T>
|
||||
inline void callback_adjust_refcount(PyObject*, type<T>) {}
|
||||
|
||||
inline void callback_adjust_refcount(PyObject* p, type<PyObject*>)
|
||||
{ Py_INCREF(p); }
|
||||
}
|
||||
|
||||
// Calling Python from C++
|
||||
template <class R>
|
||||
struct callback
|
||||
{
|
||||
static R call_method(PyObject* self, const char* name)
|
||||
{
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("()")));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
static R call(PyObject* self)
|
||||
{
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("()")));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static R call(PyObject* self, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static R call_method(PyObject* self, const char* name, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static R call(PyObject* self, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static R call_method(PyObject* self, const char* name, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get(),
|
||||
p10.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static R call(PyObject* self, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get(),
|
||||
p10.get()));
|
||||
detail::callback_adjust_refcount(result.get(), type<R>());
|
||||
return from_python(result.get(), type<R>());
|
||||
}
|
||||
};
|
||||
|
||||
// This specialization wouldn't be needed, but MSVC6 doesn't correctly allow the following:
|
||||
// void g();
|
||||
// void f() { return g(); }
|
||||
template <>
|
||||
struct callback<void>
|
||||
{
|
||||
|
||||
static void call_method(PyObject* self, const char* name)
|
||||
{
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("()")));
|
||||
}
|
||||
|
||||
static void call(PyObject* self)
|
||||
{
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("()")));
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
static void call(PyObject* self, const A1& a1)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(O)"),
|
||||
p1.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OO)"),
|
||||
p1.get(),
|
||||
p2.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static void call_method(PyObject* self, const char* name, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static void call(PyObject* self, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static void call_method(PyObject* self, const char* name, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref result(PyEval_CallMethod(self, const_cast<char*>(name),
|
||||
const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get(),
|
||||
p10.get()));
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
|
||||
static void call(PyObject* self, 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)
|
||||
{
|
||||
ref p1(to_python(a1));
|
||||
ref p2(to_python(a2));
|
||||
ref p3(to_python(a3));
|
||||
ref p4(to_python(a4));
|
||||
ref p5(to_python(a5));
|
||||
ref p6(to_python(a6));
|
||||
ref p7(to_python(a7));
|
||||
ref p8(to_python(a8));
|
||||
ref p9(to_python(a9));
|
||||
ref p10(to_python(a10));
|
||||
ref result(PyEval_CallFunction(self, const_cast<char*>("(OOOOOOOOOO)"),
|
||||
p1.get(),
|
||||
p2.get(),
|
||||
p3.get(),
|
||||
p4.get(),
|
||||
p5.get(),
|
||||
p6.get(),
|
||||
p7.get(),
|
||||
p8.get(),
|
||||
p9.get(),
|
||||
p10.get()));
|
||||
}
|
||||
};
|
||||
|
||||
// Make it a compile-time error to try to return a const char* from a virtual
|
||||
// function. The standard conversion
|
||||
//
|
||||
// from_python(PyObject* string, boost::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
|
||||
// (boost::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
|
||||
//
|
||||
// boost::python::string result(boost::python::callback<boost::python::string>::call[_method](...args...));
|
||||
// ...result.c_str()... // access the char* array
|
||||
template <>
|
||||
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 boost::python
|
||||
|
||||
#endif // CALLBACK_DWA_052100_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,176 +0,0 @@
|
||||
#ifndef CLASS_WRAPPER_DWA101000_H_
|
||||
# define CLASS_WRAPPER_DWA101000_H_
|
||||
|
||||
#include <boost/python/detail/extension_class.hpp>
|
||||
#include <boost/python/operators.hpp>
|
||||
#include <boost/python/module_builder.hpp>
|
||||
#include <boost/python/conversions.hpp>
|
||||
#include <boost/python/detail/cast.hpp>
|
||||
#include <boost/python/reference.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// Syntactic sugar to make wrapping classes more convenient
|
||||
template <class T, class U = detail::held_instance<T> >
|
||||
class class_builder
|
||||
: python_extension_class_converters<T, U> // Works around MSVC6.x/GCC2.95.2 bug described below
|
||||
{
|
||||
public:
|
||||
class_builder(module_builder& module, const char* name)
|
||||
: m_class(new detail::extension_class<T, U>(name))
|
||||
{
|
||||
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
|
||||
}
|
||||
|
||||
~class_builder()
|
||||
{}
|
||||
|
||||
// define constructors
|
||||
template <class signature>
|
||||
void def(const signature& s)
|
||||
{ m_class->def(s); }
|
||||
|
||||
// export heterogeneous reverse-argument operators
|
||||
// (type of lhs: 'left', of rhs: 'right')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
// boost::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(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
// boost::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 '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
|
||||
// PyObject * (*)(PyObject * aTuple, PyObject * aDictionary)
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{ m_class->def_raw(fn, name); }
|
||||
|
||||
// define member functions. In fact this works for free functions, too -
|
||||
// they act like static member functions, or if they start with the
|
||||
// appropriate self argument (as a pointer or reference), they can be used
|
||||
// just like ordinary member functions -- just like Python!
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
{ m_class->def(fn, name); }
|
||||
|
||||
// Define a virtual member function with a default implementation.
|
||||
// default_fn should be a function which provides the default implementation.
|
||||
// Be careful that default_fn does not in fact call fn virtually!
|
||||
template <class Fn, class DefaultFn>
|
||||
void def(Fn fn, const char* name, DefaultFn default_fn)
|
||||
{ m_class->def(fn, name, default_fn); }
|
||||
|
||||
// Provide a function which implements x.<name>, reading from the given
|
||||
// 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 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 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 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); }
|
||||
|
||||
// define the standard coercion needed for operator overloading
|
||||
void def_standard_coerce()
|
||||
{ m_class->def_standard_coerce(); }
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// conversion functions
|
||||
template <class S, class V>
|
||||
void declare_base(class_builder<S, V> const & base)
|
||||
{
|
||||
m_class->declare_base(base.get_extension_class());
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// upcast conversion function
|
||||
template <class S, class V>
|
||||
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::extension_class<T, U> * get_extension_class() const
|
||||
{
|
||||
return m_class.get();
|
||||
}
|
||||
|
||||
// set an arbitrary attribute. Useful for non-function class data members,
|
||||
// e.g. enums
|
||||
void add(PyObject* x, const char* name)
|
||||
{ m_class->set_attribute(name, x); }
|
||||
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::extension_class<S, V> * base)
|
||||
{
|
||||
m_class->declare_base(base);
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// upcast conversion function
|
||||
template <class S, class V>
|
||||
void declare_base(detail::extension_class<S, V> * base, without_downcast_t)
|
||||
{
|
||||
m_class->declare_base(base, without_downcast);
|
||||
}
|
||||
|
||||
reference<detail::extension_class<T, U> > m_class;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// helper function that does the actual work of creating a cursor for a n
|
||||
// STL conforming container. called by module_builder::def_cursor_for()
|
||||
template <class T, class U>
|
||||
void wrap_cursor_class(module_builder & module,
|
||||
class_builder<T, U> & wrapped_container)
|
||||
{
|
||||
std::string cursor_name(wrapped_container.get_extension_class()->tp_name);
|
||||
cursor_name += "_cursor";
|
||||
class_builder<cursor<T> > cursor_class(module, cursor_name.c_str());
|
||||
|
||||
cursor_class.def(&cursor<T>::get_item, "__getitem__");
|
||||
cursor_class.def(&cursor<T>::set_item, "__setitem__");
|
||||
cursor_class.def(&cursor<T>::len, "__len__");
|
||||
wrapped_container.def(&extension_class_cursor_factory<T>::get, "cursor");
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// global functions declared within the body of a class template will only be
|
||||
// generated when the class template is constructed, and when (for some reason)
|
||||
// the construction does not occur via a new-expression. Otherwise, we could
|
||||
// rely on the initialization of the m_class data member to cause all of the
|
||||
// to_/from_python functions to come into being.
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CLASS_WRAPPER_DWA101000_H_
|
||||
@@ -1,527 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef SUBCLASS_DWA051500_H_
|
||||
# define SUBCLASS_DWA051500_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/types.hpp>
|
||||
# include <boost/python/objects.hpp>
|
||||
# include <boost/python/detail/singleton.hpp>
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/python/conversions.hpp>
|
||||
# include <boost/python/callback.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// A simple type which acts something like a built-in Python class obj.
|
||||
class instance
|
||||
: public boost::python::detail::python_object
|
||||
{
|
||||
public:
|
||||
instance(PyTypeObject* class_);
|
||||
~instance();
|
||||
|
||||
// Standard Python functions.
|
||||
PyObject* repr();
|
||||
int compare(PyObject*);
|
||||
PyObject* str();
|
||||
long hash();
|
||||
PyObject* call(PyObject* args, PyObject* keywords);
|
||||
PyObject* getattr(const char* name, bool use_special_function = true);
|
||||
int setattr(const char* name, PyObject* value);
|
||||
|
||||
// Mapping methods
|
||||
int length();
|
||||
PyObject* get_subscript(PyObject* key);
|
||||
void set_subscript(PyObject* key, PyObject* value);
|
||||
|
||||
// Sequence methods
|
||||
PyObject* get_slice(int start, int finish);
|
||||
void set_slice(int start, int finish, PyObject* value);
|
||||
|
||||
// Number methods
|
||||
PyObject* add(PyObject* other);
|
||||
PyObject* subtract(PyObject* other);
|
||||
PyObject* multiply(PyObject* other);
|
||||
PyObject* divide(PyObject* other);
|
||||
PyObject* remainder(PyObject* other);
|
||||
PyObject* divmod(PyObject* other);
|
||||
PyObject* power(PyObject*, PyObject*);
|
||||
PyObject* negative();
|
||||
PyObject* positive();
|
||||
PyObject* absolute();
|
||||
int nonzero();
|
||||
PyObject* invert();
|
||||
PyObject* lshift(PyObject* other);
|
||||
PyObject* rshift(PyObject* other);
|
||||
PyObject* do_and(PyObject* other);
|
||||
PyObject* do_xor(PyObject* other);
|
||||
PyObject* do_or(PyObject* other);
|
||||
int coerce(PyObject**, PyObject**);
|
||||
PyObject* as_int();
|
||||
PyObject* as_long();
|
||||
PyObject* as_float();
|
||||
PyObject* oct();
|
||||
PyObject* hex();
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
instance(const instance&);
|
||||
void operator=(const instance&);
|
||||
|
||||
private: // helper functions
|
||||
int setattr_dict(PyObject* value);
|
||||
|
||||
private:
|
||||
dictionary m_name_space;
|
||||
};
|
||||
|
||||
template <class T> class meta_class;
|
||||
|
||||
namespace detail {
|
||||
class class_base : public type_object_base
|
||||
{
|
||||
public:
|
||||
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(ref base);
|
||||
|
||||
protected:
|
||||
bool initialize_instance(instance* obj, PyObject* args, PyObject* keywords);
|
||||
|
||||
private: // virtual functions
|
||||
// Subclasses should override this to delete the particular obj type
|
||||
virtual void delete_instance(PyObject*) const = 0;
|
||||
|
||||
private: // boost::python::type_object_base required interface implementation
|
||||
void instance_dealloc(PyObject*) const; // subclasses should not override this
|
||||
|
||||
private:
|
||||
string m_name;
|
||||
tuple m_bases;
|
||||
dictionary m_name_space;
|
||||
};
|
||||
|
||||
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 obj type,
|
||||
// so class_t<instance> is a very simple "class-alike".
|
||||
template <class T>
|
||||
class class_t
|
||||
: public boost::python::detail::class_base
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
private: // Implement mapping methods on instances
|
||||
PyObject* instance_repr(PyObject*) const;
|
||||
int instance_compare(PyObject*, PyObject* other) const;
|
||||
PyObject* instance_str(PyObject*) const;
|
||||
long instance_hash(PyObject*) const;
|
||||
int instance_mapping_length(PyObject*) const;
|
||||
PyObject* instance_mapping_subscript(PyObject*, PyObject*) const;
|
||||
int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const;
|
||||
|
||||
private: // Implement sequence methods on instances
|
||||
int instance_sequence_length(PyObject*) 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;
|
||||
|
||||
private: // Implement number methods on instances
|
||||
PyObject* instance_number_add(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_subtract(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_multiply(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_divide(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_remainder(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_divmod(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_power(PyObject*, PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_negative(PyObject*) const;
|
||||
PyObject* instance_number_positive(PyObject*) const;
|
||||
PyObject* instance_number_absolute(PyObject*) const;
|
||||
int instance_number_nonzero(PyObject*) const;
|
||||
PyObject* instance_number_invert(PyObject*) const;
|
||||
PyObject* instance_number_lshift(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_rshift(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_and(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_xor(PyObject*, PyObject*) const;
|
||||
PyObject* instance_number_or(PyObject*, PyObject*) const;
|
||||
int instance_number_coerce(PyObject*, PyObject**, PyObject**) const;
|
||||
PyObject* instance_number_int(PyObject*) const;
|
||||
PyObject* instance_number_long(PyObject*) const;
|
||||
PyObject* instance_number_float(PyObject*) const;
|
||||
PyObject* instance_number_oct(PyObject*) const;
|
||||
PyObject* instance_number_hex(PyObject*) const;
|
||||
|
||||
private: // Miscellaneous "special" methods
|
||||
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 boost::python::detail::class_base required interface
|
||||
void delete_instance(PyObject*) const;
|
||||
|
||||
private: // noncopyable, without the size bloat
|
||||
class_t(const class_t<T>&);
|
||||
void operator=(const class_t&);
|
||||
};
|
||||
|
||||
// The type of a class_t<T> object.
|
||||
template <class T>
|
||||
class meta_class
|
||||
: public boost::python::detail::reprable<
|
||||
boost::python::detail::callable<
|
||||
boost::python::detail::getattrable<
|
||||
boost::python::detail::setattrable<
|
||||
boost::python::detail::type_object<class_t<T> > > > > >,
|
||||
boost::noncopyable
|
||||
{
|
||||
public:
|
||||
meta_class();
|
||||
|
||||
// Standard Python functions.
|
||||
PyObject* call(PyObject* args, PyObject* keywords);
|
||||
|
||||
struct type_object
|
||||
: boost::python::detail::singleton<type_object,
|
||||
boost::python::detail::callable<
|
||||
boost::python::detail::type_object<meta_class> > >
|
||||
{
|
||||
type_object() : singleton_base(&PyType_Type) {}
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// Member function implementations.
|
||||
//
|
||||
template <class T>
|
||||
meta_class<T>::meta_class()
|
||||
: properties(type_object::instance())
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class_t<T>::class_t(meta_class<T>* meta_class_obj, string name, tuple bases, const dictionary& name_space)
|
||||
: boost::python::detail::class_base(meta_class_obj, name, bases, name_space)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void class_t<T>::delete_instance(PyObject* obj) const
|
||||
{
|
||||
delete downcast<T>(obj);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::call(PyObject* args, PyObject* keywords)
|
||||
{
|
||||
reference<T> result(new T(this));
|
||||
if (!this->initialize_instance(result.get(), args, keywords))
|
||||
return 0;
|
||||
else
|
||||
return result.release();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_repr(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->repr();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_compare(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->compare(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_str(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->str();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
long class_t<T>::instance_hash(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->hash();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_mapping_length(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->length();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_sequence_length(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->length();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_mapping_subscript(PyObject* obj, PyObject* key) const
|
||||
{
|
||||
return downcast<T>(obj)->get_subscript(key);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_sequence_item(PyObject* obj, int n) const
|
||||
{
|
||||
ref key(to_python(n));
|
||||
return downcast<T>(obj)->get_subscript(key.get());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const
|
||||
{
|
||||
ref key(to_python(n));
|
||||
downcast<T>(obj)->set_subscript(key.get(), value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyObject* value) const
|
||||
{
|
||||
downcast<T>(obj)->set_subscript(key, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adjust_slice_indices(PyObject* obj, int& start, int& finish);
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_sequence_slice(PyObject* obj, int start, int finish) const
|
||||
{
|
||||
adjust_slice_indices(obj, start, finish);
|
||||
return downcast<T>(obj)->get_slice(start, finish);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const
|
||||
{
|
||||
adjust_slice_indices(obj, start, finish);
|
||||
downcast<T>(obj)->set_slice(start, finish, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
return downcast<T>(obj)->call(args, keywords);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_getattr(PyObject* obj, const char* name) const
|
||||
{
|
||||
return downcast<T>(obj)->getattr(name);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_setattr(PyObject* obj, const char* name, PyObject* value) const
|
||||
{
|
||||
return downcast<T>(obj)->setattr(name, value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_add(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->add(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_subtract(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->subtract(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_multiply(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->multiply(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_divide(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->divide(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_remainder(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->remainder(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_divmod(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->divmod(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const
|
||||
{
|
||||
return downcast<T>(obj)->power(exponent, modulus);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_negative(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->negative();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_positive(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->positive();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_absolute(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->absolute();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_number_nonzero(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->nonzero();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_invert(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->invert();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_lshift(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->lshift(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_rshift(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->rshift(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_and(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->do_and(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_xor(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->do_xor(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_or(PyObject* obj, PyObject* other) const
|
||||
{
|
||||
return downcast<T>(obj)->do_or(other);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int class_t<T>::instance_number_coerce(PyObject* obj, PyObject** x, PyObject** y) const
|
||||
{
|
||||
return downcast<T>(obj)->coerce(x, y);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_int(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->as_int();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_long(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->as_long();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_float(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->as_float();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_oct(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->oct();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* class_t<T>::instance_number_hex(PyObject* obj) const
|
||||
{
|
||||
return downcast<T>(obj)->hex();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
inline dictionary& class_base::dict()
|
||||
{
|
||||
return m_name_space;
|
||||
}
|
||||
|
||||
inline tuple class_base::bases() const
|
||||
{
|
||||
return m_bases;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* meta_class<T>::call(PyObject* args, PyObject* /*keywords*/)
|
||||
{
|
||||
PyObject* name;
|
||||
PyObject* bases;
|
||||
PyObject* name_space;
|
||||
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O!O!O!"),
|
||||
&PyString_Type, &name,
|
||||
&PyTuple_Type, &bases,
|
||||
&PyDict_Type, &name_space))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return as_object(
|
||||
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();
|
||||
|
||||
inline string class_base::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::python
|
||||
#endif
|
||||
@@ -1,325 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef METHOD_DWA122899_H_
|
||||
# define METHOD_DWA122899_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <string>
|
||||
|
||||
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, boost::python::type<EnumType>)
|
||||
{
|
||||
return static_cast<EnumType>(
|
||||
from_python(x, boost::python::type<long>()));
|
||||
}
|
||||
|
||||
friend EnumType from_python(PyObject* x, boost::python::type<const EnumType&>)
|
||||
{
|
||||
return static_cast<EnumType>(
|
||||
from_python(x, boost::python::type<long>()));
|
||||
}
|
||||
|
||||
friend PyObject* to_python(EnumType x)
|
||||
{
|
||||
return to_python(static_cast<long>(x));
|
||||
}
|
||||
};
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
template <class EnumType> class enum_as_int_converters
|
||||
: public BOOST_PYTHON_CONVERSION::py_enum_as_int_converters<EnumType> {};
|
||||
|
||||
template <class P, class T> class wrapped_pointer;
|
||||
|
||||
//#pragma warn_possunwant off
|
||||
inline void decref_impl(PyObject* p) { Py_DECREF(p); }
|
||||
inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); }
|
||||
//#pragma warn_possunwant reset
|
||||
|
||||
template <class T>
|
||||
inline void decref(T* p)
|
||||
{
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
decref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void xdecref(T* p)
|
||||
{
|
||||
char* const raw_p = reinterpret_cast<char*>(p);
|
||||
char* const p_base = raw_p - offsetof(PyObject, ob_refcnt);
|
||||
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
//
|
||||
// Converters
|
||||
//
|
||||
PyObject* to_python(long);
|
||||
long from_python(PyObject* p, boost::python::type<long>);
|
||||
long from_python(PyObject* p, boost::python::type<const long&>);
|
||||
|
||||
PyObject* to_python(unsigned long);
|
||||
unsigned long from_python(PyObject* p, boost::python::type<unsigned long>);
|
||||
unsigned long from_python(PyObject* p, boost::python::type<const unsigned long&>);
|
||||
|
||||
PyObject* to_python(int);
|
||||
int from_python(PyObject*, boost::python::type<int>);
|
||||
int from_python(PyObject*, boost::python::type<const int&>);
|
||||
|
||||
PyObject* to_python(unsigned int);
|
||||
unsigned int from_python(PyObject*, boost::python::type<unsigned int>);
|
||||
unsigned int from_python(PyObject*, boost::python::type<const unsigned int&>);
|
||||
|
||||
PyObject* to_python(short);
|
||||
short from_python(PyObject*, boost::python::type<short>);
|
||||
short from_python(PyObject*, boost::python::type<const short&>);
|
||||
|
||||
PyObject* to_python(unsigned short);
|
||||
unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
|
||||
unsigned short from_python(PyObject*, boost::python::type<const unsigned short&>);
|
||||
|
||||
PyObject* to_python(signed char);
|
||||
signed char from_python(PyObject*, boost::python::type<signed char>);
|
||||
signed char from_python(PyObject*, boost::python::type<const signed char&>);
|
||||
|
||||
PyObject* to_python(unsigned char);
|
||||
unsigned char from_python(PyObject*, boost::python::type<unsigned char>);
|
||||
unsigned char from_python(PyObject*, boost::python::type<const unsigned char&>);
|
||||
|
||||
PyObject* to_python(float);
|
||||
float from_python(PyObject*, boost::python::type<float>);
|
||||
float from_python(PyObject*, boost::python::type<const float&>);
|
||||
|
||||
PyObject* to_python(double);
|
||||
double from_python(PyObject*, boost::python::type<double>);
|
||||
double from_python(PyObject*, boost::python::type<const double&>);
|
||||
|
||||
PyObject* to_python(bool);
|
||||
bool from_python(PyObject*, boost::python::type<bool>);
|
||||
bool from_python(PyObject*, boost::python::type<const bool&>);
|
||||
|
||||
PyObject* to_python(void);
|
||||
void from_python(PyObject*, boost::python::type<void>);
|
||||
|
||||
PyObject* to_python(const char* s);
|
||||
const char* from_python(PyObject*, boost::python::type<const char*>);
|
||||
|
||||
PyObject* to_python(const std::string& s);
|
||||
std::string from_python(PyObject*, boost::python::type<std::string>);
|
||||
std::string from_python(PyObject*, boost::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*, boost::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
|
||||
// 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 wrapped_type<T>.
|
||||
//
|
||||
|
||||
// Unfortunately, MSVC6 is so incredibly lame that we have to rely on the friend
|
||||
// technique to auto_generate standard pointer conversions for wrapped
|
||||
// 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 boost { 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<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.
|
||||
//
|
||||
// #else
|
||||
//
|
||||
// // Just once for all MyPtr<T>
|
||||
// template <class T>
|
||||
// MyPtr<T> from_python(PyObject*p, type<MyPtr<T> >)
|
||||
// {
|
||||
// return smart_ptr_from_python(p, type<MyPtr<T> >(), type<T>());
|
||||
// }
|
||||
//
|
||||
// #endif
|
||||
// }} // namespace boost::python
|
||||
|
||||
#if !defined(BOOST_MSVC6_OR_EARLIER)
|
||||
template <class T>
|
||||
boost::shared_ptr<T> from_python(PyObject*p, boost::python::type<boost::shared_ptr<T> >)
|
||||
{
|
||||
return smart_ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >(), boost::python::type<T>());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
template <class T>
|
||||
PyObject* to_python(std::auto_ptr<T> p)
|
||||
{
|
||||
return new boost::python::wrapped_pointer<std::auto_ptr<T>, T>(p);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* to_python(boost::shared_ptr<T> p)
|
||||
{
|
||||
return new boost::python::wrapped_pointer<boost::shared_ptr<T>, T>(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// inline implementations
|
||||
//
|
||||
|
||||
#ifndef BOOST_MSVC6_OR_EARLIER
|
||||
inline PyObject* to_python(double d)
|
||||
{
|
||||
return PyFloat_FromDouble(d);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(float f)
|
||||
{
|
||||
return PyFloat_FromDouble(f);
|
||||
}
|
||||
#endif // BOOST_MSVC6_OR_EARLIER
|
||||
|
||||
inline PyObject* to_python(long l)
|
||||
{
|
||||
return PyInt_FromLong(l);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(int x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(short x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(bool b)
|
||||
{
|
||||
return PyInt_FromLong(b);
|
||||
}
|
||||
|
||||
inline PyObject* to_python(void)
|
||||
{
|
||||
return boost::python::detail::none();
|
||||
}
|
||||
|
||||
inline PyObject* to_python(const char* s)
|
||||
{
|
||||
return PyString_FromString(s);
|
||||
}
|
||||
|
||||
inline std::string from_python(PyObject* p, boost::python::type<const std::string&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<std::string>());
|
||||
}
|
||||
|
||||
inline PyObject* to_python(PyObject* p)
|
||||
{
|
||||
Py_INCREF(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
inline PyObject* from_python(PyObject* p, boost::python::type<PyObject*>)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
inline const char* from_python(PyObject* p, boost::python::type<const char* const&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<const char*>());
|
||||
}
|
||||
|
||||
inline double from_python(PyObject* p, boost::python::type<const double&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<double>());
|
||||
}
|
||||
|
||||
inline float from_python(PyObject* p, boost::python::type<const float&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<float>());
|
||||
}
|
||||
|
||||
inline int from_python(PyObject* p, boost::python::type<const int&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<int>());
|
||||
}
|
||||
|
||||
inline short from_python(PyObject* p, boost::python::type<const short&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<short>());
|
||||
}
|
||||
|
||||
inline long from_python(PyObject* p, boost::python::type<const long&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<long>());
|
||||
}
|
||||
|
||||
inline bool from_python(PyObject* p, boost::python::type<const bool&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<bool>());
|
||||
}
|
||||
|
||||
inline unsigned int from_python(PyObject* p, boost::python::type<const unsigned int&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<unsigned int>());
|
||||
}
|
||||
|
||||
inline unsigned short from_python(PyObject* p, boost::python::type<const unsigned short&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<unsigned short>());
|
||||
}
|
||||
|
||||
inline signed char from_python(PyObject* p, boost::python::type<const signed char&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<signed char>());
|
||||
}
|
||||
|
||||
inline unsigned char from_python(PyObject* p, boost::python::type<const unsigned char&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<unsigned char>());
|
||||
}
|
||||
|
||||
inline unsigned long from_python(PyObject* p, boost::python::type<const unsigned long&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<unsigned long>());
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
#endif // METHOD_DWA122899_H_
|
||||
@@ -1,62 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef BASE_OBJECT_DWA051600_H_
|
||||
# define BASE_OBJECT_DWA051600_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/signatures.hpp> // really just for type<>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <cstring>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// base_object - adds a constructor and non-virtual destructor to a
|
||||
// base Python type (e.g. PyObject, PyTypeObject).
|
||||
template <class python_type>
|
||||
struct base_object : python_type
|
||||
{
|
||||
typedef python_type base_python_type;
|
||||
|
||||
// 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
|
||||
~base_object();
|
||||
};
|
||||
|
||||
// Easy typedefs for common usage
|
||||
typedef base_object<PyObject> python_object;
|
||||
typedef base_object<PyTypeObject> python_type;
|
||||
|
||||
|
||||
//
|
||||
// class_t template member function implementations
|
||||
//
|
||||
template <class python_type>
|
||||
base_object<python_type>::base_object(PyTypeObject* type_obj)
|
||||
{
|
||||
base_python_type* bp = this;
|
||||
#if !defined(_MSC_VER) || defined(__STLPORT)
|
||||
std::
|
||||
#endif
|
||||
memset(bp, 0, sizeof(base_python_type));
|
||||
ob_refcnt = 1;
|
||||
ob_type = type_obj;
|
||||
Py_INCREF(type_obj);
|
||||
}
|
||||
|
||||
template <class python_type>
|
||||
inline base_object<python_type>::~base_object()
|
||||
{
|
||||
Py_DECREF(ob_type);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // BASE_OBJECT_DWA051600_H_
|
||||
@@ -1,81 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef CAST_DWA052500_H_
|
||||
# define CAST_DWA052500_H_
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail {
|
||||
// The default way of converting a PyObject* or PyTypeObject* to a T*
|
||||
template <class T>
|
||||
struct downcast_traits
|
||||
{
|
||||
template <class U>
|
||||
static T* cast(U* p) { return static_cast<T*>(p); }
|
||||
};
|
||||
|
||||
inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p)
|
||||
{
|
||||
return reinterpret_cast<PyTypeObject*>(p);
|
||||
}
|
||||
|
||||
inline PyObject* as_base_object(const PyObject*, PyObject* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
inline const PyTypeObject* as_base_object(const PyTypeObject*, const PyObject* p)
|
||||
{
|
||||
return reinterpret_cast<const PyTypeObject*>(p);
|
||||
}
|
||||
|
||||
inline const PyObject* as_base_object(const PyObject*, const PyObject* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// Convert a pointer to any type derived from PyObject or PyTypeObject to a PyObject*
|
||||
inline PyObject* as_object(PyObject* p) { return p; }
|
||||
inline PyObject* as_object(PyTypeObject* p) { return reinterpret_cast<PyObject*>(p); }
|
||||
|
||||
// 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*>
|
||||
{
|
||||
downcast(PyObject* p)
|
||||
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((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::downcast_traits<T>::cast(p))
|
||||
{}
|
||||
|
||||
downcast(const PyTypeObject* p)
|
||||
: m_p(detail::downcast_traits<T>::cast(p))
|
||||
{}
|
||||
|
||||
operator T*() const { return m_p; }
|
||||
T* get() const { return m_p; }
|
||||
T& operator*() const { return *m_p; }
|
||||
private:
|
||||
T* m_p;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CAST_DWA052500_H_
|
||||
@@ -1,56 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef CONFIG_DWA052200_H_
|
||||
# define CONFIG_DWA052200_H_
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <cstddef>
|
||||
|
||||
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
// A gcc bug forces some symbols into the global namespace
|
||||
# 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 BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
|
||||
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
|
||||
# define BOOST_PYTHON_CONVERSION boost::python
|
||||
# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_MSVC)
|
||||
# if _MSC_VER <= 1200
|
||||
# define BOOST_MSVC6_OR_EARLIER 1
|
||||
# endif
|
||||
|
||||
# pragma warning (disable : 4786)
|
||||
|
||||
# endif
|
||||
|
||||
// Work around the broken library implementation/strict ansi checking on some
|
||||
// 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 BOOST_OFFSETOF(s_name, s_member) \
|
||||
((size_t)__INTADDR__(&(((s_name *)0)->s_member)))
|
||||
# else
|
||||
# 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(BOOST_MSVC6_OR_EARLIER) && !defined(__STLPORT)
|
||||
# define BOOST_CSTD_
|
||||
# else
|
||||
# define BOOST_CSTD_ std
|
||||
# endif
|
||||
|
||||
#endif // CONFIG_DWA052200_H_
|
||||
@@ -1,924 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
//
|
||||
// This file automatically generated for 5-argument constructors by
|
||||
// gen_extclass.python
|
||||
|
||||
#ifndef EXTENSION_CLASS_DWA052000_H_
|
||||
# define EXTENSION_CLASS_DWA052000_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/classes.hpp>
|
||||
# include <vector>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
# include <boost/python/objects.hpp>
|
||||
# include <boost/python/detail/functions.hpp>
|
||||
# include <memory>
|
||||
# include <boost/python/detail/init_function.hpp>
|
||||
# include <typeinfo>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// forward declarations
|
||||
template <long which, class operand> struct operators;
|
||||
template <class T> struct left_operand;
|
||||
template <class T> struct right_operand;
|
||||
|
||||
enum without_downcast_t { without_downcast };
|
||||
|
||||
namespace detail {
|
||||
|
||||
// forward declarations
|
||||
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;
|
||||
|
||||
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&);
|
||||
|
||||
template <class T>
|
||||
T* check_non_null(T* p)
|
||||
{
|
||||
if (p == 0)
|
||||
report_released_smart_pointer(typeid(T));
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T> class held_instance;
|
||||
|
||||
typedef void* (*conversion_function_ptr)(void*);
|
||||
|
||||
struct base_class_info
|
||||
{
|
||||
base_class_info(extension_class_base* t, conversion_function_ptr f)
|
||||
:class_object(t), convert(f)
|
||||
{}
|
||||
|
||||
extension_class_base* class_object;
|
||||
conversion_function_ptr convert;
|
||||
};
|
||||
|
||||
typedef base_class_info derived_class_info;
|
||||
|
||||
struct add_operator_base;
|
||||
|
||||
class extension_class_base : public class_t<extension_instance>
|
||||
{
|
||||
public:
|
||||
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(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, ref x);
|
||||
|
||||
private:
|
||||
virtual void* extract_object_from_holder(instance_holder_base* v) const = 0;
|
||||
virtual std::vector<base_class_info> const& base_classes() const = 0;
|
||||
virtual std::vector<derived_class_info> const& derived_classes() const = 0;
|
||||
|
||||
protected:
|
||||
friend struct add_operator_base;
|
||||
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);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class class_registry
|
||||
{
|
||||
public:
|
||||
static extension_class_base* class_object()
|
||||
{ return static_class_object; }
|
||||
|
||||
// Register/unregister the Python class object corresponding to T
|
||||
static void register_class(extension_class_base*);
|
||||
static void unregister_class(extension_class_base*);
|
||||
|
||||
// Establish C++ inheritance relationships
|
||||
static void register_base_class(base_class_info const&);
|
||||
static void register_derived_class(derived_class_info const&);
|
||||
|
||||
// Query the C++ inheritance relationships
|
||||
static std::vector<base_class_info> const& base_classes();
|
||||
static std::vector<derived_class_info> const& derived_classes();
|
||||
private:
|
||||
static extension_class_base* static_class_object;
|
||||
static std::vector<base_class_info> static_base_class_info;
|
||||
static std::vector<derived_class_info> static_derived_class_info;
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
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 = held_instance<T>.
|
||||
template <class T, class U = boost::python::detail::held_instance<T> >
|
||||
class python_extension_class_converters
|
||||
{
|
||||
public:
|
||||
// Get an object which can be used to convert T to/from python. This is used
|
||||
// as a kind of concept check by the global template
|
||||
//
|
||||
// PyObject* to_python(const T& x)
|
||||
//
|
||||
// below this class, to prevent the confusing messages that would otherwise
|
||||
// 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 python_extension_class_converters py_extension_class_converters(boost::python::type<T>)
|
||||
{
|
||||
return python_extension_class_converters();
|
||||
}
|
||||
|
||||
// This is a member function because in a conforming implementation, friend
|
||||
// funcitons defined inline in the class body are all instantiated as soon
|
||||
// as the enclosing class is instantiated. If T is not copyable, that causes
|
||||
// a compiler error. Instead, we access this function through the global
|
||||
// template
|
||||
//
|
||||
// PyObject* to_python(const T& x)
|
||||
//
|
||||
// defined below this class. Since template functions are instantiated only
|
||||
// on demand, errors will be avoided unless T is noncopyable and the user
|
||||
// writes code which causes us to try to copy a T.
|
||||
PyObject* to_python(const T& x) const
|
||||
{
|
||||
boost::python::reference<boost::python::detail::extension_instance> result(create_instance());
|
||||
result->add_implementation(
|
||||
std::auto_ptr<boost::python::detail::instance_holder_base>(
|
||||
new boost::python::detail::instance_value_holder<T,U>(result.get(), x)));
|
||||
return result.release();
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
friend T* from_python(PyObject* obj, boost::python::type<T*>)
|
||||
{
|
||||
// downcast to an extension_instance, then find the actual T
|
||||
boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj);
|
||||
typedef std::vector<boost::python::detail::instance_holder_base*>::const_iterator iterator;
|
||||
for (iterator p = self->wrapped_objects().begin();
|
||||
p != self->wrapped_objects().end(); ++p)
|
||||
{
|
||||
boost::python::detail::instance_holder<T>* held = dynamic_cast<boost::python::detail::instance_holder<T>*>(*p);
|
||||
if (held != 0)
|
||||
return held->target();
|
||||
|
||||
// see extclass.cpp for an explanation of try_class_conversions()
|
||||
void* target = boost::python::detail::class_registry<T>::class_object()->try_class_conversions(*p);
|
||||
if(target)
|
||||
return static_cast<T*>(target);
|
||||
}
|
||||
boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::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, boost::python::type<PtrType>)
|
||||
{
|
||||
// downcast to an extension_instance, then find the actual T
|
||||
boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj);
|
||||
typedef std::vector<boost::python::detail::instance_holder_base*>::const_iterator iterator;
|
||||
for (iterator p = self->wrapped_objects().begin();
|
||||
p != self->wrapped_objects().end(); ++p)
|
||||
{
|
||||
boost::python::detail::instance_ptr_holder<PtrType, T>* held =
|
||||
dynamic_cast<boost::python::detail::instance_ptr_holder<PtrType, T>*>(*p);
|
||||
if (held != 0)
|
||||
return held->ptr();
|
||||
}
|
||||
boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
|
||||
template <class PtrType>
|
||||
static PyObject* ptr_to_python(PtrType x)
|
||||
{
|
||||
boost::python::reference<boost::python::detail::extension_instance> result(create_instance());
|
||||
result->add_implementation(
|
||||
std::auto_ptr<boost::python::detail::instance_holder_base>(
|
||||
new boost::python::detail::instance_ptr_holder<PtrType,T>(x)));
|
||||
return result.release();
|
||||
}
|
||||
|
||||
static boost::python::reference<boost::python::detail::extension_instance> create_instance()
|
||||
{
|
||||
PyTypeObject* class_object = boost::python::detail::class_registry<T>::class_object();
|
||||
if (class_object == 0)
|
||||
boost::python::detail::report_missing_class_object(typeid(T));
|
||||
|
||||
return boost::python::reference<boost::python::detail::extension_instance>(
|
||||
new boost::python::detail::extension_instance(class_object));
|
||||
}
|
||||
|
||||
// Convert to const T*
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*>)
|
||||
{ return from_python(p, boost::python::type<T*>()); }
|
||||
|
||||
// Convert to const T* const&
|
||||
friend const T* from_python(PyObject* p, boost::python::type<const T*const&>)
|
||||
{ return from_python(p, boost::python::type<const T*>()); }
|
||||
|
||||
// Convert to T* const&
|
||||
friend T* from_python(PyObject* p, boost::python::type<T* const&>)
|
||||
{ return from_python(p, boost::python::type<T*>()); }
|
||||
|
||||
// Convert to T&
|
||||
friend T& from_python(PyObject* p, boost::python::type<T&>)
|
||||
{ return *boost::python::detail::check_non_null(from_python(p, boost::python::type<T*>())); }
|
||||
|
||||
// Convert to const T&
|
||||
friend const T& from_python(PyObject* p, boost::python::type<const T&>)
|
||||
{ return from_python(p, boost::python::type<T&>()); }
|
||||
|
||||
// Convert to T
|
||||
friend const T& from_python(PyObject* p, boost::python::type<T>)
|
||||
{ return from_python(p, boost::python::type<T&>()); }
|
||||
|
||||
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T>&>)
|
||||
{ return ptr_from_python(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
|
||||
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T> >)
|
||||
{ return ptr_from_python(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
|
||||
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<const std::auto_ptr<T>&>)
|
||||
{ return ptr_from_python(p, boost::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, boost::python::type<boost::shared_ptr<T>&>)
|
||||
{ return ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T> >)
|
||||
{ return ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<const boost::shared_ptr<T>&>)
|
||||
{ return ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x)
|
||||
{ return ptr_to_python(x); }
|
||||
};
|
||||
|
||||
// Convert T to_python, instantiated on demand and only if there isn't a
|
||||
// non-template overload for this function. This version is the one invoked when
|
||||
// T is a wrapped class. See the first 2 functions declared in
|
||||
// python_extension_class_converters above for more info.
|
||||
template <class T>
|
||||
PyObject* to_python(const T& x)
|
||||
{
|
||||
return py_extension_class_converters(boost::python::type<T>()).to_python(x);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters);
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T> class instance_holder;
|
||||
|
||||
class read_only_setattr_function : public function
|
||||
{
|
||||
public:
|
||||
read_only_setattr_function(const char* name);
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
const char* description() const;
|
||||
private:
|
||||
string m_name;
|
||||
};
|
||||
|
||||
|
||||
/* helper class to wrap STL conforming iterators.
|
||||
|
||||
Given a wrapped container ("FooList", say), this template is used to create
|
||||
an auxiliary class "FooList_cursor" that wraps the container's iterator.
|
||||
The cursor can be used in Python loops likes this:
|
||||
|
||||
>>> for i in foo_list.cursor():
|
||||
... print i.get_data()
|
||||
|
||||
The auxiliary cursor class can be created for any STL conforming
|
||||
container. It implements random access functions (get_item() and
|
||||
set_item()) for any iterator, but these will only be as efficient as the
|
||||
underlying iterator allows. However, this is not a problem because
|
||||
the above Python loop accesses the items in forward order anyway.
|
||||
*/
|
||||
template <class Container>
|
||||
struct cursor
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
typedef typename Container::value_type value_type;
|
||||
|
||||
cursor(Container & c, ref python_object)
|
||||
: m_python_object(python_object),
|
||||
m_begin(c.begin()),
|
||||
m_iter(c.begin()),
|
||||
m_size(c.size()),
|
||||
m_index(0)
|
||||
{}
|
||||
|
||||
void advance(int index, std::forward_iterator_tag)
|
||||
{
|
||||
if(index < 0 || index >= m_size)
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(index));
|
||||
throw python::error_already_set();
|
||||
}
|
||||
|
||||
int delta = index - m_index;
|
||||
if(delta < 0)
|
||||
{
|
||||
m_iter = m_begin;
|
||||
delta = index;
|
||||
}
|
||||
std::advance(m_iter, delta);
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
void advance(int index, std::bidirectional_iterator_tag)
|
||||
{
|
||||
if(index < 0 || index >= m_size)
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(index));
|
||||
throw python::error_already_set();
|
||||
}
|
||||
int delta = index - m_index;
|
||||
std::advance(m_iter, delta);
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
value_type const & get_item(int index)
|
||||
{
|
||||
advance(index, std::iterator_category(m_iter));
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
void set_item(int index, value_type const & v)
|
||||
{
|
||||
advance(index, std::iterator_category(m_iter));
|
||||
*m_iter = v;
|
||||
}
|
||||
|
||||
int len() const
|
||||
{ return m_size; }
|
||||
|
||||
ref m_python_object;
|
||||
iterator m_begin, m_iter;
|
||||
int m_index, m_size;
|
||||
};
|
||||
|
||||
/* create a cursor for an STL conforming container */
|
||||
template <class T>
|
||||
struct extension_class_cursor_factory
|
||||
{
|
||||
static cursor<T> get(ref container)
|
||||
{
|
||||
return cursor<T>(
|
||||
BOOST_PYTHON_CONVERSION::from_python(container.get(), type<T&>()),
|
||||
container);
|
||||
}
|
||||
};
|
||||
|
||||
template <class From, class To>
|
||||
struct define_conversion
|
||||
{
|
||||
static void* upcast_ptr(void* v)
|
||||
{
|
||||
return static_cast<To*>(static_cast<From*>(v));
|
||||
}
|
||||
|
||||
static void* downcast_ptr(void* v)
|
||||
{
|
||||
return dynamic_cast<To*>(static_cast<From*>(v));
|
||||
}
|
||||
};
|
||||
|
||||
// An easy way to make an extension base class which wraps T. Note that Python
|
||||
// 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.
|
||||
//
|
||||
// U is optional, but you won't be able to override any member functions in
|
||||
// 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 = held_instance<T> >
|
||||
class extension_class
|
||||
: public python_extension_class_converters<T, U>, // This generates the to_python/from_python functions
|
||||
public extension_class_base
|
||||
{
|
||||
public:
|
||||
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()
|
||||
extension_class();
|
||||
|
||||
// Construct with the given name. The name only affects the objects of this
|
||||
// class are represented through repr()
|
||||
extension_class(const char* name);
|
||||
|
||||
~extension_class();
|
||||
|
||||
// define constructors
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
inline void def(constructor<A1, A2, A3, A4, A5>)
|
||||
// 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(),
|
||||
signature0()))))));
|
||||
}
|
||||
|
||||
|
||||
// export homogeneous operators (type of both lhs and rhs is 'operator')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>());
|
||||
|
||||
// export homogeneous operators (type of both lhs and rhs is 'T const&')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>());
|
||||
template <long which, class Operand>
|
||||
inline void def(operators<which,Operand>)
|
||||
{
|
||||
typedef typename operand_select<Operand>::template wrapped<T>::type true_operand;
|
||||
def_operators(operators<which,true_operand>());
|
||||
}
|
||||
|
||||
// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
// boost::python::right_operand<int const&>());
|
||||
|
||||
// export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
|
||||
// boost::python::right_operand<int const&>());
|
||||
template <long which, class Left, class Right>
|
||||
inline void def(operators<which,Left>, right_operand<Right> r)
|
||||
{
|
||||
typedef typename operand_select<Left>::template wrapped<T>::type true_left;
|
||||
def_operators(operators<which,true_left>(), r);
|
||||
}
|
||||
|
||||
// export heterogeneous reverse-argument operators
|
||||
// (type of lhs: 'left', of rhs: 'right')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
|
||||
// boost::python::left_operand<int const&>());
|
||||
|
||||
// export heterogeneous reverse-argument operators
|
||||
// (type of lhs: 'left', of rhs: 'T const&')
|
||||
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
|
||||
// boost::python::left_operand<int const&>());
|
||||
template <long which, class Left, class Right>
|
||||
inline void def(operators<which,Right>, left_operand<Left> l)
|
||||
{
|
||||
typedef typename operand_select<Right>::template wrapped<T>::type true_right;
|
||||
def_operators(operators<which,true_right>(), l);
|
||||
}
|
||||
|
||||
// define a function that passes Python arguments and keywords
|
||||
// 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
|
||||
// PyObject* (*)(PyObject* aTuple, PyObject* aDictionary)
|
||||
template <class Fn>
|
||||
inline void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
this->add_method(new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
// define member functions. In fact this works for free functions, too -
|
||||
// they act like static member functions, or if they start with the
|
||||
// appropriate self argument (as a pointer), they can be used just like
|
||||
// ordinary member functions -- just like Python!
|
||||
template <class Fn>
|
||||
inline void def(Fn fn, const char* name)
|
||||
{
|
||||
this->add_method(new_wrapped_function(fn), name);
|
||||
}
|
||||
|
||||
// Define a virtual member function with a default implementation.
|
||||
// default_fn should be a function which provides the default implementation.
|
||||
// Be careful that default_fn does not in fact call fn virtually!
|
||||
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);
|
||||
}
|
||||
|
||||
// Provide a function which implements x.<name>, reading from the given
|
||||
// member (pm) of the T obj
|
||||
template <class MemberType>
|
||||
inline void def_getter(MemberType T::*pm, const char* 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 obj
|
||||
template <class MemberType>
|
||||
inline void def_setter(MemberType T::*pm, const char* name)
|
||||
{
|
||||
this->add_setter_method(new setter_function<T, MemberType>(pm), name);
|
||||
}
|
||||
|
||||
// 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 read_only_setattr_function(name), name);
|
||||
this->def_getter(pm, name);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
this->def_getter(pm, name);
|
||||
this->def_setter(pm, name);
|
||||
}
|
||||
|
||||
// define the standard coercion needed for operator overloading
|
||||
void def_standard_coerce();
|
||||
|
||||
// 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(extension_class<S, V>* base)
|
||||
{
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
base_class_info baseInfo(base,
|
||||
&define_conversion<S, T>::downcast_ptr);
|
||||
class_registry<T>::register_base_class(baseInfo);
|
||||
add_base(ref(as_object(base), ref::increment_count));
|
||||
|
||||
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(extension_class<S, V>* base, without_downcast_t)
|
||||
{
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
base_class_info baseInfo(base, 0);
|
||||
class_registry<T>::register_base_class(baseInfo);
|
||||
add_base(ref(as_object(base), ref::increment_count));
|
||||
|
||||
derived_class_info derivedInfo(this,
|
||||
&define_conversion<T, S>::upcast_ptr);
|
||||
class_registry<S>::register_derived_class(derivedInfo);
|
||||
}
|
||||
|
||||
private: // types
|
||||
typedef instance_value_holder<T,U> holder;
|
||||
|
||||
private: // extension_class_base virtual function implementations
|
||||
std::vector<base_class_info> const& base_classes() 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>
|
||||
inline void def_operators(operators<which,Operand>)
|
||||
{
|
||||
def_standard_coerce();
|
||||
|
||||
// for some strange reason, this prevents MSVC from having an
|
||||
// "unrecoverable block scoping error"!
|
||||
typedef choose_op<(which & op_add)> choose_add;
|
||||
|
||||
choose_op<(which & op_add)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_sub)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_mul)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_div)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_mod)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_divmod)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_pow)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_lshift)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_rshift)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_and)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_xor)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_or)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_invert)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_int)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_long)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_float)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_cmp)>::template args<Operand>::add(this);
|
||||
choose_unary_op<(which & op_str)>::template args<Operand>::add(this);
|
||||
}
|
||||
|
||||
template <long which, class Left, class Right>
|
||||
inline void def_operators(operators<which,Left>, right_operand<Right>)
|
||||
{
|
||||
def_standard_coerce();
|
||||
|
||||
choose_op<(which & op_add)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_sub)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_mul)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_div)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_mod)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_divmod)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_pow)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_lshift)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_rshift)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_and)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
|
||||
}
|
||||
|
||||
template <long which, class Left, class Right>
|
||||
inline void def_operators(operators<which,Right>, left_operand<Left>)
|
||||
{
|
||||
def_standard_coerce();
|
||||
|
||||
choose_rop<(which & op_add)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_sub)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_mul)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_div)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_mod)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_divmod)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_pow)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_lshift)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_rshift)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_and)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_xor)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_or)>::template args<Left,Right>::add(this);
|
||||
choose_rop<(which & op_cmp)>::template args<Left,Right>::add(this);
|
||||
}
|
||||
|
||||
template <class signature>
|
||||
void add_constructor(signature sig)
|
||||
{
|
||||
this->add_constructor_object(init_function<holder>::create(sig));
|
||||
}
|
||||
};
|
||||
|
||||
// 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 held_instance : public T
|
||||
{
|
||||
// There are no member functions: we want to avoid inadvertently overriding
|
||||
// any virtual functions in T.
|
||||
public:
|
||||
held_instance(PyObject*) : T() {}
|
||||
template <class A1>
|
||||
held_instance(PyObject*, A1 a1) : T(a1) {}
|
||||
template <class A1, class A2>
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : T(a1, a2) {}
|
||||
template <class A1, class A2, class A3>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : T(a1, a2, a3) {}
|
||||
template <class A1, class A2, class A3, class 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>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : T(a1, a2, a3, a4, a5) {}
|
||||
};
|
||||
|
||||
// Abstract base class for all obj holders. Base for template class
|
||||
// instance_holder<>, below.
|
||||
class instance_holder_base
|
||||
{
|
||||
public:
|
||||
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 instance_holder : public instance_holder_base
|
||||
{
|
||||
public:
|
||||
virtual Held*target() = 0;
|
||||
};
|
||||
|
||||
// Concrete class which holds a Held by way of a wrapper class Wrapper. If Held
|
||||
// can be constructed with arguments (A1...An), Wrapper must have a
|
||||
// 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). held_instance (above) is used as a default Wrapper class when
|
||||
// there are no virtual functions.
|
||||
template <class Held, class Wrapper>
|
||||
class instance_value_holder : public instance_holder<Held>
|
||||
{
|
||||
public:
|
||||
Held* target() { return &m_held; }
|
||||
Wrapper* value_target() { return &m_held; }
|
||||
|
||||
instance_value_holder(extension_instance* p) :
|
||||
m_held(p) {}
|
||||
template <class A1>
|
||||
instance_value_holder(extension_instance* p, A1 a1) :
|
||||
m_held(p, a1) {}
|
||||
template <class A1, class A2>
|
||||
instance_value_holder(extension_instance* p, A1 a1, A2 a2) :
|
||||
m_held(p, a1, a2) {}
|
||||
template <class A1, class A2, class 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>
|
||||
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>
|
||||
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
|
||||
m_held(p, a1, a2, a3, a4, a5) {}
|
||||
|
||||
public: // implementation of instance_holder_base required interface
|
||||
bool held_by_value() { return true; }
|
||||
|
||||
private:
|
||||
Wrapper m_held;
|
||||
};
|
||||
|
||||
// Concrete class which holds a HeldType by way of a (possibly smart) pointer
|
||||
// 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 instance_ptr_holder : public instance_holder<HeldType>
|
||||
{
|
||||
public:
|
||||
HeldType* target() { return &*m_ptr; }
|
||||
PtrType& ptr() { return m_ptr; }
|
||||
|
||||
instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {}
|
||||
|
||||
public: // implementation of instance_holder_base required interface
|
||||
bool held_by_value() { return false; }
|
||||
private:
|
||||
PtrType m_ptr;
|
||||
};
|
||||
|
||||
class extension_instance : public instance
|
||||
{
|
||||
public:
|
||||
extension_instance(PyTypeObject* class_);
|
||||
~extension_instance();
|
||||
|
||||
void add_implementation(std::auto_ptr<instance_holder_base> holder);
|
||||
|
||||
typedef std::vector<instance_holder_base*> held_objects;
|
||||
const held_objects& wrapped_objects() const
|
||||
{ return m_wrapped_objects; }
|
||||
private:
|
||||
held_objects m_wrapped_objects;
|
||||
};
|
||||
|
||||
//
|
||||
// Template function implementations
|
||||
//
|
||||
|
||||
template <class T, class U>
|
||||
extension_class<T, U>::extension_class()
|
||||
: extension_class_base(typeid(T).name())
|
||||
{
|
||||
class_registry<T>::register_class(this);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
extension_class<T, U>::extension_class(const char* name)
|
||||
: extension_class_base(name)
|
||||
{
|
||||
class_registry<T>::register_class(this);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
void extension_class<T, U>::def_standard_coerce()
|
||||
{
|
||||
ref coerce_fct = dict().get_item(string("__coerce__"));
|
||||
|
||||
if(coerce_fct.get() == 0) // not yet defined
|
||||
this->def(&standard_coerce, "__coerce__");
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
std::vector<base_class_info> const&
|
||||
extension_class<T, U>::base_classes() const
|
||||
{
|
||||
return class_registry<T>::base_classes();
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline
|
||||
std::vector<derived_class_info> const&
|
||||
extension_class<T, U>::derived_classes() const
|
||||
{
|
||||
return class_registry<T>::derived_classes();
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
void* extension_class<T, U>::extract_object_from_holder(instance_holder_base* v) const
|
||||
{
|
||||
instance_holder<T>* held = dynamic_cast<instance_holder<T>*>(v);
|
||||
if(held)
|
||||
return held->target();
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
extension_class<T, U>::~extension_class()
|
||||
{
|
||||
class_registry<T>::unregister_class(this);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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);
|
||||
static_class_object = p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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);
|
||||
(void)p; // unused in shipping version
|
||||
static_class_object = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void class_registry<T>::register_base_class(base_class_info const& i)
|
||||
{
|
||||
static_base_class_info.push_back(i);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void class_registry<T>::register_derived_class(derived_class_info const& i)
|
||||
{
|
||||
static_derived_class_info.push_back(i);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::vector<base_class_info> const& class_registry<T>::base_classes()
|
||||
{
|
||||
return static_base_class_info;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::vector<derived_class_info> const& class_registry<T>::derived_classes()
|
||||
{
|
||||
return static_derived_class_info;
|
||||
}
|
||||
|
||||
//
|
||||
// Static data member declaration.
|
||||
//
|
||||
template <class T>
|
||||
extension_class_base* class_registry<T>::static_class_object;
|
||||
template <class T>
|
||||
std::vector<base_class_info> class_registry<T>::static_base_class_info;
|
||||
template <class T>
|
||||
std::vector<derived_class_info> class_registry<T>::static_derived_class_info;
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // EXTENSION_CLASS_DWA052000_H_
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef FUNCTIONS_DWA051400_H_
|
||||
# define FUNCTIONS_DWA051400_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/python/caller.hpp>
|
||||
# include <boost/call_traits.hpp>
|
||||
# include <boost/python/objects.hpp>
|
||||
# include <boost/python/detail/base_object.hpp>
|
||||
# include <typeinfo>
|
||||
# include <vector>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// forward declaration
|
||||
class extension_instance;
|
||||
|
||||
|
||||
// function --
|
||||
// the common base class for all overloadable function and method objects
|
||||
// supplied by the library.
|
||||
class function : public python_object
|
||||
{
|
||||
public:
|
||||
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() {}
|
||||
|
||||
PyObject* call(PyObject* args, PyObject* keywords) const;
|
||||
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 type_object;
|
||||
private:
|
||||
reference<function> m_overloads;
|
||||
};
|
||||
|
||||
// wrapped_function_pointer<> --
|
||||
// A single function or member function pointer wrapped and presented to
|
||||
// Python as a callable object.
|
||||
//
|
||||
// Template parameters:
|
||||
// R - the return type of the function pointer
|
||||
// F - the complete type of the wrapped function pointer
|
||||
template <class R, class F>
|
||||
struct wrapped_function_pointer : function
|
||||
{
|
||||
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
|
||||
|
||||
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); }
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(F).name(); }
|
||||
|
||||
private:
|
||||
const ptr_fun m_pf;
|
||||
};
|
||||
|
||||
// raw_arguments_function
|
||||
// A function that passes the Python argument tuple and keyword dictionary
|
||||
// verbatim to C++ (useful for customized argument parsing and variable
|
||||
// argument lists)
|
||||
template <class Ret, class Args, class Keywords>
|
||||
struct raw_arguments_function : function
|
||||
{
|
||||
typedef Ret (*ptr_fun)(Args, Keywords);
|
||||
|
||||
raw_arguments_function(ptr_fun pf)
|
||||
: m_pf(pf) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
ref dict(keywords ?
|
||||
ref(keywords, ref::increment_count) :
|
||||
ref(PyDict_New()));
|
||||
|
||||
return to_python(
|
||||
(*m_pf)(from_python(args, boost::python::type<Args>()),
|
||||
from_python(dict.get(), boost::python::type<Keywords>())));
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(ptr_fun).name(); }
|
||||
|
||||
private:
|
||||
const ptr_fun m_pf;
|
||||
};
|
||||
|
||||
// virtual_function<> --
|
||||
// A virtual function with a default implementation wrapped and presented
|
||||
// to Python as a callable object.
|
||||
//
|
||||
// Template parameters:
|
||||
// T - the type of the target class
|
||||
// R - the return type of the function pointer
|
||||
// V - the virtual function pointer being wrapped
|
||||
// (should be of the form R(T::*)(<args>), or R (*)(T, <args>))
|
||||
// D - a function which takes a T&, const T&, T*, or const T* first
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
virtual_function(V virtual_function_ptr, D default_implementation)
|
||||
: m_virtual_function_ptr(virtual_function_ptr),
|
||||
m_default_implementation(default_implementation)
|
||||
{}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(V).name(); }
|
||||
|
||||
private:
|
||||
const V m_virtual_function_ptr;
|
||||
const D m_default_implementation;
|
||||
};
|
||||
|
||||
// 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.
|
||||
template <class F, class R>
|
||||
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 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)
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
return new raw_arguments_function<R, Args, keywords>(pmf);
|
||||
}
|
||||
|
||||
|
||||
// A helper function for new_virtual_function(), below. Implements the core
|
||||
// functionality once the return type has already been deduced. R is expected to
|
||||
// be type<X>, where X is the actual return type of V.
|
||||
template <class T, class R, class V, class D>
|
||||
inline function* new_virtual_function_aux(
|
||||
type<T>, R, V virtual_function_ptr, D default_implementation
|
||||
)
|
||||
{
|
||||
// We can't just use "typename R::Type" below because MSVC (incorrectly) pukes.
|
||||
typedef typename R::type 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
|
||||
)
|
||||
{
|
||||
// Deduce the return type and pass it off to the helper function above
|
||||
return new_virtual_function_aux(
|
||||
type<T>(), return_value(virtual_function_ptr),
|
||||
virtual_function_ptr, default_implementation);
|
||||
}
|
||||
|
||||
// A function with a bundled "bound target" object. This is what is produced by
|
||||
// the expression a.b where a is an instance or extension_instance object and b
|
||||
// is a callable object not found in the obj namespace but on its class or
|
||||
// a base class.
|
||||
class bound_function : public python_object
|
||||
{
|
||||
public:
|
||||
static bound_function* create(const ref& target, const ref& fn);
|
||||
|
||||
bound_function(const ref& target, const ref& fn);
|
||||
PyObject* call(PyObject*args, PyObject* keywords) const;
|
||||
PyObject* getattr(const char* name) const;
|
||||
|
||||
private:
|
||||
struct type_object;
|
||||
friend struct type_object;
|
||||
|
||||
ref m_target;
|
||||
ref m_unbound_function;
|
||||
|
||||
private: // data members for allocation/deallocation optimization
|
||||
bound_function* m_free_list_link;
|
||||
|
||||
static bound_function* free_list;
|
||||
};
|
||||
|
||||
// Special functions designed to access data members of a wrapped C++ object.
|
||||
template <class ClassType, class MemberType>
|
||||
class getter_function : public function
|
||||
{
|
||||
public:
|
||||
typedef MemberType ClassType::* pointer_to_member;
|
||||
|
||||
getter_function(pointer_to_member pm)
|
||||
: m_pm(pm) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(MemberType (*)(const ClassType&)).name(); }
|
||||
private:
|
||||
pointer_to_member m_pm;
|
||||
};
|
||||
|
||||
template <class ClassType, class MemberType>
|
||||
class setter_function : public function
|
||||
{
|
||||
public:
|
||||
typedef MemberType ClassType::* pointer_to_member;
|
||||
|
||||
setter_function(pointer_to_member pm)
|
||||
: m_pm(pm) {}
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(const ClassType&, const MemberType&)).name(); }
|
||||
private:
|
||||
pointer_to_member m_pm;
|
||||
};
|
||||
|
||||
template <class ClassType, class MemberType>
|
||||
PyObject* getter_function<ClassType, MemberType>::do_call(
|
||||
PyObject* args, PyObject* /* keywords */) const
|
||||
{
|
||||
PyObject* self;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("O"), &self))
|
||||
return 0;
|
||||
|
||||
return to_python(
|
||||
from_python(self, type<const ClassType*>())->*m_pm);
|
||||
}
|
||||
|
||||
template <class ClassType, class MemberType>
|
||||
PyObject* setter_function<ClassType, MemberType>::do_call(
|
||||
PyObject* args, PyObject* /* keywords */) const
|
||||
{
|
||||
PyObject* self;
|
||||
PyObject* value;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &self, &value))
|
||||
return 0;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
template <class T, class R, class V, class D>
|
||||
PyObject* virtual_function<T,R,V,D>::do_call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
// If the target object is held by pointer, we must call through the virtual
|
||||
// function pointer to the most-derived override.
|
||||
PyObject* target = PyTuple_GetItem(args, 0);
|
||||
if (target != 0)
|
||||
{
|
||||
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_default_implementation, args, keywords);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // FUNCTIONS_DWA051400_H_
|
||||
@@ -1,507 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// 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.python
|
||||
|
||||
#ifndef INIT_FUNCTION_DWA052000_H_
|
||||
# define INIT_FUNCTION_DWA052000_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/functions.hpp>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <typeinfo>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// parameter_traits - so far, this is a way to pass a const T& when we can be
|
||||
// sure T is not a reference type, and a raw T otherwise. This should be
|
||||
// rolled into boost::call_traits. Ordinarily, parameter_traits would be
|
||||
// written:
|
||||
//
|
||||
// template <class T> struct parameter_traits
|
||||
// {
|
||||
// typedef const T& const_reference;
|
||||
// };
|
||||
//
|
||||
// template <class T> struct parameter_traits<T&>
|
||||
// {
|
||||
// typedef T& const_reference;
|
||||
// };
|
||||
//
|
||||
// template <> struct parameter_traits<void>
|
||||
// {
|
||||
// typedef void const_reference;
|
||||
// };
|
||||
//
|
||||
// ...but since we can't partially specialize on reference types, we need this
|
||||
// long-winded but equivalent incantation.
|
||||
|
||||
// const_ref_selector -- an implementation detail of parameter_traits (below). This uses
|
||||
// the usual "poor man's partial specialization" hack for MSVC.
|
||||
template <bool is_ref>
|
||||
struct const_ref_selector
|
||||
{
|
||||
template <class T>
|
||||
struct const_ref
|
||||
{
|
||||
typedef const T& type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct const_ref_selector<true>
|
||||
{
|
||||
template <class T>
|
||||
struct const_ref
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4181)
|
||||
# endif // BOOST_MSVC
|
||||
template <class T>
|
||||
struct parameter_traits
|
||||
{
|
||||
private:
|
||||
typedef const_ref_selector<boost::is_reference<T>::value> selector;
|
||||
public:
|
||||
typedef typename selector::template const_ref<T>::type const_reference;
|
||||
};
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
# endif // BOOST_MSVC
|
||||
|
||||
// Full spcialization for void
|
||||
template <>
|
||||
struct parameter_traits<void>
|
||||
{
|
||||
typedef void const_reference;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class reference_parameter
|
||||
{
|
||||
typedef typename parameter_traits<T>::const_reference const_reference;
|
||||
public:
|
||||
reference_parameter(const_reference value)
|
||||
: value(value) {}
|
||||
operator const_reference() { return value; }
|
||||
private:
|
||||
const_reference value;
|
||||
};
|
||||
|
||||
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;
|
||||
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;
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> struct Init9;
|
||||
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 init_function
|
||||
{
|
||||
static init* create(signature0) {
|
||||
return new init0<T>;
|
||||
}
|
||||
|
||||
template <class A1>
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5>
|
||||
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,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference>;
|
||||
}
|
||||
|
||||
template <class A1, class A2, class A3, class A4, class A5, class 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,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference>;
|
||||
}
|
||||
|
||||
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>) {
|
||||
return new Init7<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference>;
|
||||
}
|
||||
|
||||
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>) {
|
||||
return new Init8<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference,
|
||||
detail::parameter_traits<A8>::const_reference>;
|
||||
}
|
||||
|
||||
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>) {
|
||||
return new Init9<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference,
|
||||
detail::parameter_traits<A8>::const_reference,
|
||||
detail::parameter_traits<A9>::const_reference>;
|
||||
}
|
||||
|
||||
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>) {
|
||||
return new Init10<T,
|
||||
detail::parameter_traits<A1>::const_reference,
|
||||
detail::parameter_traits<A2>::const_reference,
|
||||
detail::parameter_traits<A3>::const_reference,
|
||||
detail::parameter_traits<A4>::const_reference,
|
||||
detail::parameter_traits<A5>::const_reference,
|
||||
detail::parameter_traits<A6>::const_reference,
|
||||
detail::parameter_traits<A7>::const_reference,
|
||||
detail::parameter_traits<A8>::const_reference,
|
||||
detail::parameter_traits<A9>::const_reference,
|
||||
detail::parameter_traits<A10>::const_reference>;
|
||||
}
|
||||
};
|
||||
|
||||
class init : public function
|
||||
{
|
||||
private: // override function hook
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const;
|
||||
private:
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct init0 : init
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("")))
|
||||
throw argument_error();
|
||||
return new T(self
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1>
|
||||
struct init1 : init
|
||||
{
|
||||
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 argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
struct init2 : init
|
||||
{
|
||||
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 argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3>
|
||||
struct init3 : init
|
||||
{
|
||||
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 argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4>
|
||||
struct init4 : init
|
||||
{
|
||||
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 argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5>
|
||||
struct init5 : init
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOO"), &a1, &a2, &a3, &a4, &a5))
|
||||
throw argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
|
||||
boost::python::detail::reference_parameter<A5>(from_python(a5, type<A5>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
struct Init6 : init
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
PyObject* a6;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6))
|
||||
throw argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
|
||||
boost::python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
|
||||
boost::python::detail::reference_parameter<A6>(from_python(a6, type<A6>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
struct Init7 : init
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
PyObject* a6;
|
||||
PyObject* a7;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7))
|
||||
throw argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
|
||||
boost::python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
|
||||
boost::python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
|
||||
boost::python::detail::reference_parameter<A7>(from_python(a7, type<A7>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
struct Init8 : init
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
PyObject* a6;
|
||||
PyObject* a7;
|
||||
PyObject* a8;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8))
|
||||
throw argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
|
||||
boost::python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
|
||||
boost::python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
|
||||
boost::python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
|
||||
boost::python::detail::reference_parameter<A8>(from_python(a8, type<A8>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8)).name(); }
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
struct Init9 : init
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
PyObject* a6;
|
||||
PyObject* a7;
|
||||
PyObject* a8;
|
||||
PyObject* a9;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9))
|
||||
throw argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
|
||||
boost::python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
|
||||
boost::python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
|
||||
boost::python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
|
||||
boost::python::detail::reference_parameter<A8>(from_python(a8, type<A8>())),
|
||||
boost::python::detail::reference_parameter<A9>(from_python(a9, type<A9>()))
|
||||
);
|
||||
}
|
||||
const char* description() const
|
||||
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9)).name(); }
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyObject* a1;
|
||||
PyObject* a2;
|
||||
PyObject* a3;
|
||||
PyObject* a4;
|
||||
PyObject* a5;
|
||||
PyObject* a6;
|
||||
PyObject* a7;
|
||||
PyObject* a8;
|
||||
PyObject* a9;
|
||||
PyObject* a10;
|
||||
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10))
|
||||
throw argument_error();
|
||||
return new T(self,
|
||||
boost::python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
|
||||
boost::python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
|
||||
boost::python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
|
||||
boost::python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
|
||||
boost::python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
|
||||
boost::python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
|
||||
boost::python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
|
||||
boost::python::detail::reference_parameter<A8>(from_python(a8, type<A8>())),
|
||||
boost::python::detail::reference_parameter<A9>(from_python(a9, type<A9>())),
|
||||
boost::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 boost::python::detail
|
||||
|
||||
#endif // INIT_FUNCTION_DWA052000_H_
|
||||
@@ -1,21 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef NONE_DWA_052000_H_
|
||||
# define NONE_DWA_052000_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
inline PyObject* none() { Py_INCREF(Py_None); return Py_None; }
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // NONE_DWA_052000_H_
|
||||
@@ -1,251 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
//
|
||||
// This file automatically generated by gen_signatures.python for 10 arguments.
|
||||
#ifndef SIGNATURES_DWA050900_H_
|
||||
# define SIGNATURES_DWA050900_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
|
||||
namespace boost { 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_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
|
||||
// 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_t>::id is just void_t.
|
||||
template <class T>
|
||||
struct type
|
||||
{
|
||||
typedef type id;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type<boost::python::detail::void_t>
|
||||
{
|
||||
typedef boost::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
|
||||
// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs
|
||||
// that involve recursive template nesting.
|
||||
//
|
||||
// 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 {};
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
|
||||
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>)
|
||||
{ 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>)
|
||||
{ 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>)
|
||||
{ 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>)
|
||||
{ return signature7<X, T1, T2, T3, T4, T5, T6>(); }
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
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>)
|
||||
{ return signature6<X, T1, T2, T3, T4, T5>(); }
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
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>(); }
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
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>(); }
|
||||
|
||||
template <class T1, class T2>
|
||||
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>(); }
|
||||
|
||||
template <class T1>
|
||||
struct signature1 {};
|
||||
|
||||
template <class T1, class X>
|
||||
inline signature2<X, T1> prepend(type<X>, signature1<T1>)
|
||||
{ return signature2<X, T1>(); }
|
||||
|
||||
struct signature0 {};
|
||||
|
||||
template <class X>
|
||||
inline signature1<X> prepend(type<X>, signature0)
|
||||
{ return signature1<X>(); }
|
||||
|
||||
|
||||
// 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_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
|
||||
// thought this would be clearer.
|
||||
template <class T>
|
||||
struct return_value_select { typedef T type; };
|
||||
|
||||
// free functions
|
||||
template <class R>
|
||||
return_value_select<R> return_value(R (*)()) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class A1>
|
||||
return_value_select<R> return_value(R (*)(A1)) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
return_value_select<R> return_value(R (*)(A1, A2)) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
return_value_select<R> return_value(R (T::*)()) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class T, class A1>
|
||||
return_value_select<R> return_value(R (T::*)(A1)) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class T, class A1, class A2>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
return_value_select<R> return_value(R (T::*)() const) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class T, class A1>
|
||||
return_value_select<R> return_value(R (T::*)(A1) const) { return return_value_select<R>(); }
|
||||
|
||||
template <class R, class T, class A1, class A2>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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 boost::python::detail
|
||||
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef SINGLETON_DWA051900_H_
|
||||
# define SINGLETON_DWA051900_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct empty {};
|
||||
template <class Derived, class Base = empty>
|
||||
struct singleton : Base
|
||||
{
|
||||
typedef singleton singleton_base; // Convenience type for derived class constructors
|
||||
|
||||
static Derived* instance();
|
||||
|
||||
// Pass-through constructors
|
||||
singleton() : Base() {}
|
||||
|
||||
template <class A1>
|
||||
singleton(const A1& a1) : Base(a1) {}
|
||||
|
||||
template <class A1, class 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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
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) {}
|
||||
|
||||
};
|
||||
|
||||
template <class Derived, class Base>
|
||||
Derived* singleton<Derived,Base>::instance()
|
||||
{
|
||||
static Derived x;
|
||||
return &x;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif
|
||||
@@ -1,389 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef TYPES_DWA051800_H_
|
||||
# define TYPES_DWA051800_H_
|
||||
|
||||
// Usage:
|
||||
// class X : public
|
||||
// boost::python::callable<
|
||||
// boost::python::getattrable <
|
||||
// boost::python::setattrable<python_object, X> > >
|
||||
// {
|
||||
// public:
|
||||
// ref call(args, kw);
|
||||
// ref getattr(args, kw);
|
||||
// ref setattr(args, kw);
|
||||
// };
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/signatures.hpp> // really just for type<>
|
||||
# include <boost/python/detail/cast.hpp>
|
||||
# include <boost/python/detail/base_object.hpp>
|
||||
# include <typeinfo>
|
||||
# include <vector>
|
||||
# include <cassert>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class string;
|
||||
|
||||
namespace detail {
|
||||
|
||||
class instance_holder_base;
|
||||
|
||||
class type_object_base : public python_type
|
||||
{
|
||||
public:
|
||||
explicit type_object_base(PyTypeObject* type_type);
|
||||
virtual ~type_object_base();
|
||||
|
||||
public:
|
||||
enum capability {
|
||||
hash, call, str, getattr, setattr, compare, repr,
|
||||
|
||||
mapping_length, mapping_subscript, mapping_ass_subscript,
|
||||
|
||||
sequence_length, sequence_item, sequence_ass_item,
|
||||
sequence_concat, sequence_repeat, sequence_slice, sequence_ass_slice,
|
||||
|
||||
number_add, number_subtract, number_multiply, number_divide,
|
||||
number_remainder, number_divmod, number_power, number_negative,
|
||||
number_positive, number_absolute, number_nonzero, number_invert,
|
||||
number_lshift, number_rshift, number_and, number_xor, number_or,
|
||||
number_coerce, number_int, number_long, number_float, number_oct,
|
||||
number_hex
|
||||
};
|
||||
|
||||
void enable(capability);
|
||||
|
||||
//
|
||||
// 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* 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;
|
||||
|
||||
public: // Callbacks for mapping methods
|
||||
virtual int instance_mapping_length(PyObject*) const;
|
||||
virtual PyObject* instance_mapping_subscript(PyObject*, PyObject*) const ;
|
||||
virtual int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const;
|
||||
|
||||
public: // Callbacks for sequence methods
|
||||
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;
|
||||
virtual PyObject* instance_number_subtract(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_multiply(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_divide(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_remainder(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_divmod(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_power(PyObject*, PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_negative(PyObject*) const;
|
||||
virtual PyObject* instance_number_positive(PyObject*) const;
|
||||
virtual PyObject* instance_number_absolute(PyObject*) const;
|
||||
virtual int instance_number_nonzero(PyObject*) const;
|
||||
virtual PyObject* instance_number_invert(PyObject*) const;
|
||||
virtual PyObject* instance_number_lshift(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_rshift(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_and(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_xor(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_or(PyObject*, PyObject*) const;
|
||||
virtual int instance_number_coerce(PyObject*, PyObject**, PyObject**) const;
|
||||
virtual PyObject* instance_number_int(PyObject*) const;
|
||||
virtual PyObject* instance_number_long(PyObject*) const;
|
||||
virtual PyObject* instance_number_float(PyObject*) const;
|
||||
virtual PyObject* instance_number_oct(PyObject*) const;
|
||||
virtual PyObject* instance_number_hex(PyObject*) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class type_object : public type_object_base
|
||||
{
|
||||
public:
|
||||
typedef T instance;
|
||||
|
||||
type_object(PyTypeObject* type_type, const char* name)
|
||||
: type_object_base(type_type)
|
||||
{
|
||||
assert(name != 0);
|
||||
this->tp_name = const_cast<char*>(name);
|
||||
}
|
||||
|
||||
type_object(PyTypeObject* type_type)
|
||||
: type_object_base(type_type)
|
||||
{
|
||||
this->tp_name = const_cast<char*>(typeid(instance).name());
|
||||
}
|
||||
|
||||
private: // Overridable behaviors.
|
||||
// Called when the reference count goes to zero. The default implementation
|
||||
// is "delete p". If you have not allocated your object with operator new or
|
||||
// you have other constraints, you'll need to override this
|
||||
virtual void dealloc(T* p) const;
|
||||
|
||||
private: // Implementation of type_object_base hooks. Do not reimplement in derived classes.
|
||||
void instance_dealloc(PyObject*) const;
|
||||
};
|
||||
|
||||
//
|
||||
// type objects
|
||||
//
|
||||
template <class 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);
|
||||
private:
|
||||
PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const;
|
||||
};
|
||||
|
||||
template <class 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);
|
||||
private:
|
||||
PyObject* instance_getattr(PyObject* obj, const char* name) const;
|
||||
};
|
||||
|
||||
template <class 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);
|
||||
private:
|
||||
int instance_setattr(PyObject* obj, const char* name, PyObject* value) const;
|
||||
};
|
||||
|
||||
template <class 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);
|
||||
private:
|
||||
PyObject* instance_repr(PyObject* obj) const;
|
||||
};
|
||||
|
||||
//
|
||||
// Member function definitions
|
||||
//
|
||||
|
||||
// type_object<>
|
||||
template <class T>
|
||||
void type_object<T>::instance_dealloc(PyObject* obj) const
|
||||
{
|
||||
this->dealloc(downcast<instance>(obj).get());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void type_object<T>::dealloc(T* obj) const
|
||||
{
|
||||
delete obj;
|
||||
}
|
||||
|
||||
// callable
|
||||
template <class Base>
|
||||
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)
|
||||
: Base(type_type)
|
||||
{
|
||||
this->enable(call);
|
||||
}
|
||||
|
||||
template <class Base>
|
||||
PyObject* callable<Base>::instance_call(PyObject* obj, PyObject* args, PyObject* kw) const
|
||||
{
|
||||
return downcast<instance>(obj)->call(args, kw);
|
||||
}
|
||||
|
||||
// getattrable
|
||||
template <class Base>
|
||||
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)
|
||||
: Base(type_type)
|
||||
{
|
||||
this->enable(getattr);
|
||||
}
|
||||
|
||||
template <class Base>
|
||||
PyObject* getattrable<Base>::instance_getattr(PyObject* obj, const char* name) const
|
||||
{
|
||||
return downcast<instance>(obj)->getattr(name);
|
||||
}
|
||||
|
||||
// setattrable
|
||||
template <class Base>
|
||||
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)
|
||||
: Base(type_type)
|
||||
{
|
||||
this->enable(setattr);
|
||||
}
|
||||
|
||||
template <class Base>
|
||||
int setattrable<Base>::instance_setattr(PyObject* obj, const char* name, PyObject* value) const
|
||||
{
|
||||
return downcast<instance>(obj)->setattr(name, value);
|
||||
}
|
||||
|
||||
// reprable
|
||||
template <class Base>
|
||||
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)
|
||||
: Base(type_type)
|
||||
{
|
||||
this->enable(repr);
|
||||
}
|
||||
|
||||
template <class Base>
|
||||
PyObject* reprable<Base>::instance_repr(PyObject* obj) const
|
||||
{
|
||||
return downcast<instance>(obj)->repr();
|
||||
}
|
||||
|
||||
// Helper class for optimized allocation of PODs: If two PODs
|
||||
// happen to contain identical byte patterns, they may share their
|
||||
// memory. Reference counting is used to free unused memory.
|
||||
// This is useful because method tables of related extension classes tend
|
||||
// to be identical, so less memory is needed for them.
|
||||
class shared_pod_manager
|
||||
{
|
||||
typedef std::pair<char*, std::size_t> holder;
|
||||
typedef std::vector<holder> storage;
|
||||
|
||||
public:
|
||||
static shared_pod_manager& obj();
|
||||
~shared_pod_manager();
|
||||
|
||||
// Allocate memory for POD T and fill it with zeros.
|
||||
// This memory is initially not shared.
|
||||
template <class T>
|
||||
static void create(T*& t)
|
||||
{
|
||||
t = reinterpret_cast<T*>(obj().create(sizeof(T)));
|
||||
}
|
||||
|
||||
// Decrement the refcount for the memory t points to. If the count
|
||||
// goes to zero, the memory is freed.
|
||||
template <class T>
|
||||
static void dispose(T* t)
|
||||
{
|
||||
obj().dec_ref(t, sizeof(T));
|
||||
}
|
||||
|
||||
// Attempt to share the memory t points to. If memory with the same
|
||||
// contents already exists, t is replaced by a pointer to this memory,
|
||||
// and t's old memory is disposed. Otherwise, t will be registered for
|
||||
// potential future sharing.
|
||||
template <class T>
|
||||
static void replace_if_equal(T*& t)
|
||||
{
|
||||
t = reinterpret_cast<T*>(obj().replace_if_equal(t, sizeof(T)));
|
||||
}
|
||||
|
||||
// Create a copy of t's memory that is guaranteed to be private to t.
|
||||
// Afterwards t points to the new memory, unless it was already private, in
|
||||
// which case there is no change (except that t's memory will no longer
|
||||
// be considered for future sharing - see raplade_if_equal())
|
||||
// This function *must* be called before the contents of (*t) can
|
||||
// be overwritten. Otherwise, inconsistencies and crashes may result.
|
||||
template <class T>
|
||||
static void make_unique_copy(T*& t)
|
||||
{
|
||||
t = reinterpret_cast<T*>(obj().make_unique_copy(t, sizeof(T)));
|
||||
}
|
||||
|
||||
private:
|
||||
void* replace_if_equal(void* pod, std::size_t size);
|
||||
void* make_unique_copy(void* pod, std::size_t size);
|
||||
void* create(std::size_t size);
|
||||
void dec_ref(void* pod, std::size_t size);
|
||||
void erase_from_list(void* pod);
|
||||
|
||||
struct compare;
|
||||
struct identical;
|
||||
|
||||
private:
|
||||
shared_pod_manager() {} // instance
|
||||
|
||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||
public:
|
||||
#endif
|
||||
storage m_storage;
|
||||
};
|
||||
|
||||
|
||||
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(::boost::python::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0)
|
||||
|
||||
template<typename T>
|
||||
inline void countof_validate(T* const, T* const*);
|
||||
|
||||
template<typename T>
|
||||
inline int countof_validate(const void*, T);
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // TYPES_DWA051800_H_
|
||||
@@ -1,78 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
// This file serves as a wrapper around <Python.h> which allows it to be
|
||||
// compiled with GCC 2.95.2 under Win32 and which disables the default MSVC
|
||||
// behavior so that a program may be compiled in debug mode without requiring a
|
||||
// special debugging build of the Python library.
|
||||
|
||||
|
||||
// To use the Python debugging library, #define BOOST_DEBUG_PYTHON on the
|
||||
// compiler command-line.
|
||||
|
||||
#ifdef _DEBUG
|
||||
# ifndef BOOST_DEBUG_PYTHON
|
||||
# undef _DEBUG // Don't let Python force the debug library just because we're debugging.
|
||||
# define DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Some things we need in order to get Python.h to work with compilers other
|
||||
// than MSVC on Win32
|
||||
//
|
||||
#if defined(_WIN32)
|
||||
# ifdef __GNUC__
|
||||
|
||||
typedef int pid_t;
|
||||
# define WORD_BIT 32
|
||||
# define hypot _hypot
|
||||
# include <stdio.h>
|
||||
# define HAVE_CLOCK
|
||||
# define HAVE_STRFTIME
|
||||
# define HAVE_STRERROR
|
||||
# define NT_THREADS
|
||||
# define WITH_THREAD
|
||||
# ifndef NETSCAPE_PI
|
||||
# define USE_SOCKET
|
||||
# endif
|
||||
|
||||
# ifdef USE_DL_IMPORT
|
||||
# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
|
||||
# endif
|
||||
|
||||
# ifdef USE_DL_EXPORT
|
||||
# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
|
||||
# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
|
||||
# endif
|
||||
|
||||
# define HAVE_LONG_LONG 1
|
||||
# define LONG_LONG long long
|
||||
|
||||
# elif defined(__MWERKS__)
|
||||
|
||||
# ifndef _MSC_VER
|
||||
# define PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H 1
|
||||
# define _MSC_VER 900
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#ifdef PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H
|
||||
# undef _MSC_VER
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H
|
||||
# undef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H
|
||||
# define _DEBUG
|
||||
#endif
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef ERRORS_DWA052500_H_
|
||||
# define ERRORS_DWA052500_H_
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
struct error_already_set {};
|
||||
struct argument_error : error_already_set {};
|
||||
|
||||
// Handles exceptions caught just before returning to Python code.
|
||||
void handle_exception();
|
||||
|
||||
template <class T>
|
||||
T* expect_non_null(T* x)
|
||||
{
|
||||
if (x == 0)
|
||||
throw error_already_set();
|
||||
return x;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // ERRORS_DWA052500_H_
|
||||
@@ -1,88 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef MODULE_DWA051000_H_
|
||||
# define MODULE_DWA051000_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/objects.hpp>
|
||||
# include <boost/python/detail/functions.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class module_builder;
|
||||
|
||||
template <class T, class U> class class_builder;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T, class U>
|
||||
void wrap_cursor_class(module_builder & module,
|
||||
class_builder<T, U> & wrapped_container);
|
||||
} // namspace detail
|
||||
|
||||
class module_builder
|
||||
{
|
||||
public:
|
||||
// Create a module. REQUIRES: only one module_builder is created per module.
|
||||
module_builder(const char* name);
|
||||
~module_builder();
|
||||
|
||||
// Add elements to the module
|
||||
void add(detail::function* x, const char* name);
|
||||
void add(PyTypeObject* x, const char* name = 0);
|
||||
void add(ref x, const char*name);
|
||||
|
||||
template <class Fn>
|
||||
void def_raw(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_raw_arguments_function(fn), name);
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
void def(Fn fn, const char* name)
|
||||
{
|
||||
add(detail::new_wrapped_function(fn), name);
|
||||
}
|
||||
|
||||
// wrapped_container must wrap an STL conforming container;
|
||||
// this function creates a cursor that wraps this container's iterator
|
||||
// and adds the factory function "cursor()" to the wrapped container
|
||||
template <class T, class U>
|
||||
void def_cursor_for(class_builder<T, U> & wrapped_container)
|
||||
{
|
||||
detail::wrap_cursor_class(*this, wrapped_container);
|
||||
}
|
||||
|
||||
// Return true iff a module is currently being built.
|
||||
static bool initializing();
|
||||
|
||||
// Return the name of the module currently being built.
|
||||
// REQUIRES: initializing() == true
|
||||
static string name();
|
||||
|
||||
// Return a pointer to the Python module object being built
|
||||
PyObject* module() const;
|
||||
|
||||
private:
|
||||
PyObject* m_module;
|
||||
static PyMethodDef initial_methods[1];
|
||||
};
|
||||
|
||||
//
|
||||
// inline implementations
|
||||
//
|
||||
inline PyObject* module_builder::module() const
|
||||
{
|
||||
return m_module;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif
|
||||
@@ -1,334 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef OBJECTS_DWA051100_H_
|
||||
# define OBJECTS_DWA051100_H_
|
||||
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/reference.hpp>
|
||||
# include "boost/operators.hpp"
|
||||
# include <utility>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
class object
|
||||
{
|
||||
public:
|
||||
explicit object(ref p);
|
||||
|
||||
// Return a reference to the held object
|
||||
ref reference() const;
|
||||
|
||||
// Return a raw pointer to the held object
|
||||
PyObject* get() const;
|
||||
|
||||
private:
|
||||
ref m_p;
|
||||
};
|
||||
|
||||
class tuple : public object
|
||||
{
|
||||
public:
|
||||
explicit tuple(std::size_t n = 0);
|
||||
explicit tuple(ref p);
|
||||
|
||||
template <class First, class Second>
|
||||
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(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(ref(PyTuple_New(3)))
|
||||
{
|
||||
set_item(0, first);
|
||||
set_item(1, second);
|
||||
set_item(2, third);
|
||||
}
|
||||
|
||||
template <class First, class Second, class Third, class Fourth>
|
||||
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);
|
||||
set_item(2, third);
|
||||
set_item(3, fourth);
|
||||
}
|
||||
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
std::size_t size() const;
|
||||
ref operator[](std::size_t pos) const;
|
||||
|
||||
template <class T>
|
||||
void set_item(std::size_t pos, const T& rhs)
|
||||
{
|
||||
this->set_item(pos, make_ref(rhs));
|
||||
}
|
||||
|
||||
void set_item(std::size_t pos, const ref& rhs);
|
||||
|
||||
tuple slice(int low, int high) const;
|
||||
|
||||
friend tuple operator+(const tuple&, const tuple&);
|
||||
tuple& operator+=(const tuple& rhs);
|
||||
};
|
||||
|
||||
class list : public object
|
||||
{
|
||||
struct proxy;
|
||||
struct slice_proxy;
|
||||
public:
|
||||
explicit list(ref p);
|
||||
explicit list(std::size_t sz = 0);
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
std::size_t size();
|
||||
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_ref(x)); }
|
||||
void set_item(std::size_t pos, const ref& );
|
||||
|
||||
// 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_ref(x)); }
|
||||
void insert(std::size_t index, const ref& item);
|
||||
|
||||
template <class T>
|
||||
void push_back(const T& item)
|
||||
{ this->push_back(make_ref(item)); }
|
||||
void push_back(const ref& item);
|
||||
|
||||
template <class T>
|
||||
void append(const T& item)
|
||||
{ this->append(make_ref(item)); }
|
||||
void append(const ref& item);
|
||||
|
||||
list slice(int low, int high) const;
|
||||
slice_proxy slice(int low, int high);
|
||||
void sort();
|
||||
void reverse();
|
||||
tuple as_tuple() const;
|
||||
};
|
||||
|
||||
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(ref p);
|
||||
explicit string(const char* s);
|
||||
string(const char* s, std::size_t length);
|
||||
string(const string& rhs);
|
||||
|
||||
enum interned_t { interned };
|
||||
string(const char* s, interned_t);
|
||||
|
||||
// Get the type object for Strings
|
||||
static PyTypeObject* type_obj();
|
||||
|
||||
// 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;
|
||||
|
||||
// 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* 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);
|
||||
|
||||
void intern();
|
||||
|
||||
friend string operator%(const string& format, const tuple& args);
|
||||
};
|
||||
|
||||
class dictionary : public object
|
||||
{
|
||||
private:
|
||||
struct proxy;
|
||||
|
||||
public:
|
||||
explicit dictionary(ref p);
|
||||
dictionary();
|
||||
void clear();
|
||||
|
||||
static PyTypeObject* type_obj();
|
||||
static bool accepts(ref p);
|
||||
|
||||
public:
|
||||
template <class Key>
|
||||
proxy operator[](const Key& key)
|
||||
{ return this->operator[](make_ref(key)); }
|
||||
proxy operator[](ref key);
|
||||
|
||||
template <class Key>
|
||||
ref operator[](const Key& key) const
|
||||
{ return this->operator[](make_ref(key)); }
|
||||
ref operator[](ref key) const;
|
||||
|
||||
template <class Key>
|
||||
ref get_item(const Key& key) const
|
||||
{ return this->get_item(make_ref(key)); }
|
||||
ref get_item(const ref& key) const;
|
||||
|
||||
template <class Key, class Default>
|
||||
ref get_item(const Key& key, const Default& default_) const
|
||||
{ return this->get_item(make_ref(key), make_ref(default_)); }
|
||||
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_ref(key), make_ref(value)); }
|
||||
void set_item(const ref& key, const ref& value);
|
||||
|
||||
template <class Key>
|
||||
void erase(const Key& key)
|
||||
{ this->erase(make_ref(key)); }
|
||||
void erase(ref key);
|
||||
|
||||
// proxy operator[](const object& key);
|
||||
// ref operator[](const object& key) const;
|
||||
|
||||
// ref get_item(const object& key, ref default_ = ref()) const;
|
||||
// void set_item(const object& key, const ref& value);
|
||||
|
||||
// void erase(const object& key);
|
||||
|
||||
list items() const;
|
||||
list keys() const;
|
||||
list values() const;
|
||||
|
||||
std::size_t size() const;
|
||||
// TODO: iterator support
|
||||
};
|
||||
|
||||
struct dictionary::proxy
|
||||
{
|
||||
template <class T>
|
||||
const ref& operator=(const T& rhs)
|
||||
{ return (*this) = make_ref(rhs); }
|
||||
const ref& operator=(const ref& rhs);
|
||||
|
||||
operator ref() const;
|
||||
private:
|
||||
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 ref& operator=(const proxy&); // Not actually implemented
|
||||
private:
|
||||
ref m_dict;
|
||||
ref m_key;
|
||||
};
|
||||
|
||||
struct list::proxy
|
||||
{
|
||||
template <class T>
|
||||
const ref& operator=(const T& rhs)
|
||||
{ return (*this) = make_ref(rhs); }
|
||||
const ref& operator=(const ref& rhs);
|
||||
|
||||
operator ref() const;
|
||||
|
||||
private:
|
||||
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 ref& operator=(const proxy&); // Not actually implemented
|
||||
private:
|
||||
list m_list;
|
||||
std::size_t m_index;
|
||||
};
|
||||
|
||||
struct list::slice_proxy
|
||||
{
|
||||
const list& operator=(const list& rhs);
|
||||
operator ref() const;
|
||||
operator list() const;
|
||||
std::size_t size();
|
||||
ref operator[](std::size_t pos) const;
|
||||
private:
|
||||
friend class list;
|
||||
slice_proxy(const ref& list, int low, int high);
|
||||
private:
|
||||
ref m_list;
|
||||
int m_low, m_high;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
PyObject* to_python(const boost::python::tuple&);
|
||||
boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple>);
|
||||
|
||||
inline boost::python::tuple from_python(PyObject* p, boost::python::type<const boost::python::tuple&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::tuple>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::list&);
|
||||
boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list>);
|
||||
|
||||
inline boost::python::list from_python(PyObject* p, boost::python::type<const boost::python::list&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::list>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::string&);
|
||||
boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string>);
|
||||
|
||||
inline boost::python::string from_python(PyObject* p, boost::python::type<const boost::python::string&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::string>());
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::dictionary&);
|
||||
boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary>);
|
||||
|
||||
inline boost::python::dictionary from_python(PyObject* p, boost::python::type<const boost::python::dictionary&>)
|
||||
{
|
||||
return from_python(p, boost::python::type<boost::python::dictionary>());
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
#endif // OBJECTS_DWA051100_H_
|
||||
@@ -1,509 +0,0 @@
|
||||
#ifndef OPERATORS_UK112000_H_
|
||||
#define OPERATORS_UK112000_H_
|
||||
|
||||
# include <boost/python/reference.hpp>
|
||||
# include <boost/python/detail/functions.hpp>
|
||||
|
||||
// When STLport is used with native streams, _STL::ostringstream().str() is not
|
||||
// _STL::string, but std::string. This confuses to_python(), so we'll use
|
||||
// strstream instead. Also, GCC 2.95.2 doesn't have sstream.
|
||||
# if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__) || __GNUC__ > 2
|
||||
# include <sstream>
|
||||
# else
|
||||
# include <strstream>
|
||||
# endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
tuple standard_coerce(ref l, ref r);
|
||||
|
||||
namespace detail {
|
||||
|
||||
// helper class for automatic operand type detection
|
||||
// during operator wrapping.
|
||||
struct auto_operand {};
|
||||
}
|
||||
|
||||
// Define operator ids that can be or'ed together
|
||||
// (boost::python::op_add | boost::python::op_sub | boost::python::op_mul).
|
||||
// This allows to wrap several operators in one line.
|
||||
enum operator_id
|
||||
{
|
||||
op_add = 0x1,
|
||||
op_sub = 0x2,
|
||||
op_mul = 0x4,
|
||||
op_div = 0x8,
|
||||
op_mod = 0x10,
|
||||
op_divmod =0x20,
|
||||
op_pow = 0x40,
|
||||
op_lshift = 0x80,
|
||||
op_rshift = 0x100,
|
||||
op_and = 0x200,
|
||||
op_xor = 0x400,
|
||||
op_or = 0x800,
|
||||
op_neg = 0x1000,
|
||||
op_pos = 0x2000,
|
||||
op_abs = 0x4000,
|
||||
op_invert = 0x8000,
|
||||
op_int = 0x10000,
|
||||
op_long = 0x20000,
|
||||
op_float = 0x40000,
|
||||
op_str = 0x80000,
|
||||
op_cmp = 0x100000
|
||||
};
|
||||
|
||||
// Wrap the operators given by "which". Usage:
|
||||
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>());
|
||||
template <long which, class operand = boost::python::detail::auto_operand>
|
||||
struct operators {};
|
||||
|
||||
// Wrap heterogeneous operators with given left operand type. Usage:
|
||||
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
|
||||
// boost::python::left_operand<int>());
|
||||
template <class T>
|
||||
struct left_operand {};
|
||||
|
||||
// Wrap heterogeneous operators with given right operand type. Usage:
|
||||
// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
|
||||
// boost::python::right_operand<int>());
|
||||
template <class T>
|
||||
struct right_operand {};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Specified>
|
||||
struct operand_select
|
||||
{
|
||||
template <class wrapped_type>
|
||||
struct wrapped
|
||||
{
|
||||
typedef Specified type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct operand_select<auto_operand>
|
||||
{
|
||||
template <class wrapped_type>
|
||||
struct wrapped
|
||||
{
|
||||
typedef const wrapped_type& type;
|
||||
};
|
||||
};
|
||||
|
||||
template <long> struct define_operator;
|
||||
|
||||
// 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(extension_class_base* target, function* method, const char* name)
|
||||
{ target->add_method(method, name); }
|
||||
};
|
||||
|
||||
//
|
||||
// choose_op, choose_unary_op, and choose_rop
|
||||
//
|
||||
// These templates use "poor man's partial specialization" to generate the
|
||||
// appropriate add_method() call (if any) for a given operator and argument set.
|
||||
//
|
||||
// Usage:
|
||||
// choose_op<(which & op_add)>::template args<left_t,right_t>::add(ext_class);
|
||||
//
|
||||
// (see extension_class<>::def_operators() for more examples).
|
||||
//
|
||||
template <long op_selector>
|
||||
struct choose_op
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args : add_operator_base
|
||||
{
|
||||
static inline void add(extension_class_base* target)
|
||||
{
|
||||
typedef define_operator<op_selector> def_op;
|
||||
add_method(target,
|
||||
new typename def_op::template operator_function<Left, Right>(),
|
||||
def_op::name());
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// specialization for 0 has no effect
|
||||
template <>
|
||||
struct choose_op<0>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args
|
||||
{
|
||||
static inline void add(extension_class_base*)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template <long op_selector>
|
||||
struct choose_unary_op
|
||||
{
|
||||
template <class Operand>
|
||||
struct args : add_operator_base
|
||||
{
|
||||
static inline void add(extension_class_base* target)
|
||||
{
|
||||
typedef define_operator<op_selector> def_op;
|
||||
add_method(target,
|
||||
new typename def_op::template operator_function<Operand>(),
|
||||
def_op::name());
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// specialization for 0 has no effect
|
||||
template <>
|
||||
struct choose_unary_op<0>
|
||||
{
|
||||
template <class Operand>
|
||||
struct args
|
||||
{
|
||||
static inline void add(extension_class_base*)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template <long op_selector>
|
||||
struct choose_rop
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args : add_operator_base
|
||||
{
|
||||
static inline void add(extension_class_base* target)
|
||||
{
|
||||
typedef define_operator<op_selector> def_op;
|
||||
add_method(target,
|
||||
new typename def_op::template roperator_function<Right, Left>(),
|
||||
def_op::rname());
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// specialization for 0 has no effect
|
||||
template <>
|
||||
struct choose_rop<0>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct args
|
||||
{
|
||||
static inline void add(extension_class_base*)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Fully specialize define_operator for all operators defined in operator_id above.
|
||||
// Every specialization defines one function object for normal operator calls and one
|
||||
// for operator calls with operands reversed ("__r*__" function variants).
|
||||
// Specializations for most operators follow a standard pattern: execute the expression
|
||||
// that uses the operator in question. This standard pattern is realized by the following
|
||||
// macros so that the actual specialization can be done by just calling a macro.
|
||||
#define PY_DEFINE_BINARY_OPERATORS(id, oper) \
|
||||
template <> \
|
||||
struct define_operator<op_##id> \
|
||||
{ \
|
||||
template <class Left, class Right = Left> \
|
||||
struct operator_function : function \
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) oper \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
{ return "__" #id "__"; } \
|
||||
}; \
|
||||
\
|
||||
template <class Right, class Left> \
|
||||
struct roperator_function : function \
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) oper \
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
{ return "__r" #id "__"; } \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
static const char * name() { return "__" #id "__"; } \
|
||||
static const char * rname() { return "__r" #id "__"; } \
|
||||
}
|
||||
|
||||
#define PY_DEFINE_UNARY_OPERATORS(id, oper) \
|
||||
template <> \
|
||||
struct define_operator<op_##id> \
|
||||
{ \
|
||||
template <class operand> \
|
||||
struct operator_function : function \
|
||||
{ \
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
|
||||
{ \
|
||||
tuple args(ref(arguments, ref::increment_count)); \
|
||||
\
|
||||
return BOOST_PYTHON_CONVERSION::to_python( \
|
||||
oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()))); \
|
||||
} \
|
||||
\
|
||||
const char* description() const \
|
||||
{ return "__" #id "__"; } \
|
||||
}; \
|
||||
\
|
||||
static const char * name() { return "__" #id "__"; } \
|
||||
}
|
||||
|
||||
PY_DEFINE_BINARY_OPERATORS(add, +);
|
||||
PY_DEFINE_BINARY_OPERATORS(sub, -);
|
||||
PY_DEFINE_BINARY_OPERATORS(mul, *);
|
||||
PY_DEFINE_BINARY_OPERATORS(div, /);
|
||||
PY_DEFINE_BINARY_OPERATORS(mod, %);
|
||||
PY_DEFINE_BINARY_OPERATORS(lshift, <<);
|
||||
PY_DEFINE_BINARY_OPERATORS(rshift, >>);
|
||||
PY_DEFINE_BINARY_OPERATORS(and, &);
|
||||
PY_DEFINE_BINARY_OPERATORS(xor, ^);
|
||||
PY_DEFINE_BINARY_OPERATORS(or, |);
|
||||
|
||||
PY_DEFINE_UNARY_OPERATORS(neg, -);
|
||||
PY_DEFINE_UNARY_OPERATORS(pos, +);
|
||||
PY_DEFINE_UNARY_OPERATORS(abs, abs);
|
||||
PY_DEFINE_UNARY_OPERATORS(invert, ~);
|
||||
PY_DEFINE_UNARY_OPERATORS(int, long);
|
||||
PY_DEFINE_UNARY_OPERATORS(long, PyLong_FromLong);
|
||||
PY_DEFINE_UNARY_OPERATORS(float, double);
|
||||
|
||||
#undef PY_DEFINE_BINARY_OPERATORS
|
||||
#undef PY_DEFINE_UNARY_OPERATORS
|
||||
|
||||
// Some operators need special treatment, e.g. because there is no corresponding
|
||||
// expression in C++. These are specialized manually.
|
||||
|
||||
// pow(): Manual specialization needed because an error message is required if this
|
||||
// function is called with three arguments. The "power modulo" operator is not
|
||||
// supported by define_operator, but can be wrapped manually (see special.html).
|
||||
template <>
|
||||
struct define_operator<op_pow>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(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 argument_error();
|
||||
}
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()),
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__pow__"; }
|
||||
|
||||
};
|
||||
|
||||
template <class Right, class Left>
|
||||
struct roperator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
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 argument_error();
|
||||
}
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()),
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__rpow__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__pow__"; }
|
||||
static const char * rname() { return "__rpow__"; }
|
||||
};
|
||||
|
||||
// divmod(): Manual specialization needed because we must actually call two operators and
|
||||
// return a tuple containing both results
|
||||
template <>
|
||||
struct define_operator<op_divmod>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
PyObject * res = PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(res, 0,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) /
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
PyTuple_SET_ITEM(res, 1,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) %
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__divmod__"; }
|
||||
|
||||
};
|
||||
|
||||
template <class Right, class Left>
|
||||
struct roperator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
PyObject * res = PyTuple_New(2);
|
||||
|
||||
PyTuple_SET_ITEM(res, 0,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) /
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
PyTuple_SET_ITEM(res, 1,
|
||||
BOOST_PYTHON_CONVERSION::to_python(
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) %
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__rdivmod__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__divmod__"; }
|
||||
static const char * rname() { return "__rdivmod__"; }
|
||||
};
|
||||
|
||||
// cmp(): Manual specialization needed because there is no three-way compare in C++.
|
||||
// It is implemented by two one-way comparisons with operators reversed in the second.
|
||||
template <>
|
||||
struct define_operator<op_cmp>
|
||||
{
|
||||
template <class Left, class Right = Left>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>())) ?
|
||||
- 1 :
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Right>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Left>())) ?
|
||||
1 :
|
||||
0) ;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__cmp__"; }
|
||||
|
||||
};
|
||||
|
||||
template <class Right, class Left>
|
||||
struct roperator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
return BOOST_PYTHON_CONVERSION::to_python(
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>())) ?
|
||||
- 1 :
|
||||
(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<Right>()) <
|
||||
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type<Left>())) ?
|
||||
1 :
|
||||
0) ;
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__rcmp__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__cmp__"; }
|
||||
static const char * rname() { return "__rcmp__"; }
|
||||
};
|
||||
|
||||
// str(): Manual specialization needed because the string conversion does not follow
|
||||
// the standard pattern relized by the macros.
|
||||
template <>
|
||||
struct define_operator<op_str>
|
||||
{
|
||||
template <class operand>
|
||||
struct operator_function : function
|
||||
{
|
||||
PyObject* do_call(PyObject* arguments, PyObject*) const
|
||||
{
|
||||
tuple args(ref(arguments, ref::increment_count));
|
||||
|
||||
// When STLport is used with native streams, _STL::ostringstream().str() is not
|
||||
// _STL::string, but std::string.
|
||||
#if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__)
|
||||
std::ostringstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>());
|
||||
return BOOST_PYTHON_CONVERSION::to_python(s.str());
|
||||
#else
|
||||
std::ostrstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()) << char();
|
||||
return BOOST_PYTHON_CONVERSION::to_python(const_cast<char const *>(s.str()));
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* description() const
|
||||
{ return "__str__"; }
|
||||
|
||||
};
|
||||
|
||||
static const char * name() { return "__str__"; }
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif /* OPERATORS_UK112000_H_ */
|
||||
@@ -1,173 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#ifndef PYPTR_DWA050400_H_
|
||||
# define PYPTR_DWA050400_H_
|
||||
|
||||
# include <boost/python/detail/config.hpp>
|
||||
# include <boost/operators.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/python/detail/cast.hpp>
|
||||
# include <cassert>
|
||||
# include <boost/python/detail/signatures.hpp>
|
||||
# include <boost/python/errors.hpp>
|
||||
# include <boost/python/conversions.hpp>
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
template <class T, class Value, class Base>
|
||||
struct py_ptr_conversions : Base
|
||||
{
|
||||
inline friend T from_python(PyObject* x, boost::python::type<const T&>)
|
||||
{ return T(boost::python::downcast<Value>(x).get(), T::increment_count); }
|
||||
|
||||
inline friend T from_python(PyObject* x, boost::python::type<T>)
|
||||
{ return T(boost::python::downcast<Value>(x).get(), T::increment_count); }
|
||||
|
||||
inline friend PyObject* to_python(T x)
|
||||
{ return boost::python::as_object(x.release()); }
|
||||
|
||||
};
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions);
|
||||
|
||||
template <class T>
|
||||
class reference
|
||||
: public py_ptr_conversions<reference<T>, T,
|
||||
boost::dereferenceable<reference<T>, T*> > // supplies op->
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
reference(const reference& rhs)
|
||||
: m_p(rhs.m_p)
|
||||
{
|
||||
Py_XINCREF(object());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MSVC6_OR_EARLIER)
|
||||
template <class T2>
|
||||
reference(const reference<T2>& rhs)
|
||||
: m_p(rhs.object())
|
||||
{
|
||||
Py_XINCREF(object());
|
||||
}
|
||||
#endif
|
||||
|
||||
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 increment_count_t { increment_count };
|
||||
|
||||
enum allow_null { null_ok };
|
||||
|
||||
template <class T2>
|
||||
explicit reference(T2* x)
|
||||
: m_p(expect_non_null(x)) {}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, increment_count_t)
|
||||
: m_p(expect_non_null(x)) { Py_INCREF(object()); }
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, allow_null)
|
||||
: m_p(x) {}
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, allow_null, increment_count_t)
|
||||
: m_p(x) { Py_XINCREF(object()); }
|
||||
|
||||
template <class T2>
|
||||
reference(T2* x, increment_count_t, allow_null)
|
||||
: m_p(x) { Py_XINCREF(object()); }
|
||||
|
||||
#if !defined(BOOST_MSVC6_OR_EARLIER)
|
||||
template <class T2>
|
||||
reference& operator=(const reference<T2>& rhs)
|
||||
{
|
||||
Py_XDECREF(object());
|
||||
m_p = rhs.m_p;
|
||||
Py_XINCREF(object());
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
reference& operator=(const reference& rhs)
|
||||
{
|
||||
Py_XINCREF(static_cast<PyObject*>(rhs.m_p));
|
||||
Py_XDECREF(object());
|
||||
m_p = rhs.m_p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~reference()
|
||||
{
|
||||
Py_XDECREF(m_p);
|
||||
}
|
||||
|
||||
T& operator*() const { return *m_p; }
|
||||
|
||||
T* get() const { return m_p; }
|
||||
|
||||
T* release()
|
||||
{
|
||||
T* p = m_p;
|
||||
m_p = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{ Py_XDECREF(m_p); m_p = 0; }
|
||||
|
||||
template <class T2>
|
||||
void reset(T2* x)
|
||||
{ Py_XDECREF(m_p); m_p = expect_non_null(x);}
|
||||
|
||||
template <class T2>
|
||||
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, allow_null)
|
||||
{ Py_XDECREF(m_p); m_p = x;}
|
||||
|
||||
template <class T2>
|
||||
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, increment_count_t, allow_null)
|
||||
{ Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); }
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
private:
|
||||
template<typename Y> friend class shared_ptr;
|
||||
#endif
|
||||
|
||||
inline PyObject* object() const
|
||||
{ return as_object(m_p); }
|
||||
|
||||
T* m_p;
|
||||
};
|
||||
|
||||
typedef reference<PyObject> ref;
|
||||
|
||||
template <class T>
|
||||
ref make_ref(const T& x)
|
||||
{
|
||||
return ref(to_python(x));
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // PYPTR_DWA050400_H_
|
||||
15
libs/python/Makefile
Normal file
15
libs/python/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
all: lib test
|
||||
|
||||
|
||||
lib::
|
||||
@cd src ; $(MAKE) lib ; cd ..
|
||||
|
||||
test::
|
||||
@cd test ; $(MAKE) test ; cd ..
|
||||
|
||||
install: all
|
||||
@cd src ; $(MAKE) install ; cd ..
|
||||
|
||||
clean:
|
||||
@cd src ; $(MAKE) clean ; cd ..
|
||||
@cd test ; $(MAKE) clean ; cd ..
|
||||
53
libs/python/README
Normal file
53
libs/python/README
Normal file
@@ -0,0 +1,53 @@
|
||||
To build using g++:
|
||||
===================
|
||||
|
||||
> setenv CXX g++
|
||||
>
|
||||
> ./configure \
|
||||
--with-pythoninc=/usr/local/include/python1.5 \
|
||||
--with-extra-includes=/usr/local/STLport
|
||||
>
|
||||
> make install
|
||||
|
||||
where
|
||||
--with-pythoninc: the directory where 'Python.h' lives
|
||||
--with-extra-includes: the directory where STLport includes
|
||||
or the 'limits' header are
|
||||
|
||||
|
||||
To build using another compiler:
|
||||
================================
|
||||
|
||||
> setenv CXX CC # your compiler
|
||||
>
|
||||
> ./configure \
|
||||
--with-pythoninc=/usr/local/include/python1.5 \
|
||||
--with-shared-cxx-linker="$CXX -G" \
|
||||
--with-position-independent-code-flag=-pic
|
||||
>
|
||||
> make install
|
||||
|
||||
where
|
||||
--with-pythoninc: as above
|
||||
--with-shared-cxx-linker: command to build a shared library from C++
|
||||
object files (needed for Python modules)
|
||||
--with-position-independent-code-flag: flag that tells the compiler
|
||||
to create position independent code (needed for shared linking)
|
||||
|
||||
|
||||
more options:
|
||||
=============
|
||||
|
||||
> ./configure --help
|
||||
|
||||
of particular interest are:
|
||||
|
||||
--libdir: the install directory for 'libboostpython.a'
|
||||
--with-shared-library-extension: the file extension for shared libraries
|
||||
--with-extra-libs: link modules against these extra libs
|
||||
(on CYGWIN, you need to link against python15.lib)
|
||||
|
||||
For most options, configure provides reasonable defaults, given in brackets.
|
||||
In particular, it is able to guess the right settings for shared library
|
||||
creation and linking on some common systems. Likewise, it tries to find Python
|
||||
in some standard directories if you don't specify a path explicitly.
|
||||
22
libs/python/build/Makefile.in
Normal file
22
libs/python/build/Makefile.in
Normal file
@@ -0,0 +1,22 @@
|
||||
CXXINCLUDES = @CXXINCLUDES@
|
||||
SCXXFLAGS = @SCXXFLAGS@
|
||||
CXX = @CXX@
|
||||
CXX_SHARED_LINKER = @CXX_SHARED_LINKER@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
TARGET_LIBDIR = @libdir@
|
||||
TARGET_LIBNAME = boostpython
|
||||
TARGET_LIBFILENAME = lib$(TARGET_LIBNAME).a
|
||||
MODULE_EXTENSION = @shared_library_extension@
|
||||
LIBS = @LIBS@
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(SCXXFLAGS) $(CXXINCLUDES) -c $*.cpp
|
||||
|
||||
%.d: %.cpp
|
||||
@echo creating $@
|
||||
@set -e; $(CXX) -M $(SCXXFLAGS) $(CXXINCLUDES) -c $*.cpp \
|
||||
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
1012
libs/python/build/config.guess
vendored
Executable file
1012
libs/python/build/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1238
libs/python/build/config.sub
vendored
Executable file
1238
libs/python/build/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,9 @@
|
||||
BOOST_INLUDES = /local/boost/boost
|
||||
PYTHON_INCLUDES = /local/python/include/python1.5
|
||||
USER_INCLUDES = /local/include
|
||||
LIBDIR = ../../../lib
|
||||
|
||||
|
||||
LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
@@ -11,26 +17,24 @@ LIBSRC = \
|
||||
LIBOBJ = $(LIBSRC:.cpp=.o)
|
||||
OBJ = $(LIBOBJ)
|
||||
|
||||
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
PYTHON_LIB=c:/tools/python/libs/python15.lib
|
||||
INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include
|
||||
MODULE_EXTENSION=dll
|
||||
else
|
||||
INC = -I/usr/local/include/python1.5
|
||||
INC = -I$(USER_INCLUDES) -I$(BOOST_INLUDES) -I$(PYTHON_INCLUDES)
|
||||
MODULE_EXTENSION=so
|
||||
endif
|
||||
|
||||
%.o: ../src/%.cpp
|
||||
g++ -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
|
||||
|
||||
%.d: ../src/%.cpp
|
||||
@echo creating $@
|
||||
@set -e; g++ -M $(INC) -c $< \
|
||||
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
|
||||
example1: example1.o libpycpp.a
|
||||
g++ -shared -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lpycpp
|
||||
python ../example/test_example1.py
|
||||
@@ -38,16 +42,6 @@ example1: example1.o libpycpp.a
|
||||
example1.o: ../example/example1.cpp
|
||||
g++ -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out
|
||||
|
||||
libpycpp.a: $(LIBOBJ)
|
||||
rm -f libpycpp.a
|
||||
ar cq libpycpp.a $(LIBOBJ)
|
||||
|
||||
DEP = $(OBJ:.o=.d)
|
||||
|
||||
ifneq "$(MAKECMDGOALS)" "clean"
|
||||
include $(DEP)
|
||||
endif
|
||||
251
libs/python/build/install-sh
Executable file
251
libs/python/build/install-sh
Executable file
@@ -0,0 +1,251 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
chmodcmd=""
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
||||
1495
libs/python/configure
vendored
Executable file
1495
libs/python/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
308
libs/python/configure.in
Normal file
308
libs/python/configure.in
Normal file
@@ -0,0 +1,308 @@
|
||||
AC_INIT(src/extension_class.cpp)
|
||||
|
||||
AC_PREFIX_DEFAULT([`pwd | sed 's?/libs/python$??'`])
|
||||
|
||||
AC_CONFIG_AUX_DIR(build)
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
||||
AC_CYGWIN
|
||||
AC_MINGW32
|
||||
|
||||
CCFLAGS=-O
|
||||
CXXFLAGS=-O
|
||||
dnl AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
|
||||
AC_DEFUN(AC_SHARED_LINKING,
|
||||
[
|
||||
dnl AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_PROG_CXX])
|
||||
AC_REQUIRE([AC_CYGWIN])
|
||||
AC_REQUIRE([AC_MINGW32])
|
||||
|
||||
# try to guess the right configurations
|
||||
if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
|
||||
shared_library_extension=".dll"
|
||||
else
|
||||
shared_library_extension=".so"
|
||||
fi
|
||||
|
||||
cxx_tmp="dummy $CXX dummy"
|
||||
if test "$GXX" = "yes"; then # g++
|
||||
shared_cxx_linker="g++ -shared"
|
||||
position_independent_code_flag="-fPIC"
|
||||
elif test "$cxx_tmp[2]" = "como"; then # Comeau C++
|
||||
shared_cxx_linker="como-dyn-link"
|
||||
position_independent_code_flag="--pic"
|
||||
elif test "$cxx_tmp[2]" = "cxx"; then # Compaq C++
|
||||
case "$target" in
|
||||
*dec*) shared_cxx_linker="cxx -shared -expect_unresolved '*'"
|
||||
position_independent_code_flag="";;
|
||||
esac
|
||||
elif test "$cxx_tmp[2]" = "CC"; then # native compilers
|
||||
case "$target" in
|
||||
*solaris*) shared_cxx_linker="CC -G"
|
||||
position_independent_code_flag="-pic";;
|
||||
*irix*) shared_cxx_linker="CC -shared"
|
||||
position_independent_code_flag="";;
|
||||
*hpux*) shared_cxx_linker="ld -b"
|
||||
position_independent_code_flag="+z";;
|
||||
esac
|
||||
else
|
||||
shared_c_linker=""
|
||||
shared_cxx_linker=""
|
||||
position_independent_code_flag=""
|
||||
fi
|
||||
|
||||
ifelse( $1, "", [
|
||||
AC_ARG_ENABLE(shared,
|
||||
[ --enable-shared: build shared libraries. This activates default settings for
|
||||
shared linking and position independent code generation (see below).],
|
||||
, )], [enable_shared=$1])
|
||||
|
||||
if test "$enable_shared" != "no" ; then
|
||||
AC_MSG_CHECKING(for shared library extension )
|
||||
AC_ARG_WITH(shared-library-extension,
|
||||
[ --with-shared-library-extension: file extension for shared libraries
|
||||
(including the dot) [UNIX: .so | Win32: .dll] ],, )
|
||||
if test "${with_shared_library_extension:+X}" != ""; then
|
||||
shared_library_extension=$with_shared_library_extension
|
||||
fi
|
||||
AC_MSG_RESULT([$shared_library_extension])
|
||||
AC_SUBST(shared_library_extension)
|
||||
|
||||
dnl AC_MSG_CHECKING(for shared linker for C objects )
|
||||
dnl AC_ARG_WITH(shared-c-linker,
|
||||
dnl [ --with-shared-c-linker: command for creating a shared library from C objects.
|
||||
dnl [ gcc: $(CC) -shared
|
||||
dnl SUN cc: $(CC) -G
|
||||
dnl IRIX cc: $(CC) -shared ] ],
|
||||
dnl , )
|
||||
dnl if test "${with_shared_c_linker:+X}" != ""; then
|
||||
dnl shared_c_linker=$with_shared_c_linker
|
||||
dnl fi
|
||||
dnl AC_MSG_RESULT([$shared_c_linker])
|
||||
dnl CC_SHARED_LINKER="$shared_c_linker"
|
||||
dnl AC_SUBST(CC_SHARED_LINKER)
|
||||
|
||||
AC_MSG_CHECKING(for shared linker for C++ objects )
|
||||
AC_ARG_WITH(shared-cxx-linker,
|
||||
[ --with-shared-cxx-linker: command for creating a shared library from C++ objects.
|
||||
[ g++: $CXX -shared
|
||||
Comeau C++: como-dyn-link
|
||||
Compaq C++: $CXX -shared -expect_unresolved '*'
|
||||
SUN CC: $CXX -G
|
||||
IRIX CC: $CXX -shared
|
||||
HP-UX aCC: ld -b ] ],
|
||||
, )
|
||||
if test "${with_shared_cxx_linker:+X}" != ""; then
|
||||
shared_cxx_linker=$with_shared_cxx_linker
|
||||
fi
|
||||
AC_MSG_RESULT([$shared_cxx_linker])
|
||||
CXX_SHARED_LINKER="$shared_cxx_linker"
|
||||
AC_SUBST(CXX_SHARED_LINKER)
|
||||
|
||||
AC_MSG_CHECKING(for flag to create position independent code )
|
||||
AC_ARG_WITH(position-independent-code-flag,
|
||||
[ --with-position-independent-code-flag: flag that tells the compiler to generate
|
||||
position independent code
|
||||
[ gcc/g++: -fPIC
|
||||
Comeau C++: --pic
|
||||
Compaq C++: <empty>
|
||||
SUN CC: $CXX -pic
|
||||
IRIX CC: <empty>
|
||||
HP-UX aCC: +z ] ],
|
||||
, )
|
||||
if test "${with_position_independent_code_flag:+X}" != ""; then
|
||||
position_independent_code_flag=$with_position_independent_code_flag
|
||||
fi
|
||||
AC_MSG_RESULT([$position_independent_code_flag])
|
||||
SCCFLAGS="$CCFLAGS $position_independent_code_flag"
|
||||
SCXXFLAGS="$CXXFLAGS $position_independent_code_flag"
|
||||
AC_SUBST(SCCFLAGS)
|
||||
AC_SUBST(SCXXFLAGS)
|
||||
fi
|
||||
])
|
||||
|
||||
#########################################################
|
||||
|
||||
AC_DEFUN([AC_WITH_EXTRA_INCLUDES],
|
||||
[
|
||||
AC_ARG_WITH(extra-includes,
|
||||
[ --with-extra-includes=\"dir1 dir2 ...\" : look in these directories for include files],,)
|
||||
|
||||
for i in $with_extra_includes; do
|
||||
CINCLUDES="$CINCLUDES -I"$i
|
||||
CXXINCLUDES="$CXXINCLUDES -I"$i
|
||||
done
|
||||
])
|
||||
|
||||
#########################################################
|
||||
|
||||
AC_DEFUN([AC_WITH_EXTRA_LIBS],
|
||||
[
|
||||
AC_ARG_WITH(extra-libs,
|
||||
[ --with-extra-libs=\"-Ldir1 -llib1 -Ldir2 -llib2 ...\" : link against these libraries ],,)
|
||||
|
||||
LIBS="$CINCLUDES "$with_extra_libs
|
||||
])
|
||||
|
||||
#########################################################
|
||||
|
||||
dnl AC_EXTRACT_REGEX(list, regEx)
|
||||
dnl variable $regExResult returns the first entry in 'list' that matches the
|
||||
dnl regular expression 'regEx', using the 'expr' utility
|
||||
dnl $regExResult = "" if nothing is found
|
||||
AC_DEFUN(AC_EXTRACT_REGEX,
|
||||
[
|
||||
regExResult=""
|
||||
if test "$1" != ""; then
|
||||
for i in $1; do
|
||||
regExResult=`expr "$i" : "$2"`
|
||||
if test "$regExResult" != ""; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
#########################################################
|
||||
|
||||
dnl AC_FIND_PACKAGE(packageName, packageLib, packageInc, packageComment, default)
|
||||
dnl defines with_packageName=yes/no
|
||||
dnl packageNamelib=<path>/not found
|
||||
dnl packageNameinclude=<path>/not found
|
||||
dnl and adds the paths to $LIBS, $CINCLUDES, and $CXXINCLUDES
|
||||
dnl example:
|
||||
dnl AC_FIND_PACKAGE(tiff, tiff, tiff.h, support import/export of tiff images, yes)
|
||||
AC_DEFUN([AC_FIND_PACKAGE],
|
||||
[
|
||||
ifelse($5, "yes",
|
||||
[AC_ARG_WITH([$1], [ --with-$1=dir : $4.
|
||||
if dir=yes: $1 package files will be searched for
|
||||
in some standard directories.
|
||||
if dir is a directory: $1 package files will be searched for
|
||||
using 'find' below dir.
|
||||
alternatively, you can specify:], ,)],
|
||||
[AC_ARG_WITH([$1], [ --with-$1=dir : $4.
|
||||
if dir=yes (default): $1 package files will be searched for
|
||||
in some standard directories.
|
||||
if dir is a directory: $1 package files will be searched for
|
||||
using 'find' below dir.
|
||||
alternatively, you can specify:], ,)])
|
||||
|
||||
ifelse($2, "", ,[AC_ARG_WITH([$1lib], [ --with-$1lib=dir : the $1 package's lib directory], ,)])
|
||||
ifelse($3, "", ,[AC_ARG_WITH([$1inc], [ --with-$1inc=dir : the $1 package's include directory], ,)])
|
||||
|
||||
[$1]lib="not found"
|
||||
[$1]include="not found"
|
||||
|
||||
if test ${with_[$1]:-""} = "" -a ${with_[$1]lib:-""} = "" -a ${with_[$1]inc:-""} = ""; then
|
||||
if test "[$5]" = ""; then
|
||||
with_[$1]="no"
|
||||
else
|
||||
with_[$1]=[$5]
|
||||
fi
|
||||
fi
|
||||
|
||||
if test ${with_[$1]:-""} != "no"; then
|
||||
if test ! [$2] = "" ; then # check for library
|
||||
AC_MSG_CHECKING([for lib$2 ])
|
||||
dirs=""
|
||||
if test -f ${with_[$1]lib:-""}/lib[$2].so; then
|
||||
dirs=${with_[$1]lib:-""}/lib[$2].so
|
||||
elif test -f ${with_[$1]lib:-""}/lib[$2].a; then
|
||||
dirs=${with_[$1]lib:-""}/lib[$2].a
|
||||
elif test -d ${with_[$1]:-""}; then
|
||||
dirs=`find $with_[$1] -name "lib[$2].so" -print; find $with_[$1] -name "lib[$2].a" -print`
|
||||
elif test ${with_[$1]:-""} = "yes"; then
|
||||
for i in /usr/local/lib /usr/local/gnu/lib /usr/local/[$1] /opt/lib /opt/gnu/lib /opt/[$1]; do
|
||||
if test -d $i; then
|
||||
dirs="$dirs "`find $i -name "lib[$2].so" -print; find $i -name "lib[$2].a" -print`
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_EXTRACT_REGEX($dirs, \(.*lib\)/lib$2\.so)
|
||||
if test "$regExResult" = ""; then
|
||||
AC_EXTRACT_REGEX($dirs, \(.*lib\)/lib$2\.a)
|
||||
fi
|
||||
if test "$regExResult" = ""; then
|
||||
AC_EXTRACT_REGEX($dirs, \(.*\)/lib$2\.so)
|
||||
fi
|
||||
if test "$regExResult" = ""; then
|
||||
AC_EXTRACT_REGEX($dirs, \(.*\)/lib$2\.a)
|
||||
fi
|
||||
[$1]lib=${regExResult:-"not found"}
|
||||
AC_MSG_RESULT($[$1]lib)
|
||||
else
|
||||
[$1]lib=""
|
||||
fi
|
||||
|
||||
if test ! [$3] = "" ; then # check for header
|
||||
AC_MSG_CHECKING([for $3 ])
|
||||
if test -f ${with_[$1]inc:-""}/[$3]; then
|
||||
dirs=$with_[$1]inc/[$3]
|
||||
elif test -d ${with_[$1]:-""}; then
|
||||
dirs=`find $with_[$1] -name patsubst([$3], .*/, ) -print`
|
||||
elif test ${with_[$1]:-""} = "yes"; then
|
||||
for i in /usr/local/include /usr/local/gnu/include /usr/local/[$1] \
|
||||
/opt/include /opt/gnu/include /opt/[$1]; do
|
||||
if test -d $i; then
|
||||
dirs="$dirs "`find $i -name patsubst([$3], .*/, ) -print`
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_EXTRACT_REGEX($dirs, \(.*include\)/patsubst([$3], \., \\.))
|
||||
if test "$regExResult" = ""; then
|
||||
AC_EXTRACT_REGEX($dirs, \(.*\)/patsubst([$3], \., \\.))
|
||||
fi
|
||||
[$1]include=${regExResult:-"not found"}
|
||||
AC_MSG_RESULT($[$1]include)
|
||||
else
|
||||
[$1]include=""
|
||||
fi
|
||||
|
||||
if test "$[$1]lib" = "not found" -o "$[$1]include" = "not found"; then
|
||||
with_[$1]="no"
|
||||
AC_MSG_WARN( Configuring without [$1] support)
|
||||
else
|
||||
with_[$1]="yes"
|
||||
if test ! [$2] = "" ; then
|
||||
LIBS="$LIBS -L$[$1]lib -l[$2]"
|
||||
fi
|
||||
if test ! [$3] = "" ; then
|
||||
CINCLUDES="$CINCLUDES -I$[$1]include"
|
||||
CXXINCLUDES="$CXXINCLUDES -I$[$1]include"
|
||||
AC_SUBST(CXXINCLUDES)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
#########################################################
|
||||
|
||||
AC_WITH_EXTRA_INCLUDES
|
||||
AC_WITH_EXTRA_LIBS
|
||||
AC_SHARED_LINKING(yes)
|
||||
|
||||
#########################################################
|
||||
|
||||
AC_CHECK_PROG(python_prog, python, [yes], [not found])
|
||||
if test "$python_prog" = "yes"; then
|
||||
AC_FIND_PACKAGE(python, "", Python.h, Python includes (required!), yes)
|
||||
else
|
||||
with_python="no"
|
||||
fi
|
||||
if test "$with_python" = "no"; then
|
||||
AC_MSG_ERROR(Python support required to install BPL)
|
||||
fi
|
||||
|
||||
#########################################################
|
||||
|
||||
boost_includes=[-I`pwd | sed 's?/libs/python$??'`]
|
||||
CXXINCLUDES="$CXXINCLUDES $boost_includes"
|
||||
|
||||
#########################################################
|
||||
|
||||
AC_OUTPUT(build/Makefile)
|
||||
116
libs/python/doc/building.html
Normal file
116
libs/python/doc/building.html
Normal file
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Building an Extension Module
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Building an Extension Module
|
||||
</h1>
|
||||
<p>
|
||||
Right now, the only supported configuration is one in which the BPL
|
||||
source files are statically linked with the source for your extension
|
||||
module. BPL comes with a standard build process that compiles the
|
||||
BPL sources, builds the library <code>'libboostpython.a'</code>,
|
||||
runs a comprehensive test suite and (upon success)
|
||||
copies the library into an installation directory specified by the
|
||||
user. To involke this build process, you need to do the following:
|
||||
|
||||
<h4>Compilation with GNU g++:</h4>
|
||||
|
||||
<blockquote><pre>
|
||||
> cd <boost_root>/libs/python
|
||||
> setenv CXX g++ # use g++
|
||||
>
|
||||
> ./configure \
|
||||
--with-pythoninc=/usr/local/include/python1.5 \
|
||||
--with-extra-includes=/usr/local/STLport
|
||||
>
|
||||
> make install
|
||||
</pre></blockquote>
|
||||
|
||||
where
|
||||
<blockquote><pre>
|
||||
--with-pythoninc: the directory where 'Python.h' lives
|
||||
--with-extra-includes: the directory where STLport includes
|
||||
or the 'limits' header are
|
||||
</pre></blockquote>
|
||||
|
||||
<h4>Compilation with another compiler:</h4>
|
||||
|
||||
<blockquote><pre>
|
||||
> cd <boost_root>/libs/python
|
||||
> setenv CXX CC # your compiler
|
||||
>
|
||||
> ./configure \
|
||||
--with-pythoninc=/usr/local/include/python1.5 \
|
||||
--with-shared-cxx-linker="$CXX -G" \
|
||||
--with-position-independent-code-flag=-pic
|
||||
>
|
||||
> make install
|
||||
</pre></blockquote>
|
||||
|
||||
where
|
||||
<blockquote><pre>
|
||||
--with-pythoninc: as above
|
||||
--with-shared-cxx-linker: command to build a shared library from C++
|
||||
object files (needed for Python modules)
|
||||
--with-position-independent-code-flag: flag that tells the compiler
|
||||
to create position independent code (needed for shared linking)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
<code>configure</code> provides additional options that are listed
|
||||
after invoking
|
||||
|
||||
<blockquote><pre>
|
||||
> ./configure --help
|
||||
</pre></blockquote>
|
||||
|
||||
Of particular interest are the following options:
|
||||
|
||||
<blockquote><pre>
|
||||
--libdir: the install directory for 'libboostpython.a'
|
||||
--enable-shared-library-extension: the file extension for shared libraries
|
||||
</pre></blockquote>
|
||||
|
||||
For most options, configure provides reasonable defaults, given in
|
||||
brackets. In particular, it is able to guess the right settings for
|
||||
shared library creation and linking on some common systems. Likewise,
|
||||
it tries to find Python in some standard directories if you don't
|
||||
specify a path explicitly.
|
||||
<p>
|
||||
If this build process doesn't work for you, you must compile the
|
||||
source files manually. The BPL source files are:
|
||||
<blockquote>
|
||||
<pre>
|
||||
<a href="../../../libs/python/src/extension_class.cpp">extclass.cpp</a>
|
||||
<a href="../../../libs/python/src/functions.cpp">functions.cpp</a>
|
||||
<a href="../../../libs/python/src/init_function.cpp">init_function.cpp</a>
|
||||
<a href="../../../libs/python/src/module_builder.cpp">module.cpp</a>
|
||||
<a href="../../../libs/python/src/types.cpp">newtypes.cpp</a>
|
||||
<a href="../../../libs/python/src/objects.cpp">objects.cpp</a>
|
||||
<a href="../../../libs/python/src/conversions.cpp">py.cpp</a>
|
||||
<a href="../../../libs/python/src/classes.cpp">subclass.cpp</a>
|
||||
</pre>
|
||||
</blockquote>
|
||||
You may first build them into a library and link it with your
|
||||
extension module source, but the effect is the same as compiling all
|
||||
the source files together. Some users have successfully built the
|
||||
sources into a shared library, and support for a shared library
|
||||
build is planned, but not yet implemented.
|
||||
<p>
|
||||
Next: <a href="enums.html">Enums</a>
|
||||
Previous: <a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as
|
||||
is'' without express or implied warranty, and with no claim as to
|
||||
its suitability for any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
</div>
|
||||
|
||||
@@ -657,7 +657,7 @@ for i in S:
|
||||
for (iterator i = S.begin(), end = S.end(); i != end; ++i)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>One could try to wrap C++ iterators directly in order to carry the C++ idiom into
|
||||
<p>One could try to wrap C++ iterators in order to carry the C++ idiom into
|
||||
Python. However, this does not work very well because
|
||||
|
||||
<ol>
|
||||
@@ -671,78 +671,10 @@ for (iterator i = S.begin(), end = S.end(); i != end; ++i)
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Therefore, BPL provides a special helper class "cursor" that acts as
|
||||
an adapter for STL iterators and enables them to be used within
|
||||
normal Python loops. Suppose, for example, that we want to wrap a
|
||||
<code>std::list<BigNum></code>. First, we have to wrap this class itself,
|
||||
as usual:
|
||||
|
||||
<blockquote><pre>
|
||||
// wrap an STL conforming container
|
||||
boost::python::class_builder<std::list<BigNum> > bignum_list_class(my_module, "BigNumList");
|
||||
|
||||
bignum_list_class.def(boost::python::constructor<>());
|
||||
|
||||
bignum_list_class.def((void (std::list<BigNum>::*)(BigNum const &))
|
||||
&std::list<BigNum>::push_back, "push_back");
|
||||
</pre></blockquote>
|
||||
|
||||
Since <code>std::list</code> conforms to the requirements
|
||||
of an STL container, we may create a cursor for it:
|
||||
|
||||
<blockquote><pre>
|
||||
// define cursor for an STL conforming container
|
||||
my_module.def_cursor_for(bignum_list_class);
|
||||
</pre></blockquote>
|
||||
|
||||
This enables the following use of <code>BigNumList</code> within Python:
|
||||
|
||||
<blockquote><pre>
|
||||
>>> l = BigNumList()
|
||||
>>>
|
||||
>>> l.push_back(BigNum(1)) # fill the list
|
||||
>>> l.push_back(BigNum(2))
|
||||
>>> l.push_back(BigNum(3))
|
||||
>>>
|
||||
>>> for i in l.cursor(): # use list's cursor in a loop
|
||||
... print i
|
||||
...
|
||||
1
|
||||
2
|
||||
3
|
||||
</pre></blockquote>
|
||||
|
||||
The cursor defines random access functions ("__getitem__" and
|
||||
"__setitem__") for any iterator, but these functions will only be
|
||||
as efficient as the underlying iterator allows. Indices are in the
|
||||
range <code>[0, cursor.len()-1]</code>. You can always
|
||||
access items in any order:
|
||||
|
||||
<blockquote><pre>
|
||||
>>> cursor = l.cursor() # get cursor
|
||||
>>> cursor.len() # length of the sequence
|
||||
3
|
||||
>>> print cursor[2] # read element at index
|
||||
3
|
||||
>>> print cursor[0]
|
||||
1
|
||||
>>> cursor[1] = BigNum(42) # write element at index
|
||||
>>> print cursor[1]
|
||||
42
|
||||
</pre></blockquote>
|
||||
|
||||
but this may be slow (linear time per access) on a large list
|
||||
which provides only a forward or bi-directional iterator. Note that this
|
||||
is not a problem for the loop above because it always accesses items
|
||||
in forward order.
|
||||
|
||||
<p>
|
||||
An alternative way of wrapping your containers is to support
|
||||
Python's standard <a
|
||||
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/sequence-types.html">
|
||||
sequence and mapping protocols</a>. The special functions
|
||||
required by these protocols have to be wrapped manually because there
|
||||
are no corresponding
|
||||
It is a better idea to support the standard <a
|
||||
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/sequence-types.html">Python
|
||||
sequence and mapping protocols</a> 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">
|
||||
27
libs/python/src/Makefile
Normal file
27
libs/python/src/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
include ../build/Makefile
|
||||
|
||||
LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
module_builder.cpp \
|
||||
objects.cpp \
|
||||
types.cpp
|
||||
|
||||
LIBOBJ = $(LIBSRC:.cpp=.o)
|
||||
|
||||
lib: $(TARGET_LIBFILENAME)
|
||||
|
||||
install: lib
|
||||
@if [ ! -d $(TARGET_LIBDIR) ] ; then mkdir -p $(TARGET_LIBDIR) ; fi
|
||||
cp $(TARGET_LIBFILENAME) $(TARGET_LIBDIR)
|
||||
|
||||
$(TARGET_LIBFILENAME): $(LIBOBJ)
|
||||
rm -f $(TARGET_LIBFILENAME)
|
||||
ar cq $(TARGET_LIBFILENAME) $(LIBOBJ)
|
||||
|
||||
clean:
|
||||
rm -rf *.o *$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out
|
||||
|
||||
@@ -324,98 +324,6 @@ class read_only_setattr_function : public function
|
||||
string m_name;
|
||||
};
|
||||
|
||||
|
||||
/* helper class to wrap STL conforming iterators.
|
||||
|
||||
Given a wrapped container ("FooList", say), this template is used to create
|
||||
an auxiliary class "FooList_cursor" that wraps the container's iterator.
|
||||
The cursor can be used in Python loops likes this:
|
||||
|
||||
>>> for i in foo_list.cursor():
|
||||
... print i.get_data()
|
||||
|
||||
The auxiliary cursor class can be created for any STL conforming
|
||||
container. It implements random access functions (get_item() and
|
||||
set_item()) for any iterator, but these will only be as efficient as the
|
||||
underlying iterator allows. However, this is not a problem because
|
||||
the above Python loop accesses the items in forward order anyway.
|
||||
*/
|
||||
template <class Container>
|
||||
struct cursor
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
typedef typename Container::value_type value_type;
|
||||
|
||||
cursor(Container & c, ref python_object)
|
||||
: m_python_object(python_object),
|
||||
m_begin(c.begin()),
|
||||
m_iter(c.begin()),
|
||||
m_size(c.size()),
|
||||
m_index(0)
|
||||
{}
|
||||
|
||||
void advance(int index, std::forward_iterator_tag)
|
||||
{
|
||||
if(index < 0 || index >= m_size)
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(index));
|
||||
throw python::error_already_set();
|
||||
}
|
||||
|
||||
int delta = index - m_index;
|
||||
if(delta < 0)
|
||||
{
|
||||
m_iter = m_begin;
|
||||
delta = index;
|
||||
}
|
||||
std::advance(m_iter, delta);
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
void advance(int index, std::bidirectional_iterator_tag)
|
||||
{
|
||||
if(index < 0 || index >= m_size)
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(index));
|
||||
throw python::error_already_set();
|
||||
}
|
||||
int delta = index - m_index;
|
||||
std::advance(m_iter, delta);
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
value_type const & get_item(int index)
|
||||
{
|
||||
advance(index, std::iterator_category(m_iter));
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
void set_item(int index, value_type const & v)
|
||||
{
|
||||
advance(index, std::iterator_category(m_iter));
|
||||
*m_iter = v;
|
||||
}
|
||||
|
||||
int len() const
|
||||
{ return m_size; }
|
||||
|
||||
ref m_python_object;
|
||||
iterator m_begin, m_iter;
|
||||
int m_index, m_size;
|
||||
};
|
||||
|
||||
/* create a cursor for an STL conforming container */
|
||||
template <class T>
|
||||
struct extension_class_cursor_factory
|
||||
{
|
||||
static cursor<T> get(ref container)
|
||||
{
|
||||
return cursor<T>(
|
||||
BOOST_PYTHON_CONVERSION::from_python(container.get(), type<T&>()),
|
||||
container);
|
||||
}
|
||||
};
|
||||
|
||||
template <class From, class To>
|
||||
struct define_conversion
|
||||
{
|
||||
19
libs/python/test/Makefile
Normal file
19
libs/python/test/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
include ../build/Makefile
|
||||
|
||||
LIBBPL = ../src/$(TARGET_LIBFILENAME)
|
||||
|
||||
test: test_result
|
||||
@if [ ! -f test_result -o -s test_result ] ; then \
|
||||
echo "tests failed:" ; cat test_result ; exit 1; \
|
||||
else echo "tests OK" ; fi
|
||||
|
||||
test_result: testmodule$(MODULE_EXTENSION) comprehensive.py
|
||||
@rm -f test_result
|
||||
python comprehensive.py > test_result
|
||||
|
||||
testmodule$(MODULE_EXTENSION): $(LIBBPL) comprehensive.o
|
||||
$(CXX_SHARED_LINKER) -o testmodule$(MODULE_EXTENSION) comprehensive.o $(LIBBPL) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o *$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out test_result
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <stdio.h> // used for portability on broken compilers
|
||||
#include <math.h> // for pow()
|
||||
#include <boost/rational.hpp>
|
||||
#include <list>
|
||||
|
||||
namespace bpl_test {
|
||||
|
||||
@@ -1010,15 +1009,6 @@ void init_module(boost::python::module_builder& m)
|
||||
// export non-operator function as heterogeneous reverse-argument operator
|
||||
int_class.def(&rmul, "__rmul__");
|
||||
|
||||
// wrap an STL conforming container
|
||||
boost::python::class_builder<std::list<Int> > intlist_class(m, "IntList");
|
||||
|
||||
intlist_class.def(boost::python::constructor<>());
|
||||
intlist_class.def((void (std::list<Int>::*)(Int const &))
|
||||
&std::list<Int>::push_back, "append");
|
||||
|
||||
// wrap the iterator of an STL conforming container in a cursor
|
||||
m.def_cursor_for(intlist_class);
|
||||
|
||||
boost::python::class_builder<EnumOwner> enum_owner(m, "EnumOwner");
|
||||
enum_owner.def(boost::python::constructor<EnumOwner::enum_type, const EnumOwner::enum_type&>());
|
||||
@@ -1029,30 +1029,6 @@ Test operator export to a subclass
|
||||
>>> j.i()
|
||||
15
|
||||
|
||||
========= Test creation of a cursor for an STL conforming container ==========
|
||||
|
||||
>>> i1 = Int(1)
|
||||
>>> i2 = Int(2)
|
||||
>>> i3 = Int(3)
|
||||
>>> l = IntList()
|
||||
>>> l.append(i1)
|
||||
>>> l.append(i2)
|
||||
>>> l.append(i3)
|
||||
>>> for i in l.cursor():
|
||||
... print i.i()
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
test that cursor keeps a reference to its container
|
||||
|
||||
>>> c = l.cursor()
|
||||
>>> del l
|
||||
>>> for i in c:
|
||||
... print i.i()
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
========= Prove that the "phantom base class" issue is resolved ==========
|
||||
|
||||
Reference in New Issue
Block a user