mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 04:42:28 +00:00
Compare commits
181 Commits
svn-branch
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c75c27e7ca | ||
|
|
4eadbb299e | ||
|
|
ac20fcca63 | ||
|
|
cd00f7b01f | ||
|
|
d4b215a66b | ||
|
|
1a13387012 | ||
|
|
291c36df05 | ||
|
|
bed2c8a371 | ||
|
|
e65ca4ccac | ||
|
|
f9e6933840 | ||
|
|
5134fb2ec1 | ||
|
|
3a86a69964 | ||
|
|
c6fd3c47a4 | ||
|
|
a365fa6109 | ||
|
|
160451b210 | ||
|
|
2f6e3cc09d | ||
|
|
d05cc7ccec | ||
|
|
ccfd4acbda | ||
|
|
6a6084ed0e | ||
|
|
0dbb780a2f | ||
|
|
e6efa6e13e | ||
|
|
76768120d4 | ||
|
|
7d6ff83760 | ||
|
|
5bec0d2d98 | ||
|
|
aad05325a6 | ||
|
|
6e7f1bc257 | ||
|
|
634d0848c8 | ||
|
|
b7e1059227 | ||
|
|
e7904fa67a | ||
|
|
e38bc7cbce | ||
|
|
b211f8a096 | ||
|
|
b4a1a6c688 | ||
|
|
6cb4b790b9 | ||
|
|
a245bdbc2a | ||
|
|
e63451a9e7 | ||
|
|
e552607c95 | ||
|
|
c7f1c5e29c | ||
|
|
37b6e22321 | ||
|
|
6e6ae18aab | ||
|
|
9f3cda0ac3 | ||
|
|
f646975c36 | ||
|
|
801cae13ac | ||
|
|
f1ae502b1f | ||
|
|
f2e34d4836 | ||
|
|
3c6a8d718f | ||
|
|
08eb28f7b8 | ||
|
|
24509a21d4 | ||
|
|
4f41a10fef | ||
|
|
26aa8b69f9 | ||
|
|
819db1524f | ||
|
|
8ad7d06ec6 | ||
|
|
606898f569 | ||
|
|
76c6adf1cf | ||
|
|
e504c3cd46 | ||
|
|
884b59a0b3 | ||
|
|
a32dedd16c | ||
|
|
ff2b37f6e3 | ||
|
|
4328ae1d8d | ||
|
|
88372000b5 | ||
|
|
081150b477 | ||
|
|
1364b97b88 | ||
|
|
7c33a46a76 | ||
|
|
8b88e9f727 | ||
|
|
91f0728b55 | ||
|
|
7a71cea92a | ||
|
|
29a855813d | ||
|
|
66da2339d4 | ||
|
|
294254efbb | ||
|
|
188597ecaf | ||
|
|
d04f613c41 | ||
|
|
25320cd0e0 | ||
|
|
00b4f09e8a | ||
|
|
fb8d9edfdf | ||
|
|
349b9bb2bf | ||
|
|
cbff11296b | ||
|
|
dc462cdc1f | ||
|
|
22024e7c1f | ||
|
|
ebb0145256 | ||
|
|
c3215d0ba5 | ||
|
|
da83f20a28 | ||
|
|
ad4b0fff56 | ||
|
|
62b90206e8 | ||
|
|
38ac4fe849 | ||
|
|
fa7b6591cf | ||
|
|
fde432601a | ||
|
|
0c954dde27 | ||
|
|
b5a86a9045 | ||
|
|
ef7c437957 | ||
|
|
8158a509c9 | ||
|
|
dc520c6c32 | ||
|
|
907033f725 | ||
|
|
533a005764 | ||
|
|
9ee563b864 | ||
|
|
748c118ea8 | ||
|
|
69e69a77d8 | ||
|
|
5a40cec1ed | ||
|
|
01bcd460da | ||
|
|
2a96c9f9ee | ||
|
|
f610e31a87 | ||
|
|
4ec0b61de5 | ||
|
|
c7d7cec281 | ||
|
|
c4775a581e | ||
|
|
591eaeaafb | ||
|
|
1f45a846c6 | ||
|
|
db943b4109 | ||
|
|
098eadefe0 | ||
|
|
13b2e072d2 | ||
|
|
c068a300f4 | ||
|
|
60b91ac678 | ||
|
|
c979ab01af | ||
|
|
012b4025a4 | ||
|
|
ff04d9f03c | ||
|
|
ed34cd45f1 | ||
|
|
7dc8fab961 | ||
|
|
14acb1af8c | ||
|
|
678fa006de | ||
|
|
f5416ebce0 | ||
|
|
585063f6e1 | ||
|
|
494f12090f | ||
|
|
55321b8778 | ||
|
|
a6b0fa546a | ||
|
|
33ea0dbdee | ||
|
|
a559480716 | ||
|
|
bdbd9a0f5f | ||
|
|
945344b3cd | ||
|
|
5759ce9ba0 | ||
|
|
a350b666fa | ||
|
|
041409d715 | ||
|
|
98b31ed073 | ||
|
|
00cea4ff83 | ||
|
|
617bcdac9f | ||
|
|
116b3db1d1 | ||
|
|
53d2398e06 | ||
|
|
dd0e42cf72 | ||
|
|
b0d6d40c2a | ||
|
|
2d568b1c0f | ||
|
|
5b13e75fa5 | ||
|
|
23725680c9 | ||
|
|
f49141f71e | ||
|
|
fdff5e33b3 | ||
|
|
149cc499ed | ||
|
|
2e145ea916 | ||
|
|
1edec9ff89 | ||
|
|
a559a371b1 | ||
|
|
7d29c6a0f7 | ||
|
|
5ad51c36fb | ||
|
|
03dd2883f7 | ||
|
|
7208104122 | ||
|
|
405710e635 | ||
|
|
f6ba5a41da | ||
|
|
af6cfd0ea8 | ||
|
|
a3f822b7d3 | ||
|
|
afdaa4d0d8 | ||
|
|
bf5eec727e | ||
|
|
f82151f925 | ||
|
|
4b926b7c7f | ||
|
|
4aa4f1c3b3 | ||
|
|
71aff9f0e8 | ||
|
|
a40daca9ef | ||
|
|
0b97d9bae5 | ||
|
|
28e6a84acb | ||
|
|
fc62d3b44e | ||
|
|
b06d9e50eb | ||
|
|
1d4427c056 | ||
|
|
51d60a6035 | ||
|
|
f5fa4a460a | ||
|
|
977841a7f3 | ||
|
|
b000c75947 | ||
|
|
f3d9193743 | ||
|
|
0d04bf8e34 | ||
|
|
1d17690f69 | ||
|
|
4d19be8ea4 | ||
|
|
1d4dfdf271 | ||
|
|
f24a95c917 | ||
|
|
e508842da6 | ||
|
|
b0d9bbc0b1 | ||
|
|
6238770324 | ||
|
|
a8641c69cc | ||
|
|
7d9332e94f | ||
|
|
7ca17b7bd9 | ||
|
|
e5670d5e3c |
142
build/Jamfile
Normal file
142
build/Jamfile
Normal file
@@ -0,0 +1,142 @@
|
||||
# (C) Copyright David Abrahams 2001. 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.
|
||||
#
|
||||
# Boost.Python build and test Jamfile
|
||||
#
|
||||
# To run all tests quietly: jam test
|
||||
# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test
|
||||
#
|
||||
# Declares the following targets:
|
||||
# 1. libboost_python, a static link library to be linked with all
|
||||
# Boost.Python modules
|
||||
#
|
||||
# 2. pairs of test targets of the form <name>.test and <name>.run
|
||||
# <name>.test runs the test when it is out-of-date, and the "test"
|
||||
# pseudotarget depends on it. <name>.run runs
|
||||
# a test unconditionally, and can be used to force a test to run.. Each
|
||||
# test target builds one or more Boost.Python modules and runs a Python
|
||||
# script to test them. The test names are:
|
||||
#
|
||||
# from ../test
|
||||
#
|
||||
# comprehensive - a comprehensive test of Boost.Python features
|
||||
#
|
||||
# from ../example:
|
||||
# abstract -
|
||||
# getting_started1 -
|
||||
# getting_started2 -
|
||||
# simple_vector -
|
||||
# do_it_yourself_convts -
|
||||
# pickle1 -
|
||||
# pickle2 -
|
||||
# pickle3 -
|
||||
#
|
||||
# dvect1 -
|
||||
# dvect2 -
|
||||
# ivect1 -
|
||||
# ivect2 -
|
||||
# noncopyable -
|
||||
#
|
||||
# subproject-specific environment/command-line variables:
|
||||
#
|
||||
# PYTHON - How to invoke the Python interpreter. Defaults to "python"
|
||||
#
|
||||
# PYTHON_ROOT - Windows only: where Python is installed. Defaults to "c:/tools/python"
|
||||
#
|
||||
# PYTHON_VERSION - Version of Python. Defaults to "2.1" on Windows, "1.5" on Unix
|
||||
#
|
||||
# PYTHON_TEST_ARGS - specifies arguments to be passed to test scripts on
|
||||
# the command line. "-v" can be useful if you want to
|
||||
# see the output of successful tests.
|
||||
#
|
||||
# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for
|
||||
# the dvect and ivect tests above.
|
||||
|
||||
# declare the location of this subproject relative to the root
|
||||
subproject libs/python/build ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
#######################
|
||||
local rule bpl-test ( test-name : sources + )
|
||||
{
|
||||
boost-python-test $(test-name) : $(sources) <lib>libboost_python ;
|
||||
}
|
||||
|
||||
#######################
|
||||
|
||||
#
|
||||
# Declare the boost python static link library
|
||||
#
|
||||
|
||||
# Base names of the source files for libboost_python
|
||||
local CPP_SOURCES =
|
||||
types classes conversions extension_class functions
|
||||
init_function module_builder objects cross_module ;
|
||||
|
||||
lib libboost_python : ../src/$(CPP_SOURCES).cpp
|
||||
# requirements
|
||||
: $(BOOST_PYTHON_INCLUDES)
|
||||
<shared-linkable>true
|
||||
$(PYTHON_PROPERTIES) ;
|
||||
|
||||
|
||||
############# comprehensive module and test ###########
|
||||
bpl-test boost_python_test
|
||||
: ../test/comprehensive.cpp ;
|
||||
|
||||
boost-python-runtest comprehensive
|
||||
: ../test/comprehensive.py <lib>boost_python_test <lib>libboost_python ;
|
||||
|
||||
############# simple tests from ../example ############
|
||||
|
||||
local rule boost-python-example-runtest ( name )
|
||||
{
|
||||
bpl-test $(name)
|
||||
: ../example/$(name).cpp ;
|
||||
|
||||
boost-python-runtest $(name)
|
||||
: ../example/test_$(name).py <lib>$(name) ;
|
||||
}
|
||||
|
||||
|
||||
boost-python-example-runtest abstract ;
|
||||
boost-python-example-runtest getting_started1 ;
|
||||
boost-python-example-runtest getting_started2 ;
|
||||
boost-python-example-runtest simple_vector ;
|
||||
boost-python-example-runtest do_it_yourself_convts ;
|
||||
boost-python-example-runtest pickle1 ;
|
||||
boost-python-example-runtest pickle2 ;
|
||||
boost-python-example-runtest pickle3 ;
|
||||
|
||||
|
||||
bpl-test ivect : ../example/ivect.cpp ;
|
||||
bpl-test dvect : ../example/dvect.cpp ;
|
||||
bpl-test noncopyable_export : ../example/noncopyable_export.cpp ;
|
||||
bpl-test noncopyable_import : ../example/noncopyable_import.cpp ;
|
||||
|
||||
############## cross-module tests from ../example ##########
|
||||
|
||||
# A simple rule to build a test which depends on multiple modules in the PYTHONPATH
|
||||
local rule boost-python-multi-example-runtest ( test-name : modules + )
|
||||
{
|
||||
boost-python-runtest $(test-name)
|
||||
: ../example/tst_$(test-name).py <lib>$(modules) <lib>libboost_python
|
||||
: : : $(PYTHON_VECT_ITERATIONS) ;
|
||||
}
|
||||
|
||||
PYTHON_VECT_ITERATIONS ?= 10 ;
|
||||
|
||||
boost-python-multi-example-runtest dvect1 : ivect dvect ;
|
||||
boost-python-multi-example-runtest dvect2 : ivect dvect ;
|
||||
|
||||
boost-python-multi-example-runtest ivect1 : ivect dvect ;
|
||||
boost-python-multi-example-runtest ivect2 : ivect dvect ;
|
||||
|
||||
boost-python-multi-example-runtest
|
||||
noncopyable : noncopyable_import noncopyable_export ;
|
||||
|
||||
233
include/boost/python/detail/arg_tuple_size.hpp
Normal file
233
include/boost/python/detail/arg_tuple_size.hpp
Normal file
@@ -0,0 +1,233 @@
|
||||
// (C) Copyright David Abrahams 2001. 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.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_arg_tuple_size.python
|
||||
|
||||
#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
# define ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// Computes (at compile-time) the number of elements that a Python
|
||||
// argument tuple must have in order to be passed to a wrapped C++
|
||||
// (member) function of the given type.
|
||||
template <class F> struct arg_tuple_size;
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__)
|
||||
|
||||
template <class R>
|
||||
struct arg_tuple_size<R (*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 0);
|
||||
};
|
||||
|
||||
template <class R, class A1>
|
||||
struct arg_tuple_size<R (*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
struct arg_tuple_size<R (*)(A1, A2)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
struct arg_tuple_size<R (*)(A1, A2, A3, A4, A5, A6)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
struct arg_tuple_size<R (A0::*)()>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
struct arg_tuple_size<R (A0::*)(A1)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 2);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 3);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 4);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 5);
|
||||
};
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
struct arg_tuple_size<R (A0::*)(A1, A2, A3, A4, A5)>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = 6);
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
// We will use the "sizeof() trick" to work around the lack of
|
||||
// partial specialization in MSVC6 and its broken-ness in borland.
|
||||
// See http://opensource.adobe.com or
|
||||
// http://groups.yahoo.com/group/boost/message/5441 for
|
||||
// more examples
|
||||
|
||||
// This little package is used to transmit the number of arguments
|
||||
// from the helper functions below to the sizeof() expression below.
|
||||
// Because we can never have an array of fewer than 1 element, we
|
||||
// add 1 to n and then subtract 1 from the result of sizeof() below.
|
||||
template <int n>
|
||||
struct char_array
|
||||
{
|
||||
char elements[n+1];
|
||||
};
|
||||
|
||||
// The following helper functions are never actually called, since
|
||||
// they are only used within a sizeof() expression, but the type of
|
||||
// their return value is used to discriminate between various free
|
||||
// and member function pointers at compile-time.
|
||||
|
||||
template <class R>
|
||||
char_array<0> arg_tuple_size_helper(R (*)());
|
||||
|
||||
template <class R, class A1>
|
||||
char_array<1> arg_tuple_size_helper(R (*)(A1));
|
||||
|
||||
template <class R, class A1, class A2>
|
||||
char_array<2> arg_tuple_size_helper(R (*)(A1, A2));
|
||||
|
||||
template <class R, class A1, class A2, class A3>
|
||||
char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4>
|
||||
char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5));
|
||||
|
||||
template <class R, class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6));
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)());
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1));
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4));
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5));
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() const);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const);
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() volatile);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile);
|
||||
|
||||
|
||||
template <class R, class A0>
|
||||
char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile);
|
||||
|
||||
template <class R, class A0, class A1>
|
||||
char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2>
|
||||
char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3>
|
||||
char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4>
|
||||
char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile);
|
||||
|
||||
template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile);
|
||||
|
||||
|
||||
template <class F>
|
||||
struct arg_tuple_size
|
||||
{
|
||||
// The sizeof() magic happens here
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value
|
||||
= sizeof(arg_tuple_size_helper(F(0)).elements) - 1);
|
||||
};
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // ARG_TUPLE_SIZE_DWA20011201_HPP
|
||||
|
||||
64
include/boost/python/detail/base_object.hpp
Normal file
64
include/boost/python/detail/base_object.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// (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.
|
||||
//
|
||||
// Revision History:
|
||||
// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams)
|
||||
|
||||
#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 PythonType>
|
||||
struct base_object : PythonType
|
||||
{
|
||||
typedef PythonType 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;
|
||||
|
||||
|
||||
//
|
||||
// base_object member function implementations
|
||||
//
|
||||
template <class PythonType>
|
||||
base_object<PythonType>::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));
|
||||
Py_INCREF(type_obj);
|
||||
PyObject_INIT(bp, type_obj);
|
||||
}
|
||||
|
||||
template <class PythonType>
|
||||
inline base_object<PythonType>::~base_object()
|
||||
{
|
||||
Py_DECREF(ob_type);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // BASE_OBJECT_DWA051600_H_
|
||||
27
include/boost/python/detail/caller.hpp
Normal file
27
include/boost/python/detail/caller.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright David Abrahams 2001. 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.
|
||||
#ifndef CALLER_DWA20011214_HPP
|
||||
# define CALLER_DWA20011214_HPP
|
||||
|
||||
# include <boost/python/call.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct caller
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
template <class F>
|
||||
PyObject* operator()(F f, PyObject* args, PyObject* keywords)
|
||||
{
|
||||
return call(f, args, keywords);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // CALLER_DWA20011214_HPP
|
||||
78
include/boost/python/detail/cast.hpp
Normal file
78
include/boost/python/detail/cast.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// (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 {
|
||||
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
|
||||
{
|
||||
downcast(PyObject* p)
|
||||
: m_p(static_cast<T*>(detail::as_base_object((T*)0, p)))
|
||||
{}
|
||||
|
||||
downcast(const PyObject* p)
|
||||
: m_p(static_cast<T*>(detail::as_base_object((const T*)0, p)))
|
||||
{}
|
||||
|
||||
downcast(PyTypeObject* p)
|
||||
: m_p(static_cast<T*>(p))
|
||||
{}
|
||||
|
||||
downcast(const PyTypeObject* p)
|
||||
: m_p(static_cast<T*>(p))
|
||||
{}
|
||||
|
||||
operator T*() const { return m_p; }
|
||||
|
||||
// MSVC doesn't like boost::dereferencable unless T has a default
|
||||
// constructor, so operator-> must be defined by hand :(
|
||||
T* operator->() const { return &**this; }
|
||||
|
||||
T* get() const { return m_p; }
|
||||
T& operator*() const { return *m_p; }
|
||||
private:
|
||||
T* m_p;
|
||||
};
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
#endif // CAST_DWA052500_H_
|
||||
68
include/boost/python/detail/config.hpp
Normal file
68
include/boost/python/detail/config.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// (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.
|
||||
|
||||
// Revision History:
|
||||
// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams)
|
||||
|
||||
#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 or
|
||||
// Intel C++
|
||||
# if defined(BOOST_MSVC_STD_ITERATOR)
|
||||
# define BOOST_CSTD_
|
||||
# else
|
||||
# define BOOST_CSTD_ std
|
||||
# endif
|
||||
|
||||
# ifndef BOOST_PYTHON_MODULE_INIT
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name()
|
||||
# else
|
||||
# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif // CONFIG_DWA052200_H_
|
||||
@@ -9,6 +9,11 @@
|
||||
// This file automatically generated for 10-argument constructors by
|
||||
// gen_extclass.python
|
||||
|
||||
// Revision History:
|
||||
// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve)
|
||||
// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted
|
||||
// to_python (Dave Abrahams)
|
||||
|
||||
#ifndef EXTENSION_CLASS_DWA052000_H_
|
||||
# define EXTENSION_CLASS_DWA052000_H_
|
||||
|
||||
@@ -62,7 +67,7 @@ T* check_non_null(T* p)
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T> class held_instance;
|
||||
template <class Held> class held_instance;
|
||||
|
||||
typedef void* (*conversion_function_ptr)(void*);
|
||||
|
||||
@@ -145,14 +150,14 @@ template <>
|
||||
struct is_null_helper<false>
|
||||
{
|
||||
template <class Ptr>
|
||||
static bool test(Ptr x) { return x.get() == 0; }
|
||||
static bool test(const Ptr& x) { return x.get() == 0; }
|
||||
};
|
||||
|
||||
template <class Ptr>
|
||||
bool is_null(const Ptr& x)
|
||||
{
|
||||
return is_null_helper<(is_pointer<Ptr>::value)>::test(x);
|
||||
};
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
@@ -162,6 +167,14 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
// and U. T is the class the user really intends to wrap. U is a class derived
|
||||
// from T with some virtual function overriding boilerplate, or if there are no
|
||||
// virtual functions, U = held_instance<T>.
|
||||
//
|
||||
// A look-alike of this class in root/boost/python/cross_module.hpp
|
||||
// is used for the implementation of the cross-module support
|
||||
// (export_converters and import_converters). If from_python
|
||||
// and to_python converters are added or removed from the class
|
||||
// below, the class python_import_extension_class_converters has
|
||||
// to be modified accordingly.
|
||||
//
|
||||
template <class T, class U = boost::python::detail::held_instance<T> >
|
||||
class python_extension_class_converters
|
||||
{
|
||||
@@ -220,6 +233,9 @@ class python_extension_class_converters
|
||||
}
|
||||
boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Convert to T*
|
||||
@@ -231,9 +247,9 @@ class python_extension_class_converters
|
||||
return non_null_from_python(obj, boost::python::type<T*>());
|
||||
}
|
||||
|
||||
// Convert to PtrType, where PtrType can be dereferenced to obtain a T.
|
||||
// Extract from obj a mutable reference to the PtrType object which is holding a T.
|
||||
template <class PtrType>
|
||||
static PtrType& ptr_from_python(PyObject* obj, boost::python::type<PtrType>)
|
||||
static PtrType& smart_ptr_reference(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);
|
||||
@@ -248,21 +264,28 @@ class python_extension_class_converters
|
||||
}
|
||||
boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
|
||||
throw boost::python::argument_error();
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return *(PtrType*)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Extract from obj a reference to the PtrType object which is holding a
|
||||
// T. If it weren't for auto_ptr, it would be a constant reference. Do not
|
||||
// modify the referent except by copying an auto_ptr! If obj is None, the
|
||||
// reference denotes a default-constructed PtrType
|
||||
template <class PtrType>
|
||||
static const PtrType& ptr_const_ref_from_python(PyObject* obj, boost::python::type<PtrType>)
|
||||
static PtrType& smart_ptr_value(PyObject* obj, boost::python::type<PtrType>)
|
||||
{
|
||||
if (obj == Py_None)
|
||||
{
|
||||
static PtrType null_ptr;
|
||||
return null_ptr;
|
||||
}
|
||||
return ptr_from_python(obj, boost::python::type<PtrType>());
|
||||
return smart_ptr_reference(obj, boost::python::type<PtrType>());
|
||||
}
|
||||
|
||||
template <class PtrType>
|
||||
static PyObject* ptr_to_python(PtrType x)
|
||||
static PyObject* smart_ptr_to_python(PtrType x)
|
||||
{
|
||||
if (boost::python::detail::is_null(x))
|
||||
{
|
||||
@@ -311,28 +334,28 @@ class python_extension_class_converters
|
||||
{ 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> >()); }
|
||||
{ return smart_ptr_reference(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
|
||||
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T> >)
|
||||
{ return ptr_const_ref_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 smart_ptr_value(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_const_ref_from_python(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
{ return smart_ptr_value(p, boost::python::type<std::auto_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(std::auto_ptr<T> x)
|
||||
{ return ptr_to_python(x); }
|
||||
{ return smart_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> >()); }
|
||||
{ return smart_ptr_reference(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T> >)
|
||||
{ return ptr_const_ref_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
{ return smart_ptr_value(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_const_ref_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
{ return smart_ptr_value(p, boost::python::type<boost::shared_ptr<T> >()); }
|
||||
|
||||
friend PyObject* to_python(boost::shared_ptr<T> x)
|
||||
{ return ptr_to_python(x); }
|
||||
{ return smart_ptr_to_python(x); }
|
||||
};
|
||||
|
||||
// Convert T to_python, instantiated on demand and only if there isn't a
|
||||
@@ -599,6 +622,12 @@ class extension_class
|
||||
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_op<(which & op_gt)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_ge)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_lt)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_le)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_eq)>::template args<Operand>::add(this);
|
||||
choose_op<(which & op_ne)>::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);
|
||||
@@ -628,6 +657,12 @@ class extension_class
|
||||
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);
|
||||
choose_op<(which & op_gt)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_ge)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_lt)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_le)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_eq)>::template args<Left,Right>::add(this);
|
||||
choose_op<(which & op_ne)>::template args<Left,Right>::add(this);
|
||||
}
|
||||
|
||||
template <long which, class Left, class Right>
|
||||
@@ -659,33 +694,33 @@ class extension_class
|
||||
|
||||
// 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
|
||||
template <class Held>
|
||||
class held_instance : public Held
|
||||
{
|
||||
// There are no member functions: we want to avoid inadvertently overriding
|
||||
// any virtual functions in T.
|
||||
// any virtual functions in Held.
|
||||
public:
|
||||
held_instance(PyObject*) : T() {}
|
||||
held_instance(PyObject*) : Held() {}
|
||||
template <class A1>
|
||||
held_instance(PyObject*, A1 a1) : T(a1) {}
|
||||
held_instance(PyObject*, A1 a1) : Held(a1) {}
|
||||
template <class A1, class A2>
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : T(a1, a2) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
|
||||
template <class A1, class A2, class A3>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : T(a1, a2, a3) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(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) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(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) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : T(a1, a2, a3, a4, a5, a6) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : T(a1, a2, a3, a4, a5, a6, a7) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {}
|
||||
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : T(a1, a2, a3, a4, a5, a6, a7, a8) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(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>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(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>
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
|
||||
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
|
||||
};
|
||||
|
||||
// Abstract base class for all obj holders. Base for template class
|
||||
|
||||
311
include/boost/python/detail/functions.hpp
Normal file
311
include/boost/python/detail/functions.hpp
Normal file
@@ -0,0 +1,311 @@
|
||||
// (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; // A linked list of the function 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
|
||||
{
|
||||
// This is where the boundary between the uniform Python function
|
||||
// interface and the statically-checked C++ function interface is
|
||||
// crossed.
|
||||
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_
|
||||
508
include/boost/python/detail/init_function.hpp
Normal file
508
include/boost/python/detail/init_function.hpp
Normal file
@@ -0,0 +1,508 @@
|
||||
// (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:
|
||||
enum { is_ref = boost::is_reference<T>::value };
|
||||
typedef const_ref_selector<is_ref> 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_
|
||||
21
include/boost/python/detail/none.hpp
Normal file
21
include/boost/python/detail/none.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// (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_
|
||||
846
include/boost/python/detail/returning.hpp
Normal file
846
include/boost/python/detail/returning.hpp
Normal file
@@ -0,0 +1,846 @@
|
||||
// (C) Copyright David Abrahams 2001. 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.
|
||||
//
|
||||
// This work was funded in part by Lawrence Berkeley National Labs
|
||||
//
|
||||
// This file generated for 5-argument member functions and 6-argument free
|
||||
// functions by gen_returning.py
|
||||
|
||||
#ifndef RETURNING_DWA20011201_HPP
|
||||
# define RETURNING_DWA20011201_HPP
|
||||
|
||||
//# include <boost/python/detail/config.hpp>
|
||||
# include <boost/python/detail/wrap_python.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/python/convert.hpp>
|
||||
# include <boost/python/detail/none.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
// Calling C++ from Python
|
||||
template <class R>
|
||||
struct returning
|
||||
{
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c0);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)() );
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c1);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1) );
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c2);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c3);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c4);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c5);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) );
|
||||
};
|
||||
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c0);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)() );
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c1);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1) );
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c2);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c3);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c4);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c5);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) );
|
||||
};
|
||||
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c0);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)() );
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c1);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1) );
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c2);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c3);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c4);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c5);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) );
|
||||
};
|
||||
|
||||
|
||||
// missing const volatile type traits
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c0);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)() );
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c1);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1) );
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c2);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c3);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c4);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c5);
|
||||
if (!c0) return 0;
|
||||
return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) );
|
||||
};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ )
|
||||
{
|
||||
// find the result converter
|
||||
wrap<R> r;
|
||||
return r( (*pf)() );
|
||||
};
|
||||
template <class A0>
|
||||
static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c0);
|
||||
if (!c0) return 0;
|
||||
return r( (*pf)(*c0) );
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c1);
|
||||
if (!c0) return 0;
|
||||
return r( (*pf)(*c0, *c1) );
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c2);
|
||||
if (!c0) return 0;
|
||||
return r( (*pf)(*c0, *c1, *c2) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c3);
|
||||
if (!c0) return 0;
|
||||
return r( (*pf)(*c0, *c1, *c2, *c3) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c4);
|
||||
if (!c0) return 0;
|
||||
return r( (*pf)(*c0, *c1, *c2, *c3, *c4) );
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
// find the result converter
|
||||
wrap_more<R> r(c5);
|
||||
if (!c0) return 0;
|
||||
return r( (*pf)(*c0, *c1, *c2, *c3, *c4, *c5) );
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct returning<void>
|
||||
{
|
||||
typedef void R;
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)();
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5);
|
||||
return detail::none();
|
||||
};
|
||||
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)();
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5);
|
||||
return detail::none();
|
||||
};
|
||||
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)();
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5);
|
||||
return detail::none();
|
||||
};
|
||||
|
||||
|
||||
// missing const volatile type traits
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class A0>
|
||||
static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)();
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0 const volatile&> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
if (!c0) return 0;
|
||||
((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5);
|
||||
return detail::none();
|
||||
};
|
||||
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ )
|
||||
{
|
||||
(*pf)();
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0>
|
||||
static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
|
||||
if (!c0) return 0;
|
||||
(*pf)(*c0);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1>
|
||||
static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
|
||||
if (!c0) return 0;
|
||||
(*pf)(*c0, *c1);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
|
||||
if (!c0) return 0;
|
||||
(*pf)(*c0, *c1, *c2);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
|
||||
if (!c0) return 0;
|
||||
(*pf)(*c0, *c1, *c2, *c3);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
|
||||
if (!c0) return 0;
|
||||
(*pf)(*c0, *c1, *c2, *c3, *c4);
|
||||
return detail::none();
|
||||
};
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ )
|
||||
{
|
||||
// check that each of the arguments is convertible
|
||||
unwrap<A0> c0(PyTuple_GET_ITEM(args, 0));
|
||||
unwrap_more<A1> c1(PyTuple_GET_ITEM(args, 1), c0);
|
||||
unwrap_more<A2> c2(PyTuple_GET_ITEM(args, 2), c1);
|
||||
unwrap_more<A3> c3(PyTuple_GET_ITEM(args, 3), c2);
|
||||
unwrap_more<A4> c4(PyTuple_GET_ITEM(args, 4), c3);
|
||||
unwrap_more<A5> c5(PyTuple_GET_ITEM(args, 5), c4);
|
||||
|
||||
if (!c0) return 0;
|
||||
(*pf)(*c0, *c1, *c2, *c3, *c4, *c5);
|
||||
return detail::none();
|
||||
};
|
||||
};
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // RETURNING_DWA20011201_HPP
|
||||
|
||||
251
include/boost/python/detail/signatures.hpp
Normal file
251
include/boost/python/detail/signatures.hpp
Normal file
@@ -0,0 +1,251 @@
|
||||
// (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
|
||||
68
include/boost/python/detail/singleton.hpp
Normal file
68
include/boost/python/detail/singleton.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// (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
|
||||
417
include/boost/python/detail/types.hpp
Normal file
417
include/boost/python/detail/types.hpp
Normal file
@@ -0,0 +1,417 @@
|
||||
// (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, richcompare,
|
||||
|
||||
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, number_inplace_add, number_inplace_subtract,
|
||||
number_inplace_multiply, number_inplace_divide,
|
||||
number_inplace_remainder, number_inplace_power,
|
||||
number_inplace_lshift, number_inplace_rshift,
|
||||
number_inplace_and, number_inplace_or, number_inplace_xor
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
virtual PyObject* instance_number_inplace_add(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_and(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_or(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const;
|
||||
|
||||
public: // Callbacks for rich comparisons
|
||||
virtual PyObject* instance_lt(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_le(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_eq(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_ne(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_gt(PyObject*, PyObject*) const;
|
||||
virtual PyObject* instance_ge(PyObject*, 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.
|
||||
#ifdef __BORLANDC__ // smart implementation doesn't work for borland; maybe someone knows a workaround?
|
||||
# define PY_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#else
|
||||
# define PY_ARRAY_LENGTH(a) \
|
||||
(sizeof(::boost::python::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0)
|
||||
#endif
|
||||
|
||||
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_
|
||||
39
include/boost/python/detail/void_adaptor.hpp
Normal file
39
include/boost/python/detail/void_adaptor.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// (C) Copyright David Abrahams 2001. 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.
|
||||
|
||||
#ifndef VOID_ADAPTOR_DWA20011112_HPP
|
||||
# define VOID_ADAPTOR_DWA20011112_HPP
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
extern PyObject arbitrary_object;
|
||||
|
||||
template <class T>
|
||||
struct void_adaptor
|
||||
{
|
||||
typedef PyObject* result_type;
|
||||
|
||||
void_adaptor(T const& f)
|
||||
: m_f(f)
|
||||
{}
|
||||
|
||||
PyObject* operator()() const
|
||||
{
|
||||
m_f();
|
||||
return &arbitrary_object;
|
||||
}
|
||||
private:
|
||||
T m_f;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void_adaptor<T> make_void_adaptor(T const& f)
|
||||
{
|
||||
return void_adaptor<T>(f);
|
||||
}
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
#endif // VOID_ADAPTOR_DWA20011112_HPP
|
||||
|
||||
118
include/boost/python/detail/wrap_python.hpp
Normal file
118
include/boost/python/detail/wrap_python.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
// (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.
|
||||
|
||||
// Revision History:
|
||||
// 05 Mar 01 Suppress warnings under Cygwin with Python 2.0 (Dave Abrahams)
|
||||
// 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams)
|
||||
// 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams)
|
||||
|
||||
|
||||
#include <patchlevel.h>
|
||||
|
||||
#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)
|
||||
# if defined(__GNUC__) && defined(__CYGWIN__)
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2
|
||||
typedef int pid_t;
|
||||
# define WORD_BIT 32
|
||||
# define hypot _hypot
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
|
||||
# define HAVE_CLOCK
|
||||
# define HAVE_STRFTIME
|
||||
# define HAVE_STRERROR
|
||||
# endif
|
||||
# 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
|
||||
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
|
||||
# include <config.h>
|
||||
# else
|
||||
# include <pyconfig.h>
|
||||
# endif
|
||||
# undef hypot // undo the evil #define left by Python.
|
||||
|
||||
# elif defined(__BORLANDC__)
|
||||
# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2
|
||||
# include <config.h>
|
||||
# else
|
||||
# include <pyconfig.h>
|
||||
# endif
|
||||
# undef HAVE_HYPOT
|
||||
# define HAVE_HYPOT 1
|
||||
# elif defined(_MSC_VER)
|
||||
# ifdef __cplusplus
|
||||
# include <limits> // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX
|
||||
# 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
|
||||
|
||||
#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2
|
||||
# define PyObject_INIT(op, typeobj) \
|
||||
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
# pragma warn_possunwant off
|
||||
#elif _MSC_VER
|
||||
# pragma warning(disable:4786)
|
||||
#endif
|
||||
287
src/conversions.cpp
Normal file
287
src/conversions.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
// (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.
|
||||
//
|
||||
// Revision History:
|
||||
// 05 Apr 01 added: from_python std::string type checking (rwgk)
|
||||
// 12 Mar 01 Python 1.5.2 fixes (Ralf W. Grosse-Kunstleve)
|
||||
// 11 Mar 01 std::string *MAY* include nulls (Alex Martelli)
|
||||
// 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams)
|
||||
// 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve)
|
||||
|
||||
#include <boost/python/conversions.hpp>
|
||||
#include <boost/python/detail/void_adaptor.hpp>
|
||||
#include <typeinfo>
|
||||
#include <exception>
|
||||
#ifndef BOOST_NO_LIMITS
|
||||
# include <boost/cast.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
// IMPORTANT: this function may only be called from within a catch block!
|
||||
PyObject* handle_exception_impl(object_functor_base const& f)
|
||||
{
|
||||
try
|
||||
{
|
||||
return f();
|
||||
}
|
||||
catch(const boost::python::error_already_set&)
|
||||
{
|
||||
// The python error reporting has already been handled.
|
||||
}
|
||||
catch(const std::bad_alloc&)
|
||||
{
|
||||
PyErr_NoMemory();
|
||||
}
|
||||
catch(const std::exception& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, x.what());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handle_exception(void (*f)())
|
||||
{
|
||||
handle_exception(
|
||||
boost::python::detail::make_void_adaptor(f));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
void expect_complex(PyObject* p)
|
||||
{
|
||||
if (!PyComplex_Check(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "expected a complex number");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost::python::detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
long from_python(PyObject* p, boost::python::type<long>)
|
||||
{
|
||||
// Why am I clearing the error here before trying to convert? I know there's a reason...
|
||||
long result;
|
||||
{
|
||||
result = PyInt_AsLong(p);
|
||||
if (PyErr_Occurred())
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double from_python(PyObject* p, boost::python::type<double>)
|
||||
{
|
||||
double result;
|
||||
{
|
||||
result = PyFloat_AsDouble(p);
|
||||
if (PyErr_Occurred())
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T integer_from_python(PyObject* p, boost::python::type<T>)
|
||||
{
|
||||
const long long_result = from_python(p, boost::python::type<long>());
|
||||
|
||||
#ifndef BOOST_NO_LIMITS
|
||||
try
|
||||
{
|
||||
return boost::numeric_cast<T>(long_result);
|
||||
}
|
||||
catch(const boost::bad_numeric_cast&)
|
||||
#else
|
||||
if (static_cast<T>(long_result) == long_result)
|
||||
{
|
||||
return static_cast<T>(long_result);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
char buffer[256];
|
||||
const char message[] = "%ld out of range for %s";
|
||||
sprintf(buffer, message, long_result, typeid(T).name());
|
||||
PyErr_SetString(PyExc_ValueError, buffer);
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
|
||||
return 0; // Not smart enough to know that the catch clause always rethrows
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PyObject* integer_to_python(T value)
|
||||
{
|
||||
long value_as_long;
|
||||
|
||||
#ifndef BOOST_NO_LIMITS
|
||||
try
|
||||
{
|
||||
value_as_long = boost::numeric_cast<long>(value);
|
||||
}
|
||||
catch(const boost::bad_numeric_cast&)
|
||||
#else
|
||||
value_as_long = static_cast<long>(value);
|
||||
if (value_as_long != value)
|
||||
#endif
|
||||
{
|
||||
const char message[] = "value out of range for Python int";
|
||||
PyErr_SetString(PyExc_ValueError, message);
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
return to_python(value_as_long);
|
||||
}
|
||||
|
||||
int from_python(PyObject* p, boost::python::type<int> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned int i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
unsigned int from_python(PyObject* p, boost::python::type<unsigned int> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
short from_python(PyObject* p, boost::python::type<short> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
float from_python(PyObject* p, boost::python::type<float>)
|
||||
{
|
||||
return static_cast<float>(from_python(p, boost::python::type<double>()));
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned short i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
unsigned short from_python(PyObject* p, boost::python::type<unsigned short> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(char c)
|
||||
{
|
||||
if (c == '\0') return PyString_FromString("");
|
||||
return PyString_FromStringAndSize(&c, 1);
|
||||
}
|
||||
|
||||
char from_python(PyObject* p, boost::python::type<char>)
|
||||
{
|
||||
int l = -1;
|
||||
if (PyString_Check(p)) l = PyString_Size(p);
|
||||
if (l < 0 || l > 1) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected string of length 0 or 1");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
if (l == 0) return '\0';
|
||||
return PyString_AsString(p)[0];
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned char i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
unsigned char from_python(PyObject* p, boost::python::type<unsigned char> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(signed char i)
|
||||
{
|
||||
return integer_to_python(i);
|
||||
}
|
||||
|
||||
signed char from_python(PyObject* p, boost::python::type<signed char> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(unsigned long x)
|
||||
{
|
||||
return integer_to_python(x);
|
||||
}
|
||||
|
||||
unsigned long from_python(PyObject* p, boost::python::type<unsigned long> type)
|
||||
{
|
||||
return integer_from_python(p, type);
|
||||
}
|
||||
|
||||
void from_python(PyObject* p, boost::python::type<void>)
|
||||
{
|
||||
if (p != Py_None) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected argument of type None");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
}
|
||||
|
||||
const char* from_python(PyObject* p, boost::python::type<const char*>)
|
||||
{
|
||||
const char* s = PyString_AsString(p);
|
||||
if (!s)
|
||||
throw boost::python::argument_error();
|
||||
return s;
|
||||
}
|
||||
|
||||
PyObject* to_python(const std::string& s)
|
||||
{
|
||||
return PyString_FromStringAndSize(s.data(), s.size());
|
||||
}
|
||||
|
||||
std::string from_python(PyObject* p, boost::python::type<std::string>)
|
||||
{
|
||||
if (! PyString_Check(p)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected a string");
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
return std::string(PyString_AsString(p), PyString_Size(p));
|
||||
}
|
||||
|
||||
bool from_python(PyObject* p, boost::python::type<bool>)
|
||||
{
|
||||
int value = from_python(p, boost::python::type<int>());
|
||||
if (value == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC6_OR_EARLIER
|
||||
// An optimizer bug prevents these from being inlined.
|
||||
PyObject* to_python(double d)
|
||||
{
|
||||
return PyFloat_FromDouble(d);
|
||||
}
|
||||
|
||||
PyObject* to_python(float f)
|
||||
{
|
||||
return PyFloat_FromDouble(f);
|
||||
}
|
||||
#endif // BOOST_MSVC6_OR_EARLIER
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
87
src/cross_module.cpp
Normal file
87
src/cross_module.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. 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.
|
||||
|
||||
Revision History:
|
||||
17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve)
|
||||
*/
|
||||
|
||||
# include <boost/python/cross_module.hpp>
|
||||
namespace python = boost::python;
|
||||
# include <stdio.h> // MSVC6.0SP4 does not know std::fprintf
|
||||
# include <string.h> // MSVC6.0SP4 does not know std::strcmp
|
||||
|
||||
namespace {
|
||||
|
||||
PyObject* get_module_dict(const char* module_name)
|
||||
{
|
||||
python::ref module_obj(PyImport_ImportModule((char*) module_name));
|
||||
PyObject* module_dict = PyModule_GetDict(module_obj.get());
|
||||
if (module_dict == 0) throw python::import_error();
|
||||
return module_dict;
|
||||
}
|
||||
}
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
const char* converters_attribute_name = "__converters__";
|
||||
|
||||
void* import_converter_object(const std::string& module_name,
|
||||
const std::string& py_class_name,
|
||||
const std::string& attribute_name)
|
||||
{
|
||||
static std::string err;
|
||||
PyObject* module_dict = get_module_dict(const_cast<char*>(module_name.c_str()));
|
||||
PyObject* py_class = PyDict_GetItemString(module_dict, const_cast<char*>(py_class_name.c_str()));
|
||||
if (py_class == 0) {
|
||||
err = std::string("module ") + module_name + " has no attribute " + py_class_name;
|
||||
PyErr_SetString(PyExc_RuntimeError, const_cast<char*>(err.c_str()));
|
||||
throw python::import_error();
|
||||
}
|
||||
python::ref c_obj(PyObject_GetAttrString(py_class, const_cast<char*>(attribute_name.c_str())), ref::null_ok);
|
||||
if (c_obj.get() == 0) {
|
||||
err = std::string("object ") + module_name + "." + py_class_name
|
||||
+ " has no attribute " + attribute_name;
|
||||
PyErr_SetString(PyExc_RuntimeError, const_cast<char*>(err.c_str()));
|
||||
throw python::import_error();
|
||||
}
|
||||
if (! PyCObject_Check(c_obj.get())) {
|
||||
err = std::string("object ") + module_name + "." + py_class_name + "."
|
||||
+ attribute_name + " is not a PyCObject";
|
||||
PyErr_SetString(PyExc_RuntimeError, const_cast<char*>(err.c_str()));
|
||||
throw python::import_error();
|
||||
}
|
||||
return PyCObject_AsVoidPtr(c_obj.get());
|
||||
}
|
||||
|
||||
void check_export_converters_api(const int importing_major,
|
||||
const int importing_minor,
|
||||
const int imported_major,
|
||||
const int imported_minor)
|
||||
{
|
||||
if (importing_major != imported_major) {
|
||||
// Python uses fprintf(stderr, ...) for API warnings.
|
||||
fprintf(stderr,
|
||||
"Fatal: export_converters_api mismatch:"
|
||||
" Importing module = %d.%d"
|
||||
" Imported module = %d.%d\n",
|
||||
importing_major, importing_minor,
|
||||
imported_major, imported_minor);
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Fatal: export_converters_api mismatch");
|
||||
throw import_error();
|
||||
}
|
||||
if (importing_minor != imported_minor) {
|
||||
// Python uses fprintf(stderr, ...) for API warnings.
|
||||
fprintf(stderr,
|
||||
"Warning: export_converters_api mismatch:"
|
||||
" Importing module = %d.%d"
|
||||
" Imported module = %d.%d\n",
|
||||
importing_major, importing_minor,
|
||||
imported_major, imported_minor);
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
687
src/extension_class.cpp
Normal file
687
src/extension_class.cpp
Normal file
@@ -0,0 +1,687 @@
|
||||
// (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.
|
||||
//
|
||||
// Revision History:
|
||||
// 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams)
|
||||
|
||||
#include <boost/python/detail/extension_class.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost { namespace python {
|
||||
namespace detail {
|
||||
|
||||
struct operator_dispatcher
|
||||
: public PyObject
|
||||
{
|
||||
static PyTypeObject type_obj;
|
||||
static PyNumberMethods number_methods;
|
||||
|
||||
static operator_dispatcher* create(const ref& o, const ref& s);
|
||||
|
||||
ref m_object;
|
||||
ref m_self;
|
||||
|
||||
// data members for allocation/deallocation optimization
|
||||
operator_dispatcher* m_free_list_link;
|
||||
static operator_dispatcher* free_list;
|
||||
|
||||
private:
|
||||
// only accessible through create()
|
||||
operator_dispatcher(const ref& o, const ref& s);
|
||||
};
|
||||
|
||||
operator_dispatcher* operator_dispatcher::free_list = 0;
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
inline PyObject* to_python(boost::python::detail::operator_dispatcher* n) { return n; }
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
tuple standard_coerce(ref l, ref r)
|
||||
{
|
||||
// Introduced sequence points for exception-safety.
|
||||
ref first(detail::operator_dispatcher::create(l, l));
|
||||
|
||||
ref second(r->ob_type == &detail::operator_dispatcher::type_obj
|
||||
? r
|
||||
: ref(detail::operator_dispatcher::create(r, ref())));
|
||||
|
||||
return tuple(first, second);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum { unwrap_exception_code = -1000 };
|
||||
|
||||
int unwrap_args(PyObject* left, PyObject* right, PyObject*& self, PyObject*& other)
|
||||
{
|
||||
if (left->ob_type != &operator_dispatcher::type_obj ||
|
||||
right->ob_type != &operator_dispatcher::type_obj)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_args(): expecting operator_dispatcher arguments only!");
|
||||
return unwrap_exception_code;
|
||||
}
|
||||
|
||||
typedef reference<operator_dispatcher> DPtr;
|
||||
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::increment_count);
|
||||
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::increment_count);
|
||||
|
||||
if (lwrapper->m_self.get() != 0)
|
||||
{
|
||||
self = lwrapper->m_self.get();
|
||||
other = rwrapper->m_object.get();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self = rwrapper->m_self.get();
|
||||
other = lwrapper->m_object.get();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int unwrap_pow_args(PyObject* left, PyObject* right, PyObject* m,
|
||||
PyObject*& self, PyObject*& first, PyObject*& second)
|
||||
{
|
||||
if (left->ob_type != &operator_dispatcher::type_obj ||
|
||||
right->ob_type != &operator_dispatcher::type_obj ||
|
||||
m->ob_type != &operator_dispatcher::type_obj)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_pow_args(): expecting operator_dispatcher arguments only!");
|
||||
return unwrap_exception_code;
|
||||
}
|
||||
|
||||
typedef reference<operator_dispatcher> DPtr;
|
||||
DPtr lwrapper(static_cast<operator_dispatcher*>(left), DPtr::increment_count);
|
||||
DPtr rwrapper(static_cast<operator_dispatcher*>(right), DPtr::increment_count);
|
||||
DPtr mwrapper(static_cast<operator_dispatcher*>(m), DPtr::increment_count);
|
||||
|
||||
if (lwrapper->m_self.get() != 0)
|
||||
{
|
||||
self = lwrapper->m_self.get();
|
||||
first = rwrapper->m_object.get();
|
||||
second = mwrapper->m_object.get();
|
||||
return 0;
|
||||
}
|
||||
else if (rwrapper->m_self.get() != 0)
|
||||
{
|
||||
self = rwrapper->m_self.get();
|
||||
first = lwrapper->m_object.get();
|
||||
second = mwrapper->m_object.get();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self = mwrapper->m_self.get();
|
||||
first = lwrapper->m_object.get();
|
||||
second = rwrapper->m_object.get();
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
extension_instance* get_extension_instance(PyObject* p)
|
||||
{
|
||||
// The object's type will just be some class_t<extension_instance> object,
|
||||
// but if its meta-type is right, then it is an extension_instance.
|
||||
if (p->ob_type->ob_type != extension_meta_class())
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw boost::python::argument_error();
|
||||
}
|
||||
return static_cast<extension_instance*>(p);
|
||||
}
|
||||
|
||||
void
|
||||
extension_instance::add_implementation(std::auto_ptr<instance_holder_base> holder)
|
||||
{
|
||||
for (held_objects::const_iterator p = m_wrapped_objects.begin();
|
||||
p != m_wrapped_objects.end(); ++p)
|
||||
{
|
||||
if (typeid(*holder) == typeid(**p))
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Base class already initialized");
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
m_wrapped_objects.push_back(holder.release());
|
||||
}
|
||||
|
||||
extension_instance::extension_instance(PyTypeObject* class_)
|
||||
: instance(class_)
|
||||
{
|
||||
}
|
||||
|
||||
extension_instance::~extension_instance()
|
||||
{
|
||||
for (held_objects::const_iterator p = m_wrapped_objects.begin(),
|
||||
finish = m_wrapped_objects.end();
|
||||
p != finish; ++p)
|
||||
{
|
||||
delete *p;
|
||||
}
|
||||
}
|
||||
|
||||
meta_class<extension_instance>* extension_meta_class()
|
||||
{
|
||||
static meta_class<extension_instance> result;
|
||||
return &result;
|
||||
}
|
||||
|
||||
typedef class_t<extension_instance> extension_class_t;
|
||||
|
||||
bool is_subclass(const extension_class_t* derived,
|
||||
const PyObject* possible_base)
|
||||
{
|
||||
|
||||
tuple bases = derived->bases();
|
||||
|
||||
for (std::size_t i = 0, size = bases.size(); i < size; ++i)
|
||||
{
|
||||
const PyObject* base = bases[i].get();
|
||||
|
||||
if (base == possible_base)
|
||||
return true;
|
||||
|
||||
if (base->ob_type == extension_meta_class())
|
||||
{
|
||||
const extension_class_t* base_class = downcast<const extension_class_t>(base);
|
||||
if (is_subclass(base_class, possible_base))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true iff obj is an obj of target_class
|
||||
bool is_instance(extension_instance* obj,
|
||||
class_t<extension_instance>* target_class)
|
||||
{
|
||||
if (obj->ob_type == target_class)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
return is_subclass(
|
||||
downcast<class_t<extension_instance> >(obj->ob_type).get(),
|
||||
as_object(target_class));
|
||||
}
|
||||
}
|
||||
|
||||
void two_string_error(PyObject* exception_object, const char* format, const char* s1, const char* s2)
|
||||
{
|
||||
char buffer[256];
|
||||
std::size_t format_length = BOOST_CSTD_::strlen(format);
|
||||
std::size_t length1 = BOOST_CSTD_::strlen(s1);
|
||||
std::size_t length2 = BOOST_CSTD_::strlen(s2);
|
||||
|
||||
std::size_t additional_length = length1 + length2;
|
||||
if (additional_length + format_length > format_length - 1)
|
||||
{
|
||||
std::size_t difference = sizeof(buffer) - 1 - additional_length;
|
||||
length1 -= difference / 2;
|
||||
additional_length -= difference / 2;
|
||||
}
|
||||
|
||||
sprintf(buffer, format, length1, s1, length2, s2);
|
||||
|
||||
PyErr_SetString(exception_object, buffer);
|
||||
if (exception_object == PyExc_TypeError)
|
||||
throw argument_error();
|
||||
else
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
// This is called when an attempt has been made to convert the given obj to
|
||||
// a C++ type for which it doesn't have any obj data. In that case, either
|
||||
// the obj was not derived from the target_class, or the appropriate
|
||||
// __init__ function wasn't called to initialize the obj data of the target class.
|
||||
void report_missing_instance_data(
|
||||
extension_instance* obj, // The object being converted
|
||||
class_t<extension_instance>* target_class, // the extension class of the C++ type
|
||||
const std::type_info& target_typeid, // The typeid of the C++ type
|
||||
bool target_is_ptr)
|
||||
{
|
||||
char buffer[256];
|
||||
if (is_instance(obj, target_class))
|
||||
{
|
||||
if (target_is_ptr)
|
||||
{
|
||||
two_string_error(PyExc_RuntimeError,
|
||||
"Object of extension class '%.*s' does not wrap <%.*s>.",
|
||||
obj->ob_type->tp_name, target_typeid.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
const char message[] = "__init__ function for extension class '%.*s' was never called.";
|
||||
sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1,
|
||||
target_class->tp_name);
|
||||
}
|
||||
PyErr_SetString(PyExc_RuntimeError, buffer);
|
||||
}
|
||||
else if (target_class == 0)
|
||||
{
|
||||
const char message[] = "Cannot convert to <%.*s>; its Python class was never created or has been deleted.";
|
||||
sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, target_typeid.name());
|
||||
PyErr_SetString(PyExc_RuntimeError, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
two_string_error(PyExc_TypeError, "extension class '%.*s' is not convertible into '%.*s'.",
|
||||
obj->ob_type->tp_name, target_class->tp_name);
|
||||
}
|
||||
}
|
||||
|
||||
void report_missing_instance_data(
|
||||
extension_instance* obj, // The object being converted
|
||||
class_t<extension_instance>* target_class, // the extension class of the C++ type
|
||||
const std::type_info& target_typeid) // The typeid of the C++ type
|
||||
{
|
||||
report_missing_instance_data(obj, target_class, target_typeid, false);
|
||||
}
|
||||
|
||||
void report_missing_ptr_data(
|
||||
extension_instance* obj, // The object being converted
|
||||
class_t<extension_instance>* target_class, // the extension class of the C++ type
|
||||
const std::type_info& target_typeid) // The typeid of the C++ type
|
||||
{
|
||||
report_missing_instance_data(obj, target_class, target_typeid, true);
|
||||
}
|
||||
|
||||
void report_missing_class_object(const std::type_info& info)
|
||||
{
|
||||
char buffer[256];
|
||||
const char message[] = "Cannot convert <%.*s> to python; its Python class was never created or has been deleted.";
|
||||
sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name());
|
||||
PyErr_SetString(PyExc_RuntimeError, buffer);
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
void report_released_smart_pointer(const std::type_info& info)
|
||||
{
|
||||
char buffer[256];
|
||||
const char message[] = "Converting from python, pointer or smart pointer to <%.*s> is NULL.";
|
||||
sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name());
|
||||
PyErr_SetString(PyExc_RuntimeError, buffer);
|
||||
throw argument_error();
|
||||
}
|
||||
|
||||
read_only_setattr_function::read_only_setattr_function(const char* name)
|
||||
: m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
PyObject* read_only_setattr_function::do_call(PyObject* /*args*/, PyObject* /*keywords*/) const
|
||||
{
|
||||
PyErr_SetObject(PyExc_AttributeError, ("'" + m_name + "' attribute is read-only").get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* read_only_setattr_function::description() const
|
||||
{
|
||||
return "uncallable";
|
||||
}
|
||||
|
||||
extension_class_base::extension_class_base(const char* name)
|
||||
: class_t<extension_instance>(
|
||||
extension_meta_class(), string(name), tuple(), dictionary())
|
||||
{
|
||||
}
|
||||
|
||||
// This function is used in from_python() to convert wrapped classes that are
|
||||
// related by inheritance. The problem is this: although C++ provides all necessary
|
||||
// conversion operators, source and target of a conversion must be known at compile
|
||||
// time. However, in Python we want to convert classes at runtime. The solution is to
|
||||
// generate conversion functions at compile time, register them within the appropriate
|
||||
// class objects and call them when a particular runtime conversion is required.
|
||||
|
||||
// If functions for any possible conversion have to be stored, their number will grow
|
||||
// qudratically. To reduce this number, we actually store only conversion functions
|
||||
// between adjacent levels in the inheritance tree. By traversing the tree recursively,
|
||||
// we can build any allowed conversion as a concatenation of simple conversions. This
|
||||
// traversal is done in the functions try_base_class_conversions() and
|
||||
// try_derived_class_conversions(). If a particular conversion is impossible, all
|
||||
// conversion functions will return a NULL pointer.
|
||||
|
||||
// The function extract_object_from_holder() attempts to actually extract the pointer
|
||||
// to the contained object from an instance_holder_base (a wrapper class). A conversion
|
||||
// of the held object to 'T *' is allowed when the conversion
|
||||
// 'dynamic_cast<instance_holder<T> *>(an_instance_holder_base)' succeeds.
|
||||
void* extension_class_base::try_class_conversions(instance_holder_base* object) const
|
||||
{
|
||||
void* result = try_derived_class_conversions(object);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (!object->held_by_value())
|
||||
return try_base_class_conversions(object);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* extension_class_base::try_base_class_conversions(instance_holder_base* object) const
|
||||
{
|
||||
for (std::size_t i = 0; i < base_classes().size(); ++i)
|
||||
{
|
||||
if (base_classes()[i].convert == 0)
|
||||
continue;
|
||||
void* result1 = base_classes()[i].class_object->extract_object_from_holder(object);
|
||||
if (result1)
|
||||
return (*base_classes()[i].convert)(result1);
|
||||
|
||||
void* result2 = base_classes()[i].class_object->try_base_class_conversions(object);
|
||||
if (result2)
|
||||
return (*base_classes()[i].convert)(result2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* extension_class_base::try_derived_class_conversions(instance_holder_base* object) const
|
||||
{
|
||||
for (std::size_t i = 0; i < derived_classes().size(); ++i)
|
||||
{
|
||||
void* result1 = derived_classes()[i].class_object->extract_object_from_holder(object);
|
||||
if (result1)
|
||||
return (*derived_classes()[i].convert)(result1);
|
||||
|
||||
void* result2 = derived_classes()[i].class_object->try_derived_class_conversions(object);
|
||||
if (result2)
|
||||
return (*derived_classes()[i].convert)(result2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void extension_class_base::add_method(function* method, const char* name)
|
||||
{
|
||||
add_method(reference<function>(method), name);
|
||||
}
|
||||
|
||||
void extension_class_base::add_method(reference<function> method, const char* name)
|
||||
{
|
||||
// Add the attribute to the computed target
|
||||
function::add_to_namespace(method, name, this->dict().get());
|
||||
|
||||
// If it is a special member function it should be enabled both here and there.
|
||||
detail::enable_named_method(this, name);
|
||||
}
|
||||
|
||||
void extension_class_base::add_constructor_object(function* init_fn)
|
||||
{
|
||||
add_method(init_fn, "__init__");
|
||||
}
|
||||
|
||||
void extension_class_base::add_setter_method(function* setter_, const char* name)
|
||||
{
|
||||
reference<function> setter(setter_);
|
||||
add_method(setter, (detail::setattr_string() + name + "__").c_str());
|
||||
}
|
||||
|
||||
void extension_class_base::add_getter_method(function* getter_, const char* name)
|
||||
{
|
||||
reference<function> getter(getter_);
|
||||
add_method(getter, (detail::getattr_string() + name + "__").c_str());
|
||||
}
|
||||
|
||||
void extension_class_base::set_attribute(const char* name, PyObject* x_)
|
||||
{
|
||||
ref x(x_);
|
||||
set_attribute(name, x);
|
||||
}
|
||||
|
||||
void extension_class_base::set_attribute(const char* name, ref x)
|
||||
{
|
||||
dict().set_item(string(name), x);
|
||||
if (PyCallable_Check(x.get()))
|
||||
detail::enable_named_method(this, name);
|
||||
}
|
||||
|
||||
operator_dispatcher::operator_dispatcher(const ref& o, const ref& s)
|
||||
: m_object(o), m_self(s), m_free_list_link(0)
|
||||
|
||||
{
|
||||
PyObject* self = this;
|
||||
PyObject_INIT(self, &type_obj);
|
||||
}
|
||||
|
||||
operator_dispatcher*
|
||||
operator_dispatcher::create(const ref& object, const ref& self)
|
||||
{
|
||||
operator_dispatcher* const result = free_list;
|
||||
if (result == 0)
|
||||
return new operator_dispatcher(object, self);
|
||||
|
||||
free_list = result->m_free_list_link;
|
||||
result->m_object = object;
|
||||
result->m_self = self;
|
||||
|
||||
PyObject* result_as_pyobject = result;
|
||||
PyObject_INIT(result_as_pyobject, &type_obj);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void operator_dispatcher_dealloc(PyObject* self)
|
||||
{
|
||||
operator_dispatcher* obj = static_cast<operator_dispatcher*>(self);
|
||||
obj->m_free_list_link = operator_dispatcher::free_list;
|
||||
operator_dispatcher::free_list = obj;
|
||||
obj->m_object.reset();
|
||||
obj->m_self.reset();
|
||||
}
|
||||
|
||||
int operator_dispatcher_coerce(PyObject** l, PyObject** r)
|
||||
{
|
||||
Py_INCREF(*l);
|
||||
PyObject* new_r = handle_exception(
|
||||
bind(operator_dispatcher::create,
|
||||
ref(*r, ref::increment_count),
|
||||
ref()));
|
||||
if (new_r)
|
||||
{
|
||||
*r = new_r;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define PY_DEFINE_OPERATOR(id, symbol) \
|
||||
PyObject* operator_dispatcher_call_##id(PyObject* left, PyObject* right) \
|
||||
{ \
|
||||
/* unwrap the arguments from their OperatorDispatcher */ \
|
||||
PyObject* self; \
|
||||
PyObject* other; \
|
||||
int reverse = unwrap_args(left, right, self, other); \
|
||||
if (reverse == unwrap_exception_code) \
|
||||
return 0; \
|
||||
\
|
||||
/* call the function */ \
|
||||
PyObject* result = \
|
||||
PyEval_CallMethod(self, \
|
||||
const_cast<char*>(reverse ? "__r" #id "__" : "__" #id "__"), \
|
||||
const_cast<char*>("(O)"), \
|
||||
other); \
|
||||
if (result == 0 && PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError)) \
|
||||
{ \
|
||||
PyErr_Clear(); \
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for " #symbol); \
|
||||
} \
|
||||
return result; \
|
||||
}
|
||||
|
||||
PY_DEFINE_OPERATOR(add, +)
|
||||
PY_DEFINE_OPERATOR(sub, -)
|
||||
PY_DEFINE_OPERATOR(mul, *)
|
||||
PY_DEFINE_OPERATOR(div, /)
|
||||
PY_DEFINE_OPERATOR(mod, %)
|
||||
PY_DEFINE_OPERATOR(divmod, divmod)
|
||||
PY_DEFINE_OPERATOR(lshift, <<)
|
||||
PY_DEFINE_OPERATOR(rshift, >>)
|
||||
PY_DEFINE_OPERATOR(and, &)
|
||||
PY_DEFINE_OPERATOR(xor, ^)
|
||||
PY_DEFINE_OPERATOR(or, |)
|
||||
|
||||
/* coercion rules for heterogeneous pow():
|
||||
pow(Foo, int): left, right coerced; m: None => reverse = 0
|
||||
pow(int, Foo): left, right coerced; m: None => reverse = 1
|
||||
pow(Foo, int, int): left, right, m coerced => reverse = 0
|
||||
pow(int, Foo, int): left, right, m coerced => reverse = 1
|
||||
pow(int, int, Foo): left, right, m coerced => reverse = 2
|
||||
pow(Foo, Foo, int): left, right coerced; m coerced twice => reverse = 0
|
||||
pow(Foo, int, Foo): left, right, m coerced => reverse = 0
|
||||
pow(int, Foo, Foo): left, right, m coerced => reverse = 1
|
||||
*/
|
||||
PyObject* operator_dispatcher_call_pow(PyObject* left, PyObject* right, PyObject* m)
|
||||
{
|
||||
int reverse;
|
||||
PyObject* self;
|
||||
PyObject* first;
|
||||
PyObject* second;
|
||||
|
||||
if (m->ob_type == Py_None->ob_type)
|
||||
{
|
||||
reverse = unwrap_args(left, right, self, first);
|
||||
second = m;
|
||||
}
|
||||
else
|
||||
{
|
||||
reverse = unwrap_pow_args(left, right, m, self, first, second);
|
||||
}
|
||||
|
||||
if (reverse == unwrap_exception_code)
|
||||
return 0;
|
||||
|
||||
// call the function
|
||||
PyObject* result =
|
||||
PyEval_CallMethod(self,
|
||||
const_cast<char*>((reverse == 0)
|
||||
? "__pow__"
|
||||
: (reverse == 1)
|
||||
? "__rpow__"
|
||||
: "__rrpow__"),
|
||||
const_cast<char*>("(OO)"),
|
||||
first, second);
|
||||
if (result == 0 &&
|
||||
(PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_TypeError) ||
|
||||
PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError)))
|
||||
{
|
||||
PyErr_Clear();
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int operator_dispatcher_call_cmp(PyObject* left, PyObject* right)
|
||||
{
|
||||
// unwrap the arguments from their OperatorDispatcher
|
||||
PyObject* self;
|
||||
PyObject* other;
|
||||
int reverse = unwrap_args(left, right, self, other);
|
||||
if (reverse == unwrap_exception_code)
|
||||
return -1;
|
||||
|
||||
// call the function
|
||||
PyObject* result =
|
||||
PyEval_CallMethod(self,
|
||||
const_cast<char*>(reverse ? "__rcmp__" : "__cmp__"),
|
||||
const_cast<char*>("(O)"),
|
||||
other);
|
||||
if (result == 0)
|
||||
{
|
||||
PyErr_Clear();
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for cmp() or <");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return BOOST_PYTHON_CONVERSION::from_python(result, type<int>());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
PyErr_Clear();
|
||||
PyErr_SetString(PyExc_TypeError, "cmp() didn't return int");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
PyTypeObject operator_dispatcher::type_obj =
|
||||
{
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0,
|
||||
const_cast<char*>("operator_dispatcher"),
|
||||
sizeof(operator_dispatcher),
|
||||
0,
|
||||
&operator_dispatcher_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&operator_dispatcher_call_cmp,
|
||||
0,
|
||||
&operator_dispatcher::number_methods,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
PyNumberMethods operator_dispatcher::number_methods =
|
||||
{
|
||||
&operator_dispatcher_call_add,
|
||||
&operator_dispatcher_call_sub,
|
||||
&operator_dispatcher_call_mul,
|
||||
&operator_dispatcher_call_div,
|
||||
&operator_dispatcher_call_mod,
|
||||
&operator_dispatcher_call_divmod,
|
||||
&operator_dispatcher_call_pow,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&operator_dispatcher_call_lshift,
|
||||
&operator_dispatcher_call_rshift,
|
||||
&operator_dispatcher_call_and,
|
||||
&operator_dispatcher_call_xor,
|
||||
&operator_dispatcher_call_or,
|
||||
&operator_dispatcher_coerce,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::python
|
||||
179
src/functions.cpp
Normal file
179
src/functions.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
// (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.
|
||||
//
|
||||
// Revision History:
|
||||
// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams)
|
||||
|
||||
#include <boost/python/detail/functions.hpp>
|
||||
#include <boost/python/detail/types.hpp>
|
||||
#include <boost/python/detail/singleton.hpp>
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
struct function::type_object :
|
||||
singleton<function::type_object, callable<boost::python::detail::type_object<function> > >
|
||||
{
|
||||
type_object() : singleton_base(&PyType_Type) {}
|
||||
};
|
||||
|
||||
|
||||
void function::add_to_namespace(reference<function> new_function, const char* name, PyObject* dict)
|
||||
{
|
||||
dictionary d(ref(dict, ref::increment_count));
|
||||
string key(name);
|
||||
|
||||
ref existing_object = d.get_item(key.reference());
|
||||
if (existing_object.get() == 0)
|
||||
{
|
||||
d[key] = ref(new_function.get(), ref::increment_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (existing_object->ob_type == type_object::instance())
|
||||
{
|
||||
function* f = static_cast<function*>(existing_object.get());
|
||||
while (f->m_overloads.get() != 0)
|
||||
f = f->m_overloads.get();
|
||||
f->m_overloads = new_function;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetObject(PyExc_RuntimeError,
|
||||
(string("Attempt to overload ") + name
|
||||
+ " failed. The existing attribute has type "
|
||||
+ existing_object->ob_type->tp_name).get());
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function::function()
|
||||
: python_object(type_object::instance())
|
||||
{
|
||||
}
|
||||
|
||||
PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
// Traverse the linked list of function overloads until we find one that
|
||||
// matches.
|
||||
for (const function* f = this; f != 0; f = f->m_overloads.get())
|
||||
{
|
||||
PyErr_Clear();
|
||||
try
|
||||
{
|
||||
PyObject* const result = f->do_call(args, keywords);
|
||||
if (result != 0)
|
||||
return result;
|
||||
}
|
||||
catch(const argument_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, no overloads matched the arguments
|
||||
|
||||
// Allow the single-function error-reporting to take effect unless there was
|
||||
// an overload
|
||||
if (m_overloads.get() == 0)
|
||||
return 0;
|
||||
|
||||
// Synthesize a more-explicit error message
|
||||
PyErr_Clear();
|
||||
string message("No overloaded functions match (");
|
||||
tuple arguments(ref(args, ref::increment_count));
|
||||
for (std::size_t i = 0; i < arguments.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
message += ", ";
|
||||
message += arguments[i]->ob_type->tp_name;
|
||||
}
|
||||
|
||||
message += "). Candidates are:\n";
|
||||
for (const function* f1 = this; f1 != 0; f1 = f1->m_overloads.get())
|
||||
{
|
||||
if (f1 != this)
|
||||
message += "\n";
|
||||
message += f1->description();
|
||||
}
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, message.get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The instance class whose obj represents the type of bound_function
|
||||
// objects in Python. bound_functions must be GetAttrable so the __doc__
|
||||
// attribute of built-in Python functions can be accessed when bound.
|
||||
struct bound_function::type_object :
|
||||
singleton<bound_function::type_object,
|
||||
getattrable<callable<boost::python::detail::type_object<bound_function> > > >
|
||||
{
|
||||
type_object() : singleton_base(&PyType_Type) {}
|
||||
|
||||
private: // type_object<bound_function> hook override
|
||||
void dealloc(bound_function*) const;
|
||||
};
|
||||
|
||||
bound_function* bound_function::create(const ref& target, const ref& fn)
|
||||
{
|
||||
bound_function* const result = free_list;
|
||||
if (result == 0)
|
||||
return new bound_function(target, fn);
|
||||
|
||||
free_list = result->m_free_list_link;
|
||||
result->m_target = target;
|
||||
result->m_unbound_function = fn;
|
||||
|
||||
PyObject* self = result;
|
||||
PyObject_INIT(self, type_object::instance());
|
||||
return result;
|
||||
}
|
||||
|
||||
bound_function::bound_function(const ref& target, const ref& fn)
|
||||
: python_object(type_object::instance()),
|
||||
m_target(target),
|
||||
m_unbound_function(fn),
|
||||
m_free_list_link(0)
|
||||
{
|
||||
}
|
||||
|
||||
PyObject*
|
||||
bound_function::call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
// Build a new tuple which prepends the target to the arguments
|
||||
tuple tail_arguments(ref(args, ref::increment_count));
|
||||
ref all_arguments(PyTuple_New(tail_arguments.size() + 1));
|
||||
|
||||
PyTuple_SET_ITEM(all_arguments.get(), 0, m_target.get());
|
||||
Py_INCREF(m_target.get());
|
||||
for (std::size_t i = 0; i < tail_arguments.size(); ++i)
|
||||
{
|
||||
PyTuple_SET_ITEM(all_arguments.get(), i + 1, tail_arguments[i].get());
|
||||
Py_INCREF(tail_arguments[i].get());
|
||||
}
|
||||
|
||||
return PyEval_CallObjectWithKeywords(m_unbound_function.get(), all_arguments.get(), keywords);
|
||||
}
|
||||
|
||||
PyObject* bound_function::getattr(const char* name) const
|
||||
{
|
||||
return PyObject_GetAttrString(m_unbound_function.get(), const_cast<char*>(name));
|
||||
}
|
||||
|
||||
void bound_function::type_object::dealloc(bound_function* obj) const
|
||||
{
|
||||
obj->m_free_list_link = free_list;
|
||||
free_list = obj;
|
||||
obj->m_target.reset();
|
||||
obj->m_unbound_function.reset();
|
||||
}
|
||||
|
||||
bound_function* bound_function::free_list;
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
36
src/init_function.cpp
Normal file
36
src/init_function.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// (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.
|
||||
|
||||
#include <boost/python/detail/init_function.hpp>
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/detail/extension_class.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
PyObject* init::do_call(PyObject* args_, PyObject* keywords) const
|
||||
{
|
||||
tuple args(ref(args_, ref::increment_count));
|
||||
if (args[0]->ob_type->ob_type != extension_meta_class())
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "argument 1 to __init__ must be an ExtensionInstance");
|
||||
return 0;
|
||||
}
|
||||
|
||||
extension_instance *self = static_cast<extension_instance*>(args[0].get());
|
||||
|
||||
tuple ctor_args = args.slice(1, args.size());
|
||||
|
||||
std::auto_ptr<instance_holder_base> result(
|
||||
create_holder(self, ctor_args.get(), keywords));
|
||||
|
||||
self->add_implementation(result);
|
||||
return none();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
62
src/module_builder.cpp
Normal file
62
src/module_builder.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// (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.
|
||||
|
||||
#include <boost/python/module_builder.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace {
|
||||
ref name_holder;
|
||||
}
|
||||
|
||||
bool module_builder::initializing()
|
||||
{
|
||||
return name_holder.get() != 0;
|
||||
}
|
||||
|
||||
string module_builder::name()
|
||||
{
|
||||
// If this fails, you haven't created a module_builder object
|
||||
assert(initializing());
|
||||
return string(name_holder);
|
||||
}
|
||||
|
||||
module_builder::module_builder(const char* name)
|
||||
: m_module(Py_InitModule(const_cast<char*>(name), initial_methods))
|
||||
{
|
||||
// If this fails, you've created more than 1 module_builder object in your module
|
||||
assert(name_holder.get() == 0);
|
||||
name_holder = ref(PyObject_GetAttrString(m_module, const_cast<char*>("__name__")));
|
||||
}
|
||||
|
||||
module_builder::~module_builder()
|
||||
{
|
||||
name_holder.reset();
|
||||
}
|
||||
|
||||
void
|
||||
module_builder::add(detail::function* x, const char* name)
|
||||
{
|
||||
reference<detail::function> f(x); // First take possession of the object.
|
||||
detail::function::add_to_namespace(f, name, PyModule_GetDict(m_module));
|
||||
}
|
||||
|
||||
void module_builder::add(ref x, const char* name)
|
||||
{
|
||||
PyObject* dictionary = PyModule_GetDict(m_module);
|
||||
PyDict_SetItemString(dictionary, const_cast<char*>(name), x.get());
|
||||
}
|
||||
|
||||
void module_builder::add(PyTypeObject* x, const char* name /*= 0*/)
|
||||
{
|
||||
this->add(ref(as_object(x)), name ? name : x->tp_name);
|
||||
}
|
||||
|
||||
PyMethodDef module_builder::initial_methods[] = { { 0, 0, 0, 0 } };
|
||||
|
||||
}} // namespace boost::python
|
||||
485
src/objects.cpp
Normal file
485
src/objects.cpp
Normal file
@@ -0,0 +1,485 @@
|
||||
// (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.
|
||||
|
||||
// TODO: Move inline implementations from objects.cpp here
|
||||
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/detail/none.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
template <class T>
|
||||
T object_from_python(PyObject* p, type<T>)
|
||||
{
|
||||
ref x(p, ref::increment_count);
|
||||
if (!T::accepts(x))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw error_already_set();
|
||||
}
|
||||
return T(x);
|
||||
}
|
||||
|
||||
inline PyObject* object_to_python(const object& x)
|
||||
{
|
||||
return x.reference().release();
|
||||
}
|
||||
|
||||
object::object(ref p)
|
||||
: m_p(p) {}
|
||||
|
||||
// Return a reference to the held object
|
||||
ref object::reference() const
|
||||
{
|
||||
return m_p;
|
||||
}
|
||||
|
||||
// Return a raw pointer to the held object
|
||||
PyObject* object::get() const
|
||||
{
|
||||
return m_p.get();
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
||||
|
||||
PyObject* to_python(const boost::python::tuple& x)
|
||||
{
|
||||
return object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::tuple from_python(PyObject* p, boost::python::type<boost::python::tuple> type)
|
||||
{
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::list& x)
|
||||
{
|
||||
return object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::list from_python(PyObject* p, boost::python::type<boost::python::list> type)
|
||||
{
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::dictionary& x)
|
||||
{
|
||||
return object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::dictionary from_python(PyObject* p, boost::python::type<boost::python::dictionary> type)
|
||||
{
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
PyObject* to_python(const boost::python::string& x)
|
||||
{
|
||||
return object_to_python(x);
|
||||
}
|
||||
|
||||
boost::python::string from_python(PyObject* p, boost::python::type<boost::python::string> type)
|
||||
{
|
||||
return boost::python::object_from_python(p, type);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
tuple::tuple(std::size_t n)
|
||||
: object(ref(PyTuple_New(n)))
|
||||
{
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
PyTuple_SET_ITEM(get(), i, detail::none());
|
||||
}
|
||||
|
||||
tuple::tuple(ref p)
|
||||
: object(p)
|
||||
{
|
||||
assert(accepts(p));
|
||||
if (!accepts(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
PyTypeObject* tuple::type_obj()
|
||||
{
|
||||
return &PyTuple_Type;
|
||||
}
|
||||
|
||||
bool tuple::accepts(ref p)
|
||||
{
|
||||
return PyTuple_Check(p.get());
|
||||
}
|
||||
|
||||
std::size_t tuple::size() const
|
||||
{
|
||||
return PyTuple_Size(get());
|
||||
}
|
||||
|
||||
ref tuple::operator[](std::size_t pos) const
|
||||
{
|
||||
return ref(PyTuple_GetItem(get(), static_cast<int>(pos)),
|
||||
ref::increment_count);
|
||||
}
|
||||
|
||||
void tuple::set_item(std::size_t pos, const ref& rhs)
|
||||
{
|
||||
int failed = PyTuple_SetItem(
|
||||
get(), static_cast<int>(pos), ref(rhs).release()); // A reference is stolen here.
|
||||
(void)failed;
|
||||
assert(failed == 0);
|
||||
}
|
||||
|
||||
tuple tuple::slice(int low, int high) const
|
||||
{
|
||||
return tuple(ref(PyTuple_GetSlice(get(), low, high)));
|
||||
}
|
||||
|
||||
tuple& tuple::operator+=(const tuple& rhs)
|
||||
{
|
||||
return *this = *this + rhs;
|
||||
}
|
||||
|
||||
|
||||
// Construct from an owned PyObject*.
|
||||
// Precondition: p must point to a python string.
|
||||
string::string(ref p)
|
||||
: object(p)
|
||||
{
|
||||
assert(accepts(p));
|
||||
if (!accepts(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
string::string(const char* s)
|
||||
: object(ref(PyString_FromString(s))) {}
|
||||
|
||||
string::string(const char* s, std::size_t length)
|
||||
: object(ref(PyString_FromStringAndSize(s, length))) {}
|
||||
|
||||
string::string(const char* s, interned_t)
|
||||
: object(ref(PyString_InternFromString(s))) {}
|
||||
|
||||
#if 0
|
||||
string::string(const char* s, std::size_t length, interned_t)
|
||||
: object(ref(PyString_InternFromStringAndSize(s, length))) {}
|
||||
#endif
|
||||
|
||||
string::string(const string& rhs)
|
||||
: object(rhs.reference()) {}
|
||||
|
||||
// Get the type object for Strings
|
||||
PyTypeObject* string::type_obj()
|
||||
{ return &PyString_Type; }
|
||||
|
||||
// Return true if the given object is a python string
|
||||
bool string::accepts(ref o)
|
||||
{ return PyString_Check(o.get()); }
|
||||
|
||||
// Return the length of the string.
|
||||
std::size_t string::size() const
|
||||
{
|
||||
int size = PyString_GET_SIZE(get());
|
||||
assert(size >= 0);
|
||||
return static_cast<std::size_t>(size);
|
||||
}
|
||||
|
||||
// Returns a null-terminated representation of the contents of string.
|
||||
// The pointer refers to the internal buffer of string, not a copy.
|
||||
// The data must not be modified in any way. It must not be de-allocated.
|
||||
const char* string::c_str() const
|
||||
{ return PyString_AS_STRING(get()); }
|
||||
|
||||
void string::intern()
|
||||
{ // UNTESTED!!
|
||||
*this = string(ref(PyString_InternFromString(c_str()), ref::increment_count));
|
||||
}
|
||||
|
||||
string& string::operator*=(unsigned int repeat_count)
|
||||
{
|
||||
*this = string(ref(PySequence_Repeat(get(), repeat_count)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
dictionary::dictionary(ref p)
|
||||
: object(p)
|
||||
{
|
||||
assert(accepts(p));
|
||||
if (!accepts(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
dictionary::dictionary()
|
||||
: object(ref(PyDict_New())) {}
|
||||
|
||||
PyTypeObject* dictionary::type_obj()
|
||||
{ return &PyDict_Type; }
|
||||
|
||||
bool dictionary::accepts(ref p)
|
||||
{ return PyDict_Check(p.get()); }
|
||||
|
||||
void dictionary::clear()
|
||||
{ PyDict_Clear(get()); }
|
||||
|
||||
const ref& dictionary::proxy::operator=(const ref& rhs)
|
||||
{
|
||||
if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1)
|
||||
throw error_already_set();
|
||||
return rhs;
|
||||
}
|
||||
|
||||
dictionary::proxy::operator ref() const
|
||||
{
|
||||
return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()),
|
||||
ref::increment_count);
|
||||
}
|
||||
|
||||
dictionary::proxy::proxy(const ref& dict, const ref& key)
|
||||
: m_dict(dict), m_key(key) {}
|
||||
|
||||
dictionary::proxy dictionary::operator[](ref key)
|
||||
{ return proxy(reference(), key); }
|
||||
|
||||
ref dictionary::operator[](ref key) const {
|
||||
// An odd MSVC bug causes the ".operator Ptr()" to be needed
|
||||
return proxy(reference(), key).operator ref();
|
||||
}
|
||||
|
||||
|
||||
ref dictionary::get_item(const ref& key) const
|
||||
{
|
||||
return get_item(key, ref());
|
||||
}
|
||||
|
||||
ref dictionary::get_item(const ref& key, const ref& default_) const
|
||||
{
|
||||
PyObject* value_or_null = PyDict_GetItem(get(), key.get());
|
||||
if (value_or_null == 0 && !PyErr_Occurred())
|
||||
return default_;
|
||||
else
|
||||
return ref(value_or_null, ref::increment_count); // Will throw if there was another error
|
||||
}
|
||||
|
||||
void dictionary::set_item(const ref& key, const ref& value)
|
||||
{
|
||||
if (PyDict_SetItem(get(), key.get(), value.get()) == -1)
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
void dictionary::erase(ref key) {
|
||||
if (PyDict_DelItem(get(), key.get()) == -1)
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
list dictionary::items() const { return list(ref(PyDict_Items(get()))); }
|
||||
list dictionary::keys() const { return list(ref(PyDict_Keys(get()))); }
|
||||
list dictionary::values() const { return list(ref(PyDict_Values(get()))); }
|
||||
|
||||
std::size_t dictionary::size() const { return static_cast<std::size_t>(PyDict_Size(get())); }
|
||||
|
||||
string operator+(string x, string y)
|
||||
{
|
||||
PyObject* io_string = x.reference().release();
|
||||
PyString_Concat(&io_string, y.get());
|
||||
return string(ref(io_string));
|
||||
}
|
||||
|
||||
string& string::operator+=(const string& rhs)
|
||||
{
|
||||
return *this = *this + rhs;
|
||||
}
|
||||
|
||||
string& string::operator+=(const char* y)
|
||||
{
|
||||
return *this += string(y);
|
||||
}
|
||||
|
||||
string operator%(const string& format, const tuple& args)
|
||||
{
|
||||
return string(ref(PyString_Format(format.get(), args.reference().get())));
|
||||
}
|
||||
|
||||
string operator+(string x, const char* y)
|
||||
{
|
||||
return x + string(y);
|
||||
}
|
||||
|
||||
string operator+(const char* x, string y)
|
||||
{
|
||||
return string(x) + y;
|
||||
}
|
||||
|
||||
tuple operator+(const tuple& x, const tuple& y)
|
||||
{
|
||||
tuple result(x.size() + y.size());
|
||||
for (std::size_t xi = 0; xi < x.size(); ++xi)
|
||||
result.set_item(xi, x[xi]);
|
||||
for (std::size_t yi = 0; yi < y.size(); ++yi)
|
||||
result.set_item(yi + x.size(), y[yi]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
list::list(ref p)
|
||||
: object(p)
|
||||
{
|
||||
assert(accepts(p));
|
||||
if (!accepts(p))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
|
||||
throw error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
list::list(std::size_t sz)
|
||||
: object(ref(PyList_New(sz)))
|
||||
{
|
||||
}
|
||||
|
||||
PyTypeObject* list::type_obj()
|
||||
{
|
||||
return &PyList_Type;
|
||||
}
|
||||
|
||||
bool list::accepts(ref p)
|
||||
{
|
||||
return PyList_Check(p.get());
|
||||
}
|
||||
|
||||
std::size_t list::size() const
|
||||
{
|
||||
return PyList_Size(get());
|
||||
}
|
||||
|
||||
ref list::operator[](std::size_t pos) const
|
||||
{
|
||||
return ref(PyList_GetItem(get(), pos), ref::increment_count);
|
||||
}
|
||||
|
||||
list::proxy list::operator[](std::size_t pos)
|
||||
{
|
||||
return proxy(reference(), pos);
|
||||
}
|
||||
|
||||
void list::insert(std::size_t index, const ref& item)
|
||||
{
|
||||
if (PyList_Insert(get(), index, item.get()) == -1)
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
void list::push_back(const ref& item)
|
||||
{
|
||||
if (PyList_Append(get(), item.get()) == -1)
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
void list::append(const ref& item)
|
||||
{
|
||||
this->push_back(item);
|
||||
}
|
||||
|
||||
list list::slice(int low, int high) const
|
||||
{
|
||||
return list(ref(PyList_GetSlice(get(), low, high)));
|
||||
}
|
||||
|
||||
list::slice_proxy list::slice(int low, int high)
|
||||
{
|
||||
return slice_proxy(reference(), low, high);
|
||||
}
|
||||
|
||||
void list::sort()
|
||||
{
|
||||
if (PyList_Sort(get()) == -1)
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
void list::reverse()
|
||||
{
|
||||
if (PyList_Reverse(get()) == -1)
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
tuple list::as_tuple() const
|
||||
{
|
||||
return tuple(ref(PyList_AsTuple(get())));
|
||||
}
|
||||
|
||||
const ref& list::proxy::operator=(const ref& rhs)
|
||||
{
|
||||
m_list.set_item(m_index, rhs);
|
||||
return rhs;
|
||||
}
|
||||
|
||||
list::proxy::operator ref() const
|
||||
{
|
||||
return ref(PyList_GetItem(m_list.get(), m_index), ref::increment_count);
|
||||
}
|
||||
|
||||
ref list::get_item(std::size_t pos) const
|
||||
{
|
||||
return ref(PyList_GetItem(this->get(), pos), ref::increment_count);
|
||||
}
|
||||
|
||||
void list::set_item(std::size_t pos, const ref& rhs)
|
||||
{
|
||||
int result = PyList_SetItem(this->get(), pos, rhs.get());
|
||||
if (result == -1)
|
||||
throw error_already_set();
|
||||
Py_INCREF(rhs.get());
|
||||
}
|
||||
|
||||
list::proxy::proxy(const ref& list, std::size_t index)
|
||||
: m_list(list), m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
const list& list::slice_proxy::operator=(const list& rhs)
|
||||
{
|
||||
if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1)
|
||||
throw error_already_set();
|
||||
return rhs;
|
||||
}
|
||||
|
||||
list::slice_proxy::operator ref() const
|
||||
{
|
||||
return ref(PyList_GetSlice(m_list.get(), m_low, m_high));
|
||||
}
|
||||
|
||||
list::slice_proxy::operator list() const
|
||||
{
|
||||
return list(this->operator ref());
|
||||
}
|
||||
|
||||
std::size_t list::slice_proxy::size() const
|
||||
{
|
||||
return this->operator list().size();
|
||||
}
|
||||
|
||||
ref list::slice_proxy::operator[](std::size_t pos) const
|
||||
{
|
||||
return this->operator list()[pos].operator ref();
|
||||
}
|
||||
|
||||
list::slice_proxy::slice_proxy(const ref& list, int low, int high)
|
||||
: m_list(list), m_low(low), m_high(high)
|
||||
{
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
||||
1347
src/types.cpp
Normal file
1347
src/types.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user