From 9048e0aa8734f7f7c6883f94dd5482bef81a926e Mon Sep 17 00:00:00 2001
From: Dominik Baack <dominik.baack@tu-dortmund.de>
Date: Mon, 5 Oct 2020 14:56:23 +0200
Subject: [PATCH] New timer class added for cleaner structure

---
 Framework/Analytics/CMakeLists.txt   |  6 +++
 Framework/Analytics/Timer.h          | 67 ++++++++++++++++++++++++++++
 Framework/Analytics/testAnalytics.cc | 61 +++++++++++++++++++++++++
 3 files changed, 134 insertions(+)
 create mode 100644 Framework/Analytics/Timer.h
 create mode 100644 Framework/Analytics/testAnalytics.cc

diff --git a/Framework/Analytics/CMakeLists.txt b/Framework/Analytics/CMakeLists.txt
index 935ddaba5..a9d33ea09 100644
--- a/Framework/Analytics/CMakeLists.txt
+++ b/Framework/Analytics/CMakeLists.txt
@@ -45,6 +45,7 @@ install (
 # ----------------
 # code unit testing
 
+<<<<<<< HEAD
 CORSIKA_ADD_TEST (testFunctionTimer)
 target_link_libraries (
  testFunctionTimer
@@ -55,6 +56,11 @@ target_link_libraries (
  CORSIKA_ADD_TEST (testClassTimer)
 target_link_libraries (
  testClassTimer
+=======
+CORSIKA_ADD_TEST (testAnalytics)
+target_link_libraries (
+ testAnalytics
+>>>>>>> New timer class added for cleaner structure
  CORSIKAanalytics
  CORSIKAtesting
  )
diff --git a/Framework/Analytics/Timer.h b/Framework/Analytics/Timer.h
new file mode 100644
index 000000000..4d305be0e
--- /dev/null
+++ b/Framework/Analytics/Timer.h
@@ -0,0 +1,67 @@
+/*
+ * (c) Copyright 2019 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.
+ */
+
+// Another possibility:
+// https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Execute-Around_Pointer
+
+#pragma once
+
+#include <chrono>
+#include <utility>
+
+namespace corsika::analytics {
+
+  template <typename TFunc, typename TClock = std::chrono::high_resolution_clock,
+            typename TDuration = std::chrono::microseconds>
+  class timeFunction {
+  private:
+    typename TClock::time_point vStart;
+    TDuration vDiff;
+
+    TFunc vFunction;
+
+  public:
+    timeFunction(TFunc f)
+        : vFunction(f) {}
+
+    template <typename... TArgs>
+    auto operator()(TArgs&&... args) -> std::invoke_result_t<TFunc, TArgs...> {
+      vStart = TClock::now();
+      auto tmp = vFunction(std::forward<TArgs>(args)...);
+      vDiff = std::chrono::duration_cast<TDuration>(TClock::now() - vStart);
+      return tmp;
+    }
+
+    inline TDuration getTime() const { return vDiff; }
+  };
+
+  template <typename TClass, typename TClock = std::chrono::high_resolution_clock,
+            typename TDuration = std::chrono::microseconds>
+  class timeProxy : public TClass {
+  private:
+    typename TClock::time_point vStart;
+    TDuration vDiff;
+
+    TClass& vObj;
+
+    /*template <typename F, typename... Args>
+    decltype(auto) call_func(F func, Args&&... args) {
+      return (vObj.*func)(std::forward<Args>(args)...);
+    }*/
+
+  public:
+    template<typename ... TArgs>
+    timeProxy(TArgs args) : TClass<TArgs...>(std::forward<TArgs>(args)...)
+    {}
+
+    auto operator->() {return 2;}
+
+    inline TDuration getTime() const { return vDiff; }
+  };
+
+} // namespace corsika::analytics
diff --git a/Framework/Analytics/testAnalytics.cc b/Framework/Analytics/testAnalytics.cc
new file mode 100644
index 000000000..8b4edbebb
--- /dev/null
+++ b/Framework/Analytics/testAnalytics.cc
@@ -0,0 +1,61 @@
+/*
+ * (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
+ * the license.
+ */
+
+#include <corsika/analytics/Timer.h>
+
+#include <catch2/catch.hpp>
+
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+using namespace corsika;
+
+int testFunc() {
+  std::this_thread::sleep_for(std::chrono::milliseconds(100));
+  return 31415;
+}
+
+class testClass {
+public:
+  int testFunc() {
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    return 31415;
+  }
+
+  int operator()() {
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    return 31415;
+  }
+};
+
+TEST_CASE("Analytics", "[Timer]") {
+  SECTION("Measure runtime of a free function") {
+
+    auto test = corsika::analytics::timeFunction(testFunc);
+
+    std::cout << test() << std::endl;
+    std::cout << test.getTime().count() << std::endl;
+  }
+
+  SECTION("Measure runtime of a class functor") {
+    testClass testC;
+    auto test = corsika::analytics::timeFunction(testC);
+
+    std::cout << test() << std::endl;
+    std::cout << test.getTime().count() << std::endl;
+  }
+
+  SECTION("Measure runtime of a class member function") {
+    testClass testC;
+    auto test = corsika::analytics::timeProxy<testClass>();
+
+    std::cout << test() << std::endl;
+    std::cout << test.getTime().count() << std::endl;
+  }
+}
-- 
GitLab