diff --git a/include/boost/python/indexing/detail/indexing_suite_detail.hpp b/include/boost/python/indexing/detail/indexing_suite_detail.hpp index da7ec576..9ba9eecd 100644 --- a/include/boost/python/indexing/detail/indexing_suite_detail.hpp +++ b/include/boost/python/indexing/detail/indexing_suite_detail.hpp @@ -14,6 +14,12 @@ # include namespace boost { namespace python { namespace detail { + +#if defined(NDEBUG) +#define CHECK_INVARIANT +#else +#define CHECK_INVARIANT check_invariant() +#endif template struct compare_proxy_index @@ -43,6 +49,7 @@ namespace boost { namespace python { namespace detail { { public: + typedef typename std::vector::const_iterator const_iterator; typedef typename std::vector::iterator iterator; typedef typename Proxy::index_type index_type; typedef typename Proxy::policies_type policies_type; @@ -69,21 +76,26 @@ namespace boost { namespace python { namespace detail { break; } } + CHECK_INVARIANT; } void add(PyObject* prox) { + CHECK_INVARIANT; // Add a proxy proxies.insert( first_proxy(extract(prox)().get_index()), prox); + CHECK_INVARIANT; } void erase(index_type from, index_type to) { + CHECK_INVARIANT; // Erase all proxies with indexes from..to replace(from, to, 0); + CHECK_INVARIANT; } void @@ -92,6 +104,7 @@ namespace boost { namespace python { namespace detail { index_type to, typename std::vector::size_type len) { + CHECK_INVARIANT; // Erase all proxies with indexes from..to. // Adjust the displaced indexes such that the // final effect is that we have inserted *len* @@ -126,30 +139,53 @@ namespace boost { namespace python { namespace detail { extract(*right)().get_index(), from, to, len)); ++right; } + CHECK_INVARIANT; } PyObject* find(index_type i) { + CHECK_INVARIANT; // Find the proxy with *exact* index i. // Return 0 (null) if no proxy with the // given index is found. iterator iter = first_proxy(i); - if (iter != proxies.end() + if (iter != proxies.end() && extract(*iter)().get_index() == i) + { + CHECK_INVARIANT; return *iter; + } + CHECK_INVARIANT; return 0; } typename std::vector::size_type size() const { + CHECK_INVARIANT; // How many proxies are there so far? return proxies.size(); } private: - + +#if !defined(NDEBUG) + void + check_invariant() const + { + for (const_iterator i = proxies.begin(); i != proxies.end(); ++i) + { + if ((*i)->ob_refcnt <= 0) + { + PyErr_SetString(PyExc_RuntimeError, + "Invariant: Proxy vector in an inconsistent state"); + throw_error_already_set(); + } + } + } +#endif + std::vector proxies; }; diff --git a/include/boost/python/indexing/indexing_suite.hpp b/include/boost/python/indexing/indexing_suite.hpp index 0f3673ff..013b83dd 100644 --- a/include/boost/python/indexing/indexing_suite.hpp +++ b/include/boost/python/indexing/indexing_suite.hpp @@ -147,7 +147,12 @@ namespace boost { namespace python { if (PyObject* shared = container_element_t::get_links().find(container.get(), idx)) { - return extract(shared)(); +// return extract(shared)(); + + handle<> h(shared); + object result(h); + h.release(); + return result; } else { @@ -218,8 +223,8 @@ namespace boost { namespace python { { if (PySlice_Check(i)) { - base_set_slice(container, - reinterpret_cast(i), v); + base_set_slice(container, + reinterpret_cast(i), v); } else { @@ -343,6 +348,7 @@ namespace boost { namespace python { temp.end()-temp.begin(), no_proxy()); DerivedPolicies::set_slice(container, from, to, temp.begin(), temp.end()); + l_.release(); } } }