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)