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