2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-24 06:02:14 +00:00

Initial work for virtual function support

[SVN r13175]
This commit is contained in:
Dave Abrahams
2002-03-11 18:43:02 +00:00
parent 2fa0910547
commit bccd854676
8 changed files with 360 additions and 49 deletions

View File

@@ -9,6 +9,7 @@
# include <boost/python/class_fwd.hpp>
# include <boost/python/reference.hpp>
# include <boost/python/object/class.hpp>
# include <boost/python/object/value_holder_fwd.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/detail/wrap_function.hpp>
# include <boost/mpl/type_list.hpp>
@@ -32,12 +33,6 @@ namespace // put some convenience classes into the unnamed namespace for the use
namespace boost { namespace python {
// Forward declarations
namespace objects
{
struct value_holder_generator;
}
namespace detail
{
// This is an mpl BinaryMetaFunction object with a runtime behavior,

View File

@@ -5,6 +5,7 @@
// to its suitability for any purpose.
#ifndef CLASS_FWD_DWA200222_HPP
# define CLASS_FWD_DWA200222_HPP
# include <boost/python/object/value_holder_fwd.hpp>
namespace boost { namespace python {
@@ -13,15 +14,10 @@ namespace detail
struct empty_list;
}
namespace objects
{
struct value_holder_generator;
}
template <
class T // class being wrapped
, class Bases = detail::empty_list
, class HolderGenerator = objects::value_holder_generator
, class HolderGenerator = objects::value_holder_generator<>
>
class class_;

View File

@@ -11,7 +11,6 @@
# include <boost/utility.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/reference.hpp>
# include <boost/iterator_adaptors.hpp>
# include <cstddef>
namespace boost { namespace python {
@@ -55,24 +54,6 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable
virtual void* holds(converter::undecorated_type_id_t) = 0;
void install(PyObject* inst) throw();
struct iterator_policies : default_iterator_policies
{
template <class Iterator>
void increment(Iterator& p)
{
p.base() = p.base()->next();
}
};
typedef iterator_adaptor<
instance_holder*
, iterator_policies
, value_type_is<noncopyable>
, reference_is<instance_holder&>
, pointer_is<instance_holder*>
, iterator_category_is<std::input_iterator_tag> > iterator;
private:
instance_holder* m_next;
};

View File

@@ -22,7 +22,7 @@ struct make_holder<0>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
static void execute(
PyObject* p)
{
@@ -38,7 +38,7 @@ struct make_holder<1>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
@@ -57,7 +57,7 @@ struct make_holder<2>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
@@ -77,7 +77,7 @@ struct make_holder<3>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
@@ -99,7 +99,7 @@ struct make_holder<4>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
@@ -123,7 +123,7 @@ struct make_holder<5>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;
@@ -149,7 +149,7 @@ struct make_holder<6>
template <class T, class Generator, class ArgList>
struct apply
{
typedef typename detail::eval<Generator,T>::type holder;
typedef typename python::detail::eval<Generator,T>::type holder;
typedef typename mpl::at<0,ArgList>::type t0;
typedef typename forward<t0>::type f0;
typedef typename mpl::at<1,ArgList>::type t1;

View File

@@ -12,6 +12,7 @@
# include <boost/python/detail/eval.hpp>
# include <boost/ref.hpp>
# include <boost/type.hpp>
# include <boost/mpl/select_type.hpp>
namespace boost { namespace python { namespace objects {
@@ -145,7 +146,137 @@ struct pointer_holder : instance_holder
Pointer m_p;
};
}}}
template <class Pointer, class Value, class BackReferenceType>
struct pointer_holder_back_reference : instance_holder
{
pointer_holder_back_reference(Pointer);
// Forward construction to the held object
pointer_holder_back_reference(PyObject* p)
: m_p(new Value(p)) {}
template <class A1>
pointer_holder_back_reference(PyObject* p, A1 a1)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
))
{}
template <class A1, class A2>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
))
{}
template <class A1, class A2, class A3>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
))
{}
template <class A1, class A2, class A3, class A4>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
))
{}
template <class A1, class A2, class A3, class A4, class A5>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
)) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
))
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
))
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
))
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
: m_p(new Value(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
, (typename unwrap_reference<A10>::type&)(a10)
))
{}
private: // required holder implementation
void* holds(converter::undecorated_type_id_t);
private: // data members
Pointer m_p;
};
}}} // namespace boost::python::objects
// back to namespace boost for this forward declaration
namespace boost
@@ -164,19 +295,54 @@ struct shared_ptr_generator
};
};
struct no_back_reference;
// Workaround lack of partial specialization
namespace detail
{
template <class BackReferenceType, class PointerGenerator>
struct pointer_holder_back_reference_generator
{
template <class Held>
struct apply
{
typedef typename boost::python::detail::eval<
PointerGenerator,BackReferenceType
>::type pointer;
typedef pointer_holder_back_reference<pointer,Held,BackReferenceType> type;
};
};
template <class PointerGenerator>
struct plain_pointer_holder_generator
{
template <class Held>
struct apply
{
typedef typename boost::python::detail::eval<
PointerGenerator,Held
>::type pointer;
typedef pointer_holder<pointer, Held> type;
};
};
}
// A generator metafunction which can be passed to make_holder
// PointerGenerator should be another generator metafunction which
// makes the appropriate (smart) pointer type to hold the argument to
// pointer_holder_generator.
template <class PointerGenerator>
template <class PointerGenerator, class BackReferenceType = no_back_reference>
struct pointer_holder_generator
: mpl::select_type<
is_same<BackReferenceType,no_back_reference>::value
, detail::plain_pointer_holder_generator<
PointerGenerator>
, detail::pointer_holder_back_reference_generator<
BackReferenceType,PointerGenerator>
>::type
{
template <class Held>
struct apply
{
typedef typename detail::eval<PointerGenerator,Held>::type pointer;
typedef pointer_holder<pointer, Held> type;
};
};
template <class Pointer, class Value>

View File

@@ -6,6 +6,7 @@
#ifndef VALUE_HOLDER_DWA20011215_HPP
# define VALUE_HOLDER_DWA20011215_HPP
# include <boost/python/object/value_holder_fwd.hpp>
# include <boost/python/object/class.hpp>
# include <boost/python/converter/type_id.hpp>
# include <boost/python/object/inheritance.hpp>
@@ -140,8 +141,136 @@ struct value_holder : instance_holder
Held m_held;
};
template <class Held,class BackReferenceType>
struct value_holder_back_reference : instance_holder
{
// Forward construction to the held object
value_holder_back_reference(PyObject* p)
: m_held() {}
template <class A1>
value_holder_back_reference(PyObject* p, A1 a1)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
)
{}
template <class A1, class A2>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
)
{}
template <class A1, class A2, class A3>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
)
{}
template <class A1, class A2, class A3, class A4>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
)
{}
template <class A1, class A2, class A3, class A4, class A5>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
) {}
template <class A1, class A2, class A3, class A4, class A5, class A6>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
) {}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
)
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
)
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
)
{}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
: m_held(p
, (typename unwrap_reference<A1>::type&)(a1)
, (typename unwrap_reference<A2>::type&)(a2)
, (typename unwrap_reference<A3>::type&)(a3)
, (typename unwrap_reference<A4>::type&)(a4)
, (typename unwrap_reference<A5>::type&)(a5)
, (typename unwrap_reference<A6>::type&)(a6)
, (typename unwrap_reference<A7>::type&)(a7)
, (typename unwrap_reference<A8>::type&)(a8)
, (typename unwrap_reference<A9>::type&)(a9)
, (typename unwrap_reference<A10>::type&)(a10)
)
{}
private: // required holder implementation
void* holds(converter::undecorated_type_id_t);
private: // data members
BackReferenceType m_held;
};
// A generator metafunction which can be passed to make_holder
struct value_holder_generator
template <>
struct value_holder_generator<no_back_reference>
{
template <class Held>
struct apply
@@ -150,6 +279,16 @@ struct value_holder_generator
};
};
template <class BackReferenceType>
struct value_holder_generator
{
template <class Held>
struct apply
{
typedef value_holder_back_reference<Held,BackReferenceType> type;
};
};
template <class Held>
void* value_holder<Held>::holds(converter::undecorated_type_id_t dst_t)
{
@@ -158,6 +297,23 @@ void* value_holder<Held>::holds(converter::undecorated_type_id_t dst_t)
: find_static_type(&m_held, src_t, dst_t);
}
template <class Held, class BackReferenceType>
void* value_holder_back_reference<Held,BackReferenceType>::holds(
converter::undecorated_type_id_t dst_t)
{
converter::undecorated_type_id_t src_t = converter::undecorated_type_id<Held>();
if (src_t == dst_t)
{
Held* x = &m_held;
return x;
}
src_t = converter::undecorated_type_id<BackReferenceType>();
return src_t == dst_t
? &m_held
: find_static_type(&m_held, src_t, dst_t);
}
}}} // namespace boost::python::objects
#endif // VALUE_HOLDER_DWA20011215_HPP

View File

@@ -0,0 +1,17 @@
// Copyright David Abrahams 2002. 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 VALUE_HOLDER_FWD_DWA2002311_HPP
# define VALUE_HOLDER_FWD_DWA2002311_HPP
namespace boost { namespace python { namespace objects {
struct no_back_reference;
template <class CallbackType = no_back_reference> struct value_holder_generator;
}}} // namespace boost::python::object
#endif // VALUE_HOLDER_FWD_DWA2002311_HPP

View File

@@ -169,9 +169,9 @@ find_instance_impl(PyObject* inst, converter::undecorated_type_id_t type)
instance* self = reinterpret_cast<instance*>(inst);
for (instance_holder::iterator match(self->objects), end(0); match != end; ++match)
for (instance_holder* match = self->objects; match != 0; match = match->next())
{
void* const found = (*match).holds(type);
void* const found = match->holds(type);
if (found)
return found;
}