CORSIKA8  0.0.0
The framework to simulate particle cascades for astroparticle physics
StackIteratorInterface.hpp
1 /*
2  * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
3  *
4  * This software is distributed under the terms of the GNU General Public
5  * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
6  * the license.
7  */
8 
9 #pragma once
10 
11 #include <corsika/framework/stack/ParticleBase.hpp>
12 
13 #include <boost/type_index.hpp>
14 
15 namespace corsika::history {
16  template <typename T, template <typename> typename TParticleInterface>
17  class HistorySecondaryProducer; // forward decl.
18 }
19 
20 namespace corsika {
21 
22  template <typename TStackData, template <typename> typename TParticleInterface,
23  template <class T1, template <class> class T2> class MSecondaryProducer>
24  class Stack; // forward decl
25 
26  template <typename TStackData, template <typename> typename TParticleInterface,
27  template <class T1, template <class> class T2> class MSecondaryProducer>
28  class SecondaryView; // forward decl
29 
30  template <typename TStackData, template <typename> typename TParticleInterface,
31  template <class T1, template <class> class T2> class MSecondaryProducer,
32  typename StackType>
33  class ConstStackIteratorInterface; // forward decl
34 
73  template <typename TStackData, template <typename> typename TParticleInterface,
74  template <typename T1, template <class> class T2> class MSecondaryProducer,
75  typename TStackType =
78  : public TParticleInterface<StackIteratorInterface<
79  TStackData, TParticleInterface, MSecondaryProducer, TStackType>> {
80 
81  public:
82  typedef TParticleInterface<corsika::StackIteratorInterface<
83  TStackData, TParticleInterface, MSecondaryProducer, TStackType>>
84  particle_interface_type;
85 
86  typedef TStackType stack_type;
87  typedef TStackData stack_data_type;
88 
89  // it is not allowed to create a "dangling" stack iterator
90  StackIteratorInterface() = delete;
91 
93  : index_(std::move(rhs.index_))
94  , data_(std::move(rhs.data_)) {}
95 
97  : index_(vR.index_)
98  , data_(vR.data_) {}
99 
100  StackIteratorInterface& operator=(StackIteratorInterface const& vR) {
101  if (&vR != this) {
102  index_ = vR.index_;
103  data_ = vR.data_;
104  }
105  return *this;
106  }
107 
112  StackIteratorInterface(stack_type& data, unsigned int const index)
113  : index_(index)
114  , data_(&data) {}
115 
123  template <typename... TArgs>
124  StackIteratorInterface(stack_type& data, unsigned int const index,
125  const TArgs... args)
126  : index_(index)
127  , data_(&data) {
128 
129  (**this).setParticleData(args...);
130  }
131 
142  template <typename... TArgs>
143  StackIteratorInterface(stack_type& data, unsigned int const index,
144  StackIteratorInterface& parent, const TArgs... args)
145  : index_(index)
146  , data_(&data) {
147 
148  (**this).setParticleData(*parent, args...);
149  }
150 
151  bool isErased() const { return getStack().isErased(*this); }
152 
153  public:
157  StackIteratorInterface& operator++() {
158  do {
159  ++index_;
160  } while (
161  getStack().isErased(*this)); // this also check the allowed bounds of index_
162  return *this;
163  }
164  StackIteratorInterface operator++(int) {
165  StackIteratorInterface tmp(*this);
166  do {
167  ++index_;
168  } while (
169  getStack().isErased(*this)); // this also check the allowed bounds of index_
170  return tmp;
171  }
172  StackIteratorInterface operator+(int delta) const {
173  return StackIteratorInterface(*data_, index_ + delta);
174  }
175  bool operator==(StackIteratorInterface const& rhs) const {
176  return index_ == rhs.index_;
177  }
178  bool operator!=(StackIteratorInterface const& rhs) const {
179  return index_ != rhs.index_;
180  }
181  bool operator==(const ConstStackIteratorInterface<
182  TStackData, TParticleInterface, MSecondaryProducer,
183  stack_type>& rhs) const; // implemented below
185  TStackData, TParticleInterface, MSecondaryProducer,
186  stack_type>& rhs) const; // implemented below
187 
192  particle_interface_type& operator*() {
193  return static_cast<particle_interface_type&>(*this);
194  }
195 
200  particle_interface_type const& operator*() const {
201  return static_cast<particle_interface_type const&>(*this);
202  }
204 
205  protected:
210  unsigned int getIndex() const { return index_; }
213  stack_type& getStack() { return *data_; }
215  stack_type const& getStack() const { return *data_; }
217  TStackData& getStackData() { return data_->getStackData(); }
219  TStackData const& getStackData() const { return data_->getStackData(); }
221  unsigned int getIndexFromIterator() const {
222  return data_->getIndexFromIterator(index_);
223  }
225 
226  // friends are needed for access to protected methods
227  friend class Stack<TStackData, TParticleInterface,
228  MSecondaryProducer>; // for access to getIndex for Stack
229  friend class Stack<TStackData&, TParticleInterface,
230  MSecondaryProducer>; // for access to getIndex
231  // SecondaryView : public Stack
232  friend class ParticleBase<StackIteratorInterface>; // for access to getStackDataType
233 
234  template <typename T1, // best fix this to: TStackData,
235  template <typename> typename M1, // best fix this to: TParticleInterface,
236  template <typename T, template <typename> typename T3> typename M2>
237  friend class SecondaryView; // access grant for SecondaryView
238 
239  template <typename T, template <typename> typename TParticleInterface_>
241 
242  friend class ConstStackIteratorInterface<TStackData, TParticleInterface,
243  MSecondaryProducer, stack_type>;
244 
245  protected:
246  unsigned int index_ = 0;
247 
248  private:
249  stack_type* data_ = 0; // info: Particles and StackIterators become invalid when
250  // parent Stack is copied or deleted!
251 
252  }; // end class StackIterator
253 
268  template <typename TStackData, template <typename> typename TParticleInterface,
269  template <typename T1, template <class> class T2> class MSecondaryProducer,
270  typename TStackType =
273  : public TParticleInterface<ConstStackIteratorInterface<
274  TStackData, TParticleInterface, MSecondaryProducer, TStackType>> {
275 
276  public:
277  typedef TParticleInterface<ConstStackIteratorInterface<
278  TStackData, TParticleInterface, MSecondaryProducer, TStackType>>
279  particle_interface_type;
280 
281  typedef TStackType stack_type;
282  typedef TStackData stack_data_type;
283 
284  // we don't want to allow dangling iterators to exist
285  ConstStackIteratorInterface() = delete;
286 
287  public:
289  : index_(std::move(rhs.index_))
290  , data_(std::move(rhs.data_)) {}
291 
292  ConstStackIteratorInterface(stack_type const& data, unsigned int const index)
293  : index_(index)
294  , data_(&data) {}
295 
296  bool isErased() const { return getStack().isErased(*this); }
297 
301  ConstStackIteratorInterface& operator++() {
302  do {
303  ++index_;
304  } while (
305  getStack().isErased(*this)); // this also check the allowed bounds of index_
306  return *this;
307  }
308  ConstStackIteratorInterface operator++(int) {
309  ConstStackIteratorInterface tmp(*this);
310  do {
311  ++index_;
312  } while (
313  getStack().isErased(*this)); // this also check the allowed bounds of index_
314  return tmp;
315  }
316  ConstStackIteratorInterface operator+(int const delta) const {
317  return ConstStackIteratorInterface(*data_, index_ + delta);
318  }
319  bool operator==(ConstStackIteratorInterface const& rhs) const {
320  return index_ == rhs.index_;
321  }
322  bool operator!=(ConstStackIteratorInterface const& rhs) const {
323  return index_ != rhs.index_;
324  }
325  bool operator==(
326  StackIteratorInterface<stack_data_type, TParticleInterface, MSecondaryProducer,
327  stack_type> const& rhs) const {
328  return index_ == rhs.index_;
329  }
330  bool operator!=(
331  StackIteratorInterface<stack_data_type, TParticleInterface, MSecondaryProducer,
332  stack_type> const& rhs) const {
333  return index_ != rhs.index_;
334  }
335 
336  particle_interface_type const& operator*() const {
337  return static_cast<particle_interface_type const&>(*this);
338  }
340 
341  protected:
346  unsigned int getIndex() const { return index_; }
347  stack_type const& getStack() const { return *data_; }
348  stack_data_type const& getStackData() const { return data_->getStackData(); }
350  unsigned int getIndexFromIterator() const {
351  return data_->getIndexFromIterator(index_);
352  }
354 
355  // friends are needed for access to protected methods
356  friend class Stack<stack_data_type, TParticleInterface,
357  MSecondaryProducer>; // for access to GetIndex for Stack
358  friend class Stack<stack_data_type&, TParticleInterface,
359  MSecondaryProducer>; // for access to GetIndex
360 
361  friend class ParticleBase<ConstStackIteratorInterface>; // for access to GetStackData
362 
363  template <typename T1, // best fix to: stack_data_type,
364  template <typename> typename M1, // best fix to: TParticleInterface,
365  template <class T2, template <class> class T3> class M2>
366  friend class SecondaryView; // access for SecondaryView
367 
368  friend class StackIteratorInterface<stack_data_type, TParticleInterface,
369  MSecondaryProducer, stack_type>;
370 
371  template <typename T, template <typename> typename TParticleInterface_>
373 
374  protected:
375  unsigned int index_ = 0;
376 
377  private:
378  stack_type const* data_ = 0; // info: Particles and StackIterators become invalid when
379  // parent Stack is copied or deleted!
380 
381  }; // end class ConstStackIterator
382 
383 } // namespace corsika
TStackData & getStackData()
Get current user particle TStackData object.
particle_interface_type const & operator*() const
Convert iterator to const value type, where value type is the user-provided particle readout class...
constexpr quantity< D, detail::PromoteMul< X, Y > > operator*(quantity< D, X > const &x, const Y &y)
quan * num
Definition: quantity.hpp:576
The Stack class provides (and connects) the main particle data storage machinery. ...
Definition: Stack.hpp:77
StackIteratorInterface(stack_type &data, unsigned int const index, const TArgs... args)
constructor that also sets new values on particle data object
STL namespace.
particle_interface_type & operator*()
Convert iterator to value type, where value type is the user-provided particle readout class...
constexpr quantity< D, X > operator+(quantity< D, X > const &x)
Definition: quantity.hpp:528
stack_type const & getStack() const
Get current particle const Stack object.
TStackData const & getStackData() const
Get current const user particle TStackData object.
The cascade namespace assembles all objects needed to simulate full particles cascades.
constexpr bool operator!=(quantity< D, X > const &x, quantity< D, Y > const &y)
inequality.
Definition: quantity.hpp:707
StackIteratorInterface(StackIteratorInterface &&rhs)
unsigned int getIndexFromIterator() const
Get data index as mapped in Stack class.
StackIteratorInterface(stack_type &data, unsigned int const index)
iterator must always point to data, with an index:
SecondaryView can only be constructed by giving a valid Projectile particle, following calls to addSe...
ConstStackIteratorInterface(ConstStackIteratorInterface &&rhs)
unsigned int getIndexFromIterator() const
Get data index as mapped in Stack class.
stack_type & getStack()
Get current particle Stack object.
The base class to define the readout of particle properties from a particle stack.
This is the iterator class for const-access to stack data.
StackIteratorInterface(stack_type &data, unsigned int const index, StackIteratorInterface &parent, const TArgs... args)
constructor that also sets new values on particle data object, including reference to parent particle...
The StackIteratorInterface is the main interface to iterator over particles on a stack.