mirror of
https://github.com/boostorg/python.git
synced 2026-01-22 17:32:55 +00:00
More "realism"
[SVN r12239]
This commit is contained in:
@@ -32,31 +32,31 @@ struct class_unwrapper
|
||||
template <class T>
|
||||
void* class_unwrapper<T>::can_convert(PyObject* p) const
|
||||
{
|
||||
return objects::find_holder<T>(p);
|
||||
return objects::find_instance<T>(p);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T& class_unwrapper<T>::convert(PyObject*, void* holder_, boost::type<T&>) const
|
||||
T& class_unwrapper<T>::convert(PyObject*, void* found, boost::type<T&>) const
|
||||
{
|
||||
return *static_cast<objects::holder<T>*>(holder_)->target();
|
||||
return *static_cast<T*>(found);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const& class_unwrapper<T>::convert(PyObject*, void* holder_, boost::type<T const&>) const
|
||||
T const& class_unwrapper<T>::convert(PyObject*, void* found, boost::type<T const&>) const
|
||||
{
|
||||
return *static_cast<objects::holder<T>*>(holder_)->target();
|
||||
return *static_cast<T*>(found);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* class_unwrapper<T>::convert(PyObject*, void* holder_, boost::type<T*>) const
|
||||
T* class_unwrapper<T>::convert(PyObject*, void* found, boost::type<T*>) const
|
||||
{
|
||||
return static_cast<objects::holder<T>*>(holder_)->target();
|
||||
return static_cast<T*>(found);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const* class_unwrapper<T>::convert(PyObject*, void* holder_, boost::type<T const*>) const
|
||||
T const* class_unwrapper<T>::convert(PyObject*, void* found, boost::type<T const*>) const
|
||||
{
|
||||
return static_cast<objects::holder<T>*>(holder_)->target();
|
||||
return static_cast<T*>(found);
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
||||
|
||||
@@ -17,15 +17,16 @@ namespace boost { namespace python { namespace objects {
|
||||
template <class T> struct holder;
|
||||
|
||||
// Base class for all holders
|
||||
struct BOOST_PYTHON_DECL holder_base : noncopyable
|
||||
struct BOOST_PYTHON_DECL instance_holder : noncopyable
|
||||
{
|
||||
public:
|
||||
holder_base(converter::type_id_t id);
|
||||
virtual ~holder_base();
|
||||
virtual bool held_by_value() const = 0;
|
||||
instance_holder();
|
||||
virtual ~instance_holder();
|
||||
|
||||
holder_base* next() const;
|
||||
converter::type_id_t type() const;
|
||||
// return the next holder in a chain
|
||||
instance_holder* next() const;
|
||||
|
||||
virtual void* holds(converter::type_id_t) = 0;
|
||||
|
||||
void install(PyObject* inst);
|
||||
|
||||
@@ -39,41 +40,30 @@ struct BOOST_PYTHON_DECL holder_base : noncopyable
|
||||
};
|
||||
|
||||
typedef iterator_adaptor<
|
||||
holder_base*
|
||||
instance_holder*
|
||||
, iterator_policies
|
||||
, value_type_is<noncopyable>
|
||||
, reference_is<holder_base&>
|
||||
, pointer_is<holder_base*>
|
||||
, reference_is<instance_holder&>
|
||||
, pointer_is<instance_holder*>
|
||||
, iterator_category_is<std::input_iterator_tag> > iterator;
|
||||
|
||||
private:
|
||||
converter::type_id_t m_type;
|
||||
holder_base* m_next;
|
||||
};
|
||||
|
||||
// Abstract base class which holds a Held, somehow. Provides a uniform
|
||||
// way to get a pointer to the held object
|
||||
template <class Held>
|
||||
struct holder : holder_base
|
||||
{
|
||||
typedef Held held_type;
|
||||
holder();
|
||||
virtual Held* target() = 0;
|
||||
instance_holder* m_next;
|
||||
};
|
||||
|
||||
// Each extension instance will be one of these
|
||||
struct instance
|
||||
{
|
||||
PyObject_HEAD
|
||||
holder_base* objects;
|
||||
instance_holder* objects;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_DECL holder_base* find_holder_impl(PyObject*, converter::type_id_t);
|
||||
BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t);
|
||||
|
||||
template <class T>
|
||||
holder<T>* find_holder(PyObject* p, T* = 0)
|
||||
T* find_instance(PyObject* p, T* = 0)
|
||||
{
|
||||
return static_cast<holder<T>*>(find_holder_impl(p, converter::type_id<T>()));
|
||||
return static_cast<T*>(find_instance_impl(p, converter::type_id<T>()));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyTypeObject* class_metatype();
|
||||
@@ -82,22 +72,11 @@ BOOST_PYTHON_DECL PyTypeObject* class_type();
|
||||
//
|
||||
// implementation
|
||||
//
|
||||
inline holder_base* holder_base::next() const
|
||||
inline instance_holder* instance_holder::next() const
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
inline converter::type_id_t holder_base::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
template <class Held>
|
||||
holder<Held>::holder()
|
||||
: holder_base(converter::type_id<Held>())
|
||||
{
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // CLASS_DWA20011214_HPP
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
# define VALUE_HOLDER_DWA20011215_HPP
|
||||
|
||||
# include <boost/python/object/class.hpp>
|
||||
# include <boost/python/converter/type_id.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
template <class Held>
|
||||
struct value_holder : holder<Held>
|
||||
struct value_holder : instance_holder
|
||||
{
|
||||
// Forward construction to the held object
|
||||
value_holder(PyObject*)
|
||||
@@ -58,8 +59,7 @@ struct value_holder : holder<Held>
|
||||
: m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {}
|
||||
|
||||
private: // required holder implementation
|
||||
Held* target() { return &m_held; }
|
||||
bool held_by_value() const { return true; }
|
||||
void* holds(converter::type_id_t);
|
||||
|
||||
private: // data members
|
||||
Held m_held;
|
||||
@@ -75,6 +75,12 @@ struct value_holder_generator
|
||||
};
|
||||
};
|
||||
|
||||
template <class Held>
|
||||
void* value_holder<Held>::holds(converter::type_id_t x)
|
||||
{
|
||||
return x == converter::type_id<Held>() ? &m_held : 0;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
#endif // VALUE_HOLDER_DWA20011215_HPP
|
||||
|
||||
@@ -11,13 +11,12 @@
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
holder_base::holder_base(converter::type_id_t id)
|
||||
: m_type(id)
|
||||
, m_next(0)
|
||||
instance_holder::instance_holder()
|
||||
: m_next(0)
|
||||
{
|
||||
}
|
||||
|
||||
holder_base::~holder_base()
|
||||
instance_holder::~instance_holder()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -134,28 +133,28 @@ BOOST_PYTHON_DECL PyTypeObject* class_type()
|
||||
return &class_type_object;
|
||||
}
|
||||
|
||||
void holder_base::install(PyObject* self)
|
||||
void instance_holder::install(PyObject* self)
|
||||
{
|
||||
assert(self->ob_type->ob_type == &class_metatype_object);
|
||||
m_next = ((instance*)self)->objects;
|
||||
((instance*)self)->objects = this;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL holder_base*
|
||||
find_holder_impl(PyObject* inst, converter::type_id_t type)
|
||||
BOOST_PYTHON_DECL void*
|
||||
find_instance_impl(PyObject* inst, converter::type_id_t type)
|
||||
{
|
||||
if (inst->ob_type->ob_type != &class_metatype_object)
|
||||
return 0;
|
||||
|
||||
instance* self = reinterpret_cast<instance*>(inst);
|
||||
|
||||
holder_base::iterator match = std::find_if(
|
||||
holder_base::iterator(self->objects), holder_base::iterator(0)
|
||||
, bind<bool>(std::equal_to<converter::type_id_t>()
|
||||
, bind<converter::type_id_t>(mem_fn(&holder_base::type), _1)
|
||||
, type));
|
||||
|
||||
return match != holder_base::iterator(0)
|
||||
? match.base() : 0;
|
||||
for (instance_holder::iterator match(self->objects), end(0); match != end; ++match)
|
||||
{
|
||||
void* const found = (*match).holds(type);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
||||
|
||||
Reference in New Issue
Block a user