2
0
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:
Dave Abrahams
2002-01-07 06:47:22 +00:00
parent 0dafa9e229
commit 9923a4c4ff
4 changed files with 48 additions and 64 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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