IAP GITLAB

Skip to content
Snippets Groups Projects
Commit f132223e authored by ralfulrich's avatar ralfulrich
Browse files

first workin version of testStackInterface

parent 3fdf333d
No related branches found
No related tags found
1 merge request!6848 particle creator
...@@ -31,10 +31,15 @@ namespace corsika::stack { ...@@ -31,10 +31,15 @@ namespace corsika::stack {
class ParticleBase { class ParticleBase {
public: public:
ParticleBase() {} ParticleBase() = default;
private: private:
ParticleBase(ParticleBase&); ParticleBase(ParticleBase&) = delete;
ParticleBase operator=(ParticleBase&) = delete;
ParticleBase(ParticleBase&&) = delete;
ParticleBase operator=(ParticleBase&&) = delete;
ParticleBase(const ParticleBase&) = delete;
ParticleBase operator=(const ParticleBase&) = delete;
public: public:
/// delete this particle on the stack. The corresponding iterator /// delete this particle on the stack. The corresponding iterator
...@@ -52,6 +57,8 @@ namespace corsika::stack { ...@@ -52,6 +57,8 @@ namespace corsika::stack {
/// access to underling stack data /// access to underling stack data
auto& GetStackData() { return GetIterator().GetStackData(); } auto& GetStackData() { return GetIterator().GetStackData(); }
const auto& GetStackData() const { return GetIterator().GetStackData(); } const auto& GetStackData() const { return GetIterator().GetStackData(); }
auto& GetStack() { return GetIterator().GetStack(); }
const auto& GetStack() const { return GetIterator().GetStack(); }
/// return the index number of the underlying iterator object /// return the index number of the underlying iterator object
int GetIndex() const { return GetIterator().GetIndex(); } int GetIndex() const { return GetIterator().GetIndex(); }
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <corsika/stack/StackIterator.h> // include here, to help application programmres #include <corsika/stack/StackIterator.h> // include here, to help application programmres
#include <stdexcept>
/** /**
All classes around management of particles on a stack. All classes around management of particles on a stack.
*/ */
...@@ -35,9 +37,11 @@ namespace corsika::stack { ...@@ -35,9 +37,11 @@ namespace corsika::stack {
public: public:
typedef Stack<StackData, PI> StackType; typedef Stack<StackData, PI> StackType;
typedef StackIteratorInterface<StackData, PI> StackIterator; typedef StackIteratorInterface<StackData, PI> StackIterator;
typedef const StackIterator ConstStackIterator; typedef ConstStackIteratorInterface<StackData, PI> ConstStackIterator;
// typedef const StackIterator ConstStackIterator;
typedef typename StackIterator::ParticleInterfaceType ParticleType; typedef typename StackIterator::ParticleInterfaceType ParticleType;
friend class StackIteratorInterface<StackData, PI>; friend class StackIteratorInterface<StackData, PI>;
friend class ConstStackIteratorInterface<StackData, PI>;
public: public:
using StackData::GetCapacity; using StackData::GetCapacity;
...@@ -57,20 +61,28 @@ namespace corsika::stack { ...@@ -57,20 +61,28 @@ namespace corsika::stack {
StackIterator end() { return StackIterator(*this, GetSize()); } StackIterator end() { return StackIterator(*this, GetSize()); }
StackIterator last() { return StackIterator(*this, GetSize() - 1); } StackIterator last() { return StackIterator(*this, GetSize() - 1); }
/// these are functions required by std containers and std loops ConstStackIterator begin() const { return ConstStackIterator(*this, 0); }
ConstStackIterator end() const { return ConstStackIterator(*this, GetSize()); }
ConstStackIterator last() const { return ConstStackIterator(*this, GetSize() - 1); }
ConstStackIterator cbegin() const { return ConstStackIterator(*this, 0); } ConstStackIterator cbegin() const { return ConstStackIterator(*this, 0); }
ConstStackIterator cend() const { return ConstStackIterator(*this, GetSize()); } ConstStackIterator cend() const { return ConstStackIterator(*this, GetSize()); }
ConstStackIterator clast() const { return ConstStackIterator(*this, GetSize() - 1); } ConstStackIterator clast() const { return ConstStackIterator(*this, GetSize() - 1); }
/// increase stack size, create new particle at end of stack /// increase stack size, create new particle at end of stack
StackIterator NewParticle() { template <typename... Args>
StackIterator AddParticle(Args... v) {
IncrementSize(); IncrementSize();
return StackIterator(*this, GetSize() - 1); return StackIterator(*this, GetSize() - 1, v...);
// auto p = StackIterator(*this, GetSize() - 1);
// p.SetParticleData(v...);
// return p;
} }
void Copy(StackIterator& a, StackIterator& b) { Copy(a.GetIndex(), b.GetIndex()); } void Copy(StackIterator& a, StackIterator& b) { Copy(a.GetIndex(), b.GetIndex()); }
/// delete this particle /// delete this particle
void Delete(StackIterator& p) { void Delete(StackIterator& p) {
if (GetSize() == 0) { /*error*/ if (GetSize() == 0) { /*error*/
throw std::runtime_error("Stack, cannot delete entry since size is zero");
} }
if (p.GetIndex() < GetSize() - 1) Copy(GetSize() - 1, p.GetIndex()); if (p.GetIndex() < GetSize() - 1) Copy(GetSize() - 1, p.GetIndex());
DeleteLast(); DeleteLast();
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <corsika/stack/ParticleBase.h> #include <corsika/stack/ParticleBase.h>
#include <type_traits>
class StackData; // forward decl class StackData; // forward decl
namespace corsika::stack { namespace corsika::stack {
...@@ -47,10 +49,15 @@ namespace corsika::stack { ...@@ -47,10 +49,15 @@ namespace corsika::stack {
template <typename StackData, template <typename> typename ParticleInterface> template <typename StackData, template <typename> typename ParticleInterface>
class StackIteratorInterface class StackIteratorInterface
: public ParticleInterface<StackIteratorInterface<StackData, ParticleInterface> > { : public ParticleInterface<StackIteratorInterface<
StackData /*typename std::decay<StackData>::type*/, ParticleInterface>> {
typedef Stack<StackData, ParticleInterface> StackType; typedef Stack<StackData, ParticleInterface> StackType;
typedef ParticleInterface<StackIteratorInterface<StackData, ParticleInterface> > /*typedef
typename std::conditional<std::is_const<StackData>::value,
const Stack<const StackData, ParticleInterface>&,
Stack<StackData, ParticleInterface>&>::type StackType;*/
typedef ParticleInterface<StackIteratorInterface<StackData, ParticleInterface>>
ParticleInterfaceType; ParticleInterfaceType;
// friend class ParticleInterface<StackIterator<StackData>>; // to access GetStackData // friend class ParticleInterface<StackIterator<StackData>>; // to access GetStackData
...@@ -59,24 +66,33 @@ namespace corsika::stack { ...@@ -59,24 +66,33 @@ namespace corsika::stack {
private: private:
int fIndex = 0; int fIndex = 0;
StackType* fData = 0; // todo is this problematic, when stacks are copied? StackType* fData = 0; // info: Particles and StackIterators become invalid when parent
// Stack is copied or deleted!
StackIteratorInterface() = delete;
public: public:
// StackIterator() : fData(0), fIndex(0) { } /*
StackIteratorInterface(const StackType& data, const int index)
: fIndex(index)
, fData(&data) {}*/
StackIteratorInterface(StackType& data, const int index) StackIteratorInterface(StackType& data, const int index)
: fIndex(index) : fIndex(index)
, fData(&data) {} , fData(&data) {}
/*
private: StackIteratorInterface(StackType& data, const int index, typename
StackIteratorInterface(const StackIteratorInterface& mit) std::enable_if<!std::is_const<StackData>::value>::type* = 0) : fIndex(index) ,
: fIndex(mit.fIndex) fData(&data) {}
, fData(mit.fData) {}
StackIteratorInterface(const StackType& data, const int index, typename
public: std::enable_if<std::is_const<StackData>::value>::type* = 0) : fIndex(index) ,
StackIteratorInterface& operator=(const StackIteratorInterface& mit) { fData(&data) {}
fIndex = mit.fIndex; */
fData = mit.fData; template <typename... Args>
return *this; StackIteratorInterface(StackType& data, const int index, const Args... args)
: fIndex(index)
, fData(&data) {
(**this).SetParticleData(args...);
} }
public: public:
...@@ -103,11 +119,96 @@ namespace corsika::stack { ...@@ -103,11 +119,96 @@ namespace corsika::stack {
int GetIndex() const { return fIndex; } int GetIndex() const { return fIndex; }
StackType& GetStack() { return *fData; } StackType& GetStack() { return *fData; }
const StackType& GetStack() const { return *fData; } const StackType& GetStack() const { return *fData; }
StackData& GetStackData() { return fData->GetStackData(); } StackData& /*typename std::decay<StackData>::type&*/ GetStackData() {
const StackData& GetStackData() const { return fData->GetStackData(); } return fData->GetStackData();
}
const StackData& /*typename std::decay<StackData>::type&*/ GetStackData() const {
return fData->GetStackData();
}
}; // end class StackIterator }; // end class StackIterator
template <typename StackData, template <typename> typename ParticleInterface>
class ConstStackIteratorInterface
: public ParticleInterface<ConstStackIteratorInterface<
StackData /*typename std::decay<StackData>::type*/, ParticleInterface>> {
typedef Stack<StackData, ParticleInterface> StackType;
/*typedef
typename std::conditional<std::is_const<StackData>::value,
const Stack<const StackData, ParticleInterface>&,
Stack<StackData, ParticleInterface>&>::type StackType;*/
typedef ParticleInterface<ConstStackIteratorInterface<StackData, ParticleInterface>>
ParticleInterfaceType;
// friend class ParticleInterface<StackIterator<StackData>>; // to access GetStackData
friend class Stack<StackData, ParticleInterface>; // for access to GetIndex
friend class ParticleBase<ConstStackIteratorInterface>; // for access to GetStackData
private:
int fIndex = 0;
const StackType* fData = 0; // info: Particles and StackIterators become invalid when
// parent Stack is copied or deleted!
ConstStackIteratorInterface() = delete;
public:
// StackIteratorInterface(const StackType& data, const int index)
// : fIndex(index)
// , fData(&data) {}
ConstStackIteratorInterface(const StackType& data, const int index)
: fIndex(index)
, fData(&data) {}
/*
StackIteratorInterface(StackType& data, const int index, typename
std::enable_if<!std::is_const<StackData>::value>::type* = 0) : fIndex(index) ,
fData(&data) {}
StackIteratorInterface(const StackType& data, const int index, typename
std::enable_if<std::is_const<StackData>::value>::type* = 0) : fIndex(index) ,
fData(&data) {}
*/
template <typename... Args>
ConstStackIteratorInterface(StackType data, const int index, const Args... args)
: fIndex(index)
, fData(data) {
(**this).SetParticleData(args...);
}
public:
ConstStackIteratorInterface& operator++() {
++fIndex;
return *this;
}
ConstStackIteratorInterface operator++(int) {
ConstStackIteratorInterface tmp(*this);
++fIndex;
return tmp;
}
bool operator==(const ConstStackIteratorInterface& rhs) {
return fIndex == rhs.fIndex;
}
bool operator!=(const ConstStackIteratorInterface& rhs) {
return fIndex != rhs.fIndex;
}
ParticleInterfaceType& operator*() {
return static_cast<ParticleInterfaceType&>(*this);
}
const ParticleInterfaceType& operator*() const {
return static_cast<const ParticleInterfaceType&>(*this);
}
protected:
int GetIndex() const { return fIndex; }
// StackType GetStack() { return *fData; }
const StackType& GetStack() const { return *fData; }
// StackData& /*typename std::decay<StackData>::type&*/ GetStackData() { return
// fData->GetStackData(); }
const StackData& /*typename std::decay<StackData>::type&*/ GetStackData() const {
return fData->GetStackData();
}
}; // end class ConstStackIterator
} // namespace corsika::stack } // namespace corsika::stack
#endif #endif
...@@ -23,7 +23,7 @@ using namespace corsika::stack; ...@@ -23,7 +23,7 @@ using namespace corsika::stack;
using namespace std; using namespace std;
// definition of stack-data object // definition of stack-data object
class StackOneData { class TestStackData {
public: public:
// these functions are needed for the Stack interface // these functions are needed for the Stack interface
...@@ -57,22 +57,38 @@ private: ...@@ -57,22 +57,38 @@ private:
// defintion of a stack-readout object, the iteractor dereference // defintion of a stack-readout object, the iteractor dereference
// operator will deliver access to these function // operator will deliver access to these function
template <typename StackIteratorInterface> template <typename StackIteratorInterface>
class ParticleInterface : public ParticleBase<StackIteratorInterface> { class TestParticleInterface : public ParticleBase<StackIteratorInterface> {
// using ParticleBase<StackIteratorInterface>::Delete; using ParticleBase<StackIteratorInterface>::GetStack;
using ParticleBase<StackIteratorInterface>::GetStackData; using ParticleBase<StackIteratorInterface>::GetStackData;
using ParticleBase<StackIteratorInterface>::GetIndex; using ParticleBase<StackIteratorInterface>::GetIndex;
public: public:
// one version
void AddSecondary(const double v) { GetStack().AddParticle(v); }
// another version
void AddSecondary(const double v, const double p) { GetStack().AddParticle(v + p); }
void SetParticleData(const double v) { SetData(v); }
void SetData(const double v) { GetStackData().SetData(GetIndex(), v); } void SetData(const double v) { GetStackData().SetData(GetIndex(), v); }
double GetData() const { return GetStackData().GetData(GetIndex()); } double GetData() const { return GetStackData().GetData(GetIndex()); }
}; };
typedef Stack<TestStackData, TestParticleInterface> StackTest;
typedef StackTest::ParticleType Particle;
TEST_CASE("Stack", "[Stack]") { TEST_CASE("Stack", "[Stack]") {
// helper function for sum over stack data
auto sum = [](const StackTest& stack) {
double v = 0;
for (const auto&& p : stack) v += p.GetData();
return v;
};
SECTION("StackInterface") { SECTION("StackInterface") {
// construct a valid Stack object // construct a valid Stack object
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s; StackTest s;
s.Init(); s.Init();
s.Clear(); s.Clear();
...@@ -85,44 +101,55 @@ TEST_CASE("Stack", "[Stack]") { ...@@ -85,44 +101,55 @@ TEST_CASE("Stack", "[Stack]") {
REQUIRE(s.GetSize() == 0); REQUIRE(s.GetSize() == 0);
} }
SECTION("write") { SECTION("construct") {
// construct a valid Stack object // construct a valid, empty Stack object
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s; StackTest s;
} }
SECTION("read") { SECTION("write and read") {
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s; StackTest s;
s.NewParticle().SetData(9.9); s.AddParticle(9.9);
cout << "kk" << endl; const double v = sum(s);
double v = 0;
for (auto& p : s) {
cout << typeid(p).name() << endl;
v += p.GetData();
}
cout << "k222k" << endl;
REQUIRE(v == 9.9); REQUIRE(v == 9.9);
} }
SECTION("delete_stack") { SECTION("delete from stack") {
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s; StackTest s;
auto p = s.NewParticle(); REQUIRE(s.GetSize() == 0);
StackTest::StackIterator p = s.AddParticle(0.); // valid way to access particle data
p.SetData(9.9); p.SetData(9.9);
REQUIRE(s.GetSize() == 1);
s.Delete(p); s.Delete(p);
REQUIRE(s.GetSize() == 0);
} }
SECTION("delete_particle") { SECTION("delete particle") {
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s; StackTest s;
auto p = s.NewParticle(); REQUIRE(s.GetSize() == 0);
p.SetData(9.9); auto p =
s.AddParticle(9.9); // also valid way to access particle data, identical to above
REQUIRE(s.GetSize() == 1);
p.Delete(); p.Delete();
REQUIRE(s.GetSize() == 0);
}
SECTION("create secondaries") {
StackTest s;
REQUIRE(s.GetSize() == 0);
auto iter = s.AddParticle(9.9);
Particle& p = *iter; // also this is valid to access particle data
REQUIRE(s.GetSize() == 1);
p.AddSecondary(4.4);
REQUIRE(s.GetSize() == 2);
p.AddSecondary(3.3, 2.2);
REQUIRE(s.GetSize() == 3);
double v = 0;
for (auto& p : s) { v += p.GetData(); }
REQUIRE(v == 9.9 + 4.4 + 3.3 + 2.2);
} }
} }
...@@ -38,10 +38,12 @@ namespace corsika::stack { ...@@ -38,10 +38,12 @@ namespace corsika::stack {
template <typename StackIteratorInterface> template <typename StackIteratorInterface>
class ParticleInterface : public ParticleBase<StackIteratorInterface> { class ParticleInterface : public ParticleBase<StackIteratorInterface> {
using corsika::stack::ParticleBase<StackIteratorInterface>::GetStack;
using corsika::stack::ParticleBase<StackIteratorInterface>::GetStackData; using corsika::stack::ParticleBase<StackIteratorInterface>::GetStackData;
using corsika::stack::ParticleBase<StackIteratorInterface>::GetIndex; using corsika::stack::ParticleBase<StackIteratorInterface>::GetIndex;
public: public:
/// individual setters
void SetPID(const corsika::particles::Code id) { void SetPID(const corsika::particles::Code id) {
GetStackData().SetPID(GetIndex(), id); GetStackData().SetPID(GetIndex(), id);
} }
...@@ -62,6 +64,7 @@ namespace corsika::stack { ...@@ -62,6 +64,7 @@ namespace corsika::stack {
GetStackData().SetTime(GetIndex(), v); GetStackData().SetTime(GetIndex(), v);
} }
/// individual getters
corsika::particles::Code GetPID() const { corsika::particles::Code GetPID() const {
return GetStackData().GetPID(GetIndex()); return GetStackData().GetPID(GetIndex());
} }
......
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