mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 05:42:30 +00:00
Modified Files:
boost/python/detail:
base_object.hpp - Changed template parameter to MixedCase
cast.hpp - Killed off unused downcast_traits<>
functions.hpp - Added commentary
libs/python/src
functions.cpp, types.cpp - Added comments
tools/build
TODO.txt - updated
allyourbase.jam - fixed a nasty typo which caused all kinds of bugs
boost-base.jam - changes to support the use of command files
intel-win32-tools.jam -
A feeble attempt at allowing intel to work without prior tool setup. More work needed
msvc-tools.jam - A first cut at command file support
tools/build/jam_src
jam.h - Fixed MAXLINE for NT
[SVN r11489]
This commit is contained in:
@@ -21,10 +21,10 @@ namespace boost { namespace python { namespace detail {
|
||||
|
||||
// base_object - adds a constructor and non-virtual destructor to a
|
||||
// base Python type (e.g. PyObject, PyTypeObject).
|
||||
template <class python_type>
|
||||
struct base_object : python_type
|
||||
template <class PythonType>
|
||||
struct base_object : PythonType
|
||||
{
|
||||
typedef python_type base_python_type;
|
||||
typedef PythonType base_python_type;
|
||||
|
||||
// Initializes type and reference count. All other fields of base_python_type are 0
|
||||
base_object(PyTypeObject* type_obj);
|
||||
@@ -41,8 +41,8 @@ typedef base_object<PyTypeObject> python_type;
|
||||
//
|
||||
// base_object member function implementations
|
||||
//
|
||||
template <class python_type>
|
||||
base_object<python_type>::base_object(PyTypeObject* type_obj)
|
||||
template <class PythonType>
|
||||
base_object<PythonType>::base_object(PyTypeObject* type_obj)
|
||||
{
|
||||
base_python_type* bp = this;
|
||||
#if !defined(_MSC_VER) || defined(__STLPORT)
|
||||
@@ -53,8 +53,8 @@ base_object<python_type>::base_object(PyTypeObject* type_obj)
|
||||
PyObject_INIT(bp, type_obj);
|
||||
}
|
||||
|
||||
template <class python_type>
|
||||
inline base_object<python_type>::~base_object()
|
||||
template <class PythonType>
|
||||
inline base_object<PythonType>::~base_object()
|
||||
{
|
||||
Py_DECREF(ob_type);
|
||||
}
|
||||
|
||||
@@ -15,14 +15,6 @@
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail {
|
||||
// The default way of converting a PyObject* or PyTypeObject* to a T*
|
||||
template <class T>
|
||||
struct downcast_traits
|
||||
{
|
||||
template <class U>
|
||||
static T* cast(U* p) { return static_cast<T*>(p); }
|
||||
};
|
||||
|
||||
inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p)
|
||||
{
|
||||
return reinterpret_cast<PyTypeObject*>(p);
|
||||
@@ -54,19 +46,19 @@ template <class T>
|
||||
struct downcast
|
||||
{
|
||||
downcast(PyObject* p)
|
||||
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((T*)0, p)))
|
||||
: m_p(static_cast<T*>(detail::as_base_object((T*)0, p)))
|
||||
{}
|
||||
|
||||
downcast(const PyObject* p)
|
||||
: m_p(detail::downcast_traits<T>::cast(detail::as_base_object((const T*)0, p)))
|
||||
: m_p(static_cast<T*>(detail::as_base_object((const T*)0, p)))
|
||||
{}
|
||||
|
||||
downcast(PyTypeObject* p)
|
||||
: m_p(detail::downcast_traits<T>::cast(p))
|
||||
: m_p(static_cast<T*>(p))
|
||||
{}
|
||||
|
||||
downcast(const PyTypeObject* p)
|
||||
: m_p(detail::downcast_traits<T>::cast(p))
|
||||
: m_p(static_cast<T*>(p))
|
||||
{}
|
||||
|
||||
operator T*() const { return m_p; }
|
||||
|
||||
@@ -46,7 +46,7 @@ class function : public python_object
|
||||
private:
|
||||
struct type_object;
|
||||
private:
|
||||
reference<function> m_overloads;
|
||||
reference<function> m_overloads; // A linked list of the function overloads
|
||||
};
|
||||
|
||||
// wrapped_function_pointer<> --
|
||||
@@ -66,7 +66,12 @@ struct wrapped_function_pointer : function
|
||||
|
||||
private:
|
||||
PyObject* do_call(PyObject* args, PyObject* keywords) const
|
||||
{ return caller<R>::call(m_pf, args, keywords); }
|
||||
{
|
||||
// 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(); }
|
||||
|
||||
@@ -61,6 +61,8 @@ function::function()
|
||||
|
||||
PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
// Traverse the linked list of function overloads until we find one that
|
||||
// matches.
|
||||
for (const function* f = this; f != 0; f = f->m_overloads.get())
|
||||
{
|
||||
PyErr_Clear();
|
||||
@@ -75,9 +77,14 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, no overloads matched the arguments
|
||||
|
||||
// Allow the single-function error-reporting to take effect unless there was
|
||||
// an overload
|
||||
if (m_overloads.get() == 0)
|
||||
return 0;
|
||||
|
||||
// Synthesize a more-explicit error message
|
||||
PyErr_Clear();
|
||||
string message("No overloaded functions match (");
|
||||
tuple arguments(ref(args, ref::increment_count));
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace {
|
||||
|
||||
using detail::type_object_base;
|
||||
|
||||
// Define a family of forwarding functions that can be calle from a
|
||||
// PyTypeObject's slots. These functions dispatch through a (virtual) member
|
||||
// function pointer in the type_object_base, and handle exceptions in a
|
||||
// uniform way, preventing us from having to rewrite the dispatching code over
|
||||
// and over.
|
||||
PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*) const)
|
||||
{
|
||||
try
|
||||
@@ -154,6 +159,10 @@ namespace {
|
||||
|
||||
extern "C" {
|
||||
|
||||
//
|
||||
// These functions actually go into the type object's slots, and dispatch to the
|
||||
// "call" wrappers defined above.
|
||||
//
|
||||
static PyObject* do_instance_repr(PyObject* obj)
|
||||
{
|
||||
return call(obj, &type_object_base::instance_repr);
|
||||
|
||||
Reference in New Issue
Block a user