CORSIKA  @c8_version@
The framework to simulate particle cascades for astroparticle physics
SecondaryView.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 
13 
14 #include <stdexcept>
15 #include <vector>
16 
17 namespace corsika {
18 
19  // forward-decl:
20  template <class T1, template <class> class T2>
21  class DefaultSecondaryProducer;
22 
61  template <typename TStackDataType, template <typename> typename TParticleInterface,
62  template <typename T1, template <class> class T2> class MSecondaryProducer =
63  DefaultSecondaryProducer>
65  : public Stack<TStackDataType&, TParticleInterface, MSecondaryProducer>,
66  public MSecondaryProducer<TStackDataType, TParticleInterface> {
67 
68  public:
70  view_type;
76 
84 
85  public:
87  TParticleInterface, MSecondaryProducer,
88  inner_stack_value_type>
90 
92  typename std::remove_reference<TStackDataType>::type, TParticleInterface,
93  MSecondaryProducer, inner_stack_value_type>
96 
97  typedef StackIteratorInterface<typename std::remove_reference<TStackDataType>::type,
98  TParticleInterface, MSecondaryProducer, view_type>
100 
102  typename std::remove_reference<TStackDataType>::type, TParticleInterface,
103  MSecondaryProducer, view_type>
105 
109  using ParticleType = stack_view_iterator;
110  using ParticleInterfaceType = typename stack_view_iterator::particle_interface_type;
111 
116  template <typename... TArgs>
117  SecondaryView(TArgs... args) = delete;
118  SecondaryView() = delete;
119 
124  SecondaryView(stack_value_iterator& particle)
125  : Stack<TStackDataType&, TParticleInterface, MSecondaryProducer>(
126  particle.getStackData())
127  , MSecondaryProducer<TStackDataType, TParticleInterface>{particle}
128  , inner_stack_(particle.getStack())
129  , projectile_index_(particle.getIndex()) {
130  CORSIKA_LOG_TRACE("SecondaryView::SecondaryView(particle&)");
131  }
136  SecondaryView(stack_value_iterator&& particle)
137  : Stack<TStackDataType&, TParticleInterface, MSecondaryProducer>(
138  particle.getStackData())
139  , MSecondaryProducer<TStackDataType, TParticleInterface>{particle}
140  , inner_stack_(particle.getStack())
141  , projectile_index_(particle.getIndex()) {
142  CORSIKA_LOG_TRACE("SecondaryView::SecondaryView(particle&&)");
143  }
150  SecondaryView(view_type& view, stack_view_iterator& projectile)
151  : Stack<TStackDataType&, TParticleInterface,
152  MSecondaryProducer>{view.getStackData()}
153  , MSecondaryProducer<TStackDataType, TParticleInterface>{stack_value_iterator{
154  view.inner_stack_, view.getIndexFromIterator(projectile.getIndex())}}
155  , inner_stack_{view.inner_stack_}
156  , projectile_index_{view.getIndexFromIterator(projectile.getIndex())} {
157  CORSIKA_LOG_TRACE("SecondaryView::SecondaryView(view, projectile)");
158  }
159 
165  stack_value_iterator parent()
166  const { // todo: check if this can't be Conststack_value_iterator
167  return stack_value_iterator(inner_stack_, projectile_index_);
168  }
169 
175  stack_value_iterator asNewParent() const {
176  return stack_value_iterator(inner_stack_, projectile_index_);
177  }
178 
183  stack_view_iterator getProjectile() {
184  // NOTE: 0 is special marker here for PROJECTILE, see getIndexFromIterator
185  return stack_view_iterator(*this, 0);
186  }
187 
192  const_stack_view_iterator getProjectile() const {
193  // NOTE: 0 is special marker here for PROJECTILE, see getIndexFromIterator
194  return const_stack_view_iterator(*this, 0);
195  }
196 
200  template <typename... Args>
201  stack_view_iterator addSecondary(const Args... v);
202 
206  unsigned int getSize() const { return indices_.size(); }
207 
208  unsigned int getEntries() const {
209  return getSize() - inner_stack_reference_type::getErased();
210  }
211 
212  bool isEmpty() const { return getEntries() == 0; }
213 
220  // NOTE: the "+1" is since "0" is special marker here for PROJECTILE, see
221  // getIndexFromIterator
222  stack_view_iterator begin();
223 
224  stack_view_iterator end() { return stack_view_iterator(*this, getSize() + 1); }
225 
226  stack_view_iterator last();
227 
228  const_stack_view_iterator begin() const;
229 
230  const_stack_view_iterator end() const {
231  return const_stack_view_iterator(*this, getSize() + 1);
232  }
233 
234  const_stack_view_iterator last() const;
235 
236  const_stack_view_iterator cbegin() const;
237 
238  const_stack_view_iterator cend() const {
239  return const_stack_view_iterator(*this, getSize());
240  }
241 
242  const_stack_view_iterator clast() const;
243 
244  stack_view_iterator at(unsigned int i) { return stack_view_iterator(*this, i); }
245 
246  const_stack_view_iterator at(unsigned int i) const {
247  return const_stack_view_iterator(*this, i);
248  }
249 
250  stack_view_iterator first() { return stack_view_iterator{*this, 0}; }
251 
252  const_stack_view_iterator cfirst() const {
253  return const_stack_view_iterator{*this, 0};
254  }
256 
257  void swap(stack_view_iterator a, stack_view_iterator b);
258 
259  void copy(stack_view_iterator a, stack_view_iterator b);
260 
261  void copy(const_stack_view_iterator a, stack_view_iterator b);
262 
275  void erase(stack_view_iterator p);
276 
281  stack_view_iterator getNextParticle() {
282  while (purgeLastIfDeleted()) {}
283  return last();
284  }
285 
292  bool isErased(const stack_view_iterator& p) const {
293  return isErased(p.getIndex() - 1);
294  }
295 
296  bool isErased(const const_stack_view_iterator& p) const {
297  return isErased(p.getIndex() - 1);
298  }
302  bool isErased(const ParticleInterfaceType& p) const {
303  return isErased(p.getIterator());
304  }
305 
306  bool isDeleted(const const_stack_view_iterator& p) const {
307  return isDeleted(p.getIndex() - 1);
308  }
314  bool purgeLastIfDeleted();
315 
324  void purge();
325 
326  std::string asString() const;
327 
328  protected:
329  friend class StackIteratorInterface<
330  typename std::remove_reference<TStackDataType>::type, TParticleInterface,
331  MSecondaryProducer, view_type>;
332 
333  friend class ConstStackIteratorInterface<
334  typename std::remove_reference<TStackDataType>::type, TParticleInterface,
335  MSecondaryProducer, view_type>;
336 
337  friend class ParticleBase<stack_view_iterator>;
338 
348  template <typename... Args>
349  stack_view_iterator addSecondary(stack_view_iterator& proj, const Args... v);
350 
351  // forward to inner stack
352  // this also checks the allowed bounds of 'i'
353  bool isErased(unsigned int i) const {
354  if (i >= indices_.size()) return false;
355  return inner_stack_.isErased(getIndexFromIterator(i + 1));
356  }
357 
363  unsigned int getIndexFromIterator(const unsigned int vI) const {
364  // this is too much: CORSIKA_LOG_TRACE("SecondaryView::getIndexFromIterator({})={}",
365  // vI, (vI?indices_[vI-1]:projectile_index_));
366  if (vI == 0) return projectile_index_;
367  return indices_[vI - 1];
368  }
369 
370  private:
371  inner_stack_value_type& inner_stack_;
372  unsigned int projectile_index_;
373  std::vector<unsigned int> indices_;
374  };
375 
376  /*
377  See Issue 161
378 
379  unfortunately clang does not support this in the same way (yet) as
380  gcc, so we have to distinguish here. If clang cataches up, we
381  could remove the #if here and elsewhere. The gcc code is much more
382  generic and universal.
383  */
384 #if not defined(__clang__) && defined(__GNUC__) || defined(__GNUG__)
385  template <typename TStack,
386  template <class TStack_, template <class> class pi_type_>
387  class MSecondaryProducer = corsika::DefaultSecondaryProducer,
388  template <typename> typename pi_type_ = TStack::template pi_type>
389  struct MakeView {
390  using type = corsika::SecondaryView<typename TStack::stack_data_type, pi_type_,
391  MSecondaryProducer>;
392  };
393 #endif
394 
395 } // namespace corsika
396 
397 #include <corsika/detail/framework/stack/SecondaryView.inl>
void erase(stack_view_iterator p)
need overwrite Stack::Delete, since we want to call SecondaryView::DeleteLast
SecondaryView(stack_value_iterator &&particle)
SecondaryView can only be constructed passing it a valid stack_view_iterator to another Stack object ...
The Stack class provides (and connects) the main particle data storage machinery. ...
Definition: Stack.hpp:77
CORSIKA8 logging utilities.
SecondaryView(view_type &view, stack_view_iterator &projectile)
Also allow to create a new View from a Projectile (stack_view_iterator on View)
Description of particle stacks.
stack_view_iterator getNextParticle()
return next particle from stack, need to overwrtie Stack::getNextParticle to get right reference ...
bool purgeLastIfDeleted()
Function to ultimatively remove the last entry from the stack, if it was marked as deleted before...
bool isErased(const stack_view_iterator &p) const
check if this particle was already deleted
unsigned int getIndex() const
Get current particle index.
SecondaryView(stack_value_iterator &particle)
SecondaryView can only be constructed passing it a valid stack_view_iterator to another Stack object ...
void purge()
Function to ultimatively remove all entries from the stack marked as deleted.
`, since they are used everywhere as integral part of the framework.
unsigned int getSize() const
overwrite Stack::getSize to return actual number of secondaries
unsigned int getIndexFromIterator(const unsigned int vI) const
We only want to &#39;see&#39; secondaries indexed in indices_.
stack_view_iterator addSecondary(stack_view_iterator &proj, const Args... v)
Overwrite of Stack::stack_view_iterator.
SecondaryView can only be constructed by giving a valid Projectile particle, following calls to addSe...
Class to handle the generation of new secondaries.
bool isErased(const ParticleInterfaceType &p) const
delete this particle
The base class to define the readout of particle properties from a particle stack.
Stack< TStackDataType &, TParticleInterface, MSecondaryProducer > inner_stack_reference_type
Helper type for inside this class.
This is the iterator class for const-access to stack data.
The StackIteratorInterface is the main interface to iterator over particles on a stack.