stats: Method stats source
authorStephan Diestelhorst <stephan.diestelhorst@arm.com>
Fri, 9 May 2014 22:58:46 +0000 (18:58 -0400)
committerStephan Diestelhorst <stephan.diestelhorst@arm.com>
Fri, 9 May 2014 22:58:46 +0000 (18:58 -0400)
This source for stats binds an object and a method / function from the object
to a stats object. This allows pulling out stats from object methods without
needing to go through a global, or static shim.

Syntax is somewhat unpleasant, but the templates and method pointer type
specification were quite tricky.  Interface is very clean though; and similar
to .functor

src/base/statistics.hh

index 048c1be8601c44657b82e4d92d92a2c1b89a1a13..fbf8ee7698ed26d19afe5208a20604ef3aef1660 100644 (file)
@@ -777,6 +777,25 @@ class FunctorProxy : public ProxyInfo
     Result total() const { return (*functor)(); }
 };
 
+/**
+ * A proxy similar to the FunctorProxy, but allows calling a method of a bound
+ * object, instead of a global free-standing function.
+ */
+template <class T, class V>
+class MethodProxy : public ProxyInfo
+{
+  private:
+    T *object;
+    typedef V (T::*MethodPointer) () const;
+    MethodPointer method;
+
+  public:
+    MethodProxy(T *obj, MethodPointer meth) : object(obj), method(meth) {}
+    Counter value() const { return (object->*method)(); }
+    Result result() const { return (object->*method)(); }
+    Result total() const { return (object->*method)(); }
+};
+
 template <class Derived>
 class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
 {
@@ -805,6 +824,22 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
         return this->self();
     }
 
+    /**
+     * Extended functor that calls the specified method of the provided object.
+     *
+     * @param obj Pointer to the object whose method should be called.
+     * @param method Pointer of the function / method of the object.
+     * @return Updated stats item.
+     */
+    template <class T, class V>
+    Derived &
+    method(T *obj,  V (T::*method)() const)
+    {
+        proxy = new MethodProxy<T,V>(obj, method);
+        this->setInit();
+        return this->self();
+    }
+
     Counter value() { return proxy->value(); }
     Result result() const { return proxy->result(); }
     Result total() const { return proxy->total(); };