IAP GITLAB

Skip to content
Snippets Groups Projects
StackIterator.h 3.27 KiB
Newer Older
ralfulrich's avatar
ralfulrich committed
#ifndef _include_StackIterator_h__
#define _include_StackIterator_h__

#include <iomanip>
#include <iostream>
ralfulrich's avatar
ralfulrich committed

namespace corsika::stack {
ralfulrich's avatar
ralfulrich committed

  // forward decl.
  template <class Stack, class Particle>
  class StackIteratorInfo;
ralfulrich's avatar
ralfulrich committed
     @class StackIterator
     The StackIterator is the main interface to iterator over
     particles on a stack. At the same time StackIterator is a
     Particle object by itself, thus there is no difference between
     type and ref_type for convenience of the physicist.

     This allows to write code like
     \verbatim
     for (auto& p : theStack) { p.SetEnergy(newEnergy); }
ralfulrich's avatar
ralfulrich committed
     \endverbatim

     The template argument Stack determines the type of Stack object
     the data is stored in. A pointer to the Stack object is part of
     the StackIterator. In addition to Stack the iterator only knows
     the index fIndex in the Stack data.
ralfulrich's avatar
ralfulrich committed

     The template argument Particles acts as a policy to provide
     readout function of Particle data from the stack. The Particle
     class must know how to retrieve information from the Stack data
     for a particle entry at any index fIndex.

  template <typename Stack, typename Particle>
  class StackIterator : public Particle {
ralfulrich's avatar
ralfulrich committed
    friend Stack;
    friend Particle;
    friend StackIteratorInfo<Stack, Particle>;

ralfulrich's avatar
ralfulrich committed
  private:
    int fIndex;
ralfulrich's avatar
ralfulrich committed
    //#warning stacks should not be copied because of this:
    Stack* fData;
ralfulrich's avatar
ralfulrich committed
  public:
    StackIterator()
        : fData(0)
        , fIndex(0) {}
    StackIterator(Stack& data, const int index)
        : fData(&data)
        , fIndex(index) {}
    StackIterator(const StackIterator& mit)
        : fData(mit.fData)
        , fIndex(mit.fIndex) {}

    StackIterator& operator++() {
      ++fIndex;
      return *this;
    }
    StackIterator operator++(int) {
      StackIterator tmp(*this);
      ++fIndex;
      return tmp;
    }
ralfulrich's avatar
ralfulrich committed
    bool operator==(const StackIterator& rhs) { return fIndex == rhs.fIndex; }
    bool operator!=(const StackIterator& rhs) { return fIndex != rhs.fIndex; }
ralfulrich's avatar
ralfulrich committed
    StackIterator& operator*() { return *this; }
    const StackIterator& operator*() const { return *this; }
ralfulrich's avatar
ralfulrich committed
  protected:
    int GetIndex() const { return fIndex; }
    Stack& GetStack() { return *fData; }
    const Stack& GetStack() const { return *fData; }

    // this is probably not needed rigth now:
    // inline StackIterator<Stack,Particle>& BaseRef() { return
    // static_cast<StackIterator<Stack, Particle>&>(*this); } inline const
    // StackIterator<Stack,Particle>& BaseRef() const { return static_cast<const
    // StackIterator<Stack, Particle>&>(*this); }
ralfulrich's avatar
ralfulrich committed
     @class StackIteratorInfo

     This is the class where custom ...
     Internal helper class for StackIterator. Document better...
ralfulrich's avatar
ralfulrich committed
   */

  template <typename _Stack, typename Particle>
ralfulrich's avatar
ralfulrich committed
  class StackIteratorInfo {

    friend Particle;

ralfulrich's avatar
ralfulrich committed
  private:
    StackIteratorInfo() {}
ralfulrich's avatar
ralfulrich committed
  protected:
    inline _Stack& GetStack() {
      return static_cast<StackIterator<_Stack, Particle>*>(this)->GetStack();
    }
    inline int GetIndex() const {
      return static_cast<const StackIterator<_Stack, Particle>*>(this)->GetIndex();
    }
    inline const _Stack& GetStack() const {
      return static_cast<const StackIterator<_Stack, Particle>*>(this)->GetStack();
    }
ralfulrich's avatar
ralfulrich committed
} // namespace corsika::stack
ralfulrich's avatar
ralfulrich committed
#endif