In my research code, I have a number of classes that act as wrappers for containers, and they provide begin
and end
functions. I want an easy way to provide a generator for looping over these embedded containers. Because of the way SWIG's STL wrappers work, it's not (easily?) possible to wrap a vector of pointers, and we'd like to avoid all the extra overhead those wrappers have anyway: all we need is a way to increment a pointer and to tell if it's at the end.
So, my solution is to create a thin wrapper for only the increment operator ++
, and extend the class with a function to return the "beginning" iterator and to check whether the iterator is at the end position.
For this particular instance, I have a class Mesh
that has methods for beginLeftBoundaryFaces
and endLeftBoundaryFaces
—which return STL vector iterators that point to a Face *
.
%inline %{ //! Thin wrapper for ONLY the increment operator void _bfiter_incr( std::vector<Face *>::const_iterator* iter ) { // increment the iterator ++(*iter); } %} %extend Mesh { %insert("python") %{ def left_boundary_faces(self): "A generator to iterate through boundary faces." faceIter = self._beginLeftBoundaryFaces() keepLooping = True while keepLooping == True: face = self._bfiter_dereference_Left( faceIter ) if face: _bfiter_incr( faceIter ) yield face else: keepLooping = False %} //! get the first element in the vector std::vector<Face *>::const_iterator* _beginLeftBoundaryFaces() { return new std::vector<Face *>::const_iterator( ($self->beginLeftBoundaryFaces()) ); } //! dereference the iterator; return NULL if at the end const Face* _bfiter_dereference_Left( const std::vector<Face *>::const_iterator* iter ) { // if at the end, return NULL if (*iter == ($self)->endLeftBoundaryFaces() ) { return NULL; } // otherwise, return the face to which this iterator points return **iter; } }
So now I can do:
for f in mesh.left_boundary_faces(): print f.area()
or, of course, anything else now that I'm using Python.
See further updates on the thin Python wrappers for C++ iterators.
14 comments:
Hi Seth,
I came across this blogpost while looking for ways to access C++ STL:vector elements from python through SWIG. I used your sample code to create a .i file for my project. In my case, 'left_maps' replaces 'left_boundary_faces'.
When I try to do 'for f in left_maps: print "me" ' in python, I get "NameError: global name 'left_maps' is not defined". Any ideas on how to resolve this?
-Matt
Hey Matt,
Good catch, this was an error on my part. `left_boundary_faces` is a method of the class `Mesh` that is actually a generator, so I should have said `mesh.left_boundary_faces()`.
However, rather than using this code for an STL vector, you might consider using SWIG's built-in implementation with `%include `.
Hi Seth,
I appreciate the quick response. After putting in your fix, I get "Attribute Error: 'MapSet' has no attribute 'left_maps' ". ('MapSet' is analogous to 'Mesh' in your example)
Also, could you elaborate on what you said about using the built-in implementation using '%include' or give me a pointer to some documentation on it? My understanding after reading your post was that there is no easy way wrap STL:vectors in SWIG.
Thanks.
-Matt
Matt:
Sorry, the `%include <std_vector.i>` got eaten by the HTML parser. Take a look at the SWIG documentation. I only meant that wrapping arbitrary iterators was difficult; wrapping the built-in STL classes is easy with SWIG's functionality. If this doesn't answer your question, perhaps you could email me your code and some explanation. My email link is under the "About me" section.
Nice Post. Keep sharing more and more SEO Training
Java Training
python Training
Salesforce Training
Tableau Training
AWS training
Dot Net Training
DevOps Training
Selenium Training
kayseriescortu.com - alacam.org - xescortun.com
Smm panel
Smm panel
iş ilanları
instagram takipçi satın al
hirdavatciburada.com
beyazesyateknikservisi.com.tr
servis
tiktok jeton hilesi
en son çıkan perde modelleri
nft nasıl alınır
lisans satın al
en son çıkan perde modelleri
uc satın al
yurtdışı kargo
özel ambulans
minecraft premium
Good content. You write beautiful things.
korsan taksi
mrbahis
sportsbet
vbet
vbet
taksi
mrbahis
hacklink
hacklink
Good text Write good content success. Thank you
kralbet
tipobet
betmatik
kibris bahis siteleri
slot siteleri
betpark
poker siteleri
mobil ödeme bahis
Renting a car is usually a less-than-exciting experience when traveling. Getting the keys to a bland four door is nothing to write home about. What many do not realize is that any vacation or business trip can be an adventure with a car hire. Luxury Car Rental Ahmedabad
Car rental services Ahmedabad
mecidiyeköy
sakarya
istanbul
kayseri
ordu
XWF
شركة تنظيف مسابح بجازان ePfwRolgAa
شركة مكافحة حشرات بالخبر yrSmbhW3ty
Post a Comment