IAP GITLAB

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

first workin version of testStackInterface

parent 7dd85c01
No related branches found
No related tags found
1 merge request!6848 particle creator
......@@ -31,10 +31,15 @@ namespace corsika::stack {
class ParticleBase {
public:
ParticleBase() {}
ParticleBase() = default;
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:
/// delete this particle on the stack. The corresponding iterator
......@@ -52,6 +57,8 @@ namespace corsika::stack {
/// access to underling stack data
auto& GetStackData() { 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
int GetIndex() const { return GetIterator().GetIndex(); }
......
......@@ -14,6 +14,8 @@
#include <corsika/stack/StackIterator.h> // include here, to help application programmres
#include <stdexcept>
/**
All classes around management of particles on a stack.
*/
......@@ -35,9 +37,11 @@ namespace corsika::stack {
public:
typedef Stack<StackData, PI> StackType;
typedef StackIteratorInterface<StackData, PI> StackIterator;
typedef const StackIterator ConstStackIterator;
typedef ConstStackIteratorInterface<StackData, PI> ConstStackIterator;
// typedef const StackIterator ConstStackIterator;
typedef typename StackIterator::ParticleInterfaceType ParticleType;
friend class StackIteratorInterface<StackData, PI>;
friend class ConstStackIteratorInterface<StackData, PI>;
public:
using StackData::GetCapacity;
......@@ -57,20 +61,28 @@ namespace corsika::stack {
StackIterator end() { return StackIterator(*this, GetSize()); }
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 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() {
template <typename... Args>
StackIterator AddParticle(Args... v) {
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()); }
/// delete this particle
void Delete(StackIterator& p) {
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());
DeleteLast();
......
......@@ -14,6 +14,8 @@
#include <corsika/stack/ParticleBase.h>
#include <type_traits>
class StackData; // forward decl
namespace corsika::stack {
......@@ -47,10 +49,15 @@ namespace corsika::stack {
template <typename StackData, template <typename> typename ParticleInterface>
class StackIteratorInterface
: public ParticleInterface<StackIteratorInterface<StackData, ParticleInterface> > {
: public ParticleInterface<StackIteratorInterface<
StackData /*typename std::decay<StackData>::type*/, ParticleInterface>> {
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;
// friend class ParticleInterface<StackIterator<StackData>>; // to access GetStackData
......@@ -59,24 +66,33 @@ namespace corsika::stack {
private:
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:
// StackIterator() : fData(0), fIndex(0) { }
/*
StackIteratorInterface(const StackType& data, const int index)
: fIndex(index)
, fData(&data) {}*/
StackIteratorInterface(StackType& data, const int index)
: fIndex(index)
, fData(&data) {}
private:
StackIteratorInterface(const StackIteratorInterface& mit)
: fIndex(mit.fIndex)
, fData(mit.fData) {}
public:
StackIteratorInterface& operator=(const StackIteratorInterface& mit) {
fIndex = mit.fIndex;
fData = mit.fData;
return *this;
/*
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>
StackIteratorInterface(StackType& data, const int index, const Args... args)
: fIndex(index)
, fData(&data) {
(**this).SetParticleData(args...);
}
public:
......@@ -103,11 +119,96 @@ namespace corsika::stack {
int GetIndex() const { return fIndex; }
StackType& GetStack() { return *fData; }
const StackType& GetStack() const { return *fData; }
StackData& GetStackData() { return fData->GetStackData(); }
const StackData& GetStackData() const { return fData->GetStackData(); }
StackData& /*typename std::decay<StackData>::type&*/ GetStackData() {
return fData->GetStackData();
}
const StackData& /*typename std::decay<StackData>::type&*/ GetStackData() const {
return fData->GetStackData();
}
}; // 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
#endif
......@@ -23,7 +23,7 @@ using namespace corsika::stack;
using namespace std;
// definition of stack-data object
class StackOneData {
class TestStackData {
public:
// these functions are needed for the Stack interface
......@@ -57,22 +57,38 @@ private:
// defintion of a stack-readout object, the iteractor dereference
// operator will deliver access to these function
template <typename StackIteratorInterface>
class ParticleInterface : public ParticleBase<StackIteratorInterface> {
// using ParticleBase<StackIteratorInterface>::Delete;
class TestParticleInterface : public ParticleBase<StackIteratorInterface> {
using ParticleBase<StackIteratorInterface>::GetStack;
using ParticleBase<StackIteratorInterface>::GetStackData;
using ParticleBase<StackIteratorInterface>::GetIndex;
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); }
double GetData() const { return GetStackData().GetData(GetIndex()); }
};
typedef Stack<TestStackData, TestParticleInterface> StackTest;
typedef StackTest::ParticleType Particle;
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") {
// construct a valid Stack object
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s;
s.Init();
s.Clear();
......@@ -85,44 +101,55 @@ TEST_CASE("Stack", "[Stack]") {
REQUIRE(s.GetSize() == 0);
}
SECTION("write") {
SECTION("construct") {
// construct a valid Stack object
typedef Stack<StackOneData, ParticleInterface> StackTest;
// construct a valid, empty Stack object
StackTest s;
}
SECTION("read") {
SECTION("write and read") {
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s;
s.NewParticle().SetData(9.9);
cout << "kk" << endl;
double v = 0;
for (auto& p : s) {
cout << typeid(p).name() << endl;
v += p.GetData();
}
cout << "k222k" << endl;
s.AddParticle(9.9);
const double v = sum(s);
REQUIRE(v == 9.9);
}
SECTION("delete_stack") {
SECTION("delete from stack") {
typedef Stack<StackOneData, ParticleInterface> StackTest;
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);
REQUIRE(s.GetSize() == 1);
s.Delete(p);
REQUIRE(s.GetSize() == 0);
}
SECTION("delete_particle") {
SECTION("delete particle") {
typedef Stack<StackOneData, ParticleInterface> StackTest;
StackTest s;
auto p = s.NewParticle();
p.SetData(9.9);
REQUIRE(s.GetSize() == 0);
auto p =
s.AddParticle(9.9); // also valid way to access particle data, identical to above
REQUIRE(s.GetSize() == 1);
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 {
template <typename StackIteratorInterface>
class ParticleInterface : public ParticleBase<StackIteratorInterface> {
using corsika::stack::ParticleBase<StackIteratorInterface>::GetStack;
using corsika::stack::ParticleBase<StackIteratorInterface>::GetStackData;
using corsika::stack::ParticleBase<StackIteratorInterface>::GetIndex;
public:
/// individual setters
void SetPID(const corsika::particles::Code id) {
GetStackData().SetPID(GetIndex(), id);
}
......@@ -62,6 +64,7 @@ namespace corsika::stack {
GetStackData().SetTime(GetIndex(), v);
}
/// individual getters
corsika::particles::Code GetPID() const {
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