2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 17:12:22 +00:00
Files
python/src/converter/registry.cpp
2002-01-01 18:21:06 +00:00

162 lines
3.7 KiB
C++

// Copyright David Abrahams 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.
# include <boost/python/converter/unwrapper.hpp>
# include <boost/python/converter/wrapper.hpp>
# include <map>
# include <list>
# include <algorithm>
# include <stdexcept>
# ifdef BOOST_PYTHON_TRACE
# include <iostream>
# endif
namespace boost { namespace python { namespace converter {
namespace // <unnamed>
{
typedef std::map<type_id_t, registry::entry, type_id_before> registry_t;
registry_t& entries()
{
static registry_t registry;
return registry;
}
} // namespace <unnamed>
namespace registry
{
entry* find(type_id_t type)
{
return &entries()[type];
}
entry::entry()
: m_wrapper(0)
{
}
entry::~entry()
{
if (m_wrapper != 0)
m_wrapper->m_can_unregister = false;
for (unwrappers::iterator p = m_unwrappers.begin(); p != m_unwrappers.end(); ++p)
{
(*p)->m_can_unregister = false;
}
}
std::pair<unwrapper_base*,void*>
entry::unwrapper(PyObject* p) const
{
unwrapper_base* body = 0;
void* data = 0;
for (unwrappers::const_iterator q = m_unwrappers.begin(),
finish = m_unwrappers.end();
q != finish;
++q)
{
data = (*q)->can_convert(p);
if (data != 0)
{
body = *q;
break;
}
}
return std::make_pair(body,data);
}
wrapper_base* entry::wrapper() const
{
return m_wrapper;
}
entry::unwrappers::iterator entry::find(unwrapper_base const& x)
{
return std::find(m_unwrappers.begin(), m_unwrappers.end(), &x);
}
void entry::insert(unwrapper_base& x)
{
unwrappers::iterator p = this->find(x);
assert(p == m_unwrappers.end());
if (p != m_unwrappers.end())
{
throw std::runtime_error(
"trying to register unrapper which is already registered");
}
m_unwrappers.push_back(&x);
}
void entry::remove(unwrapper_base& x)
{
unwrappers::iterator p = find(x);
// Be sure we're not removing a converter which hasn't been
// registered.
assert(p != m_unwrappers.end());
if (p == m_unwrappers.end())
{
throw std::runtime_error(
"trying to unregister unwrapper which is not registered");
}
m_unwrappers.erase(p);
}
void entry::insert(wrapper_base& x)
{
assert(m_wrapper == 0); // we have a problem otherwise
if (m_wrapper != 0)
{
throw std::runtime_error(
"trying to register wrapper for a type which already has a registered wrapper");
}
m_wrapper = &x;
}
void entry::remove(wrapper_base& x)
{
assert(m_wrapper == &x);
if (m_wrapper != &x)
{
throw std::runtime_error(
"trying to unregister a wrapper which is not registered");
}
m_wrapper = 0;
}
void insert(wrapper_base& w)
{
# ifdef BOOST_PYTHON_TRACE
std::cout << "inserting wrapper for " << w.key() << std::endl;
# endif
find(w.key())->insert(w);
}
void insert(unwrapper_base& u)
{
# ifdef BOOST_PYTHON_TRACE
std::cout << "inserting unwrapper for " << u.key() << std::endl;
# endif
find(u.key())->insert(u);
}
void remove(wrapper_base& w)
{
find(w.key())->remove(w);
}
void remove(unwrapper_base& u)
{
find(u.key())->remove(u);
}
} // namespace registry
}}} // namespace boost::python::converter