205 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
# HG changeset patch
 | 
						|
# User Lukas Heinrich <lukas.heinrich@gmail.com>
 | 
						|
# Date 1430606843 14400
 | 
						|
# Node ID 325f89b7b72922e9add9ca9dd0f7ca4a6c83bf00
 | 
						|
# Parent  e4fd953257e0d38511f2177de7ffaef662358af2
 | 
						|
add incoming/outgoing generators for GenVertex
 | 
						|
 | 
						|
diff --git a/hepmc/generators.i b/hepmc/generators.i
 | 
						|
new file mode 100644
 | 
						|
--- /dev/null
 | 
						|
+++ b/hepmc/generators.i
 | 
						|
@@ -0,0 +1,171 @@
 | 
						|
+/*!
 | 
						|
+ * \file   generators.i
 | 
						|
+ * \author Seth R. Johnson
 | 
						|
+ * \brief  Define generator/iterator for any type
 | 
						|
+
 | 
						|
+Example:
 | 
						|
+\code
 | 
						|
+    SETUP_GENERATOR( std::vector<Cell>::const_iterator )
 | 
						|
+    ADD_GENERATOR( Mesh, cells,
 | 
						|
+    std::vector<Cell>::const_iterator, Cell, beginCells, endCells)
 | 
						|
+\endcode
 | 
						|
+would be a method to add a \c cells generator method method to the Python class
 | 
						|
+\c Mesh, when the C++ class \c Mesh has a \c std::vector<Cell> accessed through
 | 
						|
+methods \c beginCells and \c endCells.
 | 
						|
+
 | 
						|
+The macro \c ADD_GENERATOR_P would be if the underlying storage were \c
 | 
						|
+std::vector<Cell*> instead.
 | 
						|
+
 | 
						|
+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:
 | 
						|
+\code
 | 
						|
+ADD_CONTAINER_ITERATOR( QuadratureSet )
 | 
						|
+\endcode
 | 
						|
+
 | 
						|
+\section License
 | 
						|
+
 | 
						|
+Copyright (c) 2010, Seth R. Johnson
 | 
						|
+All rights reserved.
 | 
						|
+
 | 
						|
+Redistribution and use in source and binary forms, with or without
 | 
						|
+modification, are permitted provided that the following conditions are met:
 | 
						|
+ * Redistributions of source code must retain the above copyright notice, this
 | 
						|
+   list of conditions and the following disclaimer.
 | 
						|
+ * Redistributions in binary form must reproduce the above copyright notice,
 | 
						|
+   this list of conditions and the following disclaimer in the documentation
 | 
						|
+   and/or other materials provided with the distribution.
 | 
						|
+ * Neither the name of the this project nor the names of its contributors
 | 
						|
+   may be used to endorse or promote products derived from this software
 | 
						|
+   without specific prior written permission.
 | 
						|
+
 | 
						|
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
						|
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
						|
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
						|
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 | 
						|
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
						|
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
						|
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
						|
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
						|
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
						|
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
+
 | 
						|
+ This material is based upon work supported under a National Science
 | 
						|
+ Foundation Graduate Research Fellowship. Any opinions, findings, conclusions
 | 
						|
+ or recommendations expressed in this publication are those of the author
 | 
						|
+ and do not necessarily reflect the views of the National Science
 | 
						|
+ Foundation.
 | 
						|
+*/
 | 
						|
+#ifndef tools_SWIG_generators_i
 | 
						|
+#define tools_SWIG_generators_i
 | 
						|
+/*----------------------------------------------------------------------------*/
 | 
						|
+
 | 
						|
+// Add a Python class to provide iterator objects
 | 
						|
+%insert("python") %{
 | 
						|
+class GenericIterator:
 | 
						|
+    def __init__(self, begin_iter_method, deref_method, incr_method):
 | 
						|
+        self.it = begin_iter_method()
 | 
						|
+        self.incr   = incr_method
 | 
						|
+        self.deref  = deref_method
 | 
						|
+
 | 
						|
+    def __iter__(self):
 | 
						|
+        return self
 | 
						|
+
 | 
						|
+    def next(self):
 | 
						|
+        obj = self.deref( self.it )
 | 
						|
+        if obj is not None:
 | 
						|
+            self.incr( self.it )
 | 
						|
+            return obj
 | 
						|
+        else:
 | 
						|
+            raise StopIteration
 | 
						|
+%}
 | 
						|
+
 | 
						|
+//============== GENERIC GENERATOR/ITERATOR WRAPPER SUPPORT ============
 | 
						|
+//! Thin wrapper for incrementing a certain type of iterator
 | 
						|
+// only need to define once per iterator type, and we can use the same name
 | 
						|
+// thanks to overloading (even though this may decrease efficiency)
 | 
						|
+%define SETUP_GENERATOR( ITERATOR... )
 | 
						|
+%inline %{
 | 
						|
+void _iter_incr( ITERATOR* iter )
 | 
						|
+{
 | 
						|
+    ++(*iter);
 | 
						|
+}
 | 
						|
+%}
 | 
						|
+%enddef
 | 
						|
+
 | 
						|
+/*----------------------------------------------------------------------------*/
 | 
						|
+// Internal method for adding common parts of the generator
 | 
						|
+%define PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN )
 | 
						|
+    %extend CLASS {
 | 
						|
+%insert("python") %{
 | 
						|
+    def PYMETHOD(self):
 | 
						|
+        "Returns an iterator for PYMETHOD."
 | 
						|
+        return GenericIterator(
 | 
						|
+                self._begin_ ## PYMETHOD,
 | 
						|
+                self._deref_ ## PYMETHOD,
 | 
						|
+                _iter_incr
 | 
						|
+                 )
 | 
						|
+%}
 | 
						|
+// get the first element in the vector
 | 
						|
+ITERATOR* _begin_ ## PYMETHOD()
 | 
						|
+{
 | 
						|
+    return new ITERATOR( ($self)->CBEGIN() );
 | 
						|
+}
 | 
						|
+    }
 | 
						|
+%enddef
 | 
						|
+/*----------------------------------------------------------------------------*/
 | 
						|
+// If the dereferenced iterator is an object
 | 
						|
+%define ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, RVALUE, CBEGIN, CEND )
 | 
						|
+
 | 
						|
+// add the python and begin method
 | 
						|
+PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN )
 | 
						|
+
 | 
						|
+    %extend CLASS {
 | 
						|
+//! Dereference the iterator; return NULL if at the end
 | 
						|
+const RVALUE* _deref_ ## PYMETHOD ## ( const ITERATOR* iter )
 | 
						|
+{
 | 
						|
+    // if at the end, return NULL
 | 
						|
+    if (*iter == ($self)->CEND() ) {
 | 
						|
+        return NULL;
 | 
						|
+    }
 | 
						|
+    // otherwise, return the POINTER to the dereferenced iterator
 | 
						|
+    return &(**iter);
 | 
						|
+}
 | 
						|
+    }
 | 
						|
+%enddef
 | 
						|
+/*----------------------------------------------------------------------------*/
 | 
						|
+// If the dereferenced iterator is a pointer
 | 
						|
+%define ADD_GENERATOR_P( CLASS, PYMETHOD, ITERATOR, RVALUE, CBEGIN, CEND )
 | 
						|
+
 | 
						|
+// add the python and begin method
 | 
						|
+PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN )
 | 
						|
+
 | 
						|
+    %extend CLASS {
 | 
						|
+//! Dereference the iterator; return NULL if at the end
 | 
						|
+const RVALUE* _deref_ ## PYMETHOD ## ( const ITERATOR* iter )
 | 
						|
+{
 | 
						|
+    // if at the end, return NULL
 | 
						|
+    if (*iter == ($self)->CEND() ) {
 | 
						|
+        return NULL;
 | 
						|
+    }
 | 
						|
+    // otherwise, return the dereferenced iterator (a pointer)
 | 
						|
+    return **iter;
 | 
						|
+}
 | 
						|
+    }
 | 
						|
+%enddef
 | 
						|
+/*----------------------------------------------------------------------------*/
 | 
						|
+//! For a regular container with "begin" and "end" and "size"
 | 
						|
+%define ADD_CONTAINER_ITERATOR( CLASS )
 | 
						|
+    SETUP_GENERATOR( CLASS::const_iterator );
 | 
						|
+    ADD_GENERATOR( CLASS, __iter__,
 | 
						|
+            CLASS ## ::const_iterator, CLASS ## ::value_type,
 | 
						|
+            begin, end)
 | 
						|
+    %extend CLASS {
 | 
						|
+    %insert("python") %{
 | 
						|
+    def __len__(self):
 | 
						|
+        return self.size()
 | 
						|
+    %}
 | 
						|
+    }
 | 
						|
+%enddef
 | 
						|
+
 | 
						|
+/*============================================================================*/
 | 
						|
+#endif
 | 
						|
+
 | 
						|
diff --git a/hepmc/hepmcwrap.i b/hepmc/hepmcwrap.i
 | 
						|
--- a/hepmc/hepmcwrap.i
 | 
						|
+++ b/hepmc/hepmcwrap.i
 | 
						|
@@ -1,5 +1,7 @@
 | 
						|
 %module hepmcwrap
 | 
						|
 
 | 
						|
+%include generators.i
 | 
						|
+
 | 
						|
 %{
 | 
						|
   #include "HepMC/GenEvent.h"
 | 
						|
   #include "HepMC/GenVertex.h"
 | 
						|
@@ -251,3 +253,9 @@
 | 
						|
     return ss.str();
 | 
						|
   }
 | 
						|
 }
 | 
						|
+
 | 
						|
+SETUP_GENERATOR( std::vector< HepMC::GenParticle* >::const_iterator )
 | 
						|
+ADD_GENERATOR_P( HepMC::GenVertex, incoming,
 | 
						|
+std::vector< HepMC::GenParticle* >::const_iterator, HepMC::GenParticle, particles_in_const_begin, particles_in_const_end)
 | 
						|
+ADD_GENERATOR_P( HepMC::GenVertex, outgoing,
 | 
						|
+std::vector< HepMC::GenParticle* >::const_iterator, HepMC::GenParticle, particles_out_const_begin, particles_out_const_end)
 |