IAP GITLAB

Skip to content
Snippets Groups Projects
Stack.h 2.89 KiB

/**
 * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
 *
 * See file AUTHORS for a list of contributors.
 *
 * This software is distributed under the terms of the GNU General Public
 * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
 * the license.
 */

#ifndef _include_Stack_h__
#define _include_Stack_h__

#include <corsika/stack/StackIterator.h> // include here, to help application programmres

/**
   All classes around management of particles on a stack.
 */

namespace corsika::stack {

  template <typename>
  class PI; // forward decl

  /**
     Interface definition of a Stack object. The Stack implements the
     std-type begin/end function to allow integration in normal for
     loops etc.
   */

  template <typename StackData, template <typename> typename PI>
  class Stack : public StackData {

  public:
    typedef Stack<StackData, PI> StackType;
    typedef StackIteratorInterface<StackData, PI> StackIterator;
    typedef const StackIterator ConstStackIterator;
    typedef typename StackIterator::ParticleInterfaceType ParticleType;
    friend class StackIteratorInterface<StackData, PI>;

  public:
    using StackData::GetCapacity;
    using StackData::GetSize;

    using StackData::Clear;
    using StackData::Copy;

    using StackData::DecrementSize;
    using StackData::IncrementSize;

    using StackData::Init;

  public:
    /// these are functions required by std containers and std loops
    StackIterator begin() { return StackIterator(*this, 0); }
    StackIterator end() { return StackIterator(*this, GetSize()); }
    StackIterator last() { return StackIterator(*this, GetSize() - 1); }

    /// these are functions required by std containers and std loops
    ConstStackIterator cbegin() const { return ConstStackIterator(*this, 0); }
    ConstStackIterator cend() const { return ConstStackIterator(*this, GetSize()); }
    ConstStackIterator clast() const { return ConstStackIterator(*this, GetSize() - 1); }

    /// increase stack size, create new particle at end of stack
    StackIterator NewParticle() {
      IncrementSize();
      return StackIterator(*this, GetSize() - 1);
    }
    /// delete this particle
    void Delete(StackIterator& p) {
      if (GetSize() == 0) { /*error*/
      }
      if (p.GetIndex() < GetSize() - 1) Copy(GetSize() - 1, p.GetIndex());
      DeleteLast();
      // p.SetInvalid();
    }
    void Delete(ParticleType& p) { Delete(p.GetIterator()); }
    /// delete last particle on stack by decrementing stack size
    void DeleteLast() { DecrementSize(); }
    /// check if there are no further particles on stack
    bool IsEmpty() { return GetSize() == 0; }
    StackIterator GetNextParticle() { return last(); }

  protected:
    StackData& GetStackData() { return static_cast<StackData&>(*this); }
    const StackData& GetStackData() const { return static_cast<const StackData&>(*this); }
  };

} // namespace corsika::stack

#endif