From 26b9e18e2bb1d4e45d1b35690214c04110a9a6d3 Mon Sep 17 00:00:00 2001 From: Dominik Baack <dominik.baack@tu-dortmund.de> Date: Tue, 6 Oct 2020 13:47:57 +0200 Subject: [PATCH] Added time measureing class fixed unit tests fixed some incosistencys --- CMakeLists.txt | 1 + Framework/Analytics/ClassTimer.h | 12 +- Framework/Analytics/testClassTimer.cc | 87 +++++++++++++- .../ProcessSequence/BoundaryCrossingProcess.h | 2 + Framework/ProcessSequence/StackProcess.h | 4 +- Processes/AnalyticProcessors/ExecTime.h | 56 +++++---- Processes/AnalyticProcessors/ImplBoundary.h | 18 ++- Processes/AnalyticProcessors/ImplContinuous.h | 6 +- Processes/AnalyticProcessors/ImplDecay.h | 4 +- .../AnalyticProcessors/ImplInteraction.h | 4 +- .../AnalyticProcessors/ImplSecondaries.h | 4 +- Processes/AnalyticProcessors/testExecTime.cc | 110 ++++++++++++++++-- .../DummyBoundaryCrossingProcess.h | 4 +- .../DummyContinuousProcess.h | 4 +- .../ExampleProcessors/DummyDecayProcess.h | 2 +- .../DummyInteractionProcess.h | 2 +- .../DummySecondariesProcess.h | 2 +- 17 files changed, 256 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c67782af8..af8d04ff8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ set (CMAKE_CXX_STANDARD 17) set (CMAKE_CXX_EXTENSIONS OFF) enable_testing () set (CTEST_OUTPUT_ON_FAILURE 1) +list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure") # Set the possible values of build type for cmake-gui and command line check set (ALLOWED_BUILD_TYPES Debug Release MinSizeRel RelWithDebInfo Coverage) diff --git a/Framework/Analytics/ClassTimer.h b/Framework/Analytics/ClassTimer.h index 68c130392..3d1102afd 100644 --- a/Framework/Analytics/ClassTimer.h +++ b/Framework/Analytics/ClassTimer.h @@ -36,7 +36,7 @@ namespace corsika::analytics { timeClass(TType& obj) : vObj(obj) {} - TRet call(TArgs&&... args) { + TRet call(TArgs... args) { vStart = TClock::now(); auto tmp = (vObj.*TFuncPtr)(std::forward<TArgs>(args)...); vDiff = std::chrono::duration_cast<TDuration>(TClock::now() - vStart); @@ -62,7 +62,7 @@ namespace corsika::analytics { timeClass(TType& obj) : vObj(obj) {} - void call(TArgs&&... args) { + void call(TArgs... args) { vStart = TClock::now(); (vObj.*TFuncPtr)(std::forward<TArgs>(args)...); vDiff = std::chrono::duration_cast<TDuration>(TClock::now() - vStart); @@ -90,7 +90,7 @@ namespace corsika::analytics { timeClass(TType& obj) : vObj(obj) {} - TRet call(TArgs&&... args) { + TRet call(TArgs... args) { vStart = TClock::now(); auto tmp = (vObj.*TFuncPtr)(std::forward<TArgs>(args)...); vDiff = std::chrono::duration_cast<TDuration>(TClock::now() - vStart); @@ -117,11 +117,11 @@ namespace corsika::analytics { timeClass(TType& obj) : vObj(obj) {} - void call(TArgs&&... args) { + void call(TArgs... args) { vStart = TClock::now(); - (vObj.*TFuncPtr)(std::forward<TArgs>(args)...); + (vObj.*TFuncPtr)(std::forward<TArgs>(args)...); vDiff = std::chrono::duration_cast<TDuration>(TClock::now() - vStart); - return ; + return; } inline TDuration getTime() const { return vDiff; } diff --git a/Framework/Analytics/testClassTimer.cc b/Framework/Analytics/testClassTimer.cc index 6e179c391..6e53a9363 100644 --- a/Framework/Analytics/testClassTimer.cc +++ b/Framework/Analytics/testClassTimer.cc @@ -16,7 +16,19 @@ using namespace corsika; -class foo { +class _foo2 { +public: + int inside(int) { return 123; } + + int inside(char) { return 312; } +}; + +class _foo1 : public _foo2 { +public: + int inside(int) { return 123; } +}; + +class foo : public _foo1 { public: int bar() { std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -32,6 +44,62 @@ public: std::this_thread::sleep_for(std::chrono::milliseconds(100)); return; } + + int inside() { + auto tc = corsika::analytics::timeClass<int (_foo1::*)(int), &_foo1::inside>(*this); + + auto r = tc.call(1); + + return r; + } +}; + +template <typename TType, TType> +class timeMin; + +template <typename TType, typename TRet, typename... TArgs, + TRet (TType::*TFuncPtr)(TArgs...)> +class timeMin<TRet (TType::*)(TArgs...), TFuncPtr> { +private: + TType& vObj; + +public: + timeMin(TType& obj) + : vObj(obj) {} + + TRet call(TArgs... args) { return (vObj.*TFuncPtr)(std::forward<TArgs>(args)...); } +}; + +// quasi processor +class fooT1 { +public: + template <typename T1, typename T2> + int inside_t(T1 a, T2 b, T2 c) { + return 123; + } +}; + +// exec_time_impl +template <typename T> +class fooT2 : public T { +public: + using _T = T; +}; + +// exec_time_impl +template <typename T> +class fooT3 : public fooT2<T> { +public: + template <typename T1, typename T2> + int inside_t(T1 a, T2 b, T2 c) { + auto tc = + timeMin<int (fooT2<T>::_T::*)(T1, T2, T2), + &fooT2<T>::_T::template inside_t<T1, T2>>(*this); // <- dependent template + + auto r = tc.call(a, b, c); + + return r; + } }; TEST_CASE("Analytics", "[Timer]") { @@ -42,7 +110,7 @@ TEST_CASE("Analytics", "[Timer]") { tc.call(); - std::cout << tc.getTime().count() << std::endl; + REQUIRE(tc.getTime().count() == Approx(100000).margin(1000)); } SECTION("Measure runtime of a function with arguments") { @@ -52,7 +120,7 @@ TEST_CASE("Analytics", "[Timer]") { tc.call(1); - std::cout << tc.getTime().count() << std::endl; + REQUIRE(tc.getTime().count() == Approx(100000).margin(1000)); } SECTION("Measure runtime of a const function without arguments") { @@ -63,6 +131,17 @@ TEST_CASE("Analytics", "[Timer]") { tc.call(); - std::cout << tc.getTime().count() << std::endl; + REQUIRE(tc.getTime().count() == Approx(100000).margin(1000)); + } + + SECTION("Measure runtime of function inside class") { + + auto test = foo(); + REQUIRE(test.inside() == 123); + } + + SECTION("Measure runtime of function inside class") { + auto test = fooT3<fooT1>(); + REQUIRE(test.inside_t(1, 'a', 'b') == 123); } } diff --git a/Framework/ProcessSequence/BoundaryCrossingProcess.h b/Framework/ProcessSequence/BoundaryCrossingProcess.h index feee4d0db..b5906f4d9 100644 --- a/Framework/ProcessSequence/BoundaryCrossingProcess.h +++ b/Framework/ProcessSequence/BoundaryCrossingProcess.h @@ -11,6 +11,8 @@ #include <corsika/process/BaseProcess.h> #include <corsika/process/ProcessReturn.h> +#include <type_traits> + namespace corsika::process { template <typename TDerived> diff --git a/Framework/ProcessSequence/StackProcess.h b/Framework/ProcessSequence/StackProcess.h index ad39f1193..6a5f8abb7 100644 --- a/Framework/ProcessSequence/StackProcess.h +++ b/Framework/ProcessSequence/StackProcess.h @@ -28,9 +28,9 @@ namespace corsika::process { class StackProcess : public BaseProcess<TDerived>{ private: protected: - using _TDerived = TDerived; - public: + using _TDerived = TDerived; + StackProcess() = delete; StackProcess(const unsigned int nStep) : fNStep(nStep) {} diff --git a/Processes/AnalyticProcessors/ExecTime.h b/Processes/AnalyticProcessors/ExecTime.h index 6d7c6de45..0a39d2805 100644 --- a/Processes/AnalyticProcessors/ExecTime.h +++ b/Processes/AnalyticProcessors/ExecTime.h @@ -31,50 +31,58 @@ namespace corsika::process { class _ExecTimeImpl : protected T { private: std::chrono::high_resolution_clock::time_point startTime_; - std::chrono::duration<double, std::micro> cumulatedTime_; - double mean_; - double mean2_; - double min_; - double max_; - long long n_; + std::chrono::duration<double, std::micro> cumulatedTime_; + volatile double mean_; + volatile double mean2_; + volatile double min_; + volatile double max_; + volatile long long n_; protected: public: + using _T = T; + _ExecTimeImpl() { - min_ = std::numeric_limits<long long>::max(); + min_ = std::numeric_limits<double>::max(); + cumulatedTime_ = std::chrono::duration<double, std::micro>(0); max_ = 0; mean_ = 0; mean2_ = 0; n_ = 0; } - void start() { startTime_ = std::chrono::high_resolution_clock::now(); } - void stop() { + inline void start() { startTime_ = std::chrono::high_resolution_clock::now(); } + inline void stop() { auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double, std::micro> timeDiv = std::chrono::duration_cast<std::chrono::duration<double, std::micro> >( end - startTime_); - cumulatedTime_ += timeDiv; + this->update(timeDiv); + } + + void update(std::chrono::duration<double, std::micro> timeDif) { + + cumulatedTime_ += timeDif; n_ = n_ + 1; - if (max_ < timeDiv.count()) max_ = timeDiv.count(); + if (max_ < timeDif.count()) max_ = timeDif.count(); - if (timeDiv.count() < min_) min_ = timeDiv.count(); + if (timeDif.count() < min_) min_ = timeDif.count(); - double delta = timeDiv.count() - mean_; + double delta = timeDif.count() - mean_; mean_ += delta / static_cast<double>(n_); - double delta2 = timeDiv.count() - mean_; + double delta2 = timeDif.count() - mean_; mean2_ += delta * delta2; } - double mean() const { return mean_; } - double min() const { return min_; } - double max() const { return max_; } - double var() const { return mean2_ / n_; } - double sumTime() const { return cumulatedTime_.count(); } + inline double mean() const { return mean_; } + inline double min() const { return min_; } + inline double max() const { return max_; } + inline double var() const { return mean2_ / n_; } + inline double sumTime() const { return cumulatedTime_.count(); } }; template <typename T> @@ -94,7 +102,11 @@ namespace corsika::process { std::is_base_of<corsika::process::InteractionProcess<typename T::_TDerived>, T>::value>, public Secondaries< - T, std::is_base_of<corsika::process::SecondariesProcess<typename T::_TDerived>, - T>::value> {}; - } // namespace devtools + T, + std::is_base_of<corsika::process::SecondariesProcess<typename T::_TDerived>, + T>::value> { + using is_process = decltype(is_process_impl(std::declval<T*>())); + static_assert(std::is_same<is_process, std::true_type>::value, "error message"); + }; + } // namespace analytic_processors } // namespace corsika::process \ No newline at end of file diff --git a/Processes/AnalyticProcessors/ImplBoundary.h b/Processes/AnalyticProcessors/ImplBoundary.h index 57fcdf7ef..ff491fc3a 100644 --- a/Processes/AnalyticProcessors/ImplBoundary.h +++ b/Processes/AnalyticProcessors/ImplBoundary.h @@ -9,6 +9,8 @@ #include <corsika/process/analytic_processors/ExecTime.h> +#include <corsika/analytics/ClassTimer.h> + namespace corsika::process { namespace analytic_processors { @@ -25,14 +27,20 @@ namespace corsika::process { class Boundary<T, true> : public _ExecTimeImpl<T> { private: public: + template <typename Particle, typename VTNType> EProcessReturn DoBoundaryCrossing(Particle& p, VTNType const& from, - VTNType const& to) { - this->start(); - auto r = T::DoBoundaryCrossing(p, from, to); - this->stop(); + VTNType const& to) { + auto tc = corsika::analytics::timeClass< + EProcessReturn (_ExecTimeImpl<T>::_T::*)(Particle&, VTNType const&, VTNType const&), + &_ExecTimeImpl<T>::_T::template DoBoundaryCrossing<Particle, VTNType>>(*this); + + EProcessReturn r = tc.call(p, from, to); + this->update( + std::chrono::duration_cast<std::chrono::duration<double, std::micro>>( + tc.getTime())); return r; } }; - } // namespace devtools + } // namespace analytic_processors } // namespace corsika::process \ No newline at end of file diff --git a/Processes/AnalyticProcessors/ImplContinuous.h b/Processes/AnalyticProcessors/ImplContinuous.h index ef36b8052..21b21ad6b 100644 --- a/Processes/AnalyticProcessors/ImplContinuous.h +++ b/Processes/AnalyticProcessors/ImplContinuous.h @@ -26,9 +26,9 @@ namespace corsika::process { private: public: template <typename Particle, typename Track> - EProcessReturn DoContinuous(Particle& p, Track const& t) const { + EProcessReturn DoContinuous(Particle& p, Track const& t) { this->start(); - auto r = T::DoContinous(p, t); + auto r = _ExecTimeImpl<T>::DoContinuous(p, t); this->stop(); return r; } @@ -41,5 +41,5 @@ namespace corsika::process { return r; } }; - } // namespace devtools + } // namespace analytic_processors } // namespace corsika::process \ No newline at end of file diff --git a/Processes/AnalyticProcessors/ImplDecay.h b/Processes/AnalyticProcessors/ImplDecay.h index b3ff6a8eb..e24ec159f 100644 --- a/Processes/AnalyticProcessors/ImplDecay.h +++ b/Processes/AnalyticProcessors/ImplDecay.h @@ -28,7 +28,7 @@ namespace corsika::process { template <typename Particle> EProcessReturn DoDecay(Particle& p) { this->start(); - auto r = T::DoDecay(p); + auto r = _ExecTimeImpl<T>::DoDecay(p); this->stop(); return r; } @@ -41,5 +41,5 @@ namespace corsika::process { return r; } }; - } // namespace devtools + } // namespace analytic_processors } // namespace corsika::process \ No newline at end of file diff --git a/Processes/AnalyticProcessors/ImplInteraction.h b/Processes/AnalyticProcessors/ImplInteraction.h index 4d1688d29..cf6786541 100644 --- a/Processes/AnalyticProcessors/ImplInteraction.h +++ b/Processes/AnalyticProcessors/ImplInteraction.h @@ -28,7 +28,7 @@ namespace corsika::process { template <typename Particle> EProcessReturn DoInteraction(Particle& p) { this->start(); - auto r = T::DoInteraction(p); + auto r = _ExecTimeImpl<T>::DoInteraction(p); this->stop(); return r; } @@ -41,5 +41,5 @@ namespace corsika::process { return r; } }; - } // namespace devtools + } // namespace analytic_processors } // namespace corsika::process \ No newline at end of file diff --git a/Processes/AnalyticProcessors/ImplSecondaries.h b/Processes/AnalyticProcessors/ImplSecondaries.h index 044c87252..42ceea871 100644 --- a/Processes/AnalyticProcessors/ImplSecondaries.h +++ b/Processes/AnalyticProcessors/ImplSecondaries.h @@ -28,10 +28,10 @@ namespace corsika::process { template <typename Secondaries> inline EProcessReturn DoSecondaries(Secondaries& sec) { this->start(); - auto r = T::DoSecondaries(sec); + auto r = _ExecTimeImpl<T>::DoSecondaries(sec); this->stop(); return r; } }; - } // namespace devtools + } // namespace analytic_processors } // namespace corsika::process \ No newline at end of file diff --git a/Processes/AnalyticProcessors/testExecTime.cc b/Processes/AnalyticProcessors/testExecTime.cc index 4b25c139e..f1bfa3537 100644 --- a/Processes/AnalyticProcessors/testExecTime.cc +++ b/Processes/AnalyticProcessors/testExecTime.cc @@ -19,6 +19,7 @@ #include <corsika/process/example_processors/DummySecondariesProcess.h> #include <random> +#include <vector> using namespace corsika::process; using namespace corsika::process::analytic_processors; @@ -26,21 +27,89 @@ using namespace corsika::process::example_processors; TEST_CASE("Timing process", "[proccesses][analytic_processors ExecTime]") { - ExecTime<DummyBoundaryCrossingProcess<50>> execTime; int tmp = 0; SECTION("BoundaryCrossing") { + ExecTime<DummyBoundaryCrossingProcess<10>> execTime; auto start = std::chrono::steady_clock::now(); REQUIRE(execTime.DoBoundaryCrossing(tmp, 0, 0) == EProcessReturn::eOk); auto end = std::chrono::steady_clock::now(); REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == - Approx(50).margin(5)); + Approx(10).margin(5)); for (int i = 0; i < 100; i++) execTime.DoBoundaryCrossing(tmp, 0, 0); + REQUIRE(execTime.mean() == Approx(10 * 1000).margin(2 * 1000)); + + REQUIRE(execTime.sumTime() == Approx(10 * 100 * 1000).margin((10 * 100) * 1000)); + + REQUIRE(execTime.var() == Approx(0).margin(20000)); + } + + SECTION("Continuous") { + ExecTime<DummyContinuousProcess<50>> execTime; + auto start = std::chrono::steady_clock::now(); + REQUIRE(execTime.DoContinuous(tmp, tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(50).margin(5)); + + for (int i = 0; i < 100; i++) execTime.DoContinuous(tmp, tmp); + REQUIRE(execTime.mean() == Approx(50 * 1000).margin(2 * 1000)); - REQUIRE(execTime.sumTime() == Approx(50 * 100 * 1000).margin(200 * 1000)); + REQUIRE(execTime.sumTime() == Approx(50 * 100 * 1000).margin((10 * 100) * 1000)); + + REQUIRE(execTime.var() == Approx(0).margin(20000)); + } + + SECTION("Decay") { + ExecTime<DummyDecayProcess<10>> execTime; + auto start = std::chrono::steady_clock::now(); + REQUIRE(execTime.DoDecay(tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(10).margin(5)); + + for (int i = 0; i < 100; i++) execTime.DoDecay(tmp); + + REQUIRE(execTime.mean() == Approx(10 * 1000).margin(2 * 1000)); + + REQUIRE(execTime.sumTime() == Approx(10 * 100 * 100).margin((10 * 100) * 1000)); + + REQUIRE(execTime.var() == Approx(0).margin(20000)); + } + + SECTION("Interaction") { + ExecTime<DummyInteractionProcess<10>> execTime; + auto start = std::chrono::steady_clock::now(); + REQUIRE(execTime.DoInteraction(tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(10).margin(5)); + + for (int i = 0; i < 100; i++) execTime.DoInteraction(tmp); + + REQUIRE(execTime.mean() == Approx(10 * 1000).margin(2 * 1000)); + + REQUIRE(execTime.sumTime() == Approx(10 * 100 * 1000).margin((10 * 100) * 1000)); + + REQUIRE(execTime.var() == Approx(0).margin(20000)); + } + + SECTION("Secondaries") { + ExecTime<DummySecondariesProcess<10>> execTime; + auto start = std::chrono::steady_clock::now(); + REQUIRE(execTime.DoSecondaries(tmp) == EProcessReturn::eOk); + auto end = std::chrono::steady_clock::now(); + REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == + Approx(10).margin(5)); + + for (int i = 0; i < 100; i++) execTime.DoSecondaries(tmp); + + REQUIRE(execTime.mean() == Approx(10 * 1000).margin(2 * 1000)); + + REQUIRE(execTime.sumTime() == Approx(10 * 100 * 1000).margin((10 * 100) * 1000)); REQUIRE(execTime.var() == Approx(0).margin(20000)); } @@ -49,16 +118,19 @@ TEST_CASE("Timing process", "[proccesses][analytic_processors ExecTime]") { std::default_random_engine generator; std::normal_distribution<double> distribution(10000.0, 200.0); - double fStart; - double fElapsedSum; - double fMean; - double fMean2; - long long fMin; - long long fMax; - long long fN; + double fElapsedSum = 0; + double fMean = 0; + double fMean2 = 0; + long long fMin = std::numeric_limits<long long>::max(); + long long fMax = std::numeric_limits<long long>::min(); + int fN = 0; + + std::vector<double> elems; for (int i = 0; i < 1000000; i++) { - auto timeDiv = distribution(generator); + double timeDiv = distribution(generator); + + elems.push_back(timeDiv); fElapsedSum += timeDiv; fN = fN + 1; @@ -75,7 +147,21 @@ TEST_CASE("Timing process", "[proccesses][analytic_processors ExecTime]") { fMean2 += delta * delta2; } - REQUIRE(fMean2 / fN == Approx(200*200).margin(200)); // Varianz + REQUIRE(fN == 1000000); + + double mean = 0; + std::for_each(elems.begin(), elems.end(), [&](double i) { mean += i; }); + mean = mean / fN; + + double var = 0; + std::for_each(elems.begin(), elems.end(), + [&](double i) { var += (mean - i) * (mean - i); }); + var = var / fN; + + REQUIRE(mean == Approx(10000.0).margin(10)); + REQUIRE(var == Approx(200.0 * 200).margin(200)); + + REQUIRE(fMean2 / fN == Approx(200 * 200).margin(200)); // Varianz REQUIRE(fMean == Approx(10000).margin(10)); } } diff --git a/Processes/ExampleProcessors/DummyBoundaryCrossingProcess.h b/Processes/ExampleProcessors/DummyBoundaryCrossingProcess.h index 2925c8c58..936a65a51 100644 --- a/Processes/ExampleProcessors/DummyBoundaryCrossingProcess.h +++ b/Processes/ExampleProcessors/DummyBoundaryCrossingProcess.h @@ -20,12 +20,14 @@ namespace corsika::process { class DummyBoundaryCrossingProcess : public BoundaryCrossingProcess<DummyBoundaryCrossingProcess<ISleep>> { private: + protected: + public: template <typename Particle, typename VTNType> EProcessReturn DoBoundaryCrossing(Particle&, VTNType const&, VTNType const&) { std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return EProcessReturn::eOk; - } + } }; } // namespace example_processors diff --git a/Processes/ExampleProcessors/DummyContinuousProcess.h b/Processes/ExampleProcessors/DummyContinuousProcess.h index 60da8466e..85cf23769 100644 --- a/Processes/ExampleProcessors/DummyContinuousProcess.h +++ b/Processes/ExampleProcessors/DummyContinuousProcess.h @@ -22,13 +22,13 @@ namespace corsika::process { private: public: template <typename Particle, typename Track> - EProcessReturn DoContinuous(Particle&, Track const&) const { + inline EProcessReturn DoContinuous(Particle&, Track const&) const { std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return process::EProcessReturn::eOk; } template <typename Particle, typename Track> - units::si::LengthType MaxStepLength(Particle const&, Track const&) const { + inline units::si::LengthType MaxStepLength(Particle const&, Track const&) const { std::this_thread::sleep_for(std::chrono::milliseconds(ISleep)); return units::si::meter * std::numeric_limits<double>::infinity(); } diff --git a/Processes/ExampleProcessors/DummyDecayProcess.h b/Processes/ExampleProcessors/DummyDecayProcess.h index 19b3a5594..b2546e529 100644 --- a/Processes/ExampleProcessors/DummyDecayProcess.h +++ b/Processes/ExampleProcessors/DummyDecayProcess.h @@ -18,7 +18,7 @@ namespace corsika::process { namespace example_processors { template <int ISleep> - class DummyDecayProcess : DecayProcess<DummyDecayProcess<ISleep>> { + class DummyDecayProcess : public DecayProcess<DummyDecayProcess<ISleep>> { private: public: template <typename Particle> diff --git a/Processes/ExampleProcessors/DummyInteractionProcess.h b/Processes/ExampleProcessors/DummyInteractionProcess.h index b69f69702..51e9bfbe8 100644 --- a/Processes/ExampleProcessors/DummyInteractionProcess.h +++ b/Processes/ExampleProcessors/DummyInteractionProcess.h @@ -17,7 +17,7 @@ namespace corsika::process { namespace example_processors { template <int ISleep> - class DummyInteractionProcess : InteractionProcess<DummyInteractionProcess<ISleep> > { + class DummyInteractionProcess : public InteractionProcess<DummyInteractionProcess<ISleep> > { private: public: template <typename Particle> diff --git a/Processes/ExampleProcessors/DummySecondariesProcess.h b/Processes/ExampleProcessors/DummySecondariesProcess.h index 980d909be..848e88411 100644 --- a/Processes/ExampleProcessors/DummySecondariesProcess.h +++ b/Processes/ExampleProcessors/DummySecondariesProcess.h @@ -17,7 +17,7 @@ namespace corsika::process { namespace example_processors { template <int ISleep> - class DummySecondariesProcess : SecondariesProcess<DummySecondariesProcess<ISleep>> { + class DummySecondariesProcess : public SecondariesProcess<DummySecondariesProcess<ISleep>> { private: public: template <typename TSecondaries> -- GitLab