6 #ifndef INDEXING_SUITE_DETAIL_JDG20036_HPP 
    7 # define INDEXING_SUITE_DETAIL_JDG20036_HPP 
    9 # include <boost/python/extract.hpp> 
   10 # include <boost/scoped_ptr.hpp> 
   11 # include <boost/get_pointer.hpp> 
   12 # include <boost/detail/binary_search.hpp> 
   13 # include <boost/numeric/conversion/cast.hpp> 
   14 # include <boost/type_traits/is_pointer.hpp> 
   19 namespace boost { 
namespace python { 
namespace detail {
 
   22 #define BOOST_PYTHON_INDEXING_CHECK_INVARIANT 
   24 #define BOOST_PYTHON_INDEXING_CHECK_INVARIANT check_invariant() 
   27     template <
class Proxy>
 
   28     struct compare_proxy_index
 
   34         template <
class Index>
 
   37             typedef typename Proxy::policies_type policies_type;
 
   38             Proxy& proxy = extract<Proxy&>(prox)();
 
   39             return policies_type::
 
   40                 compare_index(proxy.get_container(), proxy.get_index(), i);
 
   53     template <
class Proxy>
 
   59         typedef typename std::vector<PyObject*>::iterator 
iterator;
 
   67             return boost::detail::lower_bound(
 
   68                 proxies.begin(), proxies.end(), 
 
   77                 iter != proxies.end(); ++iter)
 
   79                 if (&extract<Proxy&>(*iter)() == &proxy)
 
   94                 first_proxy(extract<Proxy&>(prox)().get_index()), prox);
 
  114             extract<Proxy&> 
p(*iter);
 
  116             if (iter != proxies.end() && 
p().get_index() == i)
 
  118                 extract<Proxy&> 
p(*iter);
 
  140             typename std::vector<PyObject*>::size_type 
len)
 
  157                 if (extract<Proxy&>(*iter)().get_index() > to)
 
  162                 extract<Proxy&> 
p(*iter);
 
  166             typename std::vector<PyObject*>::size_type 
 
  167                 offset = left-proxies.begin();
 
  168             proxies.erase(left, right);
 
  169             right = proxies.begin()+offset;
 
  171             while (right != proxies.end())
 
  173                 typedef typename Proxy::container_type::difference_type difference_type;
 
  174                 extract<Proxy&> 
p(*right);
 
  176                     extract<Proxy&>(*right)().get_index() 
 
  177                     - (difference_type(to) - from - len)
 
  193             if (iter != proxies.end()
 
  194                 && extract<Proxy&>(*iter)().get_index() == i)
 
  203         typename std::vector<PyObject*>::size_type 
 
  208             return proxies.size();
 
  215         check_invariant()
 const 
  219                 if ((*i)->ob_refcnt <= 0)
 
  221                     PyErr_SetString(PyExc_RuntimeError, 
 
  222                         "Invariant: Proxy vector in an inconsistent state");
 
  223                     throw_error_already_set();
 
  226                 if (i+1 != proxies.end())
 
  228                     if (extract<Proxy&>(*(i+1))().get_index() ==
 
  229                         extract<Proxy&>(*(i))().get_index())
 
  231                         PyErr_SetString(PyExc_RuntimeError, 
 
  232                             "Invariant: Proxy vector in an inconsistent state (duplicate proxy)");
 
  233                         throw_error_already_set();
 
  240         std::vector<PyObject*> proxies;
 
  248     template <
class Proxy, 
class Container>
 
  253         typedef std::map<Container*, proxy_group<Proxy> > 
links_t;
 
  260             typename links_t::iterator r = links.find(&proxy.get_container());
 
  261             if (r != links.end())
 
  263                 r->second.remove(proxy);
 
  264                 if (r->second.size() == 0)
 
  270         add(PyObject* prox, Container& container)
 
  273             links[&container].add(prox);
 
  276         template <
class NoSlice>
 
  280             typename links_t::iterator r = links.find(&container);
 
  281             if (r != links.end())
 
  283                 r->second.erase(i, no_slice);
 
  284                 if (r->second.size() == 0)
 
  293             typename links_t::iterator r = links.find(&container);
 
  294             if (r != links.end())
 
  296                 r->second.erase(from, to);
 
  297                 if (r->second.size() == 0)
 
  304             Container& container, 
 
  314             typename links_t::iterator r = links.find(&container);
 
  315             if (r != links.end())
 
  317                 r->second.replace(from, to, len);
 
  318                 if (r->second.size() == 0)
 
  329             typename links_t::iterator r = links.find(&container);
 
  330             if (r != links.end())
 
  331                 return r->second.find(i);
 
  351     template <
class Container, 
class Index, 
class Policies>
 
  352     class container_element
 
  365             , container(container)
 
  372           , container(ce.container)
 
  405                 container = object(); 
 
  418             return extract<Container&>(container)();
 
  448         scoped_ptr<element_type> ptr;
 
  455         , 
class DerivedPolicies
 
  456         , 
class ContainerElement
 
  459     struct no_proxy_helper
 
  466         template <
class DataType> 
 
  470             return object(ptr(p));
 
  473         template <
class DataType> 
 
  484                 DerivedPolicies::get_item(
 
  485                     container.get(), DerivedPolicies::
 
  486                         convert_index(container.get(), i))
 
  487               , is_pointer<BOOST_DEDUCED_TYPENAME Container::value_type>()
 
  493             Container& container, Index from, 
 
  498         template <
class NoSlice>
 
  501             Container& container, Index i, NoSlice no_slice)
 
  513         , 
class DerivedPolicies
 
  514         , 
class ContainerElement
 
  522             register_ptr_to_python<ContainerElement>();
 
  529             Index idx = DerivedPolicies::convert_index(container.get(), i);
 
  531             if (PyObject* shared = 
 
  532                 ContainerElement::get_links().find(container.get(), idx))
 
  534                 handle<> h(python::borrowed(shared));
 
  539                 object prox(ContainerElement(container.source(), idx));
 
  541                     get_links().add(prox.ptr(), container.get());
 
  548             Container& container, Index from, 
 
  551             ContainerElement::get_links().replace(container, from, to, n);
 
  554         template <
class NoSlice>
 
  557             Container& container, Index i, NoSlice no_slice)
 
  559             ContainerElement::get_links().erase(container, i, no_slice);
 
  564             Container& container, Index from, Index to)
 
  566             ContainerElement::get_links().erase(container, from, to);
 
  572         , 
class DerivedPolicies
 
  584             return DerivedPolicies::get_slice(container, from, to);
 
  589             Container& container, PySliceObject* slice, Index& from_, Index& to_)
 
  591             if (Py_None != slice->step) {
 
  592                 PyErr_SetString( PyExc_IndexError, 
"slice step size not supported.");
 
  593                 throw_error_already_set();
 
  596             Index min_index = DerivedPolicies::get_min_index(container);
 
  597             Index max_index = DerivedPolicies::get_max_index(container);
 
  599             if (Py_None == slice->start) {
 
  603                 long from = extract<long>( slice->start);
 
  608                 from_ = boost::numeric_cast<Index>(from);
 
  609                 if (from_ > max_index) 
 
  613             if (Py_None == slice->stop) {
 
  617                 long to = extract<long>( slice->stop);
 
  622                 to_ = boost::numeric_cast<Index>(to);
 
  634             extract<Data&> elem(v);
 
  638                 ProxyHandler::base_replace_indexes(container, from, to, 1);
 
  639                 DerivedPolicies::set_slice(container, from, to, elem());
 
  644                 extract<Data> elem(v);
 
  647                     ProxyHandler::base_replace_indexes(container, from, to, 1);
 
  648                     DerivedPolicies::set_slice(container, from, to, elem());
 
  653                     handle<> l_(python::borrowed(v));
 
  656                     std::vector<Data> temp;
 
  657                     for (
int i = 0; i < l.attr(
"__len__")(); i++)
 
  660                         extract<Data const&> 
x(elem);
 
  669                             extract<Data> 
x(elem);
 
  676                                 PyErr_SetString(PyExc_TypeError, 
 
  677                                     "Invalid sequence element");
 
  678                                 throw_error_already_set();
 
  683                     ProxyHandler::base_replace_indexes(container, from, to, 
 
  684                         temp.end()-temp.begin());
 
  685                     DerivedPolicies::set_slice(container, from, to, 
 
  686                         temp.begin(), temp.end());
 
  696             ProxyHandler::base_erase_indexes(container, from, to);
 
  697             DerivedPolicies::delete_slice(container, from, to);
 
  703         , 
class DerivedPolicies
 
  708     struct no_slice_helper
 
  713             PyErr_SetString(PyExc_RuntimeError, 
"Slicing not supported");
 
  714             throw_error_already_set();
 
  737 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP 
  741     template <
class Container, 
class Index, 
class Policies>
 
  742     inline typename Policies::data_type* 
 
  744         python::detail::container_element<Container, Index, Policies> 
const& 
p)
 
  750 #ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP 
  759 #endif // INDEXING_SUITE_DETAIL_JDG20036_HPP 
container_element< Container, Index, Policies > self_t
 
static void base_delete_slice(Container &container, PySliceObject *slice)
 
Proxy::index_type index_type
 
static void register_container_element()
 
bool operator()(PyObject *prox, Index i) const 
 
void replace(Container &container, index_type from, index_type to, index_type len)
 
std::vector< PyObject * >::const_iterator const_iterator
 
element_type * get() const 
 
void add(PyObject *prox, Container &container)
 
Policies::data_type * get_pointer(python::detail::container_element< Container, Index, Policies > const &p)
 
static void base_set_slice(Container &container, PySliceObject *slice, PyObject *v)
 
proxy_group< self_t > links_type
 
static void base_erase_index(Container &container, Index i, NoSlice no_slice)
 
container_element(container_element const &ce)
 
void erase(index_type from, index_type to)
 
Policies::data_type element_type
 
void erase(Container &container, index_type i, NoSlice no_slice)
 
static object base_get_item_helper(DataType const &x, mpl::false_)
 
element_type & operator*() const 
 
static proxy_links< self_t, Container > & get_links()
 
PyObject * find(index_type i)
 
void erase(index_type i, mpl::true_)
 
static void base_erase_indexes(Container &container, Index from, Index to)
 
static void base_set_slice(Container &container, PySliceObject *slice, PyObject *v)
 
static void slicing_not_suported()
 
static void base_erase_index(Container &container, Index i, NoSlice no_slice)
 
void erase(Container &container, index_type from, index_type to)
 
static void base_replace_indexes(Container &container, Index from, Index to, Index n)
 
static void base_erase_indexes(Container &container, Index from, Index to)
 
#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT
 
container_element(object container, Index index)
 
void erase(index_type i, mpl::false_)
 
std::vector< PyObject * >::iterator iterator
 
static void base_delete_slice(Container &container, PySliceObject *slice)
 
static object base_get_item_helper(DataType const &p, mpl::true_)
 
iterator first_proxy(index_type i)
 
static object base_get_item_(back_reference< Container & > const &container, PyObject *i)
 
static void base_replace_indexes(Container &container, Index from, Index to, Index n)
 
static object base_get_slice(Container &container, PySliceObject *slice)
 
PyObject * find(Container &container, index_type i)
 
Container & get_container() const 
 
void replace(index_type from, index_type to, typename std::vector< PyObject * >::size_type len)
 
std::map< Container *, proxy_group< Proxy > > links_t
 
static void base_get_slice_data(Container &container, PySliceObject *slice, Index &from_, Index &to_)
 
std::vector< PyObject * >::size_type size() const 
 
static void register_container_element()
 
static object base_get_item_(back_reference< Container & > const &container, PyObject *i)
 
Proxy::policies_type policies_type
 
Proxy::index_type index_type
 
static object base_get_slice(Container &container, PySliceObject *slice)