Library of Assembled Shared Sources
Python Iterators

Detailed Description

Exposing iterators to Python.

Lass provides three sets of building blocks to add iterator support to your Python exports:

  1. PyIteratorRange: the central C++ type that implements the Python Iterator protocol. It's used for all exported Python iterators from the bindings. It's Python type is _lass.PyIteratorRange and will be type-hinted as Iterator[Any].

    PyIteratorRange uses the pimpl idiom to hold an object that implements the impl::PyIteratorRangeImplBase interface to perform the actual C++ iteration.

    There's two common implementations of this interface:

    You can directly return a PyIteratorRange from your bindings, or you can use one of the convenience methods below.

  2. Two groups of macros:

    These older macros help you to define the __iter__ method for your class by directly returning a PyIteratorRange object.

  3. Range views:

    The benefit of using these is that they'll use the actual value-type in the type-hints instead of Any.

Data Structures

class  lass::python::impl::PyIteratorRangeImplBase
 begin of iterators More...
 
class  lass::python::impl::PyIteratorRangeImpl< Iterator >
 Implementation of PyIteratorRangeImplBase that iterates over a C++ iterator pair. More...
 
class  lass::python::impl::PyIndexIteratorRangeImpl< ValueType, SizeType >
 Implementation of PyIteratorRangeImplBase to iterate over a sequence by index. More...
 
class  lass::python::PyIteratorRange
 Python iterator object. More...
 
class  lass::python::ContainerRangeView< SelfType, ValueType >
 View that adapts a C++ Range (begin()/end()) to a PyIteratorRange. More...
 
class  lass::python::MemberRangeView< SelfType, ValueType, GetIterator >
 View that adapts member iterator accessors to a PyIteratorRange. More...
 
class  lass::python::FreeRangeView< SelfType, ValueType, GetIterator >
 View that adapts free iterator accessors to a PyIteratorRange. More...
 
class  lass::python::IndexedRangeView< SelfType, ValueType, SizeType, AtMethod, SizeMethod >
 View that adapts index-based element access to a PyIteratorRange. More...
 
class  lass::python::FreeIndexedRangeView< SelfType, ValueType, SizeType, AtFunc, SizeFunc >
 View that adapts index-based element access to a PyIteratorRange. More...
 
struct  lass::python::PyExportTraits< PyIteratorRange * >
 Passes a PyIteratorRange to Python. More...
 
struct  lass::python::PyExportTraits< ContainerRangeView< SelfType, ValueType > >
 Builds a PyIteratorRange from a ContainerRangeView. More...
 
struct  lass::python::PyExportTraits< MemberRangeView< SelfType, ValueType, GetIterator > >
 Builds a PyIteratorRange from a MemberRangeView. More...
 
struct  lass::python::PyExportTraits< FreeRangeView< SelfType, ValueType, GetIterator > >
 Builds a PyIteratorRange from a FreeRangeView. More...
 
struct  lass::python::PyExportTraits< IndexedRangeView< SelfType, ValueType, SizeType, AtMethod, SizeMethod > >
 Builds a PyIteratorRange from a IndexedRangeView. More...
 
struct  lass::python::PyExportTraits< FreeIndexedRangeView< SelfType, ValueType, SizeType, AtFunc, SizeFunc > >
 Builds a PyIteratorRange from a FreeIndexedRangeView. More...
 

Macros

#define PY_CLASS_ITERFUNC_EX(t_cppClass, i_cppBegin, i_cppEnd, s_doc, i_dispatcher)
 Exports a set of C++ iterators to Python.
 
#define PY_CLASS_ITERFUNC_DOC(i_cppClass, i_cppBegin, icppEnd, s_doc)
 convenience macro, wraps PY_CLASS_ITERFUNC_EX with i_dispatcher = lassPyImpl_method_ ## i_cppClass ## LINE.
 
#define PY_CLASS_ITERFUNC(i_cppClass, i_cppBegin, icppEnd)
 convenience macro, wraps PY_CLASS_ITERFUNC_DOC with s_doc = 0.
 
#define PY_CLASS_FREE_ITERFUNC_DOC(i_cppClass, i_cppBegin, icppEnd, s_doc)
 convenience macro, wraps PY_CLASS_ITERFUNC_EX with i_dispatcher = lassPyImpl_method_ ## i_cppClass ## LINE.
 
#define PY_CLASS_FREE_ITERFUNC(i_cppClass, i_cppBegin, icppEnd)
 convenience macro, wraps PY_CLASS_ITERFUNC_DOC with s_doc = 0.
 

Functions

template<typename T>
auto makeContainerRangeView (const ShadoweePtr< T > &self)
 Returns a ContainerRangeView iterating over self->begin() to self->end()
 
template<typename T, typename GetIterator>
auto makeMemberRangeView (const ShadoweePtr< T > &self, GetIterator begin, GetIterator end)
 Returns a MemberRangeView iterating over (self->*begin)() and (self->*end)()
 
template<typename T, typename GetIterator>
auto makeMemberRangeViewFactory (GetIterator begin, GetIterator end)
 Returns a callable creating a MemberRangeView iterating over (self->*begin)() to (self->*end)()
 
template<typename T, typename GetIterator>
auto makeFreeRangeView (const ShadoweePtr< T > &self, GetIterator begin, GetIterator end)
 Returns a FreeRangeView iterating over begin(*self) and end(*self)
 
template<typename T, typename GetIterator>
auto makeFreeRangeViewFactory (GetIterator begin, GetIterator end)
 Returns a callable creating a FreeRangeView iterating over begin(*self) and end(*self)
 
template<typename T, typename AtMethod, typename SizeMethod>
auto makeIndexedRangeView (const ShadoweePtr< T > &self, AtMethod atMethod, SizeMethod sizeMethod)
 Returns a IndexedRangeView iterating over (self->*atMethod)(index) for index in 0 to (self->*sizeMethod)() - 1
 
template<typename T, typename AtMethod, typename SizeMethod>
auto makeIndexedRangeViewFactory (AtMethod atMethod, SizeMethod sizeMethod)
 Returns callable that creates a IndexedRangeView iterating over (self->*atMethod)(index) for index in 0 to (self->*sizeMethod)() - 1
 
template<typename T, typename AtFunc, typename SizeFunc>
auto makeFreeIndexedRangeView (const ShadoweePtr< T > &self, AtFunc atFunc, SizeFunc sizeFunc)
 Returns a FreeIndexedRangeView iterating over atFunc(*self, index) for index in 0 to sizeFunc(*self) - 1
 
template<typename T, typename AtFunc, typename SizeFunc>
auto makeFreeIndexedRangeViewFactory (AtFunc atFunc, SizeFunc sizeFunc)
 Returns a callable that creates FreeIndexedRangeView iterating over atFunc(*self, index) for index in 0 to sizeFunc(*self) - 1
 

Macro Definition Documentation

◆ PY_CLASS_ITERFUNC_EX

#define PY_CLASS_ITERFUNC_EX ( t_cppClass,
i_cppBegin,
i_cppEnd,
s_doc,
i_dispatcher )
Value:
lass::python::PyIteratorRange* LASS_CONCATENATE_3( lassPyImpl_method_, i_dispatcher, itDispatch1 ) (const ::lass::python::impl::ShadowTraits< t_cppClass >::TCppClassPtr& iObj) { \
return new lass::python::PyIteratorRange(iObj->i_cppBegin (), iObj->i_cppEnd ()); } \
PY_CLASS_FREE_METHOD_NAME_DOC( t_cppClass, LASS_CONCATENATE_3( lassPyImpl_method_, i_dispatcher, itDispatch1 ), lass::python::methods::_iter_, s_doc)
Python iterator object.
const lass::python::impl::IterSlot _iter_("__iter__", Py_tp_iter)
__iter__ method (iterator)

Exports a set of C++ iterators to Python.

Parameters
t_cppClassthe C++ class you're exporting an iterator of
i_cppBeginthe name of the method in C++ that provides the beginning of the exported iterator range
i_cppEndthe name of the method in C++ that provides the beginning of the exported iterator range
s_docdocumentation of method as shown in Python (zero terminated C string)
i_dispatcherA unique name of the static C++ dispatcher function to be generated. This name will be used for the names of automatic generated variables and functions and should be unique per exported C++ class/method pair.

Invoke this macro to export an iterator range to python. The returned object will support the iterator protocol by default. The class generating the export will also support the iterator generator protocol.

Note
the documentation of the Python method will be the s_doc of the first exported overload.
the iterator stability of C++ is inherited into Python. It is the responsibility of the user of these macro's to ensure or document the stability of the iterators.
Although you can overload the iter slot it is probably of little use. The last assigned function will return the iterator. It could be useful if some of the overloaded function throw, in that case the first non-throwing (if any) function will be chosen.
// foo.h
class Foo
{
PY_HEADER(python::PyObjectPlus)
public:
void barA(int a);
std::vector<int>::const_iterator begin() const { return vector_.begin(); }
std::vector<int>::const_iterator end() const { return vector_.end(); }
private:
std::vector<int> vector_;
};
std::vector<int> temp;
std::vector<int>::const_iterator freeBegin(Foo& iObj) { return temp.begin(); }
std::vector<int>::const_iterator freeEnd(Foo& iObj) { return temp.end(); }
// foo.cpp
PY_CLASS_ITERFUNC_EX(Foo, begin, end, 0, foo_bar_a)
PY_CLASS_FREE_ITERFUNC_EX(Foo, begin, end, 0, foo_bar_a)
#define PY_DECLARE_CLASS(i_cppClass)
Declare a Python class with automatic name and no documentation.
#define PY_CLASS_ITERFUNC_EX(t_cppClass, i_cppBegin, i_cppEnd, s_doc, i_dispatcher)
Exports a set of C++ iterators to Python.
#define PY_HEADER(t_parentClass)
Place as first line of your Pythonized class.

Definition at line 868 of file pyiteratorrange.h.

Function Documentation

◆ makeContainerRangeView()

template<typename T>
auto makeContainerRangeView ( const ShadoweePtr< T > & self)
related

Returns a ContainerRangeView iterating over self->begin() to self->end()

It automatically deduces ValueType from the container's iterators.

This function can be used as a free method:

#define PY_CLASS_FREE_METHOD_NAME(i_cppClass, f_cppFreeMethod, s_methodName)
Export a C/C++ free function as a Python method with custom name (no documentation).
auto makeContainerRangeView(const ShadoweePtr< T > &self)
Returns a ContainerRangeView iterating over self->begin() to self->end()

Definition at line 285 of file pyiteratorrange.h.

References ContainerRangeView().

◆ makeMemberRangeViewFactory()

template<typename T, typename GetIterator>
auto makeMemberRangeViewFactory ( GetIterator begin,
GetIterator end )
related

Returns a callable creating a MemberRangeView iterating over (self->*begin)() to (self->*end)()

Can be used to create a free method:

PY_CLASS_FREE_METHOD_NAME(MyContainer, makeMemberRangeViewFactory<MyContainer>(&MyContainer::begin, &MyContainer::end), methods::_iter_);
auto makeMemberRangeViewFactory(GetIterator begin, GetIterator end)
Returns a callable creating a MemberRangeView iterating over (self->*begin)() to (self->*end)()

Definition at line 378 of file pyiteratorrange.h.

◆ makeFreeRangeViewFactory()

template<typename T, typename GetIterator>
auto makeFreeRangeViewFactory ( GetIterator begin,
GetIterator end )
related

Returns a callable creating a FreeRangeView iterating over begin(*self) and end(*self)

Can be used to create a free method:

auto makeFreeRangeViewFactory(GetIterator begin, GetIterator end)
Returns a callable creating a FreeRangeView iterating over begin(*self) and end(*self)

Definition at line 479 of file pyiteratorrange.h.

◆ makeIndexedRangeViewFactory()

template<typename T, typename AtMethod, typename SizeMethod>
auto makeIndexedRangeViewFactory ( AtMethod atMethod,
SizeMethod sizeMethod )
related

Returns callable that creates a IndexedRangeView iterating over (self->*atMethod)(index) for index in 0 to (self->*sizeMethod)() - 1

Can be used to create a free method:

PY_CLASS_FREE_METHOD_NAME(MyContainer, makeIndexedRangeViewFactory<MyContainer>(&MyContainer::operator[], &MyContainer::size), methods::_iter_);
auto makeIndexedRangeViewFactory(AtMethod atMethod, SizeMethod sizeMethod)
Returns callable that creates a IndexedRangeView iterating over (self->*atMethod)(index) for index in...

Definition at line 588 of file pyiteratorrange.h.

◆ makeFreeIndexedRangeViewFactory()

template<typename T, typename AtFunc, typename SizeFunc>
auto makeFreeIndexedRangeViewFactory ( AtFunc atFunc,
SizeFunc sizeFunc )
related

Returns a callable that creates FreeIndexedRangeView iterating over atFunc(*self, index) for index in 0 to sizeFunc(*self) - 1

Can be used to create a free method:

auto makeFreeIndexedRangeViewFactory(AtFunc atFunc, SizeFunc sizeFunc)
Returns a callable that creates FreeIndexedRangeView iterating over atFunc(*self, index) for index in...

Definition at line 696 of file pyiteratorrange.h.