2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 16:52:15 +00:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Dave Abrahams
c75c27e7ca no message
[SVN r12128]
2001-12-19 22:55:37 +00:00
Dave Abrahams
4eadbb299e rollback for DLL
[SVN r12127]
2001-12-19 22:50:26 +00:00
Dave Abrahams
ac20fcca63 rollback branch for DLL changes
[SVN r12125]
2001-12-19 21:40:44 +00:00
nobody
cd00f7b01f This commit was manufactured by cvs2svn to create branch 'rollback'.
[SVN r12085]
2001-12-17 17:00:54 +00:00
132 changed files with 7303 additions and 6446 deletions

142
build/Jamfile Normal file
View 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 ;

View 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

View 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_

View 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

View 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_

View 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_

View File

@@ -0,0 +1,942 @@
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file automatically generated for 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_
# include <boost/python/detail/config.hpp>
# include <boost/python/classes.hpp>
# include <vector>
# include <boost/python/detail/none.hpp>
# include <boost/python/objects.hpp>
# include <boost/python/detail/functions.hpp>
# include <memory>
# include <boost/python/detail/init_function.hpp>
# include <typeinfo>
# include <boost/smart_ptr.hpp>
# include <boost/type_traits.hpp>
namespace boost { namespace python {
// forward declarations
template <long which, class operand> struct operators;
template <class T> struct left_operand;
template <class T> struct right_operand;
enum without_downcast_t { without_downcast };
namespace detail {
// forward declarations
class extension_instance;
class extension_class_base;
template <class T> class instance_holder;
template <class T, class U> class instance_value_holder;
template <class ref, class T> class instance_ptr_holder;
template <class Specified> struct operand_select;
template <long> struct choose_op;
template <long> struct choose_rop;
template <long> struct choose_unary_op;
template <long> struct define_operator;
meta_class<extension_instance>* extension_meta_class();
extension_instance* get_extension_instance(PyObject* p);
void report_missing_instance_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_ptr_data(extension_instance*, class_t<extension_instance>*, const std::type_info&);
void report_missing_class_object(const std::type_info&);
void report_released_smart_pointer(const std::type_info&);
template <class T>
T* check_non_null(T* p)
{
if (p == 0)
report_released_smart_pointer(typeid(T));
return p;
}
template <class Held> class held_instance;
typedef void* (*conversion_function_ptr)(void*);
struct base_class_info
{
base_class_info(extension_class_base* t, conversion_function_ptr f)
:class_object(t), convert(f)
{}
extension_class_base* class_object;
conversion_function_ptr convert;
};
typedef base_class_info derived_class_info;
struct add_operator_base;
class extension_class_base : public class_t<extension_instance>
{
public:
extension_class_base(const char* name);
public:
// the purpose of try_class_conversions() and its related functions
// is explained in extclass.cpp
void* try_class_conversions(instance_holder_base*) const;
void* try_base_class_conversions(instance_holder_base*) const;
void* try_derived_class_conversions(instance_holder_base*) const;
void set_attribute(const char* name, PyObject* x);
void set_attribute(const char* name, ref x);
private:
virtual void* extract_object_from_holder(instance_holder_base* v) const = 0;
virtual std::vector<base_class_info> const& base_classes() const = 0;
virtual std::vector<derived_class_info> const& derived_classes() const = 0;
protected:
friend struct add_operator_base;
void add_method(reference<function> method, const char* name);
void add_method(function* method, const char* name);
void add_constructor_object(function*);
void add_setter_method(function*, const char* name);
void add_getter_method(function*, const char* name);
};
template <class T>
class class_registry
{
public:
static extension_class_base* class_object()
{ return static_class_object; }
// Register/unregister the Python class object corresponding to T
static void register_class(extension_class_base*);
static void unregister_class(extension_class_base*);
// Establish C++ inheritance relationships
static void register_base_class(base_class_info const&);
static void register_derived_class(derived_class_info const&);
// Query the C++ inheritance relationships
static std::vector<base_class_info> const& base_classes();
static std::vector<derived_class_info> const& derived_classes();
private:
static extension_class_base* static_class_object;
static std::vector<base_class_info> static_base_class_info;
static std::vector<derived_class_info> static_derived_class_info;
};
template <bool is_pointer>
struct is_null_helper
{
template <class Ptr>
static bool test(Ptr x) { return x == 0; }
};
template <>
struct is_null_helper<false>
{
template <class Ptr>
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
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
// This class' only job is to define from_python and to_python converters for T
// and U. T is the class the user really intends to wrap. U is a class derived
// from T with some virtual function overriding boilerplate, or if there are no
// virtual functions, U = held_instance<T>.
//
// 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
{
public:
// Get an object which can be used to convert T to/from python. This is used
// as a kind of concept check by the global template
//
// PyObject* to_python(const T& x)
//
// below this class, to prevent the confusing messages that would otherwise
// pop up. Now, if T hasn't been wrapped as an extension class, the user
// will see an error message about the lack of an eligible
// py_extension_class_converters() function.
friend python_extension_class_converters py_extension_class_converters(boost::python::type<T>)
{
return python_extension_class_converters();
}
// This is a member function because in a conforming implementation, friend
// funcitons defined inline in the class body are all instantiated as soon
// as the enclosing class is instantiated. If T is not copyable, that causes
// a compiler error. Instead, we access this function through the global
// template
//
// PyObject* to_python(const T& x)
//
// defined below this class. Since template functions are instantiated only
// on demand, errors will be avoided unless T is noncopyable and the user
// writes code which causes us to try to copy a T.
PyObject* to_python(const T& x) const
{
boost::python::reference<boost::python::detail::extension_instance> result(create_instance());
result->add_implementation(
std::auto_ptr<boost::python::detail::instance_holder_base>(
new boost::python::detail::instance_value_holder<T,U>(result.get(), x)));
return result.release();
}
friend
T* non_null_from_python(PyObject* obj, boost::python::type<T*>)
{
// downcast to an extension_instance, then find the actual T
boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj);
typedef std::vector<boost::python::detail::instance_holder_base*>::const_iterator iterator;
for (iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
boost::python::detail::instance_holder<T>* held = dynamic_cast<boost::python::detail::instance_holder<T>*>(*p);
if (held != 0)
return held->target();
// see extclass.cpp for an explanation of try_class_conversions()
void* target = boost::python::detail::class_registry<T>::class_object()->try_class_conversions(*p);
if(target)
return static_cast<T*>(target);
}
boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
throw boost::python::argument_error();
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406
return 0;
#endif
}
// Convert to T*
friend T* from_python(PyObject* obj, boost::python::type<T*>)
{
if (obj == Py_None)
return 0;
else
return non_null_from_python(obj, boost::python::type<T*>());
}
// Extract from obj a mutable reference to the PtrType object which is holding a T.
template <class 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);
typedef std::vector<boost::python::detail::instance_holder_base*>::const_iterator iterator;
for (iterator p = self->wrapped_objects().begin();
p != self->wrapped_objects().end(); ++p)
{
boost::python::detail::instance_ptr_holder<PtrType, T>* held =
dynamic_cast<boost::python::detail::instance_ptr_holder<PtrType, T>*>(*p);
if (held != 0)
return held->ptr();
}
boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry<T>::class_object(), typeid(T));
throw boost::python::argument_error();
#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 PtrType& smart_ptr_value(PyObject* obj, boost::python::type<PtrType>)
{
if (obj == Py_None)
{
static PtrType null_ptr;
return null_ptr;
}
return smart_ptr_reference(obj, boost::python::type<PtrType>());
}
template <class PtrType>
static PyObject* smart_ptr_to_python(PtrType x)
{
if (boost::python::detail::is_null(x))
{
return boost::python::detail::none();
}
boost::python::reference<boost::python::detail::extension_instance> result(create_instance());
result->add_implementation(
std::auto_ptr<boost::python::detail::instance_holder_base>(
new boost::python::detail::instance_ptr_holder<PtrType,T>(x)));
return result.release();
}
static boost::python::reference<boost::python::detail::extension_instance> create_instance()
{
PyTypeObject* class_object = boost::python::detail::class_registry<T>::class_object();
if (class_object == 0)
boost::python::detail::report_missing_class_object(typeid(T));
return boost::python::reference<boost::python::detail::extension_instance>(
new boost::python::detail::extension_instance(class_object));
}
// Convert to const T*
friend const T* from_python(PyObject* p, boost::python::type<const T*>)
{ return from_python(p, boost::python::type<T*>()); }
// Convert to const T* const&
friend const T* from_python(PyObject* p, boost::python::type<const T*const&>)
{ return from_python(p, boost::python::type<const T*>()); }
// Convert to T* const&
friend T* from_python(PyObject* p, boost::python::type<T* const&>)
{ return from_python(p, boost::python::type<T*>()); }
// Convert to T&
friend T& from_python(PyObject* p, boost::python::type<T&>)
{ return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type<T*>())); }
// Convert to const T&
friend const T& from_python(PyObject* p, boost::python::type<const T&>)
{ return from_python(p, boost::python::type<T&>()); }
// Convert to T
friend const T& from_python(PyObject* p, boost::python::type<T>)
{ return from_python(p, boost::python::type<T&>()); }
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T>&>)
{ return smart_ptr_reference(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 smart_ptr_value(p, boost::python::type<std::auto_ptr<T> >()); }
friend PyObject* to_python(std::auto_ptr<T> x)
{ return smart_ptr_to_python(x); }
friend boost::shared_ptr<T>& from_python(PyObject* 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 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 smart_ptr_value(p, boost::python::type<boost::shared_ptr<T> >()); }
friend PyObject* to_python(boost::shared_ptr<T> x)
{ return smart_ptr_to_python(x); }
};
// Convert T to_python, instantiated on demand and only if there isn't a
// non-template overload for this function. This version is the one invoked when
// T is a wrapped class. See the first 2 functions declared in
// python_extension_class_converters above for more info.
template <class T>
PyObject* to_python(const T& x)
{
return py_extension_class_converters(boost::python::type<T>()).to_python(x);
}
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace boost { namespace python {
BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters);
namespace detail {
template <class T> class instance_holder;
class read_only_setattr_function : public function
{
public:
read_only_setattr_function(const char* name);
PyObject* do_call(PyObject* args, PyObject* keywords) const;
const char* description() const;
private:
string m_name;
};
template <class From, class To>
struct define_conversion
{
static void* upcast_ptr(void* v)
{
return static_cast<To*>(static_cast<From*>(v));
}
static void* downcast_ptr(void* v)
{
return dynamic_cast<To*>(static_cast<From*>(v));
}
};
// An easy way to make an extension base class which wraps T. Note that Python
// subclasses of this class will simply be class_t<extension_instance> objects.
//
// U should be a class derived from T which overrides virtual functions with
// boilerplate code to call back into Python. See extclass_demo.h for examples.
//
// U is optional, but you won't be able to override any member functions in
// Python which are called from C++ if you don't supply it. If you just want to
// be able to use T in python without overriding member functions, you can omit
// U.
template <class T, class U = held_instance<T> >
class extension_class
: public python_extension_class_converters<T, U>, // This generates the to_python/from_python functions
public extension_class_base
{
public:
typedef T wrapped_type;
typedef U callback_type;
// Construct with a name that comes from typeid(T).name(). The name only
// affects the objects of this class are represented through repr()
extension_class();
// Construct with the given name. The name only affects the objects of this
// class are represented through repr()
extension_class(const char* name);
~extension_class();
// define constructors
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
inline void def(constructor<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>)
// The following incantation builds a signature1, signature2,... object. It
// should _all_ get optimized away.
{ add_constructor(
prepend(type<A1>::id(),
prepend(type<A2>::id(),
prepend(type<A3>::id(),
prepend(type<A4>::id(),
prepend(type<A5>::id(),
prepend(type<A6>::id(),
prepend(type<A7>::id(),
prepend(type<A8>::id(),
prepend(type<A9>::id(),
prepend(type<A10>::id(),
signature0())))))))))));
}
// export homogeneous operators (type of both lhs and rhs is 'operator')
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>());
// export homogeneous operators (type of both lhs and rhs is 'T const&')
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>());
template <long which, class Operand>
inline void def(operators<which,Operand>)
{
typedef typename operand_select<Operand>::template wrapped<T>::type true_operand;
def_operators(operators<which,true_operand>());
}
// export heterogeneous operators (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
// boost::python::right_operand<int const&>());
// export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right')
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
// boost::python::right_operand<int const&>());
template <long which, class Left, class Right>
inline void def(operators<which,Left>, right_operand<Right> r)
{
typedef typename operand_select<Left>::template wrapped<T>::type true_left;
def_operators(operators<which,true_left>(), r);
}
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'right')
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(),
// boost::python::left_operand<int const&>());
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'T const&')
// usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(),
// boost::python::left_operand<int const&>());
template <long which, class Left, class Right>
inline void def(operators<which,Right>, left_operand<Left> l)
{
typedef typename operand_select<Right>::template wrapped<T>::type true_right;
def_operators(operators<which,true_right>(), l);
}
// define a function that passes Python arguments and keywords
// to C++ verbatim (as a 'tuple const&' and 'dictionary const&'
// respectively). This is useful for manual argument passing.
// It's also the only possibility to pass keyword arguments to C++.
// Fn must have a signatur that is compatible to
// PyObject* (*)(PyObject* aTuple, PyObject* aDictionary)
template <class Fn>
inline void def_raw(Fn fn, const char* name)
{
this->add_method(new_raw_arguments_function(fn), name);
}
// define member functions. In fact this works for free functions, too -
// they act like static member functions, or if they start with the
// appropriate self argument (as a pointer), they can be used just like
// ordinary member functions -- just like Python!
template <class Fn>
inline void def(Fn fn, const char* name)
{
this->add_method(new_wrapped_function(fn), name);
}
// Define a virtual member function with a default implementation.
// default_fn should be a function which provides the default implementation.
// Be careful that default_fn does not in fact call fn virtually!
template <class Fn, class DefaultFn>
inline void def(Fn fn, const char* name, DefaultFn default_fn)
{
this->add_method(new_virtual_function(type<T>(), fn, default_fn), name);
}
// Provide a function which implements x.<name>, reading from the given
// member (pm) of the T obj
template <class MemberType>
inline void def_getter(MemberType T::*pm, const char* name)
{
this->add_getter_method(new getter_function<T, MemberType>(pm), name);
}
// Provide a function which implements assignment to x.<name>, writing to
// the given member (pm) of the T obj
template <class MemberType>
inline void def_setter(MemberType T::*pm, const char* name)
{
this->add_setter_method(new setter_function<T, MemberType>(pm), name);
}
// Expose the given member (pm) of the T obj as a read-only attribute
template <class MemberType>
inline void def_readonly(MemberType T::*pm, const char* name)
{
this->add_setter_method(new read_only_setattr_function(name), name);
this->def_getter(pm, name);
}
// Expose the given member (pm) of the T obj as a read/write attribute
template <class MemberType>
inline void def_read_write(MemberType T::*pm, const char* name)
{
this->def_getter(pm, name);
this->def_setter(pm, name);
}
// define the standard coercion needed for operator overloading
void def_standard_coerce();
// declare the given class a base class of this one and register
// up and down conversion functions
template <class S, class V>
void declare_base(extension_class<S, V>* base)
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
base_class_info baseInfo(base,
&define_conversion<S, T>::downcast_ptr);
class_registry<T>::register_base_class(baseInfo);
add_base(ref(as_object(base), ref::increment_count));
derived_class_info derivedInfo(this,
&define_conversion<T, S>::upcast_ptr);
class_registry<S>::register_derived_class(derivedInfo);
}
// declare the given class a base class of this one and register
// only up conversion function
template <class S, class V>
void declare_base(extension_class<S, V>* base, without_downcast_t)
{
// see extclass.cpp for an explanation of why we need to register
// conversion functions
base_class_info baseInfo(base, 0);
class_registry<T>::register_base_class(baseInfo);
add_base(ref(as_object(base), ref::increment_count));
derived_class_info derivedInfo(this,
&define_conversion<T, S>::upcast_ptr);
class_registry<S>::register_derived_class(derivedInfo);
}
private: // types
typedef instance_value_holder<T,U> holder;
private: // extension_class_base virtual function implementations
std::vector<base_class_info> const& base_classes() const;
std::vector<derived_class_info> const& derived_classes() const;
void* extract_object_from_holder(instance_holder_base* v) const;
private: // Utility functions
template <long which, class Operand>
inline void def_operators(operators<which,Operand>)
{
def_standard_coerce();
// for some strange reason, this prevents MSVC from having an
// "unrecoverable block scoping error"!
typedef choose_op<(which & op_add)> choose_add;
choose_op<(which & op_add)>::template args<Operand>::add(this);
choose_op<(which & op_sub)>::template args<Operand>::add(this);
choose_op<(which & op_mul)>::template args<Operand>::add(this);
choose_op<(which & op_div)>::template args<Operand>::add(this);
choose_op<(which & op_mod)>::template args<Operand>::add(this);
choose_op<(which & op_divmod)>::template args<Operand>::add(this);
choose_op<(which & op_pow)>::template args<Operand>::add(this);
choose_op<(which & op_lshift)>::template args<Operand>::add(this);
choose_op<(which & op_rshift)>::template args<Operand>::add(this);
choose_op<(which & op_and)>::template args<Operand>::add(this);
choose_op<(which & op_xor)>::template args<Operand>::add(this);
choose_op<(which & op_or)>::template args<Operand>::add(this);
choose_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);
choose_unary_op<(which & op_invert)>::template args<Operand>::add(this);
choose_unary_op<(which & op_int)>::template args<Operand>::add(this);
choose_unary_op<(which & op_long)>::template args<Operand>::add(this);
choose_unary_op<(which & op_float)>::template args<Operand>::add(this);
choose_op<(which & op_cmp)>::template args<Operand>::add(this);
choose_unary_op<(which & op_str)>::template args<Operand>::add(this);
}
template <long which, class Left, class Right>
inline void def_operators(operators<which,Left>, right_operand<Right>)
{
def_standard_coerce();
choose_op<(which & op_add)>::template args<Left,Right>::add(this);
choose_op<(which & op_sub)>::template args<Left,Right>::add(this);
choose_op<(which & op_mul)>::template args<Left,Right>::add(this);
choose_op<(which & op_div)>::template args<Left,Right>::add(this);
choose_op<(which & op_mod)>::template args<Left,Right>::add(this);
choose_op<(which & op_divmod)>::template args<Left,Right>::add(this);
choose_op<(which & op_pow)>::template args<Left,Right>::add(this);
choose_op<(which & op_lshift)>::template args<Left,Right>::add(this);
choose_op<(which & op_rshift)>::template args<Left,Right>::add(this);
choose_op<(which & op_and)>::template args<Left,Right>::add(this);
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
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>
inline void def_operators(operators<which,Right>, left_operand<Left>)
{
def_standard_coerce();
choose_rop<(which & op_add)>::template args<Left,Right>::add(this);
choose_rop<(which & op_sub)>::template args<Left,Right>::add(this);
choose_rop<(which & op_mul)>::template args<Left,Right>::add(this);
choose_rop<(which & op_div)>::template args<Left,Right>::add(this);
choose_rop<(which & op_mod)>::template args<Left,Right>::add(this);
choose_rop<(which & op_divmod)>::template args<Left,Right>::add(this);
choose_rop<(which & op_pow)>::template args<Left,Right>::add(this);
choose_rop<(which & op_lshift)>::template args<Left,Right>::add(this);
choose_rop<(which & op_rshift)>::template args<Left,Right>::add(this);
choose_rop<(which & op_and)>::template args<Left,Right>::add(this);
choose_rop<(which & op_xor)>::template args<Left,Right>::add(this);
choose_rop<(which & op_or)>::template args<Left,Right>::add(this);
choose_rop<(which & op_cmp)>::template args<Left,Right>::add(this);
}
template <class signature>
void add_constructor(signature sig)
{
this->add_constructor_object(init_function<holder>::create(sig));
}
};
// A simple wrapper over a T which allows us to use extension_class<T> with a
// single template parameter only. See extension_class<T>, above.
template <class Held>
class held_instance : public Held
{
// There are no member functions: we want to avoid inadvertently overriding
// any virtual functions in Held.
public:
held_instance(PyObject*) : Held() {}
template <class A1>
held_instance(PyObject*, A1 a1) : Held(a1) {}
template <class A1, class 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) : Held(a1, a2, a3) {}
template <class A1, class A2, class A3, class 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) : 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) : 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) : 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) : 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) : 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) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
};
// Abstract base class for all obj holders. Base for template class
// instance_holder<>, below.
class instance_holder_base
{
public:
virtual ~instance_holder_base() {}
virtual bool held_by_value() = 0;
};
// Abstract base class which holds a Held, somehow. Provides a uniform way to
// get a pointer to the held object
template <class Held>
class instance_holder : public instance_holder_base
{
public:
virtual Held*target() = 0;
};
// Concrete class which holds a Held by way of a wrapper class Wrapper. If Held
// can be constructed with arguments (A1...An), Wrapper must have a
// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is
// neccessary to implement virtual function callbacks (there must be a
// back-pointer to the actual Python object so that we can call any
// overrides). held_instance (above) is used as a default Wrapper class when
// there are no virtual functions.
template <class Held, class Wrapper>
class instance_value_holder : public instance_holder<Held>
{
public:
Held* target() { return &m_held; }
Wrapper* value_target() { return &m_held; }
instance_value_holder(extension_instance* p) :
m_held(p) {}
template <class A1>
instance_value_holder(extension_instance* p, A1 a1) :
m_held(p, a1) {}
template <class A1, class A2>
instance_value_holder(extension_instance* p, A1 a1, A2 a2) :
m_held(p, a1, a2) {}
template <class A1, class A2, class A3>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) :
m_held(p, a1, a2, a3) {}
template <class A1, class A2, class A3, class A4>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) :
m_held(p, a1, a2, a3, a4) {}
template <class A1, class A2, class A3, class A4, class A5>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
m_held(p, a1, a2, a3, a4, a5) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
m_held(p, a1, a2, a3, a4, a5, a6) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
m_held(p, a1, a2, a3, a4, a5, a6, a7) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
public: // implementation of instance_holder_base required interface
bool held_by_value() { return true; }
private:
Wrapper m_held;
};
// Concrete class which holds a HeldType by way of a (possibly smart) pointer
// PtrType. By default, these are only generated for PtrType ==
// std::auto_ptr<HeldType> and PtrType == boost::shared_ptr<HeldType>.
template <class PtrType, class HeldType>
class instance_ptr_holder : public instance_holder<HeldType>
{
public:
HeldType* target() { return &*m_ptr; }
PtrType& ptr() { return m_ptr; }
instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {}
public: // implementation of instance_holder_base required interface
bool held_by_value() { return false; }
private:
PtrType m_ptr;
};
class extension_instance : public instance
{
public:
extension_instance(PyTypeObject* class_);
~extension_instance();
void add_implementation(std::auto_ptr<instance_holder_base> holder);
typedef std::vector<instance_holder_base*> held_objects;
const held_objects& wrapped_objects() const
{ return m_wrapped_objects; }
private:
held_objects m_wrapped_objects;
};
//
// Template function implementations
//
template <class T, class U>
extension_class<T, U>::extension_class()
: extension_class_base(typeid(T).name())
{
class_registry<T>::register_class(this);
}
template <class T, class U>
extension_class<T, U>::extension_class(const char* name)
: extension_class_base(name)
{
class_registry<T>::register_class(this);
}
template <class T, class U>
void extension_class<T, U>::def_standard_coerce()
{
ref coerce_fct = dict().get_item(string("__coerce__"));
if(coerce_fct.get() == 0) // not yet defined
this->def(&standard_coerce, "__coerce__");
}
template <class T, class U>
inline
std::vector<base_class_info> const&
extension_class<T, U>::base_classes() const
{
return class_registry<T>::base_classes();
}
template <class T, class U>
inline
std::vector<derived_class_info> const&
extension_class<T, U>::derived_classes() const
{
return class_registry<T>::derived_classes();
}
template <class T, class U>
void* extension_class<T, U>::extract_object_from_holder(instance_holder_base* v) const
{
instance_holder<T>* held = dynamic_cast<instance_holder<T>*>(v);
if(held)
return held->target();
return 0;
}
template <class T, class U>
extension_class<T, U>::~extension_class()
{
class_registry<T>::unregister_class(this);
}
template <class T>
inline void class_registry<T>::register_class(extension_class_base* p)
{
// You're not expected to create more than one of these!
assert(static_class_object == 0);
static_class_object = p;
}
template <class T>
inline void class_registry<T>::unregister_class(extension_class_base* p)
{
// The user should be destroying the same object they created.
assert(static_class_object == p);
(void)p; // unused in shipping version
static_class_object = 0;
}
template <class T>
void class_registry<T>::register_base_class(base_class_info const& i)
{
static_base_class_info.push_back(i);
}
template <class T>
void class_registry<T>::register_derived_class(derived_class_info const& i)
{
static_derived_class_info.push_back(i);
}
template <class T>
std::vector<base_class_info> const& class_registry<T>::base_classes()
{
return static_base_class_info;
}
template <class T>
std::vector<derived_class_info> const& class_registry<T>::derived_classes()
{
return static_derived_class_info;
}
//
// Static data member declaration.
//
template <class T>
extension_class_base* class_registry<T>::static_class_object;
template <class T>
std::vector<base_class_info> class_registry<T>::static_base_class_info;
template <class T>
std::vector<derived_class_info> class_registry<T>::static_derived_class_info;
}}} // namespace boost::python::detail
#endif // EXTENSION_CLASS_DWA052000_H_

View 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_

View 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_

View 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_

View 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

View 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

View 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

View 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_

View 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

View 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

View File

@@ -1,46 +0,0 @@
08 May 2003
Fixed bug where in a certain cases the GCCXMLParser would end up with multiple
declarations of the same class
22 Apr 2003
- Now shows a warning when the user tries to export a forward-declared class. Forward-declared classes are ignored by the AllFromHeader construct.
- Fixed a bug where classes, functions and enums where being exported, even if excluded from a AllFromHeader construct.
16 Apr 2003
Added a more generic (but ugly) code to declare the smart pointer converters.
07 Apr 2003
- Removed the warnings about forward declarations: it was not accurate enough.
Another strategy must be thought of.
- Fixed bug in the --multiple mode, where the order of the class instantiations
could end up wrong.
- Lots of fixes in the documentation, pointed out by Dirk Gerrits. Thanks Dirk!
- Fixed support for the return_opaque_pointer policy (the support macro was not
being declared).
06 Apr 2003
Support for the improved static data members support of Boost.Python.
05 Apr 2003
New option for generating the bindings: --multiple.
02 Apr 2003
Forward declarations are now detected and a warning is generated.
24 Mar 2003
Default policy for functions/methods that return const T& is now
return_value_policy<copy_const_reference>().
22 Mar 2003
Exporting virtual methods of the base classes in the derived classes too.
21 Mar 2003
Added manual support for boost::shared_ptr and std::auto_ptr (see doc).
19 Mar 2003
Added support for int, double, float and long operators acting as expected in
python.
14 Mar 2003
Fixed bug: Wrappers for protected and virtual methods were not being generated.

View File

@@ -1,31 +0,0 @@
Pyste - Python Semi-Automatic Exporter
======================================
Pyste is a Boost.Python code generator. The user specifies the classes and
functions to be exported using a simple interface file, which following the
Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to
parse all the headers and extract the necessary information to automatically
generate C++ code.
The documentation can be found in the file index.html accompaning this README.
Enjoy!
Bruno da Silva de Oliveira (nicodemus@globalite.com.br)
Thanks
======
- David Abrahams, creator of Boost.Python, for tips on the syntax of the interface
file and support.
- Marcelo Camelo, for design tips, support and inspiration for this project.
Also, the name was his idea. 8)
- Brad King, creator of the excellent GCCXML (http://www.gccxml.org)
- Fredrik Lundh, creator of the elementtree library (http://effbot.org)
Bugs
====
Pyste is a young tool, so please help it to get better! Send bug reports to
nicodemus@globalite.com.br, accompaining the stack trace in case of exceptions.
If possible, run pyste with --debug, and send the resulting xmls too (pyste
will output a xml file with the same of each header it parsed).

View File

@@ -1,2 +0,0 @@
*.zip
*.pyc

View File

@@ -1,51 +0,0 @@
import os
import sys
import shutil
import fnmatch
from zipfile import ZipFile, ZIP_DEFLATED
def findfiles(directory, mask):
def visit(files, dir, names):
for name in names:
if fnmatch.fnmatch(name, mask):
files.append(os.path.join(dir, name))
files = []
os.path.walk(directory, visit, files)
return files
def main():
# test if PyXML is installed
try:
import _xmlplus.parsers.expat
pyxml = '--includes _xmlplus.parsers.expat'
except ImportError:
pyxml = ''
# create exe
status = os.system('python setup.py py2exe %s >& build.log' % pyxml)
if status != 0:
raise RuntimeError, 'Error creating EXE'
# create distribution
import pyste
version = pyste.__VERSION__
zip = ZipFile('pyste-%s.zip' % version, 'w', ZIP_DEFLATED)
# include the base files
dist_dir = 'dist/pyste'
for basefile in os.listdir(dist_dir):
zip.write(os.path.join(dist_dir, basefile), os.path.join('pyste', basefile))
# include documentation
for doc_file in findfiles('../doc', '*.*'):
dest_name = os.path.join('pyste/doc', doc_file[3:])
zip.write(doc_file, dest_name)
zip.write('../index.html', 'pyste/doc/index.html')
zip.close()
# cleanup
os.remove('build.log')
shutil.rmtree('build')
shutil.rmtree('dist')
if __name__ == '__main__':
sys.path.append('../src')
main()

6
pyste/dist/setup.py vendored
View File

@@ -1,6 +0,0 @@
from distutils.core import setup
import py2exe
import sys
sys.path.append('../src')
setup(name='pyste', scripts=['../src/pyste.py'])

View File

@@ -1,77 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Exporting All Declarations from a Header</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="wrappers.html">
<link rel="next" href="smart_pointers.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Exporting All Declarations from a Header</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="wrappers.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="smart_pointers.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Pyste also supports a mechanism to export all declarations found in a header
file. Suppose again our file, <tt>hello.h</tt>:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>World
</span><span class=special>{
</span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) {}
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
};
</span><span class=keyword>enum </span><span class=identifier>choice </span><span class=special>{ </span><span class=identifier>red</span><span class=special>, </span><span class=identifier>blue </span><span class=special>};
</span><span class=keyword>void </span><span class=identifier>show</span><span class=special>(</span><span class=identifier>choice </span><span class=identifier>c</span><span class=special>) { </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>&quot;value: &quot; </span><span class=special>&lt;&lt; (</span><span class=keyword>int</span><span class=special>)</span><span class=identifier>c </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>; }
</span></pre></code>
<p>
You can just use the <tt>AllFromHeader</tt> construct:</p>
<code><pre>
<span class=identifier>hello </span><span class=special>= </span><span class=identifier>AllFromHeader</span><span class=special>(</span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span></pre></code>
<p>
this will export all the declarations found in <tt>hello.h</tt>, which is equivalent
to write:</p>
<code><pre>
<span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>Enum</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;show&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span></pre></code>
<p>
Note that you can still use the functions <tt>rename</tt>, <tt>set_policy</tt>, <tt>exclude</tt>, etc. Just access
the members of the header object like this:</p>
<code><pre>
<span class=identifier>rename</span><span class=special>(</span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>greet</span><span class=special>, </span><span class=string>&quot;Greet&quot;</span><span class=special>)
</span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>set</span><span class=special>, </span><span class=string>&quot;Set&quot;</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="wrappers.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="smart_pointers.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,74 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Introduction</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="next" href="running_pyste.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Introduction</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
<td width="20"><a href="running_pyste.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<a name="what_is_pyste_"></a><h2>What is Pyste?</h2><p>
Pyste is a <a href="../../index.html">
Boost.Python</a> code generator. The user specifies the classes and
functions to be exported using a simple <i>interface file</i>, which following the
<a href="../../index.html">
Boost.Python</a>'s philosophy, is simple Python code. Pyste then uses <a href="http://www.gccxml.org">
GCCXML</a> to
parse all the headers and extract the necessary information to automatically
generate C++ code.</p>
<a name="example"></a><h2>Example</h2><p>
Let's borrow the class <tt>World</tt> from the <a href="../../doc/tutorial/doc/exposing_classes.html">
tutorial</a>: </p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>World
</span><span class=special>{
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
};
</span></pre></code>
<p>
Here's the interface file for it, named <tt>world.pyste</tt>:</p>
<code><pre>
<span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;world.h&quot;</span><span class=special>)
</span></pre></code>
<p>
and that's it!</p>
<p>
The next step is invoke Pyste in the command-line:</p>
<code><pre>python pyste.py --module=hello world.pyste</pre></code><p>
this will create a file &quot;<tt>hello.cpp</tt>&quot; in the directory where the command was
run. </p>
<p>
Pyste supports the following features:</p>
<ul><li>Functions</li><li>Classes</li><li>Class Templates</li><li>Virtual Methods</li><li>Overloading</li><li>Attributes </li><li>Enums (both &quot;free&quot; enums and class enums)</li><li>Nested Classes</li><li>Support for <tt>boost::shared_ptr</tt> and <tt>std::auto_ptr</tt></li></ul><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
<td width="20"><a href="running_pyste.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,90 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Policies</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="renaming_and_excluding.html">
<link rel="next" href="templates.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Policies</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="renaming_and_excluding.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="templates.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Even thought Pyste can identify various elements in the C++ code, like virtual
methods, attributes, and so on, one thing that it can't do is to guess the
semantics of functions that return pointers or references. In this case, the
user must manually specify the policy. Policies are explained in the
<a href="../../doc/tutorial/doc/call_policies.html">
tutorial</a>.</p>
<p>
The policies in Pyste are named exactly as in <a href="../../index.html">
Boost.Python</a>, only the syntax is
slightly different. For instance, this policy:</p>
<code><pre>
<span class=identifier>return_internal_reference</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=identifier>with_custodian_and_ward</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt; &gt;()
</span></pre></code>
<p>
becomes in Pyste: </p>
<code><pre>
<span class=identifier>return_internal_reference</span><span class=special>(</span><span class=number>1</span><span class=special>, </span><span class=identifier>with_custodian_and_ward</span><span class=special>(</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>))
</span></pre></code>
<p>
The user can specify policies for functions and methods with the <tt>set_policy</tt>
function:</p>
<code><pre>
<span class=identifier>set_policy</span><span class=special>(</span><span class=identifier>f</span><span class=special>, </span><span class=identifier>return_internal_reference</span><span class=special>())
</span><span class=identifier>set_policy</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>return_value_policy</span><span class=special>(</span><span class=identifier>manage_new_object</span><span class=special>))
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> <b>What if a function or method needs a policy and the user
doesn't set one?</b><br><br> If a function/method needs a policy and one was not
set, Pyste will issue a error. The user should then go in the interface file
and set the policy for it, otherwise the generated cpp won't compile.
</td>
</tr>
</table>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img>
Note that, for functions/methods that return <tt>const T&amp;</tt>, the policy
<tt>return_value_policy&lt;copy_const_reference&gt;()</tt> wil be used by default, because
that's normally what you want. You can change it to something else if you need
to, though.
</td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="renaming_and_excluding.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="templates.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,467 +0,0 @@
[doc Pyste Documentation]
[def GCCXML [@http://www.gccxml.org GCCXML]]
[def Boost.Python [@../../index.html Boost.Python]]
[page Introduction]
[h2 What is Pyste?]
Pyste is a Boost.Python code generator. The user specifies the classes and
functions to be exported using a simple ['interface file], which following the
Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to
parse all the headers and extract the necessary information to automatically
generate C++ code.
[h2 Example]
Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]:
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
Here's the interface file for it, named [^world.pyste]:
Class("World", "world.h")
and that's it!
The next step is invoke Pyste in the command-line:
[pre python pyste.py --module=hello world.pyste]
this will create a file "[^hello.cpp]" in the directory where the command was
run.
Pyste supports the following features:
* Functions
* Classes
* Class Templates
* Virtual Methods
* Overloading
* Attributes
* Enums (both "free" enums and class enums)
* Nested Classes
* Support for [^boost::shared_ptr] and [^std::auto_ptr]
[page Running Pyste]
To run Pyste, you will need:
* Python 2.2, available at [@http://www.python.org python's website].
* The great [@http://effbot.org elementtree] library, from Fredrik Lundh.
* The excellent GCCXML, from Brad King.
Installation for the tools is available in their respective webpages.
[blurb
[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so
that Pyste can call it. How to do this varies from platform to platform.
]
[h2 Ok, now what?]
Well, now let's fire it up:
[pre
'''
>python pyste.py
Pyste version 0.6.5
Usage:
pyste [options] --module=<name> interface-files
where options are:
-I <path> add an include path
-D <symbol> define symbol
--multiple create various cpps, instead of only one
(useful during development)
--out specify output filename (default: <module>.cpp)
in --multiple mode, this will be a directory
--no-using do not declare "using namespace boost";
use explicit declarations instead
--pyste-ns=<name> set the namespace where new types will be declared;
default is the empty namespace
--debug writes the xml for each file parsed in the current
directory
-h, --help print this help and exit
-v, --version print version information
'''
]
Options explained:
The [^-I] and [^-D] are preprocessor flags, which are needed by GCCXML to parse
the header files correctly and by Pyste to find the header files declared in the
interface files.
[^--multiple] tells Pyste to generate multiple cpps for this module (one for
each header parsed) in the directory named by [^--out], instead of the usual
single cpp file. This mode is useful during development of a binding, because
you are constantly changing source files, re-generating the bindings and
recompiling. This saves a lot of time in compiling.
[^--out] names the output file (default: [^<module>.cpp]), or in multiple mode,
names a output directory for the files (default: [^<module>]).
[^--no-using] tells Pyste to don't declare "[^using namespace boost;]" in the
generated cpp, using the namespace boost::python explicitly in all declarations.
Use only if you're having a name conflict in one of the files.
Use [^--pyste-ns] to change the namespace where new types are declared (for
instance, the virtual wrappers). Use only if you are having any problems. By
default, Pyste uses the empty namespace.
[^--debug] will write in the current directory a xml file as outputted by GCCXML
for each header parsed. Useful for bug reports.
[^-h, --help, -v, --version] are self-explaining, I believe. ;)
So, the usage is simple enough:
[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...]
will generate a file [^mymodule.cpp] in the same dir where the command was
executed. Now you can compile the file using the same instructions of the
[@../../doc/tutorial/doc/building_hello_world.html tutorial]. Or, if you prefer:
[pre >python pyste.py --module=mymodule --multiple file.pyste file2.pyste ...]
will create a directory named "mymodule" in the current directory, and will
generate a bunch of cpp files, one for each header exported. You can then
compile them all into a single shared library (or dll).
[h2 Wait... how do I set those I and D flags?]
Don't worry: normally GCCXML is already configured correctly for your plataform,
so the search path to the standard libraries and the standard defines should
already be set. You only have to set the paths to other libraries that your code
needs, like Boost, for example.
Plus, Pyste automatically uses the contents of the environment variable
[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file,
which for Visual C++ 6 is normally located at:
C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
with that, you should have little trouble setting up the flags.
[blurb [$theme/note.gif][*A note about Psyco][br][br]
Although you don't have to install [@http://psyco.sourceforge.net/ Psyco] to use Pyste, if you do, Pyste will make use of it to speed up the wrapper generation. Speed ups of 30% can be achieved, so it's highly recommended.
]
[page The Interface Files]
The interface files are the heart of Pyste. The user creates one or more
interface files declaring the classes and functions he wants to export, and then
invokes Pyste passing the interface files to it. Pyste then generates a single
cpp file with Boost.Python code, with all the classes and functions exported.
Besides declaring the classes and functions, the user has a number of other
options, like renaming classes and methods, excluding methods and attributes,
and so on.
[h2 Basics]
Suppose we have a class and some functions that we want to expose to Python
declared in the header [^hello.h]:
struct World
{
World(std::string msg): msg(msg) {}
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
enum choice { red, blue };
namespace test {
void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
}
We create a file named [^hello.pyste] and create instances of the classes
[^Function], [^Class] and [^Enum]:
Function("test::show", "hello.h")
Class("World", "hello.h")
Enum("choice", "hello.h")
That will expose the class, the free function and the enum found in [^hello.h].
[page:1 Renaming and Excluding]
You can easily rename functions, classes, methods, attributes, etc. Just use the
function [^rename], like this:
World = Class("World", "hello.h")
rename(World, "IWorld")
show = Function("choice", "hello.h")
rename(show, "Show")
You can rename methods and attributes using this syntax:
rename(World.greet, "Greet")
rename(World.set, "Set")
choice = Enum("choice", "hello.h")
rename(choice.red, "Red")
rename(choice.blue, "Blue")
You can exclude functions, classes, methods, attributes, etc, in the same way,
with the function [^exclude]:
exclude(World.greet)
exclude(World.msg)
To access the operators of a class, access the member [^operator] like this
(supposing that [^C] is a class being exported):
exclude(C.operator['+'])
exclude(C.operator['*'])
exclude(C.operator['<<'])
The string inside the brackets is the same as the name of the operator in C++.[br]
[page:1 Policies]
Even thought Pyste can identify various elements in the C++ code, like virtual
methods, attributes, and so on, one thing that it can't do is to guess the
semantics of functions that return pointers or references. In this case, the
user must manually specify the policy. Policies are explained in the
[@../../doc/tutorial/doc/call_policies.html tutorial].
The policies in Pyste are named exactly as in Boost.Python, only the syntax is
slightly different. For instance, this policy:
return_internal_reference<1, with_custodian_and_ward<1, 2> >()
becomes in Pyste:
return_internal_reference(1, with_custodian_and_ward(1, 2))
The user can specify policies for functions and methods with the [^set_policy]
function:
set_policy(f, return_internal_reference())
set_policy(C.foo, return_value_policy(manage_new_object))
[blurb
[$theme/note.gif] [*What if a function or method needs a policy and the user
doesn't set one?][br][br] If a function/method needs a policy and one was not
set, Pyste will issue a error. The user should then go in the interface file
and set the policy for it, otherwise the generated cpp won't compile.
]
[blurb
[$theme/note.gif]
Note that, for functions/methods that return [^const T&], the policy
[^return_value_policy<copy_const_reference>()] wil be used by default, because
that's normally what you want. You can change it to something else if you need
to, though.
]
[page:1 Templates]
Template classes can easily be exported too, but you can't export the template
itself... you have to export instantiations of it! So, if you want to export a
[^std::vector], you will have to export vectors of int, doubles, etc.
Suppose we have this code:
template <class T>
struct Point
{
T x;
T y;
};
And we want to export [^Point]s of int and double:
Point = Template("Point", "point.h")
Point("int")
Point("double")
Pyste will assign default names for each instantiation. In this example, those
would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to
rename the instantiations:
Point("int", "IPoint") // renames the instantiation
double_inst = Point("double") // another way to do the same
rename(double_inst, "DPoint")
Note that you can rename, exclude, set policies, etc, in the [^Template] object
like you would do with a [^Function] or a [^Class]. This changes affect all
[*future] instantiations:
Point = Template("Point", "point.h")
Point("float", "FPoint") // will have x and y as data members
rename(Point.x, "X")
rename(Point.y, "Y")
Point("int", "IPoint") // will have X and Y as data members
Point("double", "DPoint") // also will have X and Y as data member
If you want to change a option of a particular instantiation, you can do so:
Point = Template("Point", "point.h")
Point("int", "IPoint")
d_inst = Point("double", "DPoint")
rename(d_inst.x, "X") // only DPoint is affect by this renames,
rename(d_inst.y, "Y") // IPoint stays intact
[blurb [$theme/note.gif] [*What if my template accepts more than one type?]
[br][br]
When you want to instantiate a template with more than one type, you can pass
either a string with the types separated by whitespace, or a list of strings
'''("int double" or ["int", "double"]''' would both work).
]
[page:1 Wrappers]
Suppose you have this function:
std::vector<std::string> names();
But you don't want to export [^std::vector<std::string>], you want this function
to return a python list of strings. Boost.Python has excellent support for
that:
list names_wrapper()
{
list result;
// call original function
vector<string> v = names();
// put all the strings inside the python list
vector<string>::iterator it;
for (it = v.begin(); it != v.end(); ++it){
result.append(*it);
}
return result;
}
BOOST_PYTHON_MODULE(test)
{
def("names", &names_wrapper);
}
Nice heh? Pyste supports this mechanism too. You declare the [^names_wrapper]
function in a header named "[^test_wrappers.h]" and in the interface file:
Include("test_wrappers.h")
names = Function("names", "test.h")
set_wrapper(names, "names_wrapper")
You can optionally declare the function in the interface file itself:
names_wrapper = Wrapper("names_wrapper",
"""
list names_wrapper()
{
// code to call name() and convert the vector to a list...
}
""")
names = Function("names", "test.h")
set_wrapper(names, names_wrapper)
The same mechanism can be used with methods too. Just remember that the first
parameter of wrappers for methods is a pointer to the class, like in
Boost.Python:
struct C
{
std::vector<std::string> names();
}
list names_wrapper(C* c)
{
// same as before, calling c->names() and converting result to a list
}
And then in the interface file:
C = Class("C", "test.h")
set_wrapper(C.names, "names_wrapper")
[blurb
[$theme/note.gif]Even though Boost.Python accepts either a pointer or a
reference to the class in wrappers for member functions as the first parameter,
Pyste expects them to be a [*pointer]. Doing otherwise will prevent your
code to compile when you set a wrapper for a virtual method.
]
[page:1 Exporting All Declarations from a Header]
Pyste also supports a mechanism to export all declarations found in a header
file. Suppose again our file, [^hello.h]:
struct World
{
World(std::string msg): msg(msg) {}
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
enum choice { red, blue };
void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
You can just use the [^AllFromHeader] construct:
hello = AllFromHeader("hello.h")
this will export all the declarations found in [^hello.h], which is equivalent
to write:
Class("World", "hello.h")
Enum("choice", "hello.h")
Function("show", "hello.h")
Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access
the members of the header object like this:
rename(hello.World.greet, "Greet")
exclude(hello.World.set, "Set")
[page:1 Smart Pointers]
Pyste for now has manual support for smart pointers. Suppose:
struct C
{
int value;
};
boost::shared_ptr<C> newC(int value)
{
boost::shared_ptr<C> c( new C() );
c->value = value;
return c;
}
void printC(boost::shared_ptr<C> c)
{
std::cout << c->value << std::endl;
}
To make [^newC] and [^printC] work correctly, you have to tell Pyste that a
convertor for [^boost::shared_ptr<C>] is needed.
C = Class('C', 'C.h')
use_shared_ptr(C)
Function('newC', 'C.h')
Function('printC', 'C.h')
For [^std::auto_ptr]'s, use the function [^use_auto_ptr].
This system is temporary, and in the future the converters will automatically be
exported if needed, without the need to tell Pyste about them explicitly.

View File

@@ -1,76 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Renaming and Excluding</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="the_interface_files.html">
<link rel="next" href="policies.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Renaming and Excluding</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="the_interface_files.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
You can easily rename functions, classes, methods, attributes, etc. Just use the
function <tt>rename</tt>, like this:</p>
<code><pre>
<span class=identifier>World </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>World</span><span class=special>, </span><span class=string>&quot;IWorld&quot;</span><span class=special>)
</span><span class=identifier>show </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>show</span><span class=special>, </span><span class=string>&quot;Show&quot;</span><span class=special>)
</span></pre></code>
<p>
You can rename methods and attributes using this syntax:</p>
<code><pre>
<span class=identifier>rename</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>greet</span><span class=special>, </span><span class=string>&quot;Greet&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>set</span><span class=special>, </span><span class=string>&quot;Set&quot;</span><span class=special>)
</span><span class=identifier>choice </span><span class=special>= </span><span class=identifier>Enum</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>choice</span><span class=special>.</span><span class=identifier>red</span><span class=special>, </span><span class=string>&quot;Red&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>choice</span><span class=special>.</span><span class=identifier>blue</span><span class=special>, </span><span class=string>&quot;Blue&quot;</span><span class=special>)
</span></pre></code>
<p>
You can exclude functions, classes, methods, attributes, etc, in the same way,
with the function <tt>exclude</tt>:</p>
<code><pre>
<span class=identifier>exclude</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>greet</span><span class=special>)
</span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>msg</span><span class=special>)
</span></pre></code>
<p>
To access the operators of a class, access the member <tt>operator</tt> like this
(supposing that <tt>C</tt> is a class being exported):</p>
<code><pre>
<span class=identifier>exclude</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=keyword>operator</span><span class=special>[</span><span class=literal>'+'</span><span class=special>])
</span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=keyword>operator</span><span class=special>[</span><span class=literal>'*'</span><span class=special>])
</span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=keyword>operator</span><span class=special>[</span><span class=literal>'&lt;&lt;'</span><span class=special>])
</span></pre></code>
<p>
The string inside the brackets is the same as the name of the operator in C++.<br></p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="the_interface_files.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,150 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Running Pyste</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="introduction.html">
<link rel="next" href="the_interface_files.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Running Pyste</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="the_interface_files.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
To run Pyste, you will need:</p>
<ul><li>Python 2.2, available at <a href="http://www.python.org">
python's website</a>.</li><li>The great <a href="http://effbot.org">
elementtree</a> library, from Fredrik Lundh.</li><li>The excellent <a href="http://www.gccxml.org">
GCCXML</a>, from Brad King.</li></ul><p>
Installation for the tools is available in their respective webpages.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> <a href="http://www.gccxml.org">
GCCXML</a> must be accessible in the PATH environment variable, so
that Pyste can call it. How to do this varies from platform to platform.
</td>
</tr>
</table>
<a name="ok__now_what_"></a><h2>Ok, now what?</h2><p>
Well, now let's fire it up:</p>
<code><pre>
&gt;python pyste.py
Pyste version 0.6.5
Usage:
pyste [options] --module=&lt;name&gt; interface-files
where options are:
-I &lt;path&gt; add an include path
-D &lt;symbol&gt; define symbol
--multiple create various cpps, instead of only one
(useful during development)
--out specify output filename (default: &lt;module&gt;.cpp)
in --multiple mode, this will be a directory
--no-using do not declare &quot;using namespace boost&quot;;
use explicit declarations instead
--pyste-ns=&lt;name&gt; set the namespace where new types will be declared;
default is the empty namespace
--debug writes the xml for each file parsed in the current
directory
-h, --help print this help and exit
-v, --version print version information
</pre></code><p>
Options explained:</p>
<p>
The <tt>-I</tt> and <tt>-D</tt> are preprocessor flags, which are needed by <a href="http://www.gccxml.org">
GCCXML</a> to parse
the header files correctly and by Pyste to find the header files declared in the
interface files.</p>
<p>
<tt>--multiple</tt> tells Pyste to generate multiple cpps for this module (one for
each header parsed) in the directory named by <tt>--out</tt>, instead of the usual
single cpp file. This mode is useful during development of a binding, because
you are constantly changing source files, re-generating the bindings and
recompiling. This saves a lot of time in compiling.</p>
<p>
<tt>--out</tt> names the output file (default: <tt>&lt;module&gt;.cpp</tt>), or in multiple mode,
names a output directory for the files (default: <tt>&lt;module&gt;</tt>).</p>
<p>
<tt>--no-using</tt> tells Pyste to don't declare &quot;<tt>using namespace boost;</tt>&quot; in the
generated cpp, using the namespace boost::python explicitly in all declarations.
Use only if you're having a name conflict in one of the files.</p>
<p>
Use <tt>--pyste-ns</tt> to change the namespace where new types are declared (for
instance, the virtual wrappers). Use only if you are having any problems. By
default, Pyste uses the empty namespace.</p>
<p>
<tt>--debug</tt> will write in the current directory a xml file as outputted by <a href="http://www.gccxml.org">
GCCXML</a>
for each header parsed. Useful for bug reports.</p>
<p>
<tt>-h, --help, -v, --version</tt> are self-explaining, I believe. ;)</p>
<p>
So, the usage is simple enough:</p>
<code><pre>&gt;python pyste.py --module=mymodule file.pyste file2.pyste ...</pre></code><p>
will generate a file <tt>mymodule.cpp</tt> in the same dir where the command was
executed. Now you can compile the file using the same instructions of the
<a href="../../doc/tutorial/doc/building_hello_world.html">
tutorial</a>. Or, if you prefer:</p>
<code><pre>&gt;python pyste.py --module=mymodule --multiple file.pyste file2.pyste ...</pre></code><p>
will create a directory named &quot;mymodule&quot; in the current directory, and will
generate a bunch of cpp files, one for each header exported. You can then
compile them all into a single shared library (or dll).</p>
<a name="wait____how_do_i_set_those_i_and_d_flags_"></a><h2>Wait... how do I set those I and D flags?</h2><p>
Don't worry: normally <a href="http://www.gccxml.org">
GCCXML</a> is already configured correctly for your plataform,
so the search path to the standard libraries and the standard defines should
already be set. You only have to set the paths to other libraries that your code
needs, like Boost, for example.</p>
<p>
Plus, Pyste automatically uses the contents of the environment variable
<tt>INCLUDE</tt> if it exists. Visual C++ users should run the <tt>Vcvars32.bat</tt> file,
which for Visual C++ 6 is normally located at:</p>
<code><pre>
<span class=identifier>C</span><span class=special>:\</span><span class=identifier>Program </span><span class=identifier>Files</span><span class=special>\</span><span class=identifier>Microsoft </span><span class=identifier>Visual </span><span class=identifier>Studio</span><span class=special>\</span><span class=identifier>VC98</span><span class=special>\</span><span class=identifier>bin</span><span class=special>\</span><span class=identifier>Vcvars32</span><span class=special>.</span><span class=identifier>bat
</span></pre></code>
<p>
with that, you should have little trouble setting up the flags.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img><b>A note about Psyco</b><br><br>
Although you don't have to install <a href="http://psyco.sourceforge.net/">
Psyco</a> to use Pyste, if you do, Pyste will make use of it to speed up the wrapper generation. Speed ups of 30% can be achieved, so it's highly recommended.
</td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="the_interface_files.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,74 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Smart Pointers</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="exporting_all_declarations_from_a_header.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Smart Pointers</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exporting_all_declarations_from_a_header.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<p>
Pyste for now has manual support for smart pointers. Suppose:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>C
</span><span class=special>{
</span><span class=keyword>int </span><span class=identifier>value</span><span class=special>;
};
</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>shared_ptr</span><span class=special>&lt;</span><span class=identifier>C</span><span class=special>&gt; </span><span class=identifier>newC</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>value</span><span class=special>)
{
</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>shared_ptr</span><span class=special>&lt;</span><span class=identifier>C</span><span class=special>&gt; </span><span class=identifier>c</span><span class=special>( </span><span class=keyword>new </span><span class=identifier>C</span><span class=special>() );
</span><span class=identifier>c</span><span class=special>-&gt;</span><span class=identifier>value </span><span class=special>= </span><span class=identifier>value</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>c</span><span class=special>;
}
</span><span class=keyword>void </span><span class=identifier>printC</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>shared_ptr</span><span class=special>&lt;</span><span class=identifier>C</span><span class=special>&gt; </span><span class=identifier>c</span><span class=special>)
{
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>c</span><span class=special>-&gt;</span><span class=identifier>value </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;
}
</span></pre></code>
<p>
To make <tt>newC</tt> and <tt>printC</tt> work correctly, you have to tell Pyste that a
convertor for <tt>boost::shared_ptr&lt;C&gt;</tt> is needed.</p>
<code><pre>
<span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
</span><span class=identifier>use_shared_ptr</span><span class=special>(</span><span class=identifier>C</span><span class=special>)
</span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'newC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
</span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'printC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
</span></pre></code>
<p>
For <tt>std::auto_ptr</tt>'s, use the function <tt>use_auto_ptr</tt>.</p>
<p>
This system is temporary, and in the future the converters will automatically be
exported if needed, without the need to tell Pyste about them explicitly.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exporting_all_declarations_from_a_header.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,103 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Templates</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="policies.html">
<link rel="next" href="wrappers.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Templates</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="wrappers.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Template classes can easily be exported too, but you can't export the template
itself... you have to export instantiations of it! So, if you want to export a
<tt>std::vector</tt>, you will have to export vectors of int, doubles, etc.</p>
<p>
Suppose we have this code:</p>
<code><pre>
<span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>class </span><span class=identifier>T</span><span class=special>&gt;
</span><span class=keyword>struct </span><span class=identifier>Point
</span><span class=special>{
</span><span class=identifier>T </span><span class=identifier>x</span><span class=special>;
</span><span class=identifier>T </span><span class=identifier>y</span><span class=special>;
};
</span></pre></code>
<p>
And we want to export <tt>Point</tt>s of int and double:</p>
<code><pre>
<span class=identifier>Point </span><span class=special>= </span><span class=identifier>Template</span><span class=special>(</span><span class=string>&quot;Point&quot;</span><span class=special>, </span><span class=string>&quot;point.h&quot;</span><span class=special>)
</span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>)
</span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>)
</span></pre></code>
<p>
Pyste will assign default names for each instantiation. In this example, those
would be &quot;<tt>Point_int</tt>&quot; and &quot;<tt>Point_double</tt>&quot;, but most of the time users will want to
rename the instantiations:</p>
<code><pre>
<span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>, </span><span class=string>&quot;IPoint&quot;</span><span class=special>) // </span><span class=identifier>renames </span><span class=identifier>the </span><span class=identifier>instantiation
</span><span class=identifier>double_inst </span><span class=special>= </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>) // </span><span class=identifier>another </span><span class=identifier>way </span><span class=identifier>to </span><span class=keyword>do </span><span class=identifier>the </span><span class=identifier>same
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>double_inst</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>)
</span></pre></code>
<p>
Note that you can rename, exclude, set policies, etc, in the <tt>Template</tt> object
like you would do with a <tt>Function</tt> or a <tt>Class</tt>. This changes affect all
<b>future</b> instantiations:</p>
<code><pre>
<span class=identifier>Point </span><span class=special>= </span><span class=identifier>Template</span><span class=special>(</span><span class=string>&quot;Point&quot;</span><span class=special>, </span><span class=string>&quot;point.h&quot;</span><span class=special>)
</span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;float&quot;</span><span class=special>, </span><span class=string>&quot;FPoint&quot;</span><span class=special>) // </span><span class=identifier>will </span><span class=identifier>have </span><span class=identifier>x </span><span class=keyword>and </span><span class=identifier>y </span><span class=identifier>as </span><span class=identifier>data </span><span class=identifier>members
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>Point</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=string>&quot;X&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>Point</span><span class=special>.</span><span class=identifier>y</span><span class=special>, </span><span class=string>&quot;Y&quot;</span><span class=special>)
</span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>, </span><span class=string>&quot;IPoint&quot;</span><span class=special>) // </span><span class=identifier>will </span><span class=identifier>have </span><span class=identifier>X </span><span class=keyword>and </span><span class=identifier>Y </span><span class=identifier>as </span><span class=identifier>data </span><span class=identifier>members
</span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>) // </span><span class=identifier>also </span><span class=identifier>will </span><span class=identifier>have </span><span class=identifier>X </span><span class=keyword>and </span><span class=identifier>Y </span><span class=identifier>as </span><span class=identifier>data </span><span class=identifier>member
</span></pre></code>
<p>
If you want to change a option of a particular instantiation, you can do so:</p>
<code><pre>
<span class=identifier>Point </span><span class=special>= </span><span class=identifier>Template</span><span class=special>(</span><span class=string>&quot;Point&quot;</span><span class=special>, </span><span class=string>&quot;point.h&quot;</span><span class=special>)
</span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>, </span><span class=string>&quot;IPoint&quot;</span><span class=special>)
</span><span class=identifier>d_inst </span><span class=special>= </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>)
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>d_inst</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=string>&quot;X&quot;</span><span class=special>) // </span><span class=identifier>only </span><span class=identifier>DPoint </span><span class=identifier>is </span><span class=identifier>affect </span><span class=identifier>by </span><span class=keyword>this </span><span class=identifier>renames</span><span class=special>,
</span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>d_inst</span><span class=special>.</span><span class=identifier>y</span><span class=special>, </span><span class=string>&quot;Y&quot;</span><span class=special>) // </span><span class=identifier>IPoint </span><span class=identifier>stays </span><span class=identifier>intact
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> <b>What if my template accepts more than one type?</b>
<br><br>
When you want to instantiate a template with more than one type, you can pass
either a string with the types separated by whitespace, or a list of strings
(&quot;int double&quot; or [&quot;int&quot;, &quot;double&quot;] would both work).
</td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="wrappers.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,81 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>The Interface Files</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="running_pyste.html">
<link rel="next" href="renaming_and_excluding.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>The Interface Files</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="running_pyste.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="renaming_and_excluding.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
The interface files are the heart of Pyste. The user creates one or more
interface files declaring the classes and functions he wants to export, and then
invokes Pyste passing the interface files to it. Pyste then generates a single
cpp file with <a href="../../index.html">
Boost.Python</a> code, with all the classes and functions exported.</p>
<p>
Besides declaring the classes and functions, the user has a number of other
options, like renaming classes and methods, excluding methods and attributes,
and so on. </p>
<a name="basics"></a><h2>Basics</h2><p>
Suppose we have a class and some functions that we want to expose to Python
declared in the header <tt>hello.h</tt>:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>World
</span><span class=special>{
</span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) {}
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
};
</span><span class=keyword>enum </span><span class=identifier>choice </span><span class=special>{ </span><span class=identifier>red</span><span class=special>, </span><span class=identifier>blue </span><span class=special>};
</span><span class=keyword>namespace </span><span class=identifier>test </span><span class=special>{
</span><span class=keyword>void </span><span class=identifier>show</span><span class=special>(</span><span class=identifier>choice </span><span class=identifier>c</span><span class=special>) { </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>&quot;value: &quot; </span><span class=special>&lt;&lt; (</span><span class=keyword>int</span><span class=special>)</span><span class=identifier>c </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>; }
}
</span></pre></code>
<p>
We create a file named <tt>hello.pyste</tt> and create instances of the classes
<tt>Function</tt>, <tt>Class</tt> and <tt>Enum</tt>:</p>
<code><pre>
<span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;test::show&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span><span class=identifier>Enum</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
</span></pre></code>
<p>
That will expose the class, the free function and the enum found in <tt>hello.h</tt>. </p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="running_pyste.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="renaming_and_excluding.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 879 B

View File

@@ -1,170 +0,0 @@
body
{
background-image: url(bkd.gif);
background-color: #FFFFFF;
margin: 1em 2em 1em 2em;
}
h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; }
h2 { font: 140% sans-serif; font-weight: bold; text-align: left; }
h3 { font: 120% sans-serif; font-weight: bold; text-align: left; }
h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; }
h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; }
h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; }
pre
{
border-top: gray 1pt solid;
border-right: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
padding-top: 2pt;
padding-right: 2pt;
padding-left: 2pt;
padding-bottom: 2pt;
display: block;
font-family: "courier new", courier, mono;
background-color: #eeeeee; font-size: small
}
code
{
font-family: "Courier New", Courier, mono;
font-size: small
}
tt
{
display: inline;
font-family: "Courier New", Courier, mono;
color: #000099;
font-size: small
}
p
{
text-align: justify;
font-family: Georgia, "Times New Roman", Times, serif
}
ul
{
list-style-image: url(bullet.gif);
font-family: Georgia, "Times New Roman", Times, serif
}
ol
{
font-family: Georgia, "Times New Roman", Times, serif
}
a
{
font-weight: bold;
color: #003366;
text-decoration: none;
}
a:hover { color: #8080FF; }
.literal { color: #666666; font-style: italic}
.keyword { color: #000099}
.identifier {}
.comment { font-style: italic; color: #990000}
.special { color: #800040}
.preprocessor { color: #FF0000}
.string { font-style: italic; color: #666666}
.copyright { color: #666666; font-size: small}
.white_bkd { background-color: #FFFFFF}
.dk_grey_bkd { background-color: #999999}
.quotes { color: #666666; font-style: italic; font-weight: bold}
.note_box
{
display: block;
border-top: gray 1pt solid;
border-right: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
padding-right: 12pt;
padding-left: 12pt;
padding-bottom: 12pt;
padding-top: 12pt;
font-family: Arial, Helvetica, sans-serif;
background-color: #E2E9EF;
font-size: small; text-align: justify
}
.table_title
{
background-color: #648CCA;
font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF;
font-weight: bold
; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px
}
.table_cells
{
background-color: #E2E9EF;
font-family: Geneva, Arial, Helvetica, san-serif;
font-size: small
; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px
}
.toc
{
DISPLAY: block;
background-color: #E2E9EF
font-family: Arial, Helvetica, sans-serif;
border-top: gray 1pt solid;
border-left: gray 1pt solid;
border-bottom: gray 1pt solid;
border-right: gray 1pt solid;
padding-top: 24pt;
padding-right: 24pt;
padding-left: 24pt;
padding-bottom: 24pt;
}
.toc_title
{
background-color: #648CCA;
padding-top: 4px;
padding-right: 4px;
padding-bottom: 4px;
padding-left: 4px;
font-family: Geneva, Arial, Helvetica, san-serif;
color: #FFFFFF;
font-weight: bold
}
.toc_cells
{
background-color: #E2E9EF;
padding-top: 4px;
padding-right: 4px;
padding-bottom: 4px;
padding-left: 4px;
font-family: Geneva, Arial, Helvetica, san-serif;
font-size: small
}
div.logo
{
float: right;
}
.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }
.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

View File

@@ -1,125 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Wrappers</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="templates.html">
<link rel="next" href="exporting_all_declarations_from_a_header.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Wrappers</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="templates.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exporting_all_declarations_from_a_header.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Suppose you have this function:</p>
<code><pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>names</span><span class=special>();
</span></pre></code>
<p>
But you don't want to export <tt>std::vector&lt;std::string&gt;</tt>, you want this function
to return a python list of strings. <a href="../../index.html">
Boost.Python</a> has excellent support for
that:</p>
<code><pre>
<span class=identifier>list </span><span class=identifier>names_wrapper</span><span class=special>()
{
</span><span class=identifier>list </span><span class=identifier>result</span><span class=special>;
// </span><span class=identifier>call </span><span class=identifier>original </span><span class=identifier>function
</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>names</span><span class=special>();
// </span><span class=identifier>put </span><span class=identifier>all </span><span class=identifier>the </span><span class=identifier>strings </span><span class=identifier>inside </span><span class=identifier>the </span><span class=identifier>python </span><span class=identifier>list
</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt;::</span><span class=identifier>iterator </span><span class=identifier>it</span><span class=special>;
</span><span class=keyword>for </span><span class=special>(</span><span class=identifier>it </span><span class=special>= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(); </span><span class=identifier>it </span><span class=special>!= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>(); ++</span><span class=identifier>it</span><span class=special>){
</span><span class=identifier>result</span><span class=special>.</span><span class=identifier>append</span><span class=special>(*</span><span class=identifier>it</span><span class=special>);
}
</span><span class=keyword>return </span><span class=identifier>result</span><span class=special>;
}
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>test</span><span class=special>)
{
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, &amp;</span><span class=identifier>names_wrapper</span><span class=special>);
}
</span></pre></code>
<p>
Nice heh? Pyste supports this mechanism too. You declare the <tt>names_wrapper</tt>
function in a header named &quot;<tt>test_wrappers.h</tt>&quot; and in the interface file:</p>
<code><pre>
<span class=identifier>Include</span><span class=special>(</span><span class=string>&quot;test_wrappers.h&quot;</span><span class=special>)
</span><span class=identifier>names </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
</span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>names</span><span class=special>, </span><span class=string>&quot;names_wrapper&quot;</span><span class=special>)
</span></pre></code>
<p>
You can optionally declare the function in the interface file itself:</p>
<code><pre>
<span class=identifier>names_wrapper </span><span class=special>= </span><span class=identifier>Wrapper</span><span class=special>(</span><span class=string>&quot;names_wrapper&quot;</span><span class=special>,
</span><span class=string>&quot;&quot;</span><span class=string>&quot;
list names_wrapper()
{
// code to call name() and convert the vector to a list...
}
&quot;</span><span class=string>&quot;&quot;</span><span class=special>)
</span><span class=identifier>names </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
</span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>names</span><span class=special>, </span><span class=identifier>names_wrapper</span><span class=special>)
</span></pre></code>
<p>
The same mechanism can be used with methods too. Just remember that the first
parameter of wrappers for methods is a pointer to the class, like in
<a href="../../index.html">
Boost.Python</a>:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>C
</span><span class=special>{
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>names</span><span class=special>();
}
</span><span class=identifier>list </span><span class=identifier>names_wrapper</span><span class=special>(</span><span class=identifier>C</span><span class=special>* </span><span class=identifier>c</span><span class=special>)
{
// </span><span class=identifier>same </span><span class=identifier>as </span><span class=identifier>before</span><span class=special>, </span><span class=identifier>calling </span><span class=identifier>c</span><span class=special>-&gt;</span><span class=identifier>names</span><span class=special>() </span><span class=keyword>and </span><span class=identifier>converting </span><span class=identifier>result </span><span class=identifier>to </span><span class=identifier>a </span><span class=identifier>list
</span><span class=special>}
</span></pre></code>
<p>
And then in the interface file:</p>
<code><pre>
<span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;C&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
</span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=identifier>names</span><span class=special>, </span><span class=string>&quot;names_wrapper&quot;</span><span class=special>)
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img>Even though <a href="../../index.html">
Boost.Python</a> accepts either a pointer or a
reference to the class in wrappers for member functions as the first parameter,
Pyste expects them to be a <b>pointer</b>. Doing otherwise will prevent your
code to compile when you set a wrapper for a virtual method.
</td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="templates.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exporting_all_declarations_from_a_header.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1,2 +0,0 @@
.sconsign
*.obj

View File

@@ -1,5 +0,0 @@
To use this examples, just execute the command-line:
pyste --module=<example> <example>.pyste
For more information, please refer to the documentation.

View File

@@ -1,8 +0,0 @@
#include "basic.h"
namespace basic {
int C::static_value = 3;
const int C::const_static_value = 100;
}

View File

@@ -1,59 +0,0 @@
#ifndef BASIC_H
#define BASIC_H
#include <string>
namespace basic {
struct C
{
// test virtuallity
C(): value(1), const_value(0) {}
virtual int f(int x = 10)
{
return x*2;
}
int foo(int x=1){
return x+1;
}
const std::string& name() { return _name; }
void set_name(const std::string& name) { _name = name; }
std::string _name;
// test data members
static int static_value;
static const int const_static_value;
int value;
const int const_value;
// test static functions
static int mul(int x=2, int y=3) { return x*y; }
};
inline int call_f(C& c)
{
return c.f();
}
inline int call_f(C& c, int x)
{
return c.f(x);
}
inline int get_static()
{
return C::static_value;
}
inline int get_value(C& c)
{
return c.value;
}
}
#endif

View File

@@ -1,5 +0,0 @@
Class('basic::C', 'basic.h')
Function('basic::call_f', 'basic.h')
Function('basic::get_static', 'basic.h')
Function('basic::get_value', 'basic.h')

View File

@@ -1,24 +0,0 @@
#ifndef ENUMS_H
#define ENUMS_H
namespace enums {
enum color { red, blue };
struct X
{
enum choices
{
good = 1,
bad = 2
};
int set(choices c)
{
return (int)c;
}
};
}
#endif

View File

@@ -1,8 +0,0 @@
color = Enum('enums::color', 'enums.h')
rename(color.red, 'Red')
rename(color.blue, 'Blue')
X = Class('enums::X', 'enums.h')
rename(X.choices.bad, 'Bad')
rename(X.choices.good, 'Good')
rename(X.choices, 'Choices')

View File

@@ -1,38 +0,0 @@
#ifndef HEADER_TEST_H
#define HEADER_TEST_H
#include <map>
#include <string>
namespace header_test {
enum choice { red, blue };
inline std::string choice_str(choice c)
{
std::map<choice, std::string> choice_map;
choice_map[red] = "red";
choice_map[blue] = "blue";
return choice_map[c];
}
struct C
{
choice c;
std::string get()
{
return choice_str(c);
}
};
// test the exclusion of the following
struct ForwardDeclared; // should be excluded automatically
struct A {};
void foo();
enum bar { value };
}
#endif

View File

@@ -1,4 +0,0 @@
h = AllFromHeader('header_test.h')
exclude(h.A)
exclude(h.foo)
exclude(h.bar)

View File

@@ -1,18 +0,0 @@
template<typename T>
class A
{
public:
void set(T v) { mData = v; }
T get() const { return mData; }
private:
T mData;
};
class B : public A<int>
{
public:
int go() { return get(); }
};

View File

@@ -1,8 +0,0 @@
# Doesn't work:
A = Template('A', 'inherit.h')
A_int = A('int')
Class('B', 'inherit.h')
# Does work:
#AllFromHeader('inherit.h')

View File

@@ -1,4 +0,0 @@
#include "nested.h"
int nested::X::staticXValue = 10;
int nested::X::Y::staticYValue = 20;

View File

@@ -1,26 +0,0 @@
#ifndef NESTED_H
#define NESTED_H
namespace nested {
struct X
{
struct Y
{
int valueY;
static int staticYValue;
struct Z
{
int valueZ;
};
};
static int staticXValue;
int valueX;
};
typedef X Root;
}
#endif

View File

@@ -1 +0,0 @@
Class('nested::Root', 'nested.h')

View File

@@ -1,47 +0,0 @@
#ifndef OPAQUE_H
#define OPAQUE_H
#include <iostream>
namespace opaque {
struct C {
C(int v): value(v) {}
int value;
};
inline C* new_C()
{
return new C(10);
}
inline int get(C* c)
{
return c->value;
}
struct D {
D(double v): value(v) {}
double value;
};
struct A
{
D* new_handle()
{
return new D(3.0);
}
double get(D* d)
{
return d->value;
}
int f(int x=0) { return x; }
};
}
#endif

View File

@@ -1,5 +0,0 @@
foo = Function('opaque::new_C', 'opaque.h')
set_policy(foo, return_value_policy(return_opaque_pointer))
Function('opaque::get', 'opaque.h' )
A = Class('opaque::A', 'opaque.h')
set_policy(A.new_handle, return_value_policy(return_opaque_pointer))

View File

@@ -1,3 +0,0 @@
#include "operators.h"
double operators::C::x = 10;

View File

@@ -1,49 +0,0 @@
#ifndef OPERATORS_H
#define OPERATORS_H
#include <iostream>
namespace operators {
struct C
{
static double x;
double value;
const C operator+(const C other) const
{
C c;
c.value = value + other.value;
return c;
}
operator int() const
{
return (int)value;
}
double operator()()
{
return C::x;
}
double operator()(double other)
{
return C::x + other;
}
operator const char*() { return "C"; }
};
inline const C operator*(const C& lhs, const C& rhs)
{
C c;
c.value = lhs.value * rhs.value;
return c;
}
}
#endif

View File

@@ -1,2 +0,0 @@
C = Class('operators::C', 'operators.h')
#exclude(C.operator['+'])

View File

@@ -1,44 +0,0 @@
#ifndef SMART_PTR_H
#define SMART_PTR_H
#include <memory>
#include <boost/shared_ptr.hpp>
namespace smart_ptr {
struct C
{
int value;
};
inline boost::shared_ptr<C> NewC() { return boost::shared_ptr<C>( new C() ); }
struct D
{
boost::shared_ptr<C> Get() { return ptr; }
void Set( boost::shared_ptr<C> c ) { ptr = c; }
private:
boost::shared_ptr<C> ptr;
};
inline std::auto_ptr<D> NewD() { return std::auto_ptr<D>( new D() ); }
// test an abstract class
struct A
{
virtual int f() = 0;
};
struct B: A
{
virtual int f(){ return 1; }
};
inline boost::shared_ptr<A> NewA() { return boost::shared_ptr<A>(new B()); }
inline int GetA(boost::shared_ptr<A> a) { return a->f(); }
}
#endif

View File

@@ -1,13 +0,0 @@
C = Class('smart_ptr::C', 'smart_ptr.h')
use_shared_ptr(C)
D = Class('smart_ptr::D', 'smart_ptr.h')
use_auto_ptr(D)
A = Class('smart_ptr::A', 'smart_ptr.h')
use_shared_ptr(A)
Function('smart_ptr::NewC', 'smart_ptr.h')
Function('smart_ptr::NewD', 'smart_ptr.h')
Function('smart_ptr::NewA', 'smart_ptr.h')
Function('smart_ptr::GetA', 'smart_ptr.h')

View File

@@ -1,10 +0,0 @@
namespace templates {
template <class T>
struct Point
{
T x;
T y;
};
}

View File

@@ -1,8 +0,0 @@
Point = Template('templates::Point', 'templates.h')
rename(Point.x, 'i')
rename(Point.y, 'j')
IPoint = Point('int')
FPoint = Point('double', 'FPoint')
rename(IPoint, 'IPoint')
rename(IPoint.x, 'x')
rename(IPoint.y, 'y')

View File

@@ -1,16 +0,0 @@
namespace unions {
class UnionTest
{
public:
union // unions are not supported for now
{
int i;
short s1;
short s2;
} mBad;
int mGood;
};
}

View File

@@ -1,2 +0,0 @@
UnionTest = Class('unions::UnionTest', 'unions.h')
exclude(UnionTest.mBad)

View File

@@ -1,28 +0,0 @@
namespace virtual_ {
struct C
{
public:
virtual int f()
{
return f_abs();
}
virtual void bar(int) {}
virtual void bar(char*) {}
const char* get_name()
{
return name();
}
protected:
virtual int f_abs() = 0;
private:
virtual const char* name() { return "C"; }
};
inline int call_f(C& c) { return c.f(); }
}

View File

@@ -1,2 +0,0 @@
Class('virtual_::C', 'virtual.h')
Function('virtual_::call_f', 'virtual.h')

View File

@@ -1,27 +0,0 @@
namespace virtual2 {
struct A
{
virtual int f() { return 0; }
virtual int f1() { return 10; }
};
struct B: A
{
virtual int f() { return 1; }
virtual int f2() { return 20; }
};
inline int call_fs(A*a)
{
int r = a->f1();
B* b = dynamic_cast<B*>(a);
return r + b->f2();
}
inline int call_f(A* a)
{
return a->f();
}
}

View File

@@ -1,4 +0,0 @@
Class('virtual2::A', 'virtual2.h')
Class('virtual2::B', 'virtual2.h')
Function('virtual2::call_fs', 'virtual2.h')
Function('virtual2::call_f', 'virtual2.h')

View File

@@ -1,46 +0,0 @@
#ifndef WRAPPER_TEST
#define WRAPPER_TEST
#include <vector>
namespace wrappertest {
inline std::vector<int> Range(int count)
{
std::vector<int> v;
v.reserve(count);
for (int i = 0; i < count; ++i){
v.push_back(i);
}
return v;
}
struct C
{
C() {}
std::vector<int> Mul(int value)
{
std::vector<int> res;
res.reserve(value);
std::vector<int>::const_iterator it;
std::vector<int> v(Range(value));
for (it = v.begin(); it != v.end(); ++it){
res.push_back(*it * value);
}
return res;
}
};
struct A
{
virtual int f() { return 1; };
};
inline int call_foo(A* a){ return a->f(); }
}
#endif

View File

@@ -1,21 +0,0 @@
Include('wrappertest_wrappers.h')
f = Function('wrappertest::Range', 'wrappertest.h')
set_wrapper(f, 'RangeWrapper')
mul = Wrapper('MulWrapper',
'''
list MulWrapper(wrappertest::C& c, int value){
return VectorToList(c.Mul(value));
}
'''
)
C = Class('wrappertest::C', 'wrappertest.h')
set_wrapper(C.Mul, mul)
A = Class('wrappertest::A', 'wrappertest.h')
set_wrapper(A.f, 'f_wrapper')
Function('wrappertest::call_foo', 'wrappertest.h')

View File

@@ -1,28 +0,0 @@
#ifndef WRAPPER_TEST_WRAPPERS
#define WRAPPER_TEST_WRAPPERS
#include <vector>
#include <boost/python.hpp>
#include "wrappertest.h"
using namespace boost::python;
template <class T>
list VectorToList(const std::vector<T> & v)
{
list res;
typename std::vector<T>::const_iterator it;
for(it = v.begin(); it != v.end(); ++it){
res.append(*it);
}
Py_XINCREF(res.ptr());
return res;
}
inline list RangeWrapper(int count){
return VectorToList(wrappertest::Range(count));
}
inline int f_wrapper(wrappertest::A*) { return 10; }
#endif

View File

@@ -1,76 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Pyste Documentation</title>
<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
<link rel="next" href="introduction.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="doc/theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Pyste Documentation</b></font>
</td>
</tr>
</table>
<br>
<table width="80%" border="0" align="center">
<tr>
<td class="toc_title">Table of contents</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/introduction.html">Introduction</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/running_pyste.html">Running Pyste</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/the_interface_files.html">The Interface Files</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/renaming_and_excluding.html">Renaming and Excluding</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/policies.html">Policies</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/templates.html">Templates</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/wrappers.html">Wrappers</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/exporting_all_declarations_from_a_header.html">Exporting All Declarations from a Header</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/smart_pointers.html">Smart Pointers</a>
</td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -1 +0,0 @@
*.pyc

View File

@@ -1,840 +0,0 @@
import exporters
from Exporter import Exporter
from declarations import *
from settings import *
from policies import *
from SingleCodeUnit import SingleCodeUnit
from EnumExporter import EnumExporter
from utils import makeid, enumerate
from copy import deepcopy
import exporterutils
import re
#==============================================================================
# ClassExporter
#==============================================================================
class ClassExporter(Exporter):
'Generates boost.python code to export a class declaration'
def __init__(self, info, parser_tail=None):
Exporter.__init__(self, info, parser_tail)
# sections of code
self.sections = {}
# template: each item in the list is an item into the class_<...>
# section.
self.sections['template'] = []
# constructor: each item in the list is a parameter to the class_
# constructor, like class_<C>(...)
self.sections['constructor'] = []
# inside: everything within the class_<> statement
self.sections['inside'] = []
# scope: items outside the class statement but within its scope.
# scope* s = new scope(class<>());
# ...
# delete s;
self.sections['scope'] = []
# declarations: outside the BOOST_PYTHON_MODULE macro
self.sections['declaration'] = []
self.sections['declaration-outside'] = []
self.sections['include'] = []
# a list of Constructor instances
self.constructors = []
self.wrapper_generator = None
# a list of code units, generated by nested declarations
self.nested_codeunits = []
self._exported_opaque_pointers = {}
def ScopeName(self):
return makeid(self.class_.FullName()) + '_scope'
def Unit(self):
return makeid(self.class_.name)
def Name(self):
return self.class_.FullName()
def SetDeclarations(self, declarations):
Exporter.SetDeclarations(self, declarations)
decl = self.GetDeclaration(self.info.name)
if isinstance(decl, Typedef):
self.class_ = self.GetDeclaration(decl.type.name)
if not self.info.rename:
self.info.rename = decl.name
else:
self.class_ = decl
self.public_members = \
[x for x in self.class_.members if x.visibility == Scope.public]
def ClassBases(self):
bases = []
def GetBases(class_):
this_bases = [self.GetDeclaration(x.name) for x in class_.bases]
bases.extend(this_bases)
for base in this_bases:
GetBases(base)
GetBases(self.class_)
return bases
def Order(self):
'''Return the TOTAL number of bases that this class has, including the
bases' bases. Do this because base classes must be instantialized
before the derived classes in the module definition.
'''
return '%s_%s' % (len(self.ClassBases()), self.class_.FullName())
def Export(self, codeunit, exported_names):
if not self.info.exclude:
self.CheckIsForwardDeclared()
self.CheckForwardDeclarations()
self.ExportBasics()
self.ExportBases(exported_names)
self.ExportConstructors()
self.ExportVariables()
self.ExportMethods()
self.ExportVirtualMethods()
self.ExportOperators()
self.ExportNestedClasses(exported_names)
self.ExportNestedEnums()
self.ExportSmartPointer()
self.ExportOpaquePointerPolicies()
self.Write(codeunit)
def CheckIsForwardDeclared(self):
if self.class_.incomplete:
print "--> Error: Class %s is forward declared! " \
"Please use the header with its complete definition." % self.class_.FullName()
print
def CheckForwardDeclarations(self):
for m in self.public_members:
if isinstance(m, Function):
exporterutils.WarnForwardDeclarations(m)
def Write(self, codeunit):
indent = self.INDENT
boost_ns = namespaces.python
pyste_ns = namespaces.pyste
code = ''
# begin a scope for this class if needed
nested_codeunits = self.nested_codeunits
needs_scope = self.sections['scope'] or nested_codeunits
if needs_scope:
scope_name = self.ScopeName()
code += indent + boost_ns + 'scope* %s = new %sscope(\n' %\
(scope_name, boost_ns)
# export the template section
template_params = ', '.join(self.sections['template'])
code += indent + boost_ns + 'class_< %s >' % template_params
# export the constructor section
constructor_params = ', '.join(self.sections['constructor'])
code += '(%s)\n' % constructor_params
# export the inside section
in_indent = indent*2
for line in self.sections['inside']:
code += in_indent + line + '\n'
# write the scope section and end it
if not needs_scope:
code += indent + ';\n'
else:
code += indent + ');\n'
for line in self.sections['scope']:
code += indent + line + '\n'
# write the contents of the nested classes
for nested_unit in nested_codeunits:
code += '\n' + nested_unit.Section('module')
# close the scope
code += indent + 'delete %s;\n' % scope_name
# write the code to the module section in the codeunit
codeunit.Write('module', code + '\n')
# write the declarations to the codeunit
declarations = '\n'.join(self.sections['declaration'])
for nested_unit in nested_codeunits:
declarations += nested_unit.Section('declaration')
if declarations:
codeunit.Write('declaration', declarations + '\n')
declarations_outside = '\n'.join(self.sections['declaration-outside'])
if declarations_outside:
codeunit.Write('declaration-outside', declarations_outside + '\n')
# write the includes to the codeunit
includes = '\n'.join(self.sections['include'])
for nested_unit in nested_codeunits:
includes += nested_unit.Section('include')
if includes:
codeunit.Write('include', includes)
def Add(self, section, item):
'Add the item into the corresponding section'
self.sections[section].append(item)
def ExportBasics(self):
'Export the name of the class and its class_ statement'
self.Add('template', self.class_.FullName())
name = self.info.rename or self.class_.name
self.Add('constructor', '"%s"' % name)
def ExportBases(self, exported_names):
'Expose the bases of the class into the template section'
bases = self.class_.bases
bases_list = []
for base in bases:
if base.visibility == Scope.public and base.name in exported_names:
bases_list.append(base.name)
if bases_list:
code = namespaces.python + 'bases< %s > ' % \
(', '.join(bases_list))
self.Add('template', code)
def ExportConstructors(self):
'''Exports all the public contructors of the class, plus indicates if the
class is noncopyable.
'''
py_ns = namespaces.python
indent = self.INDENT
def init_code(cons):
'return the init<>() code for the given contructor'
param_list = [p.FullName() for p in cons.parameters]
min_params_list = param_list[:cons.minArgs]
max_params_list = param_list[cons.minArgs:]
min_params = ', '.join(min_params_list)
max_params = ', '.join(max_params_list)
init = py_ns + 'init< '
init += min_params
if max_params:
if min_params:
init += ', '
init += py_ns + ('optional< %s >' % max_params)
init += ' >()'
return init
constructors = [x for x in self.public_members if isinstance(x, Constructor)]
self.constructors = constructors[:]
# don't export the copy constructor if the class is abstract
if self.class_.abstract:
for cons in constructors:
if cons.IsCopy():
constructors.remove(cons)
break
if not constructors:
# declare no_init
self.Add('constructor', py_ns + 'no_init')
else:
# write the constructor with less parameters to the constructor section
smaller = None
for cons in constructors:
if smaller is None or len(cons.parameters) < len(smaller.parameters):
smaller = cons
assert smaller is not None
self.Add('constructor', init_code(smaller))
constructors.remove(smaller)
# write the rest to the inside section, using def()
for cons in constructors:
code = '.def(%s)' % init_code(cons)
self.Add('inside', code)
# check if the class is copyable
if not self.class_.HasCopyConstructor() or self.class_.abstract:
self.Add('template', namespaces.boost + 'noncopyable')
def ExportVariables(self):
'Export the variables of the class, both static and simple variables'
vars = [x for x in self.public_members if isinstance(x, Variable)]
for var in vars:
if self.info[var.name].exclude:
continue
name = self.info[var.name].rename or var.name
fullname = var.FullName()
if var.type.const:
def_ = '.def_readonly'
else:
def_ = '.def_readwrite'
code = '%s("%s", &%s)' % (def_, name, fullname)
self.Add('inside', code)
def ExportMethods(self):
'Export all the non-virtual methods of this class'
def OverloadName(m):
'Returns the name of the overloads struct for the given method'
return makeid(m.FullName()) + ('_overloads_%i_%i' % (m.minArgs, m.maxArgs))
declared = {}
def DeclareOverloads(m):
'Declares the macro for the generation of the overloads'
if not m.virtual:
if m.static:
func = m.FullName()
macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS'
else:
func = m.name
macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS'
code = '%s(%s, %s, %i, %i)\n' % (macro, OverloadName(m), func, m.minArgs, m.maxArgs)
if code not in declared:
declared[code] = True
self.Add('declaration', code)
def Pointer(m):
'returns the correct pointer declaration for the method m'
# check if this method has a wrapper set for him
wrapper = self.info[method.name].wrapper
if wrapper:
return '&' + wrapper.FullName()
# return normal pointers to the methods of the class
is_unique = self.class_.IsUnique(m.name)
if is_unique:
return '&' + method.FullName()
else:
return method.PointerDeclaration()
def IsExportable(m):
'Returns true if the given method is exportable by this routine'
ignore = (Constructor, ClassOperator, Destructor)
return isinstance(m, Method) and not isinstance(m, ignore) and not m.virtual
methods = [x for x in self.public_members if IsExportable(x)]
for method in methods:
method_info = self.info[method.name]
# skip this method if it was excluded by the user
if method_info.exclude:
continue
# rename the method if the user requested
name = method_info.rename or method.name
# warn the user if this method needs a policy and doesn't have one
method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)
# check for policies
policy = method_info.policy or ''
if policy:
policy = ', %s%s()' % (namespaces.python, policy.Code())
# check for overloads
overload = ''
if method.minArgs != method.maxArgs:
# add the overloads for this method
DeclareOverloads(method)
overload_name = OverloadName(method)
overload = ', %s%s()' % (namespaces.pyste, overload_name)
# build the .def string to export the method
pointer = Pointer(method)
code = '.def("%s", %s' % (name, pointer)
code += policy
code += overload
code += ')'
self.Add('inside', code)
# static method
if method.static:
code = '.staticmethod("%s")' % name
self.Add('inside', code)
# add wrapper code if this method has one
wrapper = method_info.wrapper
if wrapper and wrapper.code:
self.Add('declaration', wrapper.code)
def ExportVirtualMethods(self):
# check if this class has any virtual methods
has_virtual_methods = False
for member in self.class_.members:
if type(member) == Method and member.virtual:
has_virtual_methods = True
break
if has_virtual_methods:
generator = _VirtualWrapperGenerator(self.class_, self.ClassBases(), self.info)
self.Add('template', generator.FullName())
for definition in generator.GenerateDefinitions():
self.Add('inside', definition)
self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT))
# operators natively supported by boost
BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -='\
'*= /= %= ^= &= |= <<= >>='.split()
# create a map for faster lookup
BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS))))
# a dict of operators that are not directly supported by boost, but can be exposed
# simply as a function with a special signature
BOOST_RENAME_OPERATORS = {
'()' : '__call__',
}
# converters which have a special name in python
# it's a map of a regular expression of the converter's result to the
# appropriate python name
SPECIAL_CONVERTERS = {
re.compile(r'(const)?\s*double$') : '__float__',
re.compile(r'(const)?\s*float$') : '__float__',
re.compile(r'(const)?\s*int$') : '__int__',
re.compile(r'(const)?\s*long$') : '__long__',
re.compile(r'(const)?\s*char\s*\*?$') : '__str__',
re.compile(r'(const)?.*::basic_string<.*>\s*(\*|\&)?$') : '__str__',
}
def ExportOperators(self):
'Export all member operators and free operators related to this class'
def GetFreeOperators():
'Get all the free (global) operators related to this class'
operators = []
for decl in self.declarations:
if isinstance(decl, Operator):
# check if one of the params is this class
for param in decl.parameters:
if param.name == self.class_.FullName():
operators.append(decl)
break
return operators
def GetOperand(param):
'Returns the operand of this parameter (either "self", or "other<type>")'
if param.name == self.class_.FullName():
return namespaces.python + 'self'
else:
return namespaces.python + ('other< %s >()' % param.name)
def HandleSpecialOperator(operator):
# gatter information about the operator and its parameters
result_name = operator.result.name
param1_name = ''
if operator.parameters:
param1_name = operator.parameters[0].name
# check for str
ostream = 'basic_ostream'
is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1
if is_str:
namespace = namespaces.python + 'self_ns::'
self_ = namespaces.python + 'self'
return '.def(%sstr(%s))' % (namespace, self_)
# is not a special operator
return None
frees = GetFreeOperators()
members = [x for x in self.public_members if type(x) == ClassOperator]
all_operators = frees + members
operators = [x for x in all_operators if not self.info['operator'][x.name].exclude]
for operator in operators:
# gatter information about the operator, for use later
wrapper = self.info['operator'][operator.name].wrapper
if wrapper:
pointer = '&' + wrapper.FullName()
if wrapper.code:
self.Add('declaration', wrapper.code)
elif isinstance(operator, ClassOperator) and self.class_.IsUnique(operator.name):
pointer = '&' + operator.FullName()
else:
pointer = operator.PointerDeclaration()
rename = self.info['operator'][operator.name].rename
# check if this operator will be exported as a method
export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS
# check if this operator has a special representation in boost
special_code = HandleSpecialOperator(operator)
has_special_representation = special_code is not None
if export_as_method:
# export this operator as a normal method, renaming or using the given wrapper
if not rename:
if wrapper:
rename = wrapper.name
else:
rename = self.BOOST_RENAME_OPERATORS[operator.name]
policy = ''
policy_obj = self.info['operator'][operator.name].policy
if policy_obj:
policy = ', %s()' % policy_obj.Code()
self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy))
elif has_special_representation:
self.Add('inside', special_code)
elif operator.name in self.BOOST_SUPPORTED_OPERATORS:
# export this operator using boost's facilities
op = operator
is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\
isinstance(op, ClassOperator) and len(op.parameters) == 0
if is_unary:
self.Add('inside', '.def( %s%sself )' % \
(operator.name, namespaces.python))
else:
# binary operator
if len(operator.parameters) == 2:
left_operand = GetOperand(operator.parameters[0])
right_operand = GetOperand(operator.parameters[1])
else:
left_operand = namespaces.python + 'self'
right_operand = GetOperand(operator.parameters[0])
self.Add('inside', '.def( %s %s %s )' % \
(left_operand, operator.name, right_operand))
# export the converters.
# export them as simple functions with a pre-determined name
converters = [x for x in self.public_members if type(x) == ConverterOperator]
def ConverterMethodName(converter):
result_fullname = converter.result.FullName()
result_name = converter.result.name
for regex, method_name in self.SPECIAL_CONVERTERS.items():
if regex.match(result_fullname):
return method_name
else:
# extract the last name from the full name
result_name = makeid(result_name)
return 'to_' + result_name
for converter in converters:
info = self.info['operator'][converter.result.FullName()]
# check if this operator should be excluded
if info.exclude:
continue
special_code = HandleSpecialOperator(converter)
if info.rename or not special_code:
# export as method
name = info.rename or ConverterMethodName(converter)
if self.class_.IsUnique(converter.name):
pointer = '&' + converter.FullName()
else:
pointer = converter.PointerDeclaration()
policy_code = ''
if info.policy:
policy_code = ', %s()' % info.policy.Code()
self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code))
elif special_code:
self.Add('inside', special_code)
def ExportNestedClasses(self, exported_names):
nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)]
for nested_class in nested_classes:
nested_info = self.info[nested_class.name]
nested_info.include = self.info.include
nested_info.name = nested_class.FullName()
exporter = ClassExporter(nested_info)
exporter.SetDeclarations(self.declarations + [nested_class])
codeunit = SingleCodeUnit(None, None)
exporter.Export(codeunit, exported_names)
self.nested_codeunits.append(codeunit)
def ExportNestedEnums(self):
nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)]
for enum in nested_enums:
enum_info = self.info[enum.name]
enum_info.include = self.info.include
enum_info.name = enum.FullName()
exporter = EnumExporter(enum_info)
exporter.SetDeclarations(self.declarations + [enum])
codeunit = SingleCodeUnit(None, None)
exporter.Export(codeunit, None)
self.nested_codeunits.append(codeunit)
def ExportSmartPointer(self):
smart_ptr = self.info.smart_ptr
if smart_ptr:
class_name = self.class_.FullName()
smart_ptr = smart_ptr % class_name
#self.Add('template', smart_ptr)
self.Add('scope', '// Temporary code for smart pointers')
self.Add('scope', namespaces.python + 'objects::class_value_wrapper< ')
self.Add('scope', ' %s, objects::make_ptr_instance< ' % smart_ptr)
self.Add('scope', ' %s, objects::pointer_holder< ' % class_name)
self.Add('scope', ' %s, %s >' % (smart_ptr, class_name))
self.Add('scope', ' >')
self.Add('scope', '>();')
def ExportOpaquePointerPolicies(self):
# check all methods for 'return_opaque_pointer' policies
methods = [x for x in self.public_members if isinstance(x, Method)]
for method in methods:
return_opaque_policy = return_value_policy(return_opaque_pointer)
if self.info[method.name].policy == return_opaque_policy:
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % method.result.name
if macro not in self._exported_opaque_pointers:
self.Add('declaration-outside', macro)
self._exported_opaque_pointers[macro] = 1
#==============================================================================
# Virtual Wrapper utils
#==============================================================================
def _ParamsInfo(m, count=None):
if count is None:
count = len(m.parameters)
param_names = ['p%i' % i for i in range(count)]
param_types = [x.FullName() for x in m.parameters[:count]]
params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)]
#for i, p in enumerate(m.parameters[:count]):
# if p.default is not None:
# #params[i] += '=%s' % p.default
# params[i] += '=%s' % (p.name + '()')
params = ', '.join(params)
return params, param_names, param_types
class _VirtualWrapperGenerator(object):
'Generates code to export the virtual methods of the given class'
def __init__(self, class_, bases, info):
self.class_ = class_
self.bases = bases[:]
self.info = info
self.wrapper_name = makeid(class_.FullName()) + '_Wrapper'
self.virtual_methods = None
self._method_count = {}
self.GenerateVirtualMethods()
def DefaultImplementationNames(self, method):
'''Returns a list of default implementations for this method, one for each
number of default arguments. Always returns at least one name, and return from
the one with most arguments to the one with the least.
'''
base_name = 'default_' + method.name
minArgs = method.minArgs
maxArgs = method.maxArgs
if minArgs == maxArgs:
return [base_name]
else:
return [base_name + ('_%i' % i) for i in range(minArgs, maxArgs+1)]
def Declaration(self, method, indent):
'''Returns a string with the declarations of the virtual wrapper and
its default implementations. This string must be put inside the Wrapper
body.
'''
pyste = namespaces.pyste
python = namespaces.python
rename = self.info[method.name].rename or method.name
result = method.result.FullName()
return_str = 'return '
if result == 'void':
return_str = ''
params, param_names, param_types = _ParamsInfo(method)
constantness = ''
if method.const:
constantness = ' const'
# call_method callback
decl = indent + '%s %s(%s)%s {\n' % (result, method.name, params, constantness)
param_names_str = ', '.join(param_names)
if param_names_str:
param_names_str = ', ' + param_names_str
decl += indent*2 + '%s%scall_method< %s >(self, "%s"%s);\n' %\
(return_str, python, result, rename, param_names_str)
decl += indent + '}\n'
# default implementations (with overloading)
def DefaultImpl(method, param_names):
'Return the body of a default implementation wrapper'
wrapper = self.info[method.name].wrapper
if not wrapper:
# return the default implementation of the class
return '%s%s::%s(%s);\n' % \
(return_str, self.class_.FullName(), method.name, ', '.join(param_names))
else:
# return a call for the wrapper
params = ', '.join(['this'] + param_names)
return '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
if not method.abstract and method.visibility != Scope.private:
minArgs = method.minArgs
maxArgs = method.maxArgs
impl_names = self.DefaultImplementationNames(method)
for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)):
params, param_names, param_types = _ParamsInfo(method, argNum)
decl += '\n'
decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness)
decl += indent*2 + DefaultImpl(method, param_names)
decl += indent + '}\n'
return decl
def MethodDefinition(self, method):
'''Returns a list of lines, which should be put inside the class_
statement to export this method.'''
# dont define abstract methods
pyste = namespaces.pyste
rename = self.info[method.name].rename or method.name
default_names = self.DefaultImplementationNames(method)
class_name = self.class_.FullName()
wrapper_name = pyste + self.wrapper_name
result = method.result.FullName()
is_method_unique = self.IsMethodUnique(method.name)
constantness = ''
if method.const:
constantness = ' const'
# create a list of default-impl pointers
minArgs = method.minArgs
maxArgs = method.maxArgs
if is_method_unique:
default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names]
else:
default_pointers = []
for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)):
param_list = [x.FullName() for x in method.parameters[:argNum]]
params = ', '.join(param_list)
signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness)
default_pointer = '(%s)&%s::%s' % (signature, wrapper_name, impl_name)
default_pointers.append(default_pointer)
# get the pointer of the method
if is_method_unique:
pointer = '&' + method.FullName()
else:
pointer = method.PointerDeclaration()
# generate the defs
definitions = []
# basic def
definitions.append('.def("%s", %s, %s)' % (rename, pointer, default_pointers[-1]))
for default_pointer in default_pointers[:-1]:
definitions.append('.def("%s", %s)' % (rename, default_pointer))
return definitions
def FullName(self):
return namespaces.pyste + self.wrapper_name
def GenerateVirtualMethods(self):
'''To correctly export all virtual methods, we must also make wrappers
for the virtual methods of the bases of this class, as if the methods
were from this class itself.
This method creates the instance variable self.virtual_methods.
'''
def IsVirtual(m):
return m.virtual and m.visibility != Scope.private
all_members = self.class_.members[:]
for base in self.bases:
for base_member in base.members:
base_member.class_ = self.class_.FullName()
all_members.append(base_member)
# extract the virtual methods, avoiding duplications. The duplication
# must take in account the full signature without the class name, so
# that inherited members are correctly excluded if the subclass overrides
# them.
def MethodSig(method):
if method.const:
const = 'const'
else:
const = ''
if method.result:
result = method.result.FullName()
else:
result = ''
params = ', '.join([x.FullName() for x in method.parameters])
return '%s %s(%s) %s' % (result, method.name, params, const)
all_members = [x for x in all_members if type(x) == Method]
self.virtual_methods = []
already_added = {}
for member in all_members:
sig = MethodSig(member)
if IsVirtual(member) and not sig in already_added:
self.virtual_methods.append(member)
already_added[sig] = 0
def IsMethodUnique(self, method):
if not self._method_count:
for m in self.virtual_methods:
self._method_count[m.name] = self._method_count.get(m.name, 0) + 1
return self._method_count[method] == 1
def Constructors(self):
def IsValid(m):
return isinstance(m, Constructor) and m.visibility == Scope.public
return [m for m in self.class_.members if IsValid(m)]
def GenerateDefinitions(self):
defs = []
for method in self.virtual_methods:
exclude = self.info[method.name].exclude
# generate definitions only for public methods and non-abstract methods
if method.visibility == Scope.public and not method.abstract and not exclude:
defs.extend(self.MethodDefinition(method))
return defs
def GenerateVirtualWrapper(self, indent):
'Return the wrapper for this class'
# generate the class code
class_name = self.class_.FullName()
code = 'struct %s: %s\n' % (self.wrapper_name, class_name)
code += '{\n'
# generate constructors (with the overloads for each one)
for cons in self.Constructors(): # only public constructors
minArgs = cons.minArgs
maxArgs = cons.maxArgs
# from the min number of arguments to the max number, generate
# all version of the given constructor
cons_code = ''
for argNum in range(minArgs, maxArgs+1):
params, param_names, param_types = _ParamsInfo(cons, argNum)
if params:
params = ', ' + params
cons_code += indent + '%s(PyObject* self_%s):\n' % \
(self.wrapper_name, params)
cons_code += indent*2 + '%s(%s), self(self_) {}\n\n' % \
(class_name, ', '.join(param_names))
code += cons_code
# generate the body
body = []
for method in self.virtual_methods:
if not self.info[method.name].exclude:
body.append(self.Declaration(method, indent))
body = '\n'.join(body)
code += body + '\n'
# add the self member
code += indent + 'PyObject* self;\n'
code += '};\n'
return code

View File

@@ -1,117 +0,0 @@
from GCCXMLParser import ParseDeclarations
import tempfile
import shutil
import os
import os.path
import settings
class CppParserError(Exception): pass
class CppParser:
'Parses a header file and returns a list of declarations'
def __init__(self, includes=None, defines=None):
'includes and defines ar the directives given to gcc'
if includes is None:
includes = []
if defines is None:
defines = []
self.includes = includes
self.defines = defines
self._cache = []
self._CACHE_SIZE = 5
def _includeparams(self, filename):
includes = self.includes[:]
filedir = os.path.dirname(filename)
if not filedir:
filedir = '.'
includes.insert(0, filedir)
includes = ['-I "%s"' % x for x in includes]
return ' '.join(includes)
def _defineparams(self):
defines = ['-D "%s"' % x for x in self.defines]
return ' '.join(defines)
def UpdateCache(self, include, tail, decl_name, declarations, header):
self._cache.append((include, tail, decl_name, declarations, header))
if len(self._cache) > self._CACHE_SIZE:
self._cache.pop(0)
def Cache(self, include, tail, decl_name):
for cache_include, cache_tail, cache_decl, declarations, header in self._cache:
if cache_include == include \
and cache_tail == tail \
and cache_decl == decl_name:
return declarations, header
return None
def FindFileName(self, include):
if os.path.isfile(include):
return include
for path in self.includes:
filename = os.path.join(path, include)
if os.path.isfile(filename):
return filename
name = os.path.basename(include)
raise RuntimeError, 'Header file "%s" not found!' % name
def parse(self, include, tail=None, decl_name=None):
'''Parses the given filename, and returns (declaration, header). The
header returned is normally the same as the given to this method,
except if tail is not None: in this case, the header is copied to a temp
filename and the tail code is appended to it before being passed on to gcc.
This temp filename is then returned.
'''
# check if this header was already parsed
cached = self.Cache(include, tail, decl_name)
if cached:
return cached
filename = self.FindFileName(include)
# copy file to temp folder, if needed
if tail:
tempfilename = tempfile.mktemp('.h')
infilename = tempfilename
shutil.copyfile(filename, infilename)
f = file(infilename, 'a')
f.write('\n\n'+tail)
f.close()
else:
infilename = filename
xmlfile = tempfile.mktemp('.xml')
try:
# get the params
includes = self._includeparams(filename)
defines = self._defineparams()
# call gccxml
cmd = 'gccxml %s %s %s -fxml=%s' \
% (includes, defines, infilename, xmlfile)
if decl_name is not None:
cmd += ' "-fxml-start=%s"' % decl_name
status = os.system(cmd)
if status != 0 or not os.path.isfile(xmlfile):
raise CppParserError, 'Error executing gccxml'
# parse the resulting xml
declarations = ParseDeclarations(xmlfile)
# cache the results
self.UpdateCache(include, tail, decl_name, declarations, infilename)
# return the declarations
return declarations, infilename
finally:
if settings.DEBUG and os.path.isfile(xmlfile):
filename = os.path.basename(include)
shutil.copy(xmlfile, os.path.splitext(filename)[0] + '.xml')
# delete the temporary files
try:
os.remove(xmlfile)
if tail:
os.remove(tempfilename)
except OSError: pass

View File

@@ -1,40 +0,0 @@
from Exporter import Exporter
from settings import *
import utils
#==============================================================================
# EnumExporter
#==============================================================================
class EnumExporter(Exporter):
'Exports enumerators'
def __init__(self, info):
Exporter.__init__(self, info)
def SetDeclarations(self, declarations):
Exporter.SetDeclarations(self, declarations)
self.enum = self.GetDeclaration(self.info.name)
def Export(self, codeunit, expoted_names):
if not self.info.exclude:
indent = self.INDENT
in_indent = self.INDENT*2
rename = self.info.rename or self.enum.name
full_name = self.enum.FullName()
code = indent + namespaces.python + 'enum_< %s >("%s")\n' % (full_name, rename)
for name in self.enum.values:
rename = self.info[name].rename or name
value_fullname = self.enum.ValueFullName(name)
code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname)
code += indent + ';\n\n'
codeunit.Write('module', code)
def Unit(self):
return utils.makeid(self.info.include)
def Order(self):
return self.info.name

View File

@@ -1,74 +0,0 @@
import os.path
#==============================================================================
# Exporter
#==============================================================================
class Exporter:
'Base class for objects capable to generate boost.python code.'
INDENT = ' ' * 4
def __init__(self, info, parser_tail=None, parser_decl=None):
self.info = info
self.parser_tail = parser_tail
self.parser_decl = parser_decl
def Name(self):
return self.info.name
def Parse(self, parser):
self.parser = parser
header = self.info.include
tail = self.parser_tail
decl = self.parser_decl
declarations, parser_header = parser.parse(header, tail, decl)
self.parser_header = parser_header
self.SetDeclarations(declarations)
def SetDeclarations(self, declarations):
self.declarations = declarations
def GenerateCode(self, codeunit, exported_names):
self.WriteInclude(codeunit)
self.Export(codeunit, exported_names)
def WriteInclude(self, codeunit):
codeunit.Write('include', '#include <%s>\n' % self.info.include)
def Export(self, codeunit, exported_names):
'subclasses must override this to do the real work'
pass
def Unit(self):
raise NotImplementedError
def GetDeclarations(self, fullname):
decls = [x for x in self.declarations if x.FullName() == fullname]
if not decls:
raise RuntimeError, 'no %s declaration found!' % fullname
return decls
def GetDeclaration(self, fullname):
decls = self.GetDeclarations(fullname)
assert len(decls) == 1
return decls[0]
def Order(self):
'''Returns a string that uniquely identifies this instance. All
exporters will be sorted by Order before being exported.
'''
raise NotImplementedError
def Unit(self):
return self.info.include

View File

@@ -1,95 +0,0 @@
from Exporter import Exporter
from policies import *
from declarations import *
from settings import *
import utils
import exporterutils
#==============================================================================
# FunctionExporter
#==============================================================================
class FunctionExporter(Exporter):
'Generates boost.python code to export the given function.'
def __init__(self, info, tail=None):
Exporter.__init__(self, info, tail)
self._exported_opaque_pointers = {}
def Export(self, codeunit, exported_names):
if not self.info.exclude:
decls = self.GetDeclarations(self.info.name)
for decl in decls:
self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy)
exporterutils.WarnForwardDeclarations(decl)
self.ExportDeclaration(decl, len(decls) == 1, codeunit)
self.ExportOpaquePointer(decl, codeunit)
self.GenerateOverloads(decls, codeunit)
def ExportDeclaration(self, decl, unique, codeunit):
name = self.info.rename or decl.name
defs = namespaces.python + 'def("%s", ' % name
wrapper = self.info.wrapper
if wrapper:
pointer = '&' + wrapper.FullName()
elif not unique:
pointer = decl.PointerDeclaration()
else:
pointer = '&' + decl.FullName()
defs += pointer
defs += self.PolicyCode()
overload = self.OverloadName(decl)
if overload:
defs += ', %s()' % (namespaces.pyste + overload)
defs += ');'
codeunit.Write('module', self.INDENT + defs + '\n')
# add the code of the wrapper
if wrapper and wrapper.code:
codeunit.Write('declaration', code + '\n')
def OverloadName(self, decl):
if decl.minArgs != decl.maxArgs:
return '%s_overloads_%i_%i' % \
(decl.name, decl.minArgs, decl.maxArgs)
else:
return ''
def GenerateOverloads(self, declarations, codeunit):
codes = {}
for decl in declarations:
overload = self.OverloadName(decl)
if overload and overload not in codes:
code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\
(overload, decl.FullName(), decl.minArgs, decl.maxArgs)
codeunit.Write('declaration', code + '\n')
codes[overload] = None
def PolicyCode(self):
policy = self.info.policy
if policy is not None:
assert isinstance(policy, Policy)
return ', %s()' % policy.Code()
else:
return ''
def ExportOpaquePointer(self, function, codeunit):
if self.info.policy == return_value_policy(return_opaque_pointer):
type = function.result.name
macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % type
if macro not in self._exported_opaque_pointers:
codeunit.Write('declaration-outside', macro)
self._exported_opaque_pointers[macro] = 1
def Order(self):
return self.info.name
def Unit(self):
return utils.makeid(self.info.include)

View File

@@ -1,417 +0,0 @@
from declarations import *
from elementtree.ElementTree import ElementTree
from xml.parsers.expat import ExpatError
from copy import deepcopy
class InvalidXMLError(Exception): pass
class ParserError(Exception): pass
class InvalidContextError(ParserError): pass
class GCCXMLParser(object):
'Parse a GCC_XML file and extract the top-level declarations.'
interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0}
def Parse(self, filename):
self.elements = self.GetElementsFromXML(filename)
# high level declarations
self.declarations = []
# parse the elements
for id in self.elements:
element, decl = self.elements[id]
if decl is None:
try:
self.ParseElement(id, element)
except InvalidContextError:
pass # ignore those nodes with invalid context
# (workaround gccxml bug)
def Declarations(self):
return self.declarations
def AddDecl(self, decl):
self.declarations.append(decl)
def ParseElement(self, id, element):
method = 'Parse' + element.tag
if hasattr(self, method):
func = getattr(self, method)
func(id, element)
def GetElementsFromXML(self,filename):
'Extracts a dictionary of elements from the gcc_xml file.'
tree = ElementTree()
try:
tree.parse(filename)
except ExpatError:
raise InvalidXMLError, 'Not a XML file: %s' % filename
root = tree.getroot()
if root.tag != 'GCC_XML':
raise InvalidXMLError, 'Not a valid GCC_XML file'
# build a dictionary of id -> element, None
elementlist = root.getchildren()
elements = {}
for element in elementlist:
id = element.get('id')
if id:
elements[id] = element, None
return elements
def GetDecl(self, id):
if id not in self.elements:
if id == '_0':
raise InvalidContextError, 'Invalid context found in the xml file.'
else:
msg = 'ID not found in elements: %s' % id
raise ParserError, msg
elem, decl = self.elements[id]
if decl is None:
self.ParseElement(id, elem)
elem, decl = self.elements[id]
if decl is None:
raise ParserError, 'Could not parse element: %s' % elem.tag
return decl
def GetType(self, id):
def Check(id, feature):
pos = id.find(feature)
if pos != -1:
id = id[:pos] + id[pos+1:]
return True, id
else:
return False, id
const, id = Check(id, 'c')
volatile, id = Check(id, 'v')
restricted, id = Check(id, 'r')
decl = self.GetDecl(id)
if isinstance(decl, Type):
res = decl.Copy()
if const:
res.const = const
if volatile:
res.volatile = volatile
if restricted:
res.restricted = restricted
else:
res = Type(decl.FullName(), const)
res.volatile = volatile
res.restricted = restricted
res.incomplete = decl.incomplete
return res
def GetLocation(self, location):
file, line = location.split(':')
file = self.GetDecl(file)
return file, int(line)
def Update(self, id, decl):
element, _ = self.elements[id]
self.elements[id] = element, decl
def ParseNamespace(self, id, element):
namespace = element.get('name')
context = element.get('context')
if context:
outerns = self.GetDecl(context)
if not outerns.endswith('::'):
outerns += '::'
namespace = outerns + namespace
if namespace.startswith('::'):
namespace = namespace[2:]
self.Update(id, namespace)
def ParseFile(self, id, element):
filename = element.get('name')
self.Update(id, filename)
def ParseVariable(self, id, element):
# in gcc_xml, a static Field is declared as a Variable, so we check
# this and call the Field parser if apply.
context = self.GetDecl(element.get('context'))
if isinstance(context, Class):
self.ParseField(id, element)
elem, decl = self.elements[id]
decl.static = True
else:
namespace = context
name = element.get('name')
type_ = self.GetType(element.get('type'))
location = self.GetLocation(element.get('location'))
variable = Variable(type_, name, namespace)
variable.location = location
self.AddDecl(variable)
self.Update(id, variable)
def GetArguments(self, element):
args = []
for child in element:
if child.tag == 'Argument':
type_ = self.GetType(child.get('type'))
type_.default = child.get('default')
args.append(type_)
return args
def ParseFunction(self, id, element, functionType=Function):
'''functionType is used because a Operator is identical to a normal
function, only the type of the function changes.'''
name = element.get('name')
returns = self.GetType(element.get('returns'))
namespace = self.GetDecl(element.get('context'))
location = self.GetLocation(element.get('location'))
params = self.GetArguments(element)
function = functionType(name, namespace, returns, params)
function.location = location
self.AddDecl(function)
self.Update(id, function)
def ParseOperatorFunction(self, id, element):
self.ParseFunction(id, element, Operator)
def GetBases(self, bases):
'Parses the string "bases" from the xml into a list of Base instances.'
if bases is None:
return []
bases = bases.split()
baseobjs = []
for base in bases:
# get the visibility
split = base.split(':')
if len(split) == 2:
visib = split[0]
base = split[1]
else:
visib = Scope.public
decl = self.GetDecl(base)
baseobj = Base(decl.FullName(), visib)
baseobjs.append(baseobj)
return baseobjs
def GetMembers(self, members):
# members must be a string with the ids of the members
if members is None:
return []
memberobjs = []
for member in members.split():
memberobjs.append(self.GetDecl(member))
return memberobjs
def ParseClass(self, id, element):
name = element.get('name')
abstract = bool(int(element.get('abstract', '0')))
location = self.GetLocation(element.get('location'))
context = self.GetDecl(element.get('context'))
incomplete = bool(element.get('incomplete', False))
if isinstance(context, str):
class_ = Class(name, context, [], abstract, [])
self.AddDecl(class_)
else:
# a nested class
visib = element.get('access', Scope.public)
class_ = NestedClass(
name, context.FullName(), visib, [], abstract, [])
# we have to add the declaration of the class before trying
# to parse its members and bases, to avoid recursion.
class_.location = location
class_.incomplete = incomplete
self.Update(id, class_)
# now we can get the members and the bases
class_.bases = self.GetBases(element.get('bases'))
class_.members = self.GetMembers(element.get('members'))
def ParseStruct(self, id, element):
self.ParseClass(id, element)
def ParseFundamentalType(self, id, element):
name = element.get('name')
type_ = FundamentalType(name)
self.Update(id, type_)
def ParseArrayType(self, id, element):
type_ = self.GetType(element.get('type'))
min = element.get('min')
max = element.get('max')
array = ArrayType(type_.name, type_.const)
array.min = min
array.max = max
self.Update(id, array)
def ParseReferenceType(self, id, element):
type_ = self.GetType(element.get('type'))
expand = not isinstance(type_, FunctionType)
ref = ReferenceType(type_.name, type_.const, None, type_.incomplete, expand)
self.Update(id, ref)
def ParsePointerType(self, id, element):
type_ = self.GetType(element.get('type'))
expand = not isinstance(type_, FunctionType)
ref = PointerType(type_.name, type_.const, None, type_.incomplete, expand)
self.Update(id, ref)
def ParseFunctionType(self, id, element):
result = self.GetType(element.get('returns'))
args = self.GetArguments(element)
func = FunctionType(result, args)
self.Update(id, func)
def ParseMethodType(self, id, element):
class_ = self.GetDecl(element.get('basetype')).FullName()
result = self.GetType(element.get('returns'))
args = self.GetArguments(element)
method = MethodType(result, args, class_)
self.Update(id, method)
def ParseField(self, id, element):
name = element.get('name')
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context')).FullName()
type_ = self.GetType(element.get('type'))
static = bool(int(element.get('extern', '0')))
location = self.GetLocation(element.get('location'))
var = ClassVariable(type_, name, classname, visib, static)
var.location = location
self.Update(id, var)
def ParseMethod(self, id, element, methodType=Method):
name = element.get('name')
result = self.GetType(element.get('returns'))
classname = self.GetDecl(element.get('context')).FullName()
visib = element.get('access', Scope.public)
static = bool(int(element.get('static', '0')))
virtual = bool(int(element.get('virtual', '0')))
abstract = bool(int(element.get('pure_virtual', '0')))
const = bool(int(element.get('const', '0')))
location = self.GetLocation(element.get('location'))
params = self.GetArguments(element)
method = methodType(
name, classname, result, params, visib, virtual, abstract, static, const)
method.location = location
self.Update(id, method)
def ParseOperatorMethod(self, id, element):
self.ParseMethod(id, element, ClassOperator)
def ParseConstructor(self, id, element):
name = element.get('name')
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context')).FullName()
location = self.GetLocation(element.get('location'))
params = self.GetArguments(element)
ctor = Constructor(name, classname, params, visib)
ctor.location = location
self.Update(id, ctor)
def ParseDestructor(self, id, element):
name = element.get('name')
visib = element.get('access', Scope.public)
classname = self.GetDecl(element.get('context')).FullName()
virtual = bool(int(element.get('virtual', '0')))
location = self.GetLocation(element.get('location'))
des = Destructor(name, classname, visib, virtual)
des.location = location
self.Update(id, des)
def ParseConverter(self, id, element):
self.ParseMethod(id, element, ConverterOperator)
def ParseTypedef(self, id, element):
name = element.get('name')
type = self.GetType(element.get('type'))
context = self.GetDecl(element.get('context'))
if isinstance(context, Class):
context = context.FullName()
typedef = Typedef(type, name, context)
self.Update(id, typedef)
self.AddDecl(typedef)
def ParseEnumeration(self, id, element):
name = element.get('name')
location = self.GetLocation(element.get('location'))
context = self.GetDecl(element.get('context'))
if isinstance(context, str):
enum = Enumeration(name, context)
self.AddDecl(enum) # in this case, is a top level decl
else:
visib = element.get('access', Scope.public)
enum = ClassEnumeration(name, context.FullName(), visib)
enum.location = location
for child in element:
if child.tag == 'EnumValue':
name = child.get('name')
value = int(child.get('init'))
enum.values[name] = value
self.Update(id, enum)
def ParseUnimplemented(self, id, element):
'No idea of what this is'
self.Update(id, Declaration('', ''))
def ParseUnion(self, id, element):
name = element.get('name')
context = self.GetDecl(element.get('context'))
location = self.GetLocation(element.get('location'))
if isinstance(context, str):
# a free union
union = Union(name, context)
self.AddDecl(union)
else:
visib = element.get('access', Scope.public)
union = ClassUnion(name, context.FullName(), visib)
union.location = location
self.Update(id, union)
def ParseDeclarations(filename):
'Returns a list of the top declarations found in the gcc_xml file.'
parser = GCCXMLParser()
parser.Parse(filename)
return parser.Declarations()
if __name__ == '__main__':
ParseDeclarations(r'D:\Programming\Libraries\boost-cvs\boost\libs\python\pyste\example\test.xml')

View File

@@ -1,75 +0,0 @@
from Exporter import Exporter
from ClassExporter import ClassExporter
from FunctionExporter import FunctionExporter
from EnumExporter import EnumExporter
from infos import *
from declarations import *
import os.path
import exporters
#==============================================================================
# HeaderExporter
#==============================================================================
class HeaderExporter(Exporter):
'Exports all declarations found in the given header'
def __init__(self, info, parser_tail=None):
Exporter.__init__(self, info, parser_tail)
def WriteInclude(self, codeunit):
pass
def SetDeclarations(self, declarations):
def IsInternalName(name):
'''Returns true if the given name looks like a internal compiler
structure'''
return name.startswith('__')
Exporter.SetDeclarations(self, declarations)
header = os.path.normpath(self.parser_header)
for decl in declarations:
# check if this declaration is in the header
location = os.path.normpath(decl.location[0])
if location != header or IsInternalName(decl.name):
continue
# ok, check the type of the declaration and export it accordingly
self.HandleDeclaration(decl)
def HandleDeclaration(self, decl):
'''Dispatch the declaration to the appropriate method, that must create
a suitable info object for a Exporter, create a Exporter, set its
declarations and append it to the list of exporters.
'''
dispatch_table = {
Class : ClassExporter,
Enumeration : EnumExporter,
Function : FunctionExporter,
}
exporter_class = dispatch_table.get(type(decl))
if exporter_class is not None:
self.HandleExporter(decl, exporter_class)
def HandleExporter(self, decl, exporter_type):
# only export complete declarations
if not getattr(decl, "incomplete", False):
info = self.info[decl.name]
info.name = decl.FullName()
info.include = self.info.include
exporter = exporter_type(info)
exporter.SetDeclarations(self.declarations)
exporters.exporters.append(exporter)
def Unit(self):
return None # doesn't write anything by himself
def Order(self):
return self.info.include

View File

@@ -1,24 +0,0 @@
import os.path
from Exporter import Exporter
#==============================================================================
# IncludeExporter
#==============================================================================
class IncludeExporter(Exporter):
'''Writes an include declaration to the module. Useful to add extra code
for use in the Wrappers.
This class just reimplements the Parse method to do nothing: the
WriteInclude in Exporter already does the work for us.
'''
def __init__(self, info, parser_tail=None):
Exporter.__init__(self, info, parser_tail)
def Parse(self, parser):
pass
def Order(self):
return self.info.include
def Unit(self):
return '__all__' # include it in all generated cpps (multiple mode)

View File

@@ -1,104 +0,0 @@
from SingleCodeUnit import SingleCodeUnit
import os
import utils
from SmartFile import SmartFile
#==============================================================================
# MultipleCodeUnit
#==============================================================================
class MultipleCodeUnit(object):
'''
Represents a bunch of cpp files, where each cpp file represents a header
to be exported by pyste. Another cpp, named <module>.cpp is created too.
'''
def __init__(self, modulename, outdir):
self.modulename = modulename
self.outdir = outdir
self.codeunits = {} # maps from a header to a SingleCodeUnit
self.functions = []
self._current = None
def _FunctionName(self, code_unit_name):
return '_Export_%s' % utils.makeid(code_unit_name)
def _FileName(self, code_unit_name):
filename = os.path.basename(code_unit_name)
filename = '_%s.cpp' % os.path.splitext(filename)[0]
return os.path.join(self.outdir, filename)
def SetCurrent(self, code_unit_name):
'Changes the current code unit'
try:
if code_unit_name is not None:
codeunit = self.codeunits[code_unit_name]
else:
codeunit = None
except KeyError:
filename = self._FileName(code_unit_name)
function_name = self._FunctionName(code_unit_name)
codeunit = SingleCodeUnit(None, filename)
codeunit.module_definition = 'void %s()' % function_name
self.codeunits[code_unit_name] = codeunit
if code_unit_name != '__all__':
self.functions.append(function_name)
self._current = codeunit
def Current(self):
return self._current
current = property(Current, SetCurrent)
def Write(self, section, code):
if self._current is not None:
self.current.Write(section, code)
def Section(self, section):
if self._current is not None:
return self.current.Section(section)
def _CreateOutputDir(self):
try:
os.mkdir(self.outdir)
except OSError: pass # already created
def Save(self):
# create the directory where all the files will go
self._CreateOutputDir();
# write all the codeunits, merging first the contents of
# the special code unit named __all__
__all__ = self.codeunits.get('__all__')
for name, codeunit in self.codeunits.items():
if name != '__all__':
if __all__:
codeunit.Merge(__all__)
codeunit.Save()
# generate the main cpp
filename = os.path.join(self.outdir, self.modulename + '.cpp')
fout = SmartFile(filename, 'w')
fout.write(utils.left_equals('Include'))
fout.write('#include <boost/python.hpp>\n\n')
fout.write(utils.left_equals('Exports'))
for function in self.functions:
fout.write('void %s();\n' % function)
fout.write('\n')
fout.write(utils.left_equals('Module'))
fout.write('BOOST_PYTHON_MODULE(%s)\n' % self.modulename)
fout.write('{\n')
indent = ' ' * 4
for function in self.functions:
fout.write(indent)
fout.write('%s();\n' % function)
fout.write('}\n')

View File

@@ -1,84 +0,0 @@
from settings import namespaces
import settings
from utils import remove_duplicated_lines, left_equals
from SmartFile import SmartFile
#==============================================================================
# SingleCodeUnit
#==============================================================================
class SingleCodeUnit:
'''
Represents a cpp file, where other objects can write in one of the
predefined sections.
The avaiable sections are:
include - The include area of the cpp file
declaration - The part before the module definition
module - Inside the BOOST_PYTHON_MODULE macro
'''
def __init__(self, modulename, filename):
self.modulename = modulename
self.filename = filename
# define the avaiable sections
self.code = {}
# include section
self.code['include'] = ''
# declaration section (inside namespace)
self.code['declaration'] = ''
# declaration (outside namespace)
self.code['declaration-outside'] = ''
# inside BOOST_PYTHON_MACRO
self.code['module'] = ''
# create the default module definition
self.module_definition = 'BOOST_PYTHON_MODULE(%s)' % modulename
def Write(self, section, code):
'write the given code in the section of the code unit'
if section not in self.code:
raise RuntimeError, 'Invalid CodeUnit section: %s' % section
self.code[section] += code
def Merge(self, other):
for section in ('include', 'declaration', 'declaration-outside', 'module'):
self.code[section] = self.code[section] + other.code[section]
def Section(self, section):
return self.code[section]
def Save(self):
'Writes this code unit to the filename'
space = '\n\n'
fout = SmartFile(self.filename, 'w')
# includes
includes = remove_duplicated_lines(self.code['include'])
fout.write('\n' + left_equals('Includes'))
fout.write('#include <boost/python.hpp>\n')
fout.write(includes)
fout.write(space)
# using
if settings.USING_BOOST_NS:
fout.write(left_equals('Using'))
fout.write('using namespace boost::python;\n\n')
# declarations
declaration = self.code['declaration']
declaration_outside = self.code['declaration-outside']
if declaration_outside or declaration:
fout.write(left_equals('Declarations'))
fout.write(declaration_outside + '\n\n')
if declaration:
pyste_namespace = namespaces.pyste[:-2]
fout.write('namespace %s {\n\n\n' % pyste_namespace)
fout.write(declaration)
fout.write('\n\n}// namespace %s\n' % pyste_namespace)
fout.write(space)
# module
fout.write(left_equals('Module'))
fout.write(self.module_definition + '\n')
fout.write('{\n')
fout.write(self.code['module'])
fout.write('}\n')

View File

@@ -1,55 +0,0 @@
import os
import md5
#==============================================================================
# SmartFile
#==============================================================================
class SmartFile(object):
'''
A file-like object used for writing files. The given file will only be
actually written to disk if there's not a file with the same name, or if
the existing file is *different* from the file to be written.
'''
def __init__(self, filename, mode='w'):
self.filename = filename
self.mode = mode
self._contents = []
self._closed = False
def __del__(self):
if not self._closed:
self.close()
def write(self, string):
self._contents.append(string)
def _dowrite(self, contents):
f = file(self.filename, self.mode)
f.write(contents)
f.close()
def _GetMD5(self, string):
return md5.new(string).digest()
def close(self):
# if the filename doesn't exist, write the file right away
this_contents = ''.join(self._contents)
if not os.path.isfile(self.filename):
self._dowrite(this_contents)
else:
# read the contents of the file already in disk
f = file(self.filename)
other_contents = f.read()
f.close()
# test the md5 for both files
this_md5 = self._GetMD5(this_contents)
other_md5 = self._GetMD5(other_contents)
if this_md5 != other_md5:
self._dowrite(this_contents)
self._closed = True

View File

@@ -1,538 +0,0 @@
'''
Module declarations
Defines classes that represent declarations found in C++ header files.
'''
class Declaration(object):
'Represents a basic declaration.'
__slots__ = 'name namespace location incomplete'.split()
def __init__(self, name, namespace):
# the declaration name
self.name = name
# all the namespaces, separated by '::' = 'boost::inner'
self.namespace = namespace
# tuple (filename, line)
self.location = '', -1
# if a declaration is incomplete it means that it was
# forward declared
self.incomplete = False
def FullName(self):
'Returns the full qualified name: "boost::inner::Test"'
namespace = self.namespace or ''
#if not namespace:
# namespace = ''
if namespace and not namespace.endswith('::'):
namespace += '::'
return namespace + self.name
def __repr__(self):
return '<Declaration %s at %s>' % (self.FullName(), id(self))
def __str__(self):
return 'Declaration of %s' % self.FullName()
class Class(Declaration):
'The declaration of a class or struct.'
__slots__= 'members abstract bases _members_count'.split()
def __init__(self, name, namespace, members, abstract, bases):
Declaration.__init__(self, name, namespace)
# list of members
self.members = members
# whatever the class has any abstract methods
self.abstract = abstract
# instances of Base
self.bases = bases
self._members_count = {}
def __iter__(self):
return iter(self.members)
def IsAbstract(self):
'Returns True if any method of this class is abstract'
for member in self.members:
if isinstance(member, Method):
if member.abstract:
return True
return False
def RawName(self):
'Returns the raw name of a template class. name = Foo<int>, raw = Foo'
lesspos = self.name.find('<')
if lesspos != -1:
return self.name[:lesspos]
else:
return self.name
def Constructors(self, publics_only=True):
constructors = []
for member in self:
if isinstance(member, Constructor):
if publics_only and member.visibility != Scope.public:
continue
constructors.append(member)
return constructors
def HasCopyConstructor(self):
for cons in self.Constructors():
if cons.IsCopy():
return True
return False
def HasDefaultConstructor(self):
for cons in self.Constructors():
if cons.IsDefault():
return True
return False
def IsUnique(self, member_name):
if not self._members_count:
for m in self:
self._members_count[m.name] = self._members_count.get(m.name, 0) + 1
try:
return self._members_count[member_name] == 1
except KeyError:
print self._members_count
print 'Key', member_name
class NestedClass(Class):
'The declaration of a class/struct inside another class/struct.'
__slots__= 'class_ visibility'.split()
def __init__(self, name, class_, visib, members, abstract, bases):
Class.__init__(self, name, None, members, abstract, bases)
self.class_ = class_
self.visibility = visib
def FullName(self):
return '%s::%s' % (self.class_, self.name)
class Base:
'Represents a base class of another class.'
__slots__= 'name visibility'.split()
def __init__(self, name, visibility=None):
# class_ is the full name of the base class
self.name = name
# visibility of the derivation
if visibility is None:
visibility = Scope.public
self.visibility = visibility
class Scope:
public = 'public'
private = 'private'
protected = 'protected'
class Function(Declaration):
'The declaration of a function.'
__slots__= 'result parameters'.split()
def __init__(self, name, namespace, result, params):
Declaration.__init__(self, name, namespace)
# the result type: instance of Type, or None (constructors)
self.result = result
# the parameters: instances of Type
self.parameters = params
def PointerDeclaration(self):
'returns a declaration of a pointer to this function'
result = self.result.FullName()
params = ', '.join([x.FullName() for x in self.parameters])
return '(%s (*)(%s))&%s' % (result, params, self.FullName())
def _MinArgs(self):
min = 0
for arg in self.parameters:
if arg.default is None:
min += 1
return min
minArgs = property(_MinArgs)
def _MaxArgs(self):
return len(self.parameters)
maxArgs = property(_MaxArgs)
class Operator(Function):
'The declaration of a custom operator.'
def FullName(self):
namespace = self.namespace or ''
if not namespace.endswith('::'):
namespace += '::'
return namespace + 'operator' + self.name
class Method(Function):
'The declaration of a method.'
__slots__= 'visibility virtual abstract static class_ const'.split()
def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const):
Function.__init__(self, name, None, result, params)
self.visibility = visib
self.virtual = virtual
self.abstract = abstract
self.static = static
self.class_ = class_
self.const = const
def FullName(self):
return self.class_ + '::' + self.name
def PointerDeclaration(self):
'returns a declaration of a pointer to this function'
if self.static:
# static methods are like normal functions
return Function.PointerDeclaration(self)
else:
# using syntax of methods
result = self.result.FullName()
params = ', '.join([x.FullName() for x in self.parameters])
const = ''
if self.const:
const = 'const'
return '(%s (%s::*)(%s) %s)&%s' %\
(result, self.class_, params, const, self.FullName())
class Constructor(Method):
'A constructor of a class.'
def __init__(self, name, class_, params, visib):
Method.__init__(self, name, class_, None, params, visib, False, False, False, False)
def IsDefault(self):
return len(self.parameters) == 0
def IsCopy(self):
if len(self.parameters) != 1:
return False
param = self.parameters[0]
class_as_param = self.parameters[0].name == self.class_
param_reference = isinstance(param, ReferenceType)
return param_reference and class_as_param and param.const
class Destructor(Method):
'The destructor of a class.'
def __init__(self, name, class_, visib, virtual):
Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False)
def FullName(self):
return self.class_ + '::~' + self.name
class ClassOperator(Method):
'The declaration of a custom operator in a class.'
def FullName(self):
return self.class_ + '::operator ' + self.name
class ConverterOperator(ClassOperator):
'An operator in the form "operator OtherClass()".'
def FullName(self):
return self.class_ + '::operator ' + self.result.FullName()
class Type(Declaration):
'Represents a type.'
__slots__= 'const default volatile restricted incomplete'.split()
def __init__(self, name, const=False, default=None, incomplete=False):
Declaration.__init__(self, name, None)
# whatever the type is constant or not
self.const = const
# used when the Type is a function argument
self.default = default
self.volatile = False
self.restricted = False
self.incomplete = incomplete
def __repr__(self):
if self.const:
const = 'const '
else:
const = ''
return '<Type ' + const + self.name + '>'
def FullName(self):
if self.const:
const = 'const '
else:
const = ''
return const + self.name
def Copy(self):
t = self.__class__(self.name, self.const, self.default, self.incomplete)
t.volatile = self.volatile
t.restricted = self.restricted
return t
class ArrayType(Type):
'Represents an array.'
__slots__= 'min max'.split()
def __init__(self, name, const=False, default=None, incomplete=False):
'min and max can be None.'
Type.__init__(self, name, const)
self.min = None
self.max = None
def Copy(self):
t = Type.Copy(self)
t.min = self.min
t.max = self.max
return t
class ReferenceType(Type):
'A reference type.'
__slots__= 'expand'.split()
def __init__(self, name, const=False, default=None, incomplete=False, expandRef=True):
Type.__init__(self, name, const, default, incomplete)
self.expand = expandRef
def FullName(self):
'expand is False for function pointers'
expand = ' &'
if not self.expand:
expand = ''
return Type.FullName(self) + expand
def Copy(self):
t = Type.Copy(self)
t.expand = self.expand
return t
class PointerType(Type):
'A pointer type.'
__slots__= 'expand'.split()
def __init__(self, name, const=False, default=None, incomplete=False, expandPointer=False):
Type.__init__(self, name, const, default, incomplete)
self.expand = expandPointer
def FullName(self):
'expand is False for function pointer'
expand = ' *'
if not self.expand:
expand = ''
return Type.FullName(self) + expand
def Copy(self):
t = Type.Copy(self)
t.expand = self.expand
return t
class FundamentalType(Type):
'One of the fundamental types (int, void...).'
def __init__(self, name, const=False, default=None, incomplete=False):
Type.__init__(self, name, const, default, incomplete)
class FunctionType(Type):
'A pointer to a function.'
__slots__= 'result parameters name'.split()
def __init__(self, result, parameters):
Type.__init__(self, '', False)
self.result = result
self.parameters = parameters
self.name = self.FullName()
def FullName(self):
full = '%s (*)' % self.result.FullName()
params = [x.FullName() for x in self.parameters]
full += '(%s)' % ', '.join(params)
return full
def Copy(self):
return FunctionType(self.result, self.parameters[:])
class MethodType(FunctionType):
'A pointer to a member function of a class.'
__slots__= 'result parameters class_ name'.split()
def __init__(self, result, parameters, class_):
Type.__init__(self, '', False)
self.result = result
self.parameters = parameters
self.class_ = class_
self.name = self.FullName()
def FullName(self):
full = '%s (%s::*)' % (self.result.FullName(), self.class_)
params = [x.FullName() for x in self.parameters]
full += '(%s)' % ', '.join(params)
return full
def Copy(self):
return MethodType(self.result, self.parameters[:], self.class_)
class Variable(Declaration):
'Represents a global variable.'
__slots__= 'type'.split()
def __init__(self, type, name, namespace):
Declaration.__init__(self, name, namespace)
# instance of Type
self.type = type
class ClassVariable(Variable):
'Represents a class variable.'
__slots__= 'visibility static class_'.split()
def __init__(self, type, name, class_, visib, static):
Variable.__init__(self, type, name, None)
self.visibility = visib
self.static = static
self.class_ = class_
def FullName(self):
return self.class_ + '::' + self.name
class Enumeration(Declaration):
__slots__= 'values'.split()
def __init__(self, name, namespace):
Declaration.__init__(self, name, namespace)
self.values = {} # dict of str => int
def ValueFullName(self, name):
assert name in self.values
namespace = self.namespace
if namespace:
namespace += '::'
return namespace + name
class ClassEnumeration(Enumeration):
__slots__= 'class_ visibility'.split()
def __init__(self, name, class_, visib):
Enumeration.__init__(self, name, None)
self.class_ = class_
self.visibility = visib
def FullName(self):
return '%s::%s' % (self.class_, self.name)
def ValueFullName(self, name):
assert name in self.values
return '%s::%s' % (self.class_, name)
class Typedef(Declaration):
__slots__= 'type visibility'.split()
def __init__(self, type, name, namespace):
Declaration.__init__(self, name, namespace)
self.type = type
self.visibility = Scope.public
class Union(Declaration):
'Shallow declaration, because Unions are not supported yet'
def __init__(self, name, namespace):
Declaration.__init__(self, name, namespace)
class ClassUnion(Union):
__slots__= 'class_ visibility'.split()
def __init__(self, name, class_, visib):
Union.__init__(self, name, None)
self.class_ = class_
self.visibility = visib
def FullName(self):
return '%s::%s' % (self.class_, self.name)

View File

@@ -1,3 +0,0 @@
# a list of Exporter instances
exporters = []

View File

@@ -1,91 +0,0 @@
'''
Various helpers for interface files.
'''
from settings import *
from policies import *
from declarations import *
#==============================================================================
# FunctionWrapper
#==============================================================================
class FunctionWrapper(object):
'''Holds information about a wrapper for a function or a method. It is in 2
parts: the name of the Wrapper, and its code. The code is placed in the
declaration section of the module, while the name is used to def' the
function or method (with the pyste namespace prepend to it). If code is None,
the name is left unchanged.
'''
def __init__(self, name, code=None):
self.name = name
self.code = code
def FullName(self):
if self.code:
return namespaces.pyste + self.name
else:
return self.name
_printed_warnings = {} # used to avoid double-prints of warnings
#==============================================================================
# HandlePolicy
#==============================================================================
def HandlePolicy(function, policy):
'''Show a warning to the user if the function needs a policy and doesn't
have one. Return a policy to the function, which is the given policy itself
if it is not None, or a default policy for this method.
'''
def IsString(type):
'Return True if the Type instance can be considered a string'
return type.const and type.name == 'char' and isinstance(type, PointerType)
def IsPyObject(type):
return type.FullName() == '_object *' # internal name of PyObject
result = function.result
# if the function returns const char*, a policy is not needed
if IsString(result) or IsPyObject(result):
return policy
# if returns a const T&, set the default policy
if policy is None and result.const and isinstance(result, ReferenceType):
policy = return_value_policy(copy_const_reference)
# basic test if the result type demands a policy
needs_policy = isinstance(result, (ReferenceType, PointerType))
# show a warning to the user, if needed
if needs_policy and policy is None:
global _printed_warnings
warning = '---> Error: %s returns a pointer or a reference, ' \
'but no policy was specified.' % function.FullName()
if warning not in _printed_warnings:
print warning
print
# avoid double prints of the same warning
_printed_warnings[warning] = 1
return policy
#==============================================================================
# WarnForwardDeclarations
#==============================================================================
def WarnForwardDeclarations(function):
'''Checks if any of the parameters or the result of the function are
incomplete types.'''
types = [function.result] + function.parameters
types = [x for x in types if x]
for type in types:
if type.incomplete:
msg = '---> Error: %s is forward declared. Please include the ' \
'appropriate header with its definition' % type.name
# disable this for now... it was reporting too many false
# forward declarations to be useful
if 0 and msg not in _printed_warnings:
print msg
print
_printed_warnings[msg] = 1

View File

@@ -1,198 +0,0 @@
import os.path
import copy
import exporters
from ClassExporter import ClassExporter
from FunctionExporter import FunctionExporter
from IncludeExporter import IncludeExporter
from EnumExporter import EnumExporter
from HeaderExporter import HeaderExporter
from exporterutils import FunctionWrapper
from utils import makeid
#==============================================================================
# DeclarationInfo
#==============================================================================
class DeclarationInfo:
def __init__(self, otherInfo=None):
self.__infos = {}
self.__attributes = {}
if otherInfo is not None:
self.__infos = copy.deepcopy(otherInfo.__infos)
self.__attributes = copy.deepcopy(otherInfo.__attributes)
def __getitem__(self, name):
'Used to access sub-infos'
if name.startswith('__'):
raise AttributeError
default = DeclarationInfo()
default._Attribute('name', name)
return self.__infos.setdefault(name, default)
def __getattr__(self, name):
return self[name]
def _Attribute(self, name, value=None):
if value is None:
# get value
return self.__attributes.get(name)
else:
# set value
self.__attributes[name] = value
#==============================================================================
# FunctionInfo
#==============================================================================
class FunctionInfo(DeclarationInfo):
def __init__(self, name, include, tail=None, otherOption=None):
DeclarationInfo.__init__(self, otherOption)
self._Attribute('name', name)
self._Attribute('include', include)
self._Attribute('exclude', False)
# create a FunctionExporter
exporter = FunctionExporter(InfoWrapper(self), tail)
exporters.exporters.append(exporter)
#==============================================================================
# ClassInfo
#==============================================================================
class ClassInfo(DeclarationInfo):
def __init__(self, name, include, tail=None, otherInfo=None):
DeclarationInfo.__init__(self, otherInfo)
self._Attribute('name', name)
self._Attribute('include', include)
self._Attribute('exclude', False)
# create a ClassExporter
exporter = ClassExporter(InfoWrapper(self), tail)
exporters.exporters.append(exporter)
#==============================================================================
# IncludeInfo
#==============================================================================
class IncludeInfo(DeclarationInfo):
def __init__(self, include):
DeclarationInfo.__init__(self)
self._Attribute('include', include)
exporter = IncludeExporter(InfoWrapper(self))
exporters.exporters.append(exporter)
#==============================================================================
# templates
#==============================================================================
def GenerateName(name, type_list):
name = name.replace('::', '_')
names = [name] + type_list
return makeid('_'.join(names))
class ClassTemplateInfo(DeclarationInfo):
def __init__(self, name, include):
DeclarationInfo.__init__(self)
self._Attribute('name', name)
self._Attribute('include', include)
def Instantiate(self, type_list, rename=None):
if not rename:
rename = GenerateName(self._Attribute('name'), type_list)
# generate code to instantiate the template
types = ', '.join(type_list)
tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename)
tail += 'void __instantiate_%s()\n' % rename
tail += '{ sizeof(%s); }\n\n' % rename
# create a ClassInfo
class_ = ClassInfo(rename, self._Attribute('include'), tail, self)
return class_
def __call__(self, types, rename=None):
if isinstance(types, str):
types = types.split()
return self.Instantiate(types, rename)
#==============================================================================
# EnumInfo
#==============================================================================
class EnumInfo(DeclarationInfo):
def __init__(self, name, include):
DeclarationInfo.__init__(self)
self._Attribute('name', name)
self._Attribute('include', include)
self._Attribute('exclude', False)
exporter = EnumExporter(InfoWrapper(self))
exporters.exporters.append(exporter)
#==============================================================================
# HeaderInfo
#==============================================================================
class HeaderInfo(DeclarationInfo):
def __init__(self, include):
DeclarationInfo.__init__(self)
self._Attribute('include', include)
exporter = HeaderExporter(InfoWrapper(self))
exporters.exporters.append(exporter)
#==============================================================================
# InfoWrapper
#==============================================================================
class InfoWrapper:
'Provides a nicer interface for a info'
def __init__(self, info):
self.__dict__['_info'] = info # so __setattr__ is not called
def __getitem__(self, name):
return InfoWrapper(self._info[name])
def __getattr__(self, name):
return self._info._Attribute(name)
def __setattr__(self, name, value):
self._info._Attribute(name, value)
#==============================================================================
# Functions
#==============================================================================
def exclude(option):
option._Attribute('exclude', True)
def set_policy(option, policy):
option._Attribute('policy', policy)
def rename(option, name):
option._Attribute('rename', name)
def set_wrapper(option, wrapper):
if isinstance(wrapper, str):
wrapper = FunctionWrapper(wrapper)
option._Attribute('wrapper', wrapper)
def instantiate(template, types, rename=None):
if isinstance(types, str):
types = types.split()
return template.Instantiate(types, rename)
def use_shared_ptr(option):
option._Attribute('smart_ptr', 'boost::shared_ptr< %s >')
def use_auto_ptr(option):
option._Attribute('smart_ptr', 'std::auto_ptr< %s >')

View File

@@ -1,83 +0,0 @@
class Policy:
'Represents one of the call policies of boost.python.'
def __init__(self):
raise RuntimeError, "Can't create an instance of the class Policy"
def Code(self):
'Returns the string corresponding to a instancialization of the policy.'
pass
def _next(self):
if self.next is not None:
return ', %s >' % self.next.Code()
else:
return ' >'
def __eq__(self, other):
try:
return self.Code() == other.Code()
except AttributeError:
return False
class return_internal_reference(Policy):
'Ties the return value to one of the parameters.'
def __init__(self, param=1, next=None):
'''
param is the position of the parameter, or None for "self".
next indicates the next policy, or None.
'''
self.param = param
self.next=next
def Code(self):
c = 'return_internal_reference< %i' % self.param
c += self._next()
return c
class with_custodian_and_ward(Policy):
'Ties lifetime of two arguments of a function.'
def __init__(self, custodian, ward, next=None):
self.custodian = custodian
self.ward = ward
self.next = next
def Code(self):
c = 'with_custodian_and_ward< %i, %i' % (self.custodian, self.ward)
c += self._next()
return c
class return_value_policy(Policy):
'Policy to convert return values.'
def __init__(self, which, next=None):
self.which = which
self.next = next
def Code(self):
c = 'return_value_policy< %s' % self.which
c += self._next()
return c
# values for return_value_policy
reference_existing_object = 'reference_existing_object'
copy_const_reference = 'copy_const_reference'
copy_non_const_reference = 'copy_non_const_reference'
manage_new_object = 'manage_new_object'
return_opaque_pointer = 'return_opaque_pointer'

View File

@@ -1,17 +0,0 @@
import profile
import pstats
import pyste
import psyco
import elementtree.XMLTreeBuilder as XMLTreeBuilder
import GCCXMLParser
if __name__ == '__main__':
#psyco.bind(XMLTreeBuilder.fixtext)
#psyco.bind(XMLTreeBuilder.fixname)
#psyco.bind(XMLTreeBuilder.TreeBuilder)
#psyco.bind(GCCXMLParser.GCCXMLParser)
profile.run('pyste.Main()', 'profile')
p = pstats.Stats('profile')
p.strip_dirs().sort_stats(-1).print_stats()

View File

@@ -1,197 +0,0 @@
'''
Pyste version %s
Usage:
pyste [options] --module=<name> interface-files
where options are:
-I <path> add an include path
-D <symbol> define symbol
--multiple create various cpps, instead of only one
(useful during development)
--out specify output filename (default: <module>.cpp)
in --multiple mode, this will be a directory
--no-using do not declare "using namespace boost";
use explicit declarations instead
--pyste-ns=<name> set the namespace where new types will be declared;
default is the empty namespace
--debug writes the xml for each file parsed in the current
directory
-h, --help print this help and exit
-v, --version print version information
'''
import sys
import os
import getopt
import exporters
import SingleCodeUnit
import MultipleCodeUnit
import infos
import exporterutils
import settings
from policies import *
from CppParser import CppParser, CppParserError
import time
__VERSION__ = '0.7.7'
def RecursiveIncludes(include):
'Return a list containg the include dir and all its subdirectories'
dirs = [include]
def visit(arg, dir, names):
# ignore CVS dirs
if os.path.split(dir)[1] != 'CVS':
dirs.append(dir)
os.path.walk(include, visit, None)
return dirs
def GetDefaultIncludes():
if 'INCLUDE' in os.environ:
include = os.environ['INCLUDE']
return include.split(os.pathsep)
else:
return []
def ParseArguments():
def Usage():
print __doc__ % __VERSION__
sys.exit(1)
try:
options, files = getopt.getopt(
sys.argv[1:],
'R:I:D:vh',
['module=', 'multiple', 'out=', 'no-using', 'pyste-ns=', 'debug', 'version', 'help'])
except getopt.GetoptError, e:
print
print 'ERROR:', e
Usage()
includes = GetDefaultIncludes()
defines = []
module = None
out = None
multiple = False
for opt, value in options:
if opt == '-I':
includes.append(value)
elif opt == '-D':
defines.append(value)
elif opt == '-R':
includes.extend(RecursiveIncludes(value))
elif opt == '--module':
module = value
elif opt == '--out':
out = value
elif opt == '--no-using':
settings.namespaces.python = 'boost::python::'
settings.USING_BOOST_NS = False
elif opt == '--pyste-ns':
settings.namespaces.pyste = value + '::'
elif opt == '--debug':
settings.DEBUG = True
elif opt == '--multiple':
multiple = True
elif opt in ['-h', '--help']:
Usage()
elif opt in ['-v', '--version']:
print 'Pyste version %s' % __VERSION__
sys.exit(2)
else:
print 'Unknown option:', opt
Usage()
if not files or not module:
Usage()
if not out:
out = module
if not multiple:
out += '.cpp'
return includes, defines, module, out, files, multiple
def CreateContext():
'create the context where a interface file will be executed'
context = {}
# infos
context['Function'] = infos.FunctionInfo
context['Class'] = infos.ClassInfo
context['Include'] = infos.IncludeInfo
context['Template'] = infos.ClassTemplateInfo
context['Enum'] = infos.EnumInfo
context['AllFromHeader'] = infos.HeaderInfo
# functions
context['rename'] = infos.rename
context['set_policy'] = infos.set_policy
context['exclude'] = infos.exclude
context['set_wrapper'] = infos.set_wrapper
context['use_shared_ptr'] = infos.use_shared_ptr
context['use_auto_ptr'] = infos.use_auto_ptr
# policies
context['return_internal_reference'] = return_internal_reference
context['with_custodian_and_ward'] = with_custodian_and_ward
context['return_value_policy'] = return_value_policy
context['reference_existing_object'] = reference_existing_object
context['copy_const_reference'] = copy_const_reference
context['copy_non_const_reference'] = copy_non_const_reference
context['return_opaque_pointer'] = return_opaque_pointer
context['manage_new_object'] = manage_new_object
# utils
context['Wrapper'] = exporterutils.FunctionWrapper
return context
def Main():
includes, defines, module, out, interfaces, multiple = ParseArguments()
# execute the interface files
for interface in interfaces:
context = CreateContext()
execfile(interface, context)
# parse all the C++ code
parser = CppParser(includes, defines)
exports = exporters.exporters[:]
for export in exports:
try:
export.Parse(parser)
except CppParserError, e:
print '\n'
print '***', e, ': exitting'
return 2
print
# sort the exporters by its order
exports = [(x.Order(), x) for x in exporters.exporters]
exports.sort()
exports = [x for _, x in exports]
# now generate the wrapper code
if multiple:
codeunit = MultipleCodeUnit.MultipleCodeUnit(module, out)
else:
codeunit = SingleCodeUnit.SingleCodeUnit(module, out)
exported_names = []
for export in exports:
if multiple:
codeunit.SetCurrent(export.Unit())
export.GenerateCode(codeunit, exported_names)
exported_names.append(export.Name())
codeunit.Save()
print 'Module %s generated' % module
return 0
def UsePsyco():
'Tries to use psyco if possible'
try:
import psyco
psyco.profile()
except: pass
if __name__ == '__main__':
start = time.clock()
UsePsyco()
status = Main()
print '%0.2f seconds' % (time.clock()-start)
sys.exit(status)

View File

@@ -1,13 +0,0 @@
#==============================================================================
# Global information
#==============================================================================
DEBUG = False
USING_BOOST_NS = True
class namespaces:
boost = 'boost::'
pyste = ''
python = '' # default is to not use boost::python namespace explicitly, so
# use the "using namespace" statement instead

View File

@@ -1,47 +0,0 @@
from __future__ import generators
import string
#==============================================================================
# enumerate
#==============================================================================
def enumerate(seq):
i = 0
for x in seq:
yield i, x
i += 1
#==============================================================================
# makeid
#==============================================================================
_valid_chars = string.ascii_letters + string.digits + '_'
_valid_chars = dict(zip(_valid_chars, _valid_chars))
def makeid(name):
'Returns the name as a valid identifier'
newname = []
for char in name:
if char not in _valid_chars:
char = '_'
newname.append(char)
newname = ''.join(newname)
# avoid duplications of '_' chars
names = [x for x in newname.split('_') if x]
return '_'.join(names)
#==============================================================================
# remove_duplicated_lines
#==============================================================================
def remove_duplicated_lines(text):
includes = text.splitlines()
d = dict([(include, 0) for include in includes])
return '\n'.join(d.keys())
#==============================================================================
# left_equals
#==============================================================================
def left_equals(s):
s = '// %s ' % s
return s + ('='*(80-len(s))) + '\n'

Some files were not shown because too many files have changed in this diff Show More