diff --git a/include/boost/python/indexing/detail/indexing_suite_detail.hpp b/include/boost/python/indexing/detail/indexing_suite_detail.hpp index 1f7b8235..4f6dbb2c 100644 --- a/include/boost/python/indexing/detail/indexing_suite_detail.hpp +++ b/include/boost/python/indexing/detail/indexing_suite_detail.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include # include @@ -385,16 +386,17 @@ namespace boost { namespace python { namespace detail { Index index; }; - } // namespace detail + }} // namespace python::detail template inline typename Container::value_type* - get_pointer(detail::container_element const& p) + get_pointer( + python::detail::container_element const& p) { // Get the pointer of a container_element smart pointer return p.get(); } -}} // namespace boost::python +} // namespace boost #endif // INDEXING_SUITE_DETAIL_JDG20036_HPP diff --git a/include/boost/python/indexing/indexing_suite.hpp b/include/boost/python/indexing/indexing_suite.hpp index 014757c2..55c82deb 100644 --- a/include/boost/python/indexing/indexing_suite.hpp +++ b/include/boost/python/indexing/indexing_suite.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -120,17 +121,17 @@ namespace boost { namespace python { // Hook into the class_ generic visitation .def function register_ptr_to_python(); - typedef typename Container::iterator iterator; - iterator(Container::*begin_)() = &Container::begin; - iterator(Container::*end_)() = &Container::end; - cl .def("__len__", base_size) .def("__setitem__", &base_set_item) .def("__delitem__", &base_delete_item) .def("__getitem__", &base_get_item) .def("__contains__", &base_contains) - .def("__iter__", boost::python::range(begin_, end_)) + .def("__iter__", + iterator >()) + + .def("append", &base_append) + .def("extend", &base_extend) ; } @@ -398,6 +399,69 @@ namespace boost { namespace python { return false; } } + + static void + base_append(Container& container, PyObject* v) + { + extract elem(v); + // try if elem is an exact Element + if (elem.check()) + { + DerivedPolicies::append(container, elem()); + } + else + { + // try to convert elem to Element + extract elem(v); + if (elem.check()) + { + DerivedPolicies::append(container, elem()); + } + else + { + PyErr_SetString(PyExc_TypeError, + "Attempting to append an invalid type"); + throw_error_already_set(); + } + } + } + + static void + base_extend(Container& container, PyObject* v) + { + // v must be a list or some container + handle<> l_(borrowed(v)); + object l(l_); + + std::vector temp; + for (int i = 0; i < l.attr("__len__")(); i++) + { + object elem(l[i]); + extract x(elem); + // try if elem is an exact Element type + if (x.check()) + { + temp.push_back(x()); + } + else + { + // try to convert elem to Element type + extract x(elem); + if (x.check()) + { + temp.push_back(x()); + } + else + { + PyErr_SetString(PyExc_TypeError, + "Invalid list element"); + throw_error_already_set(); + } + } + } + + DerivedPolicies::extend(container, temp.begin(), temp.end()); + } static object get_slice(Container& container, Index from, Index to) diff --git a/include/boost/python/indexing/vector_indexing_suite.hpp b/include/boost/python/indexing/vector_indexing_suite.hpp index 4c7e2dff..e2c0d50c 100644 --- a/include/boost/python/indexing/vector_indexing_suite.hpp +++ b/include/boost/python/indexing/vector_indexing_suite.hpp @@ -143,6 +143,19 @@ namespace boost { namespace python { { return current - (difference_type(to) - from - len); } + + static void + append(Container& container, element_type const& v) + { + container.push_back(v); + } + + template + static void + extend(Container& container, Iter first, Iter last) + { + container.insert(container.end(), first, last); + } }; }} // namespace boost::python diff --git a/test/vector_indexing_suite.py b/test/vector_indexing_suite.py index e177aeea..063690e1 100644 --- a/test/vector_indexing_suite.py +++ b/test/vector_indexing_suite.py @@ -300,6 +300,31 @@ e >>> 12345 in v 0 +##################################################################### +# Show that iteration allows mutable access to the elements +##################################################################### +>>> v[:] = ['a','b','c','d','e'] # reset again +>>> for x in v: +... x.reset() +>>> print_xvec(v) +[ reset reset reset reset reset ] + +##################################################################### +# append +##################################################################### +>>> v[:] = ['a','b','c','d','e'] # reset again +>>> v.append('f') +>>> print_xvec(v) +[ a b c d e f ] + +##################################################################### +# extend +##################################################################### +>>> v[:] = ['a','b','c','d','e'] # reset again +>>> v.extend(['f','g','h','i','j']) +>>> print_xvec(v) +[ a b c d e f g h i j ] + ##################################################################### # END.... #####################################################################