IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 7061f830 authored by Antonio Augusto Alves Junior's avatar Antonio Augusto Alves Junior Committed by ralfulrich
Browse files

[refactory-2020] stack implementations: more cleaning up. Moving...

[refactory-2020] stack implementations: more cleaning up. Moving implemententations to inl. Stack.hpp.
parent 12fec99a
No related branches found
No related tags found
No related merge requests found
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* 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
......@@ -10,110 +8,168 @@
#pragma once
#include <corsika/framework/logging/Logging.hpp>
#include <corsika/framework/core/ParticleProperties.hpp>
#include <corsika/framework/stack/Stack.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
namespace corsika {
template <template <typename> typename ParticleInterfaceA,
template <typename> typename ParticleInterfaceB, typename StackIterator>
template <typename... Args1>
void CombinedParticleInterface<ParticleInterfaceA, ParticleInterfaceB,
StackIterator>::SetParticleData(const std::tuple<Args1...> vA) {
PI_A::SetParticleData(vA);
PI_B::SetParticleData();
}
/**
* CombinedParticleInterface can be used to combine the data of several StackData
* objects.
*
* You may combine two StackData object, see class CombinedStackImpl
* below, into one Stack, using a combined StackIterator (aka
* CombinedParticleInterface) interface class.
*
* This allows to add specific information to a given Stack, could
* be special information on a subset of entries
* (e.g. NuclearStackExtension) or also (multi) thinning weights for
* all particles.
*
* Many Stacks can be combined into more complex object.
*
* The two sub-stacks must both provide their independent
* ParticleInterface classes.
*
*/
template <template <typename> typename TParticleInterfaceA,
template <typename> class TParticleInterfaceB, typename TStackIterator>
struct CombinedParticleInterface
: public TParticleInterfaceB<TParticleInterfaceA<TStackIterator>> {
typedef CombinedParticleInterface<TParticleInterfaceA, TParticleInterfaceB,
TStackIterator>
pi_c_type;
typedef TParticleInterfaceA<TStackIterator> pi_a_type;
typedef TParticleInterfaceB<TParticleInterfaceA<TStackIterator>> pi_b_type;
protected:
using pi_b_type::getIndex; // choose B, A would also work
using pi_b_type::getStackData; // choose B, A would also work
public:
/**
* @name wrapper for user functions
* @{
*
* In this set of functions we call the user-provide
* TParticleInterface setParticleData(...) methods, either with
* parent particle reference, or w/o.
*
* There is one implicit assumption here: if only one data tuple
* is provided for setParticleData, the data is passed on to
* TParticleInterfaceA and the TParticleInterfaceB is
* default-initialized. There are many occasions where this is the
* desired behaviour, e.g. for thinning etc.
*
*/
template <template <typename> typename ParticleInterfaceA,
template <typename> typename ParticleInterfaceB, typename StackIterator>
template <typename... Args1, typename... Args2>
void CombinedParticleInterface<ParticleInterfaceA, ParticleInterfaceB,
StackIterator>::SetParticleData(const std::tuple<Args1...> vA, const std::tuple<Args2...> vB) {
PI_A::SetParticleData(vA);
PI_B::SetParticleData(vB);
template <typename... TArgs1>
void setParticleData(std::tuple<TArgs1...> const vA) {
pi_a_type::setParticleData(vA);
pi_b_type::setParticleData();
}
template <typename... TArgs1, typename... TArgs2>
void setParticleData(std::tuple<TArgs1...> const vA, std::tuple<TArgs2...> const vB) {
pi_a_type::setParticleData(vA);
pi_b_type::setParticleData(vB);
}
template <template <typename> typename ParticleInterfaceA,
template <typename> typename ParticleInterfaceB, typename StackIterator>
template <typename... Args1>
void CombinedParticleInterface<ParticleInterfaceA, ParticleInterfaceB,
StackIterator>::SetParticleData(PI_C& p, const std::tuple<Args1...> vA) {
template <typename... TArgs1>
void setParticleData(pi_a_type& p, std::tuple<TArgs1...> const vA) {
// static_assert(MT<I>::has_not, "error");
PI_A::SetParticleData(static_cast<PI_A&>(p), vA); // original stack
PI_B::SetParticleData(static_cast<PI_B&>(p)); // addon stack
pi_a_type::setParticleData(static_cast<pi_a_type&>(p), vA); // original stack
pi_b_type::setParticleData(static_cast<pi_b_type&>(p)); // addon stack
}
template <typename... TArgs1, typename... TArgs2>
void setParticleData(pi_c_type& p, std::tuple<TArgs1...> const vA,
std::tuple<TArgs2...> const vB) {
template <template <typename> typename ParticleInterfaceA,
template <typename> typename ParticleInterfaceB, typename StackIterator>
template <typename... Args1, typename... Args2>
void CombinedParticleInterface<ParticleInterfaceA, ParticleInterfaceB,
StackIterator>::SetParticleData(PI_C& p, const std::tuple<Args1...> vA,
const std::tuple<Args2...> vB) {
PI_A::SetParticleData(static_cast<PI_A&>(p), vA);
PI_B::SetParticleData(static_cast<PI_B&>(p), vB);
pi_a_type::setParticleData(static_cast<pi_a_type&>(p), vA);
pi_b_type::setParticleData(static_cast<pi_b_type&>(p), vB);
}
///@}
std::string as_string() const {
return fmt::format("[[{}][{}]]", pi_a_type::as_string(), pi_b_type::as_string());
}
namespace detail {
protected:
};
/**
* @class CombinedStackImpl
*
* Memory implementation of a combined data stack.
*
* The two stack data user objects Stack1Impl and Stack2Impl are
* merged into one consistent Stack container object providing
* access to the combined number of data entries.
*/
template <typename Stack1Impl, typename Stack2Impl>
class CombinedStackImpl : public Stack1Impl, public Stack2Impl {
public:
void Init() {
Stack1Impl::Init();
Stack2Impl::Init();
}
void Clear() {
Stack1Impl::Clear();
Stack2Impl::Clear();
void clear() {
Stack1Impl::clear();
Stack2Impl::clear();
}
unsigned int GetSize() const { return Stack1Impl::GetSize(); }
unsigned int GetCapacity() const { return Stack1Impl::GetCapacity(); }
unsigned int getSize() const { return Stack1Impl::getSize(); }
unsigned int getCapacity() const { return Stack1Impl::getCapacity(); }
/**
* Function to copy particle at location i1 in stack to i2
*/
void Copy(const unsigned int i1, const unsigned int i2) {
if (i1 >= GetSize() || i2 >= GetSize()) {
void copy(const unsigned int i1, const unsigned int i2) {
if (i1 >= getSize() || i2 >= getSize()) {
std::ostringstream err;
err << "CombinedStack: trying to access data beyond size of stack!";
throw std::runtime_error(err.str());
}
Stack1Impl::Copy(i1, i2);
Stack2Impl::Copy(i1, i2);
Stack1Impl::copy(i1, i2);
Stack2Impl::copy(i1, i2);
}
/**
* Function to copy particle at location i2 in stack to i1
*/
void Swap(const unsigned int i1, const unsigned int i2) {
if (i1 >= GetSize() || i2 >= GetSize()) {
void swap(const unsigned int i1, const unsigned int i2) {
if (i1 >= getSize() || i2 >= getSize()) {
std::ostringstream err;
err << "CombinedStack: trying to access data beyond size of stack!";
throw std::runtime_error(err.str());
}
Stack1Impl::Swap(i1, i2);
Stack2Impl::Swap(i1, i2);
Stack1Impl::swap(i1, i2);
Stack2Impl::swap(i1, i2);
}
void IncrementSize() {
Stack1Impl::IncrementSize();
Stack2Impl::IncrementSize();
void incrementSize() {
Stack1Impl::incrementSize();
Stack2Impl::incrementSize();
}
void DecrementSize() {
Stack1Impl::DecrementSize();
Stack2Impl::DecrementSize();
void decrementSize() {
Stack1Impl::decrementSize();
Stack2Impl::decrementSize();
}
}; // end class CombinedStackImpl
} // namespace detail
/**
* Helper template alias `CombinedStack` to construct new combined
* stack from two stack data objects and a particle readout interface.
*
* Note that the Stack2Impl provides only /additional/ data to
* Stack1Impl. This is important (see above) since tuple data for
* initialization are forwarded to Stack1Impl (first).
*/
template <typename Stack1Impl, typename Stack2Impl, template <typename> typename _PI>
using CombinedStack = Stack<CombinedStackImpl<Stack1Impl, Stack2Impl>, _PI>;
} // namespace corsika
//#include <corsika/detail/framework/stack/CombinedStack.inl>
This diff is collapsed.
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* 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.
*/
#pragma once
#include <corsika/framework/logging/Logging.hpp>
#include <corsika/framework/stack/StackIteratorInterface.hpp>
#include <stdexcept>
#include <string>
#include <vector>
#include <utility>
#include <type_traits>
namespace corsika {
template <typename StackData, template <typename> typename MParticleInterface>
template <typename... TArgs>
void Stack<StackData, MParticleInterface>::clear(TArgs... args) {
data_.clear(args...);
deleted_ = std::vector<bool>(data_.getSize(), false);
nDeleted_ = 0;
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::begin() {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[i]) break;
}
return stack_iterator_type(*this, i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::end() {
return stack_iterator_type(*this, getSize());
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::last() {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[getSize() - 1 - i]) break;
}
return stack_iterator_type(*this, getSize() - 1 - i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::begin() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[i]) break;
}
return const_stack_iterator_type(*this, i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::end() const {
return const_stack_iterator_type(*this, getSize());
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::last() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[getSize() - 1 - i]) break;
}
return const_stack_iterator_type(*this, getSize() - 1 - i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::cbegin() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[i]) break;
}
return const_stack_iterator_type(*this, i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::cend() const {
return const_stack_iterator_type(*this, getSize());
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::clast() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[getSize() - 1 - i]) break;
}
return const_stack_iterator_type(*this, getSize() - 1 - i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::at(unsigned int i) {
return stack_iterator_type(*this, i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::at(unsigned int i) const {
return const_stack_iterator_type(*this, i);
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::first() {
return stack_iterator_type{*this, 0};
}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::const_stack_iterator_type
Stack<StackData, MParticleInterface>::cfirst() const {
return const_stack_iterator_type{*this, 0};
}
/// @}
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::getNextParticle() {
while (purgeLastIfDeleted()) {}
return last();
}
template <typename StackData, template <typename> typename MParticleInterface>
template <typename... TArgs>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::addParticle(const TArgs... v) {
CORSIKA_LOG_TRACE("Stack::AddParticle");
data_.incrementSize();
deleted_.push_back(false);
return stack_iterator_type(*this, getSize() - 1, v...);
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::swap(stack_iterator_type a, stack_iterator_type b) {
CORSIKA_LOG_TRACE("Stack::Swap");
swap(a.getIndex(), b.getIndex());
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::copy(stack_iterator_type a, stack_iterator_type b) {
CORSIKA_LOG_TRACE("Stack::Copy");
copy(a.getIndex(), b.getIndex());
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::copy(const_stack_iterator_type a, stack_iterator_type b) {
CORSIKA_LOG_TRACE("Stack::Copy");
data_.copy(a.getIndex(), b.getIndex());
if (deleted_[b.getIndex()] && !deleted_[a.getIndex()]) nDeleted_--;
if (!deleted_[b.getIndex()] && deleted_[a.getIndex()]) nDeleted_++;
deleted_[b.getIndex()] = deleted_[a.getIndex()];
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::erase(stack_iterator_type p) {
CORSIKA_LOG_TRACE("Stack::Delete");
if (this->isEmpty()) { /*error*/
throw std::runtime_error("Stack, cannot delete entry since size is zero");
}
if (deleted_[p.getIndex()]) { /*error*/
throw std::runtime_error("Stack, cannot delete entry since already deleted");
}
this->erase(p.getIndex());
}
/**
* delete this particle
*/
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::erase(particle_interface_type p) { this->erase(p.getIterator()); }
/**
* check if there are no further non-deleted particles on stack
*/
template <typename StackData, template <typename> typename MParticleInterface>
bool Stack<StackData, MParticleInterface>::isEmpty() { return getEntries() == 0; }
/**
* check if this particle was already deleted
*/
template <typename StackData, template <typename> typename MParticleInterface>
bool Stack<StackData, MParticleInterface>::isErased(const stack_iterator_type& p) const { return isErased(p.getIndex()); }
template <typename StackData, template <typename> typename MParticleInterface>
bool Stack<StackData, MParticleInterface>::isErased(const const_stack_iterator_type& p) const {
return isErased(p.getIndex());
}
template <typename StackData, template <typename> typename MParticleInterface>
bool Stack<StackData, MParticleInterface>::isErased(const particle_interface_type& p) const {
return isErased(p.getIterator());
}
/**
* Function to ultimatively remove the last entry from the stack,
* if it was marked as deleted before. If this is not the case,
* the function will just return false and do nothing.
*/
template <typename StackData, template <typename> typename MParticleInterface>
bool Stack<StackData, MParticleInterface>::purgeLastIfDeleted() {
if (!deleted_.back())
return false; // the last particle is not marked for deletion. Do nothing.
CORSIKA_LOG_TRACE("Stack::purgeLastIfDeleted: yes");
data_.decrementSize();
nDeleted_--;
deleted_.pop_back();
return true;
}
/**
* Function to ultimatively remove all entries from the stack
* marked as deleted.
*
* Careful: this will re-order the entries on the stack, since
* "gaps" in the stack are filled with entries from the back
* (copied).
*/
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::purge() {
unsigned int iStackFront = 0;
unsigned int iStackBack = getSize() - 1;
for (unsigned int iDeleted = 0; iDeleted < getErased(); ++iDeleted) {
// search first delete entry on stack
while (!deleted_[iStackFront]) { iStackFront++; }
// search for last non-deleted particle on stack
while (deleted_[iStackBack]) { iStackBack--; }
// copy entry from iStackBack to iStackFront
data_.copy(iStackBack, iStackFront);
data_.decrementSize();
}
deleted_.clear();
nDeleted_ = 0;
}
template <typename StackData, template <typename> typename MParticleInterface>
unsigned int Stack<StackData, MParticleInterface>::getSize() const { return data_.getSize(); }
template <typename StackData, template <typename> typename MParticleInterface>
std::string Stack<StackData, MParticleInterface>::as_string() const {
std::string str(fmt::format("size {}, entries {}, deleted {} \n", getSize(),
getEntries(), getErased()));
// we make our own begin/end since we want ALL entries
std::string new_line = " ";
for (unsigned int iPart = 0; iPart != getSize(); ++iPart) {
const_stack_iterator_type itPart(*this, iPart);
str += fmt::format("{}{}{}", new_line, itPart.as_string(),
(deleted_[itPart.getIndex()] ? " [deleted]" : ""));
new_line = "\n ";
}
return str;
}
template <typename StackData, template <typename> typename MParticleInterface>
template <typename... TArgs>
typename Stack<StackData, MParticleInterface>::stack_iterator_type
Stack<StackData, MParticleInterface>::addSecondary(stack_iterator_type& parent, const TArgs... v) {
CORSIKA_LOG_TRACE("Stack::AddSecondary");
data_.incrementSize();
deleted_.push_back(false);
return stack_iterator_type(*this, getSize() - 1, parent, v...);
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::swap(unsigned int const a, unsigned int const b) {
CORSIKA_LOG_TRACE("Stack::Swap(unsigned int)");
data_.swap(a, b);
std::swap(deleted_[a], deleted_[b]);
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::copy(unsigned int const a, unsigned int const b) {
CORSIKA_LOG_TRACE("Stack::Copy");
data_.copy(a, b);
if (deleted_[b] && !deleted_[a]) nDeleted_--;
if (!deleted_[b] && deleted_[a]) nDeleted_++;
deleted_[b] = deleted_[a];
}
template <typename StackData, template <typename> typename MParticleInterface>
bool Stack<StackData, MParticleInterface>::isErased(unsigned int const i) const {
if (i >= deleted_.size()) return false;
return deleted_.at(i);
}
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::erase(unsigned int const i) {
deleted_[i] = true;
nDeleted_++;
}
/**
* will remove from storage the element i. This is a helper
* function for SecondaryView.
*/
template <typename StackData, template <typename> typename MParticleInterface>
void Stack<StackData, MParticleInterface>::purge(unsigned int i) {
unsigned int iStackBack = getSize() - 1;
// search for last non-deleted particle on stack
while (deleted_[iStackBack]) { iStackBack--; }
// copy entry from iStackBack to iStackFront
data_.copy(iStackBack, i);
if (deleted_[i]) nDeleted_--;
deleted_[i] = deleted_[iStackBack];
data_.decrementSize();
deleted_.pop_back();
}
/**
* Function to perform eventual transformation from
* StackIterator::getIndex() to index in data stored in
* StackData data_. By default (and in almost all cases) this
* should just be identiy. See class SecondaryView for an alternative implementation.
*/
template <typename StackData, template <typename> typename MParticleInterface>
unsigned int Stack<StackData, MParticleInterface>::getIndexFromIterator(const unsigned int vI) const {
// this is too much: CORSIKA_LOG_TRACE("Stack::getIndexFromIterator({})={}", vI, vI);
return vI;
}
/**
* @name Return reference to StackData object data_ for data access
* @{
*/
template <typename StackData, template <typename> typename MParticleInterface>
typename Stack<StackData, MParticleInterface>::value_type&
Stack<StackData, MParticleInterface>::getStackData() { return data_; }
template <typename StackData, template <typename> typename MParticleInterface>
const typename Stack<StackData, MParticleInterface>::value_type&
Stack<StackData, MParticleInterface>::getStackData() const { return data_; }
} // namespace corsika
......@@ -83,8 +83,6 @@ namespace corsika {
*/
typedef stack_iterator_type particle_type;
//========================
Stack() = default;
Stack(Stack&) = delete; ///< since Stack can be very big, we don't want to copy it
......@@ -130,170 +128,82 @@ namespace corsika {
unsigned int getEntries() const { return getSize() - getErased(); }
template <typename... TArgs>
void clear(TArgs... args) {
data_.clear(args...);
deleted_ = std::vector<bool>(data_.getSize(), false);
nDeleted_ = 0;
}
void clear(TArgs... args);
///@}
/**
* @name These are functions required by std containers and std loops
* @{
*/
stack_iterator_type begin() {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[i]) break;
}
return stack_iterator_type(*this, i);
}
stack_iterator_type end() { return stack_iterator_type(*this, getSize()); }
stack_iterator_type last() {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[getSize() - 1 - i]) break;
}
return stack_iterator_type(*this, getSize() - 1 - i);
}
const_stack_iterator_type begin() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[i]) break;
}
return const_stack_iterator_type(*this, i);
}
const_stack_iterator_type end() const {
return const_stack_iterator_type(*this, getSize());
}
const_stack_iterator_type last() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[getSize() - 1 - i]) break;
}
return const_stack_iterator_type(*this, getSize() - 1 - i);
}
const_stack_iterator_type cbegin() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[i]) break;
}
return const_stack_iterator_type(*this, i);
}
const_stack_iterator_type cend() const {
return const_stack_iterator_type(*this, getSize());
}
const_stack_iterator_type clast() const {
unsigned int i = 0;
for (; i < getSize(); ++i) {
if (!deleted_[getSize() - 1 - i]) break;
}
return const_stack_iterator_type(*this, getSize() - 1 - i);
}
stack_iterator_type at(unsigned int i) { return stack_iterator_type(*this, i); }
const_stack_iterator_type at(unsigned int i) const {
return const_stack_iterator_type(*this, i);
}
stack_iterator_type first() { return stack_iterator_type{*this, 0}; }
const_stack_iterator_type cfirst() const {
return const_stack_iterator_type{*this, 0};
}
/// @}
stack_iterator_type getNextParticle() {
while (purgeLastIfDeleted()) {}
return last();
}
stack_iterator_type begin();
stack_iterator_type end() ;
stack_iterator_type last();
const_stack_iterator_type begin() const;
const_stack_iterator_type end() const ;
const_stack_iterator_type last() const ;
const_stack_iterator_type cbegin() const;
const_stack_iterator_type cend() const;
const_stack_iterator_type clast() const;
stack_iterator_type at(unsigned int i);
const_stack_iterator_type at(unsigned int i) const;
stack_iterator_type first();
const_stack_iterator_type cfirst() const;
stack_iterator_type getNextParticle();
/**
* increase stack size, create new particle at end of stack
*/
template <typename... TArgs>
stack_iterator_type addParticle(const TArgs... v) {
// C8LOG_TRACE("Stack::AddParticle");
data_.incrementSize();
deleted_.push_back(false);
return stack_iterator_type(*this, getSize() - 1, v...);
}
void swap(stack_iterator_type a, stack_iterator_type b) {
// C8LOG_TRACE("Stack::Swap");
swap(a.getIndex(), b.getIndex());
}
void copy(stack_iterator_type a, stack_iterator_type b) {
// C8LOG_TRACE("Stack::Copy");
copy(a.getIndex(), b.getIndex());
}
void copy(const_stack_iterator_type a, stack_iterator_type b) {
// C8LOG_TRACE("Stack::Copy");
data_.copy(a.getIndex(), b.getIndex());
if (deleted_[b.getIndex()] && !deleted_[a.getIndex()]) nDeleted_--;
if (!deleted_[b.getIndex()] && deleted_[a.getIndex()]) nDeleted_++;
deleted_[b.getIndex()] = deleted_[a.getIndex()];
}
void erase(stack_iterator_type p) {
// C8LOG_TRACE("Stack::Delete");
if (this->isEmpty()) { /*error*/
throw std::runtime_error("Stack, cannot delete entry since size is zero");
}
if (deleted_[p.getIndex()]) { /*error*/
throw std::runtime_error("Stack, cannot delete entry since already deleted");
}
this->erase(p.getIndex());
}
stack_iterator_type addParticle(const TArgs... v) ;
void swap(stack_iterator_type a, stack_iterator_type b);
void copy(stack_iterator_type a, stack_iterator_type b);
void copy(const_stack_iterator_type a, stack_iterator_type b);
void erase(stack_iterator_type p);
/**
* delete this particle
*/
void erase(particle_interface_type p) { this->erase(p.getIterator()); }
void erase(particle_interface_type p);
/**
* check if there are no further non-deleted particles on stack
*/
bool isEmpty() { return getEntries() == 0; }
bool isEmpty();
/**
* check if this particle was already deleted
*/
bool isErased(const stack_iterator_type& p) const { return isErased(p.getIndex()); }
bool isErased(const const_stack_iterator_type& p) const {
return isErased(p.getIndex());
}
bool isErased(const stack_iterator_type& p) const;
bool isErased(const particle_interface_type& p) const {
return isErased(p.getIterator());
}
bool isErased(const const_stack_iterator_type& p) const;
bool isErased(const particle_interface_type& p) const;
/**
* Function to ultimatively remove the last entry from the stack,
* if it was marked as deleted before. If this is not the case,
* the function will just return false and do nothing.
*/
bool purgeLastIfDeleted() {
if (!deleted_.back())
return false; // the last particle is not marked for deletion. Do nothing.
// C8LOG_TRACE("Stack::purgeLastIfDeleted: yes");
data_.decrementSize();
nDeleted_--;
deleted_.pop_back();
return true;
}
bool purgeLastIfDeleted();
/**
* Function to ultimatively remove all entries from the stack
* marked as deleted.
......@@ -302,37 +212,12 @@ namespace corsika {
* "gaps" in the stack are filled with entries from the back
* (copied).
*/
void purge() {
unsigned int iStackFront = 0;
unsigned int iStackBack = getSize() - 1;
for (unsigned int iDeleted = 0; iDeleted < getErased(); ++iDeleted) {
// search first delete entry on stack
while (!deleted_[iStackFront]) { iStackFront++; }
// search for last non-deleted particle on stack
while (deleted_[iStackBack]) { iStackBack--; }
// copy entry from iStackBack to iStackFront
data_.copy(iStackBack, iStackFront);
data_.decrementSize();
}
deleted_.clear();
nDeleted_ = 0;
}
unsigned int getSize() const { return data_.getSize(); }
std::string as_string() const {
std::string str(fmt::format("size {}, entries {}, deleted {} \n", getSize(),
getEntries(), getErased()));
// we make our own begin/end since we want ALL entries
std::string new_line = " ";
for (unsigned int iPart = 0; iPart != getSize(); ++iPart) {
const_stack_iterator_type itPart(*this, iPart);
str += fmt::format("{}{}{}", new_line, itPart.as_string(),
(deleted_[itPart.getIndex()] ? " [deleted]" : ""));
new_line = "\n ";
}
return str;
}
void purge();
unsigned int getSize() const;
std::string as_string() const;
protected:
......@@ -343,110 +228,22 @@ namespace corsika {
* This should only get internally called from a
* StackIterator::AddSecondary via ParticleBase
*/
/*
template <typename... TArgs>
stack_iterator_type addSecondary(stack_iterator_type& parent, const TArgs... v) {
CORSIKA_LOG_TRACE("Stack::AddSecondary");
data_.incrementSize();
deleted_.push_back(false);
return stack_iterator_type(*this, getSize() - 1, parent, v...);
}
void swap(unsigned int a, unsigned int b) {
CORSIKA_LOG_TRACE("Stack::Swap(unsigned int)");
data_.swap(a, b);
std::swap(deleted_[a], deleted_[b]);
}
void copy(unsigned int a, unsigned int b) {
CORSIKA_LOG_TRACE("Stack::Copy");
data_.copy(a, b);
if (deleted_[b] && !deleted_[a]) nDeleted_--;
if (!deleted_[b] && deleted_[a]) nDeleted_++;
deleted_[b] = deleted_[a];
}
bool isDeleted(unsigned int i) const {
if (i >= deleted_.size()) return false;
return deleted_.at(i);
}
void erase(unsigned int i) {
deleted_[i] = true;
nDeleted_++;
}
*/
/*
* will remove from storage the element i. This is a helper
* function for SecondaryView.
*/
stack_iterator_type addSecondary(stack_iterator_type& parent, const TArgs... v) ;
/*
void purge(unsigned int i) {
unsigned int iStackBack = getSize() - 1;
// search for last non-deleted particle on stack
while (deleted_[iStackBack]) { iStackBack--; }
// copy entry from iStackBack to iStackFront
data_.copy(iStackBack, i);
if (deleted_[i]) nDeleted_--;
deleted_[i] = deleted_[iStackBack];
data_.decrementSize();
deleted_.pop_back();
}
*/
/**
* increase stack size, create new particle at end of stack, related to parent
* particle/projectile
*
* This should only get internally called from a
* StackIterator::AddSecondary via ParticleBase
*/
template <typename... TArgs>
stack_iterator_type addSecondary(stack_iterator_type& parent, const TArgs... v) {
// C8LOG_TRACE("Stack::AddSecondary");
data_.incrementSize();
deleted_.push_back(false);
return stack_iterator_type(*this, getSize() - 1, parent, v...);
}
void swap(unsigned int const a, unsigned int const b) {
// C8LOG_TRACE("Stack::Swap(unsigned int)");
data_.swap(a, b);
std::swap(deleted_[a], deleted_[b]);
}
void copy(unsigned int const a, unsigned int const b) {
// C8LOG_TRACE("Stack::Copy");
data_.copy(a, b);
if (deleted_[b] && !deleted_[a]) nDeleted_--;
if (!deleted_[b] && deleted_[a]) nDeleted_++;
deleted_[b] = deleted_[a];
}
bool isErased(unsigned int const i) const {
if (i >= deleted_.size()) return false;
return deleted_.at(i);
}
void erase(unsigned int const i) {
deleted_[i] = true;
nDeleted_++;
}
void swap(unsigned int const a, unsigned int const b);
void copy(unsigned int const a, unsigned int const b);
bool isErased(unsigned int const i) const;
void erase(unsigned int const i) ;
/**
* will remove from storage the element i. This is a helper
* function for SecondaryView.
*/
void purge(unsigned int i) {
unsigned int iStackBack = getSize() - 1;
// search for last non-deleted particle on stack
while (deleted_[iStackBack]) { iStackBack--; }
// copy entry from iStackBack to iStackFront
data_.copy(iStackBack, i);
if (deleted_[i]) nDeleted_--;
deleted_[i] = deleted_[iStackBack];
data_.decrementSize();
deleted_.pop_back();
}
void purge(unsigned int i);
/**
* Function to perform eventual transformation from
......@@ -454,22 +251,16 @@ namespace corsika {
* StackData data_. By default (and in almost all cases) this
* should just be identiy. See class SecondaryView for an alternative implementation.
*/
unsigned int getIndexFromIterator(const unsigned int vI) const {
// this is too much: //C8LOG_TRACE("Stack::getIndexFromIterator({})={}", vI, vI);
return vI;
}
unsigned int getIndexFromIterator(const unsigned int vI) const;
/**
* @name Return reference to StackData object data_ for data access
* @{
*/
value_type& getStackData() { return data_; }
const value_type& getStackData() const { return data_; }
///@}
///
value_type& getStackData();
const value_type& getStackData() const;
///
friend class StackIteratorInterface<value_type, MParticleInterface, Stack>;
friend class ConstStackIteratorInterface<value_type, MParticleInterface, Stack>;
template <typename T1, //=StackData,
......@@ -491,3 +282,5 @@ namespace corsika {
};
} // namespace corsika
#include <corsika/detail/framework/stack/Stack.inl>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment