at 18.03-beta 7.4 kB view raw
1# HG changeset patch 2# User Lukas Heinrich <lukas.heinrich@gmail.com> 3# Date 1430606843 14400 4# Node ID 325f89b7b72922e9add9ca9dd0f7ca4a6c83bf00 5# Parent e4fd953257e0d38511f2177de7ffaef662358af2 6add incoming/outgoing generators for GenVertex 7 8diff --git a/hepmc/generators.i b/hepmc/generators.i 9new file mode 100644 10--- /dev/null 11+++ b/hepmc/generators.i 12@@ -0,0 +1,171 @@ 13+/*! 14+ * \file generators.i 15+ * \author Seth R. Johnson 16+ * \brief Define generator/iterator for any type 17+ 18+Example: 19+\code 20+ SETUP_GENERATOR( std::vector<Cell>::const_iterator ) 21+ ADD_GENERATOR( Mesh, cells, 22+ std::vector<Cell>::const_iterator, Cell, beginCells, endCells) 23+\endcode 24+would be a method to add a \c cells generator method method to the Python class 25+\c Mesh, when the C++ class \c Mesh has a \c std::vector<Cell> accessed through 26+methods \c beginCells and \c endCells. 27+ 28+The macro \c ADD_GENERATOR_P would be if the underlying storage were \c 29+std::vector<Cell*> instead. 30+ 31+Alternatively, for containers of regular objects that provide \c begin(), \c end(), and \c const_iterator, you can use the \c ADD_CONTAINER_ITERATOR macro: 32+\code 33+ADD_CONTAINER_ITERATOR( QuadratureSet ) 34+\endcode 35+ 36+\section License 37+ 38+Copyright (c) 2010, Seth R. Johnson 39+All rights reserved. 40+ 41+Redistribution and use in source and binary forms, with or without 42+modification, are permitted provided that the following conditions are met: 43+ * Redistributions of source code must retain the above copyright notice, this 44+ list of conditions and the following disclaimer. 45+ * Redistributions in binary form must reproduce the above copyright notice, 46+ this list of conditions and the following disclaimer in the documentation 47+ and/or other materials provided with the distribution. 48+ * Neither the name of the this project nor the names of its contributors 49+ may be used to endorse or promote products derived from this software 50+ without specific prior written permission. 51+ 52+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 53+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 54+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 55+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 56+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 57+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 58+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 59+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 61+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62+ 63+ This material is based upon work supported under a National Science 64+ Foundation Graduate Research Fellowship. Any opinions, findings, conclusions 65+ or recommendations expressed in this publication are those of the author 66+ and do not necessarily reflect the views of the National Science 67+ Foundation. 68+*/ 69+#ifndef tools_SWIG_generators_i 70+#define tools_SWIG_generators_i 71+/*----------------------------------------------------------------------------*/ 72+ 73+// Add a Python class to provide iterator objects 74+%insert("python") %{ 75+class GenericIterator: 76+ def __init__(self, begin_iter_method, deref_method, incr_method): 77+ self.it = begin_iter_method() 78+ self.incr = incr_method 79+ self.deref = deref_method 80+ 81+ def __iter__(self): 82+ return self 83+ 84+ def next(self): 85+ obj = self.deref( self.it ) 86+ if obj is not None: 87+ self.incr( self.it ) 88+ return obj 89+ else: 90+ raise StopIteration 91+%} 92+ 93+//============== GENERIC GENERATOR/ITERATOR WRAPPER SUPPORT ============ 94+//! Thin wrapper for incrementing a certain type of iterator 95+// only need to define once per iterator type, and we can use the same name 96+// thanks to overloading (even though this may decrease efficiency) 97+%define SETUP_GENERATOR( ITERATOR... ) 98+%inline %{ 99+void _iter_incr( ITERATOR* iter ) 100+{ 101+ ++(*iter); 102+} 103+%} 104+%enddef 105+ 106+/*----------------------------------------------------------------------------*/ 107+// Internal method for adding common parts of the generator 108+%define PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN ) 109+ %extend CLASS { 110+%insert("python") %{ 111+ def PYMETHOD(self): 112+ "Returns an iterator for PYMETHOD." 113+ return GenericIterator( 114+ self._begin_ ## PYMETHOD, 115+ self._deref_ ## PYMETHOD, 116+ _iter_incr 117+ ) 118+%} 119+// get the first element in the vector 120+ITERATOR* _begin_ ## PYMETHOD() 121+{ 122+ return new ITERATOR( ($self)->CBEGIN() ); 123+} 124+ } 125+%enddef 126+/*----------------------------------------------------------------------------*/ 127+// If the dereferenced iterator is an object 128+%define ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, RVALUE, CBEGIN, CEND ) 129+ 130+// add the python and begin method 131+PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN ) 132+ 133+ %extend CLASS { 134+//! Dereference the iterator; return NULL if at the end 135+const RVALUE* _deref_ ## PYMETHOD ## ( const ITERATOR* iter ) 136+{ 137+ // if at the end, return NULL 138+ if (*iter == ($self)->CEND() ) { 139+ return NULL; 140+ } 141+ // otherwise, return the POINTER to the dereferenced iterator 142+ return &(**iter); 143+} 144+ } 145+%enddef 146+/*----------------------------------------------------------------------------*/ 147+// If the dereferenced iterator is a pointer 148+%define ADD_GENERATOR_P( CLASS, PYMETHOD, ITERATOR, RVALUE, CBEGIN, CEND ) 149+ 150+// add the python and begin method 151+PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN ) 152+ 153+ %extend CLASS { 154+//! Dereference the iterator; return NULL if at the end 155+const RVALUE* _deref_ ## PYMETHOD ## ( const ITERATOR* iter ) 156+{ 157+ // if at the end, return NULL 158+ if (*iter == ($self)->CEND() ) { 159+ return NULL; 160+ } 161+ // otherwise, return the dereferenced iterator (a pointer) 162+ return **iter; 163+} 164+ } 165+%enddef 166+/*----------------------------------------------------------------------------*/ 167+//! For a regular container with "begin" and "end" and "size" 168+%define ADD_CONTAINER_ITERATOR( CLASS ) 169+ SETUP_GENERATOR( CLASS::const_iterator ); 170+ ADD_GENERATOR( CLASS, __iter__, 171+ CLASS ## ::const_iterator, CLASS ## ::value_type, 172+ begin, end) 173+ %extend CLASS { 174+ %insert("python") %{ 175+ def __len__(self): 176+ return self.size() 177+ %} 178+ } 179+%enddef 180+ 181+/*============================================================================*/ 182+#endif 183+ 184diff --git a/hepmc/hepmcwrap.i b/hepmc/hepmcwrap.i 185--- a/hepmc/hepmcwrap.i 186+++ b/hepmc/hepmcwrap.i 187@@ -1,5 +1,7 @@ 188 %module hepmcwrap 189 190+%include generators.i 191+ 192 %{ 193 #include "HepMC/GenEvent.h" 194 #include "HepMC/GenVertex.h" 195@@ -251,3 +253,9 @@ 196 return ss.str(); 197 } 198 } 199+ 200+SETUP_GENERATOR( std::vector< HepMC::GenParticle* >::const_iterator ) 201+ADD_GENERATOR_P( HepMC::GenVertex, incoming, 202+std::vector< HepMC::GenParticle* >::const_iterator, HepMC::GenParticle, particles_in_const_begin, particles_in_const_end) 203+ADD_GENERATOR_P( HepMC::GenVertex, outgoing, 204+std::vector< HepMC::GenParticle* >::const_iterator, HepMC::GenParticle, particles_out_const_begin, particles_out_const_end)