// (C) Copyright Greg Landrum 2003-2006. // Derived from vector_indexing_suite.hpp, // which is (C) Copyright Joel de Guzman 2003. // 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. #ifndef LIST_INDEXING_SUITE_GL20042_HPP #define LIST_INDEXING_SUITE_GL20042_HPP #include #include #include #include #include "pyint_api.h" namespace boost { namespace python { // Forward declaration template class list_indexing_suite; namespace detail { template class final_list_derived_policies : public list_indexing_suite< Container, NoProxy, final_list_derived_policies> { }; } // namespace detail // The vector_indexing_suite class is a predefined indexing_suite derived // class for wrapping std::vector (and std::vector like) classes. It provides // all the policies required by the indexing_suite (see indexing_suite). // Example usage: // // class X {...}; // // ... // // class_ >("XVec") // .def(vector_indexing_suite >()) // ; // // By default indexed elements are returned by proxy. This can be // disabled by supplying *true* in the NoProxy template parameter. // template > class list_indexing_suite : public indexing_suite { public: typedef typename Container::value_type data_type; typedef typename Container::value_type key_type; typedef typename Container::size_type index_type; typedef typename Container::size_type size_type; typedef typename Container::iterator iterator_type; static typename mpl::if_, data_type&, data_type>::type get_item(Container& container, index_type i) { iterator_type pos = moveToPos(container, i); return *pos; } static object get_slice(Container& container, index_type from, index_type to) { Container res; iterator_type beg = moveToPos(container, from); iterator_type end = moveToPos(container, to); std::copy(beg, end, res.begin()); return object(res); } static void set_item(Container& container, index_type i, data_type const& v) { iterator_type pos = moveToPos(container, i); *pos = v; } static void set_slice(Container& container, index_type from, index_type to, data_type const& v) { iterator_type beg = moveToPos(container, from); iterator_type end = moveToPos(container, to); container.erase(beg, end); // FIX: didn't we just invalidate this iterator? container.insert(beg, v); } template static void set_slice(Container& container, index_type from, index_type to, Iter first, Iter last) { iterator_type beg = moveToPos(container, from); iterator_type end = moveToPos(container, to); container.erase(beg, end); // FIX: didn't we just invalidate this iterator? container.insert(beg, first, last); } static void delete_item(Container& container, index_type i) { iterator_type pos = moveToPos(container, i); container.erase(pos); } static void delete_slice(Container& container, index_type from, index_type to) { iterator_type beg = moveToPos(container, from); iterator_type end = moveToPos(container, to); container.erase(beg, end); } static size_t size(Container& container) { return container.size(); } static bool contains(Container& container, key_type const& key) { return std::find(container.begin(), container.end(), key) != container.end(); } static index_type get_min_index(Container& container) { (void)container; return 0; } static index_type get_max_index(Container& container) { return container.size(); } static bool compare_index(Container& container, index_type a, index_type b) { (void)container; return a < b; } static void append(Container& container, data_type const& v) { container.push_back(v); } template static void extend(Container& container, Iter first, Iter last) { container.insert(container.end(), first, last); } static index_type convert_index(Container& container, PyObject* i_) { extract i(i_); if (i.check()) { long index = i(); if (index < 0) { index += DerivedPolicies::size(container); } if (index >= long(container.size()) || index < 0) { PyErr_SetString(PyExc_IndexError, "Index out of range"); throw_error_already_set(); } return index; } PyErr_SetString(PyExc_TypeError, "Invalid index type"); throw_error_already_set(); return index_type(); } private: static iterator_type moveToPos(Container& container, index_type i) { iterator_type pos; index_type idx = 0; pos = container.begin(); while (idx < i && pos != container.end()) { pos++; idx++; } if (pos == container.end()) { PyErr_SetObject(PyExc_IndexError, PyInt_FromLong(i)); python::throw_error_already_set(); } return pos; } }; } // namespace python } // namespace boost #endif