From c921e1fa05ae42ed7343dd1184fa36c75fa76949 Mon Sep 17 00:00:00 2001 From: Martin Nolte <nolte@mathematik.uni-freiburg.de> Date: Tue, 7 Nov 2017 16:17:40 +0100 Subject: [PATCH] [blockvector] enhance method __getitem__ to work on sequences --- bvector.hh | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/bvector.hh b/bvector.hh index 10c142636..a9a056867 100644 --- a/bvector.hh +++ b/bvector.hh @@ -66,6 +66,22 @@ namespace Dune copy( static_cast< const char * >( info.ptr ), info.shape.data(), info.strides.data(), v ); } + + + // blockVectorGetItem + // ------------------ + + template< class BlockVector > + inline static pybind11::object blockVectorGetItem ( const pybind11::object &vObj, BlockVector &v, typename BlockVector::size_type index ) + { + auto pos = v.find( index ); + if( pos == v.end() ) + throw pybind11::index_error( "Index " + std::to_string( index ) + " does not exist in block vector." ); + pybind11::object result = pybind11::cast( *pos, pybind11::return_value_policy::reference ); + pybind11::detail::keep_alive_impl( result, vObj ); + return result; + } + } // namespace detail @@ -98,13 +114,17 @@ namespace Dune cls.def( "copy", [] ( const BlockVector &self ) { return new BlockVector( self ); } ); - cls.def( "__getitem__", [] ( BlockVector &self, size_type index ) -> block_type & { - auto pos = self.find( index ); - if( pos != self.end() ) - return *pos; - else - throw pybind11::index_error(); - }, pybind11::return_value_policy::reference, pybind11::keep_alive< 0, 1 >() ); + cls.def( "__getitem__", [] ( const pybind11::object &self, size_type index ) { + return detail::blockVectorGetItem( self, pybind11::cast< BlockVector & >( self ), index ); + } ); + cls.def( "__getitem__", [] ( const pybind11::object &self, pybind11::iterable index ) { + BlockVector &v = pybind11::cast< BlockVector & >( self ); + pybind11::tuple refs( pybind11::len( index ) ); + std::size_t j = 0; + for( pybind11::handle i : index ) + refs[ j++ ] = detail::blockVectorGetItem( self, v, pybind11::cast< size_type >( i ) ); + return refs; + } ); cls.def( "__setitem__", [] ( BlockVector &self, size_type index, block_type value ) { auto pos = self.find( index ); -- GitLab