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

This commit was manufactured by cvs2svn to create branch

'boost_python_friend_fixes'.

[SVN r10123]
This commit is contained in:
nobody
2001-05-18 15:12:31 +00:00
parent 9b602d16b4
commit 9261e2a3d9
95 changed files with 8404 additions and 925 deletions

View File

@@ -1,3 +1,6 @@
// Revision History:
// Mar 03 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve)
#ifndef CLASS_WRAPPER_DWA101000_H_
# define CLASS_WRAPPER_DWA101000_H_
@@ -24,11 +27,18 @@ class class_builder
~class_builder()
{}
inline void dict_defines_state() {
add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__dict_defines_state__");
}
inline void getstate_manages_dict() {
add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__getstate_manages_dict__");
}
// define constructors
template <class signature>
void def(const signature& signature)
{ m_class->def(signature); }
void def(const signature& s)
{ m_class->def(s); }
// export heterogeneous reverse-argument operators
// (type of lhs: 'left', of rhs: 'right')

View File

@@ -5,6 +5,11 @@
//
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// Revision History:
// 04 Mar 01 Fixed std::complex<> stuff to work with MSVC (David Abrahams)
// 03 Mar 01 added: converters for [plain] char and std::complex
// (Ralf W. Grosse-Kunstleve)
#ifndef METHOD_DWA122899_H_
# define METHOD_DWA122899_H_
@@ -17,6 +22,17 @@
# include <boost/python/errors.hpp>
# include <string>
# ifdef BOOST_MSVC6_OR_EARLIER
# pragma warning(push)
# pragma warning(disable:4275) // disable a bogus warning caused by <complex>
# endif
# include <complex>
# ifdef BOOST_MSVC6_OR_EARLIER
# pragma warning(pop)
# endif
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
// This can be instantiated on an enum to provide the to_python/from_python
@@ -70,6 +86,30 @@ inline void xdecref(T* p)
xdecref_impl(reinterpret_cast<PyObject*>(p_base));
}
namespace detail {
void expect_complex(PyObject*);
template <class T>
std::complex<T> complex_from_python(PyObject* p, boost::python::type<T>)
{
expect_complex(p);
return std::complex<T>(
static_cast<T>(PyComplex_RealAsDouble(p)),
static_cast<T>(PyComplex_ImagAsDouble(p)));
}
template <class T>
PyObject* complex_to_python(const std::complex<T>& sc) {
Py_complex pcc;
pcc.real = sc.real();
pcc.imag = sc.imag();
return PyComplex_FromCComplex(pcc);
}
}
}} // namespace boost::python
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
@@ -100,6 +140,10 @@ PyObject* to_python(unsigned short);
unsigned short from_python(PyObject*, boost::python::type<unsigned short>);
unsigned short from_python(PyObject*, boost::python::type<const unsigned short&>);
PyObject* to_python(char);
char from_python(PyObject*, boost::python::type<char>);
char from_python(PyObject*, boost::python::type<const char&>);
PyObject* to_python(signed char);
signed char from_python(PyObject*, boost::python::type<signed char>);
signed char from_python(PyObject*, boost::python::type<const signed char&>);
@@ -130,6 +174,36 @@ PyObject* to_python(const std::string& s);
std::string from_python(PyObject*, boost::python::type<std::string>);
std::string from_python(PyObject*, boost::python::type<const std::string&>);
inline PyObject* to_python(const std::complex<float>& x)
{
return boost::python::detail::complex_to_python<float>(x);
}
inline PyObject* to_python(const std::complex<double>& x)
{
return boost::python::detail::complex_to_python<double>(x);
}
inline std::complex<double> from_python(PyObject* p,
boost::python::type<std::complex<double> >) {
return boost::python::detail::complex_from_python(p, boost::python::type<double>());
}
inline std::complex<double> from_python(PyObject* p,
boost::python::type<const std::complex<double>&>) {
return boost::python::detail::complex_from_python(p, boost::python::type<double>());
}
inline std::complex<float> from_python(PyObject* p,
boost::python::type<std::complex<float> >) {
return boost::python::detail::complex_from_python(p, boost::python::type<float>());
}
inline std::complex<float> from_python(PyObject* p,
boost::python::type<const std::complex<float>&>) {
return boost::python::detail::complex_from_python(p, boost::python::type<float>());
}
// For when your C++ function really wants to pass/return a PyObject*
PyObject* to_python(PyObject*);
PyObject* from_python(PyObject*, boost::python::type<PyObject*>);
@@ -304,6 +378,11 @@ inline unsigned short from_python(PyObject* p, boost::python::type<const unsigne
return from_python(p, boost::python::type<unsigned short>());
}
inline char from_python(PyObject* p, boost::python::type<const char&>)
{
return from_python(p, boost::python::type<char>());
}
inline signed char from_python(PyObject* p, boost::python::type<const signed char&>)
{
return from_python(p, boost::python::type<signed char>());

View File

@@ -0,0 +1,322 @@
/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use,
modify, sell and distribute this software is granted provided this
copyright notice appears in all copies. This software is provided
"as is" without express or implied warranty, and with no claim as to
its suitability for any purpose.
Revision History:
17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve)
*/
/* Implementation of Boost.Python cross-module support.
See root/libs/python/doc/cross_module.html for details.
*/
#ifndef CROSS_MODULE_HPP
# define CROSS_MODULE_HPP
# include <boost/python/class_builder.hpp>
namespace boost { namespace python {
struct import_error : error_already_set {};
struct export_error : error_already_set {};
}}
namespace boost { namespace python { namespace detail {
// Concept: throw exception if api_major is changed
// show warning on stderr if api_minor is changed
const int export_converters_api_major = 4;
const int export_converters_api_minor = 1;
extern const char* converters_attribute_name;
void* import_converter_object(const std::string& module_name,
const std::string& py_class_name,
const std::string& attribute_name);
void check_export_converters_api(const int importing_major,
const int importing_minor,
const int imported_major,
const int imported_minor);
}}}
// forward declaration
namespace boost { namespace python { namespace detail {
template <class T> class import_extension_class;
}}}
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
/* This class template is instantiated by import_converters<T>.
This class is a look-alike of class python_extension_class_converters.
The converters in this class are wrappers that call converters
imported from another module.
To ensure that the dynamic loader resolves all symbols in the
intended way, the signature of all friend functions is changed with
respect to the original functions in class
python_extension_class_converters by adding an arbitrary additional
parameter with a default value, in this case "bool sig = false".
See also: comments for class export_converter_object_base below.
*/
template <class T>
class python_import_extension_class_converters
{
public:
friend python_import_extension_class_converters py_extension_class_converters(boost::python::type<T>, bool sig = false) {
return python_import_extension_class_converters();
}
PyObject* to_python(const T& x) const {
return boost::python::detail::import_extension_class<T>::get_converters()->to_python(x);
}
friend T* from_python(PyObject* p, boost::python::type<T*> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_Ts(p, t);
}
friend const T* from_python(PyObject* p, boost::python::type<const T*> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_cTs(p, t);
}
friend const T* from_python(PyObject* p, boost::python::type<const T*const&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_cTscr(p, t);
}
friend T* from_python(PyObject* p, boost::python::type<T* const&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_Tscr(p, t);
}
friend T& from_python(PyObject* p, boost::python::type<T&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_Tr(p, t);
}
friend const T& from_python(PyObject* p, boost::python::type<const T&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_cTr(p, t);
}
friend const T& from_python(PyObject* p, boost::python::type<T> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_T(p, t);
}
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T>&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_aTr(p, t);
}
friend std::auto_ptr<T> from_python(PyObject* p, boost::python::type<std::auto_ptr<T> > t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_aT(p, t);
}
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<const std::auto_ptr<T>&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_caTr(p, t);
}
friend PyObject* to_python(std::auto_ptr<T> x, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->to_python(x);
}
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T>&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_sTr(p, t);
}
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T> > t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_sT(p, t);
}
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<const boost::shared_ptr<T>&> t, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->from_python_csTr(p, t);
}
friend PyObject* to_python(boost::shared_ptr<T> x, bool sig = false) {
return boost::python::detail::import_extension_class<T>::get_converters()->to_python(x);
}
};
BOOST_PYTHON_END_CONVERSION_NAMESPACE
namespace boost { namespace python {
BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters);
/* This class template is instantiated by export_converters().
A pointer to this class is exported/imported via the Python API.
Using the Python API ensures maximum portability.
All member functions are virtual. This is, what we export/import
is essentially just a pointer to a vtbl.
To work around a deficiency of Visual C++ 6.0, the name of each
from_python() member functions is made unique by appending a few
characters (derived in a ad-hoc manner from the corresponding type).
*/
template <class T>
struct export_converter_object_base
{
virtual int get_api_major() const { return detail::export_converters_api_major; }
virtual int get_api_minor() const { return detail::export_converters_api_minor; }
virtual PyObject* to_python(const T& x) = 0;
virtual T* from_python_Ts(PyObject* p, boost::python::type<T*> t) = 0;
virtual const T* from_python_cTs(PyObject* p, boost::python::type<const T*> t) = 0;
virtual const T* from_python_cTscr(PyObject* p, boost::python::type<const T*const&> t) = 0;
virtual T* from_python_Tscr(PyObject* p, boost::python::type<T* const&> t) = 0;
virtual T& from_python_Tr(PyObject* p, boost::python::type<T&> t) = 0;
virtual const T& from_python_cTr(PyObject* p, boost::python::type<const T&> t) = 0;
virtual const T& from_python_T(PyObject* p, boost::python::type<T> t) = 0;
virtual std::auto_ptr<T>& from_python_aTr(PyObject* p, boost::python::type<std::auto_ptr<T>&> t) = 0;
virtual std::auto_ptr<T> from_python_aT(PyObject* p, boost::python::type<std::auto_ptr<T> > t) = 0;
virtual const std::auto_ptr<T>& from_python_caTr(PyObject* p, boost::python::type<const std::auto_ptr<T>&> t) = 0;
virtual PyObject* to_python(std::auto_ptr<T> x) = 0;
virtual boost::shared_ptr<T>& from_python_sTr(PyObject* p, boost::python::type<boost::shared_ptr<T>&> t) = 0;
virtual const boost::shared_ptr<T>& from_python_sT(PyObject* p, boost::python::type<boost::shared_ptr<T> > t) = 0;
virtual const boost::shared_ptr<T>& from_python_csTr(PyObject* p, boost::python::type<const boost::shared_ptr<T>&> t) = 0;
virtual PyObject* to_python(boost::shared_ptr<T> x) = 0;
};
// Converters to be used if T is not copyable.
template <class T>
struct export_converter_object_noncopyable : export_converter_object_base<T>
{
virtual PyObject* to_python(const T& x) {
PyErr_SetString(PyExc_RuntimeError,
"to_python(const T&) converter not exported");
throw import_error();
}
virtual T* from_python_Ts(PyObject* p, boost::python::type<T*> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const T* from_python_cTs(PyObject* p, boost::python::type<const T*> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const T* from_python_cTscr(PyObject* p, boost::python::type<const T*const&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual T* from_python_Tscr(PyObject* p, boost::python::type<T* const&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual T& from_python_Tr(PyObject* p, boost::python::type<T&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const T& from_python_cTr(PyObject* p, boost::python::type<const T&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const T& from_python_T(PyObject* p, boost::python::type<T> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual std::auto_ptr<T>& from_python_aTr(PyObject* p, boost::python::type<std::auto_ptr<T>&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual std::auto_ptr<T> from_python_aT(PyObject* p, boost::python::type<std::auto_ptr<T> > t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const std::auto_ptr<T>& from_python_caTr(PyObject* p, boost::python::type<const std::auto_ptr<T>&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual PyObject* to_python(std::auto_ptr<T> x) {
return BOOST_PYTHON_CONVERSION::to_python(x);
}
virtual boost::shared_ptr<T>& from_python_sTr(PyObject* p, boost::python::type<boost::shared_ptr<T>&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const boost::shared_ptr<T>& from_python_sT(PyObject* p, boost::python::type<boost::shared_ptr<T> > t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual const boost::shared_ptr<T>& from_python_csTr(PyObject* p, boost::python::type<const boost::shared_ptr<T>&> t) {
return BOOST_PYTHON_CONVERSION::from_python(p, t);
}
virtual PyObject* to_python(boost::shared_ptr<T> x) {
return BOOST_PYTHON_CONVERSION::to_python(x);
}
};
// The addditional to_python() converter that can be used if T is copyable.
template <class T>
struct export_converter_object : export_converter_object_noncopyable<T>
{
virtual PyObject* to_python(const T& x) {
return BOOST_PYTHON_CONVERSION::py_extension_class_converters(boost::python::type<T>()).to_python(x);
}
};
namespace detail {
/* This class template is instantiated by import_converters<T>.
Its purpose is to import the converter_object via the Python API.
The actual import is only done once. The pointer to the
imported converter object is kept in the static data member
imported_converters.
*/
template <class T>
class import_extension_class
: public python_import_extension_class_converters<T>
{
public:
inline import_extension_class(const char* module, const char* py_class) {
m_module = module;
m_py_class = py_class;
}
static boost::python::export_converter_object_base<T>* get_converters();
private:
static std::string m_module;
static std::string m_py_class;
static boost::python::export_converter_object_base<T>* imported_converters;
};
template <class T> std::string import_extension_class<T>::m_module;
template <class T> std::string import_extension_class<T>::m_py_class;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::imported_converters = 0;
template <class T>
boost::python::export_converter_object_base<T>*
import_extension_class<T>::get_converters() {
if (imported_converters == 0) {
void* cobject
= import_converter_object(m_module, m_py_class,
converters_attribute_name);
imported_converters
= static_cast<boost::python::export_converter_object_base<T>*>(cobject);
check_export_converters_api(
export_converters_api_major,
export_converters_api_minor,
imported_converters->get_api_major(),
imported_converters->get_api_minor());
}
return imported_converters;
}
}}} // namespace boost::python::detail
namespace boost { namespace python {
// Implementation of export_converters().
template <class T, class U>
void export_converters(class_builder<T, U>& cb)
{
static export_converter_object<T> export_cvts;
cb.add(
ref(PyCObject_FromVoidPtr(reinterpret_cast<void*>(&export_cvts), NULL)),
detail::converters_attribute_name);
}
// Implementation of export_converters_noncopyable().
template <class T, class U>
void export_converters_noncopyable(class_builder<T, U>& cb)
{
static export_converter_object_noncopyable<T> export_cvts;
cb.add(
ref(PyCObject_FromVoidPtr(reinterpret_cast<void*>(&export_cvts), NULL)),
detail::converters_attribute_name);
}
// Implementation of import_converters<T>.
template <class T>
class import_converters
: python_import_extension_class_converters<T> // Works around MSVC6.x/GCC2.95.2 bug described
// at the bottom of class_builder.hpp.
{
public:
import_converters(const char* module, const char* py_class)
: m_class(new detail::import_extension_class<T>(module, py_class))
{ }
private:
boost::shared_ptr<detail::import_extension_class<T> > m_class;
};
}} // namespace boost::python
#endif // CROSS_MODULE_HPP

View File

@@ -5,6 +5,9 @@
//
// 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_
@@ -46,9 +49,8 @@ base_object<python_type>::base_object(PyTypeObject* type_obj)
std::
#endif
memset(bp, 0, sizeof(base_python_type));
ob_refcnt = 1;
ob_type = type_obj;
Py_INCREF(type_obj);
PyObject_INIT(bp, type_obj);
}
template <class python_type>

View File

@@ -6,6 +6,9 @@
// 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_
@@ -21,7 +24,7 @@
# else
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
# define BOOST_PYTHON_CONVERSION 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
@@ -46,11 +49,18 @@
# endif
// The STLport puts all of the standard 'C' library names in std (as far as the
// user is concerned), but without it you need a fix if you're using MSVC.
# if defined(BOOST_MSVC6_OR_EARLIER) && !defined(__STLPORT)
// 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
#ifdef _WIN32
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name()
#else
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name()
#endif
#endif // CONFIG_DWA052200_H_

View File

@@ -6,9 +6,14 @@
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
//
// This file automatically generated for 5-argument constructors by
// 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_
@@ -22,6 +27,7 @@
# include <boost/python/detail/init_function.hpp>
# include <typeinfo>
# include <boost/smart_ptr.hpp>
# include <boost/type_traits.hpp>
namespace boost { namespace python {
@@ -61,7 +67,7 @@ T* check_non_null(T* p)
return p;
}
template <class T> class held_instance;
template <class Held> class held_instance;
typedef void* (*conversion_function_ptr)(void*);
@@ -133,6 +139,26 @@ class class_registry
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
@@ -141,6 +167,14 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
// and U. T is the class the user really intends to wrap. U is a class derived
// from T with some virtual function overriding boilerplate, or if there are no
// virtual functions, U = held_instance<T>.
//
// A look-alike of this class in root/boost/python/cross_module.hpp
// is used for the implementation of the cross-module support
// (export_converters and import_converters). If from_python
// and to_python converters are added or removed from the class
// below, the class python_import_extension_class_converters has
// to be modified accordingly.
//
template <class T, class U = boost::python::detail::held_instance<T> >
class python_extension_class_converters
{
@@ -178,9 +212,9 @@ class python_extension_class_converters
new boost::python::detail::instance_value_holder<T,U>(result.get(), x)));
return result.release();
}
// Convert to T*
friend T* from_python(PyObject* obj, boost::python::type<T*>)
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);
@@ -201,9 +235,18 @@ class python_extension_class_converters
throw boost::python::argument_error();
}
// Convert to PtrType, where PtrType can be dereferenced to obtain a T.
// 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& ptr_from_python(PyObject* obj, boost::python::type<PtrType>)
static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type<PtrType>)
{
// downcast to an extension_instance, then find the actual T
boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj);
@@ -220,9 +263,29 @@ class python_extension_class_converters
throw boost::python::argument_error();
}
// 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 PyObject* ptr_to_python(PtrType x)
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>(
@@ -254,7 +317,7 @@ class python_extension_class_converters
// Convert to T&
friend T& from_python(PyObject* p, boost::python::type<T&>)
{ return *boost::python::detail::check_non_null(from_python(p, boost::python::type<T*>())); }
{ 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&>)
@@ -265,28 +328,28 @@ class python_extension_class_converters
{ return from_python(p, boost::python::type<T&>()); }
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T>&>)
{ return ptr_from_python(p, boost::python::type<std::auto_ptr<T> >()); }
{ return smart_ptr_reference(p, boost::python::type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<std::auto_ptr<T> >)
{ return ptr_from_python(p, boost::python::type<std::auto_ptr<T> >()); }
friend std::auto_ptr<T> from_python(PyObject* p, boost::python::type<std::auto_ptr<T> >)
{ return smart_ptr_value(p, boost::python::type<std::auto_ptr<T> >()); }
friend const std::auto_ptr<T>& from_python(PyObject* p, boost::python::type<const std::auto_ptr<T>&>)
{ return ptr_from_python(p, boost::python::type<std::auto_ptr<T> >()); }
{ return smart_ptr_value(p, boost::python::type<std::auto_ptr<T> >()); }
friend PyObject* to_python(std::auto_ptr<T> x)
{ return ptr_to_python(x); }
{ return smart_ptr_to_python(x); }
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T>&>)
{ return ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
{ return smart_ptr_reference(p, boost::python::type<boost::shared_ptr<T> >()); }
friend boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T> >)
{ return ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<boost::shared_ptr<T> >)
{ return smart_ptr_value(p, boost::python::type<boost::shared_ptr<T> >()); }
friend const boost::shared_ptr<T>& from_python(PyObject* p, boost::python::type<const boost::shared_ptr<T>&>)
{ return ptr_from_python(p, boost::python::type<boost::shared_ptr<T> >()); }
{ return smart_ptr_value(p, boost::python::type<boost::shared_ptr<T> >()); }
friend PyObject* to_python(boost::shared_ptr<T> x)
{ return ptr_to_python(x); }
{ return smart_ptr_to_python(x); }
};
// Convert T to_python, instantiated on demand and only if there isn't a
@@ -363,8 +426,8 @@ class extension_class
~extension_class();
// define constructors
template <class A1, class A2, class A3, class A4, class A5>
inline void def(constructor<A1, A2, A3, A4, A5>)
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(
@@ -373,7 +436,12 @@ class extension_class
prepend(type<A3>::id(),
prepend(type<A4>::id(),
prepend(type<A5>::id(),
signature0()))))));
prepend(type<A6>::id(),
prepend(type<A7>::id(),
prepend(type<A8>::id(),
prepend(type<A9>::id(),
prepend(type<A10>::id(),
signature0())))))))))));
}
@@ -608,23 +676,33 @@ class extension_class
// A simple wrapper over a T which allows us to use extension_class<T> with a
// single template parameter only. See extension_class<T>, above.
template <class T>
class held_instance : public T
template <class Held>
class held_instance : public Held
{
// There are no member functions: we want to avoid inadvertently overriding
// any virtual functions in T.
// any virtual functions in Held.
public:
held_instance(PyObject*) : T() {}
held_instance(PyObject*) : Held() {}
template <class A1>
held_instance(PyObject*, A1 a1) : T(a1) {}
held_instance(PyObject*, A1 a1) : Held(a1) {}
template <class A1, class A2>
held_instance(PyObject*, A1 a1, A2 a2) : T(a1, a2) {}
held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {}
template <class A1, class A2, class A3>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : T(a1, a2, a3) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {}
template <class A1, class A2, class A3, class A4>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : T(a1, a2, a3, a4) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {}
template <class A1, class A2, class A3, class A4, class A5>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : T(a1, a2, a3, a4, a5) {}
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : 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
@@ -676,6 +754,21 @@ public:
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; }
@@ -721,8 +814,6 @@ class extension_instance : public instance
// Template function implementations
//
tuple extension_class_coerce(ref l, ref r);
template <class T, class U>
extension_class<T, U>::extension_class()
: extension_class_base(typeid(T).name())
@@ -743,7 +834,7 @@ 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(&extension_class_coerce, "__coerce__");
this->def(&standard_coerce, "__coerce__");
}
template <class T, class U>
@@ -831,4 +922,3 @@ std::vector<derived_class_info> class_registry<T>::static_derived_class_info;
}}} // namespace boost::python::detail
#endif // EXTENSION_CLASS_DWA052000_H_

View File

@@ -110,11 +110,11 @@ 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, 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
@@ -165,7 +165,7 @@ struct init_function
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,
return new init6<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -176,7 +176,7 @@ struct init_function
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,
return new init7<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -188,7 +188,7 @@ struct init_function
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,
return new init8<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -201,7 +201,7 @@ struct init_function
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,
return new init9<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -215,7 +215,7 @@ struct init_function
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,
return new init10<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
@@ -353,7 +353,7 @@ struct init5 : init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6>
struct Init6 : init
struct init6 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
@@ -379,7 +379,7 @@ struct Init6 : init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct Init7 : init
struct init7 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
@@ -407,7 +407,7 @@ struct Init7 : init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct Init8 : init
struct init8 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
@@ -437,7 +437,7 @@ struct Init8 : init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct Init9 : init
struct init9 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
@@ -469,7 +469,7 @@ struct Init9 : init
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
struct Init10 : init
struct init10 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{

View File

@@ -1,5 +1,30 @@
// (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 DEBUG_PYTHON
# 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
@@ -16,9 +41,11 @@ typedef int pid_t;
# define WORD_BIT 32
# define hypot _hypot
# include <stdio.h>
# define HAVE_CLOCK
# define HAVE_STRFTIME
# define HAVE_STRERROR
# 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
@@ -44,6 +71,8 @@ typedef int pid_t;
# define _MSC_VER 900
# endif
# elif defined(_MSC_VER)
# include <limits> // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX
# endif
#endif // _WIN32
@@ -59,3 +88,7 @@ typedef int pid_t;
# 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

View File

@@ -18,11 +18,10 @@ namespace boost { namespace python {
class module_builder
{
typedef PyObject * (*raw_function_ptr)(boost::python::tuple const &, boost::python::dictionary const &);
public:
// Create a module. REQUIRES: only one module_builder is created per module.
module_builder(const char* name);
~module_builder();
// Add elements to the module
void add(detail::function* x, const char* name);
@@ -41,13 +40,29 @@ class module_builder
add(detail::new_wrapped_function(fn), name);
}
static string name();
// Return true iff a module is currently being built.
static bool initializing();
// Return the name of the module currently being built.
// REQUIRES: initializing() == true
static string name();
// Return a pointer to the Python module object being built
PyObject* module() const;
private:
PyObject* m_module;
static PyMethodDef initial_methods[1];
};
//
// inline implementations
//
inline PyObject* module_builder::module() const
{
return m_module;
}
}} // namespace boost::python
#endif

View File

@@ -1,15 +1,38 @@
// (C) Copyright Ullrich Koethe and David Abrahams 2000-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.
//
// The authors gratefully acknowlege the support of Dragon Systems, Inc., in
// producing this work.
//
// Revision History:
// 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams)
// 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams)
#ifndef OPERATORS_UK112000_H_
#define OPERATORS_UK112000_H_
#include <boost/python/detail/functions.hpp>
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
# include <sstream>
#else
# include <strstream>
#endif
# include <boost/python/reference.hpp>
# include <boost/python/detail/functions.hpp>
// When STLport is used with native streams, _STL::ostringstream().str() is not
// _STL::string, but std::string. This confuses to_python(), so we'll use
// strstream instead. Also, GCC 2.95.2 doesn't have sstream.
# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
# define BOOST_PYTHON_USE_SSTREAM
# endif
#if defined(BOOST_PYTHON_USE_SSTREAM)
# include <sstream>
# else
# include <strstream>
# endif
namespace boost { namespace python {
tuple standard_coerce(ref l, ref r);
namespace detail {
// helper class for automatic operand type detection
@@ -461,6 +484,16 @@ namespace detail
static const char * rname() { return "__rcmp__"; }
};
# ifndef BOOST_PYTHON_USE_SSTREAM
class unfreezer {
public:
unfreezer(std::ostrstream& s) : m_stream(s) {}
~unfreezer() { m_stream.freeze(false); }
private:
std::ostrstream& m_stream;
};
# endif
// str(): Manual specialization needed because the string conversion does not follow
// the standard pattern relized by the macros.
template <>
@@ -473,19 +506,18 @@ namespace detail
{
tuple args(ref(arguments, ref::increment_count));
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
// When STLport is used with native streams, _STL::ostringstream().str() is not
// _STL::string, but std::string.
# ifdef BOOST_PYTHON_USE_SSTREAM
std::ostringstream s;
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>());
#else
return BOOST_PYTHON_CONVERSION::to_python(s.str());
# else
std::ostrstream s;
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>()) << char();
#endif
#if !defined(__GNUC__) || defined(__SGI_STL_PORT)
return BOOST_PYTHON_CONVERSION::to_python(s.str());
#else
auto unfreezer unfreeze(s);
return BOOST_PYTHON_CONVERSION::to_python(const_cast<char const *>(s.str()));
#endif
# endif
}
const char* description() const
@@ -501,4 +533,5 @@ namespace detail
}} // namespace boost::python
# undef BOOST_PYTHON_USE_SSTREAM
#endif /* OPERATORS_UK112000_H_ */