base: Make the Value stat's functor method accept lambdas.
This class can already accept a proxy variable and a "functor" which is a pointer to either a function or an instance of a class with the () operator overloaded. This change adds a FunctorProxy partial specialization which accepts anything that can be used to construct a std::function<Result()>. The constructor argument is copied and stored in the proxy which makes it possible to define a lambda inline without having to keep a copy of it around for the proxy to point to. Also, the ValueBase stat's functor method now has a second version which accepts a const reference rather than just a reference to its argument. We need both because when accepting a reference to a lambda it needs to be a const reference, but when accepting a pointer to a functor object, we don't want it to be const because that would force the () operator to also be const. Change-Id: Icb1b3682d51b721f6e16614490ed0fe289cee094 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/32901 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -791,7 +791,7 @@ class ValueProxy : public ProxyInfo
|
||||
Result total() const { return *scalar; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
template <class T, class Enabled=void>
|
||||
class FunctorProxy : public ProxyInfo
|
||||
{
|
||||
private:
|
||||
@@ -804,6 +804,27 @@ class FunctorProxy : public ProxyInfo
|
||||
Result total() const { return (*functor)(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Template specialization for type std::function<Result()> which holds a copy
|
||||
* of its target instead of a pointer to it. This makes it possible to use a
|
||||
* lambda or other type inline without having to keep track of an instance
|
||||
* somewhere else.
|
||||
*/
|
||||
template <class T>
|
||||
class FunctorProxy<T,
|
||||
typename std::enable_if<std::is_constructible<std::function<Result()>,
|
||||
const T &>::value>::type> : public ProxyInfo
|
||||
{
|
||||
private:
|
||||
std::function<Result()> functor;
|
||||
|
||||
public:
|
||||
FunctorProxy(const T &func) : functor(func) {}
|
||||
Counter value() const { return functor(); }
|
||||
Result result() const { return functor(); }
|
||||
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.
|
||||
@@ -847,6 +868,15 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
|
||||
return this->self();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Derived &
|
||||
functor(const T &func)
|
||||
{
|
||||
proxy = new FunctorProxy<T>(func);
|
||||
this->setInit();
|
||||
return this->self();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Derived &
|
||||
functor(T &func)
|
||||
|
||||
@@ -88,6 +88,7 @@ struct StatTest
|
||||
Vector2d s16;
|
||||
Value s17;
|
||||
Value s18;
|
||||
Value s19;
|
||||
Histogram h01;
|
||||
Histogram h02;
|
||||
Histogram h03;
|
||||
@@ -102,8 +103,8 @@ struct StatTest
|
||||
Histogram h12;
|
||||
SparseHistogram sh1;
|
||||
|
||||
Vector s19;
|
||||
Vector s20;
|
||||
Vector s21;
|
||||
|
||||
Formula f1;
|
||||
Formula f2;
|
||||
@@ -254,6 +255,12 @@ StatTest::init()
|
||||
.desc("this is stat 18")
|
||||
;
|
||||
|
||||
s19
|
||||
.functor([]() { return 0; })
|
||||
.name("Stat19")
|
||||
.desc("this is stat 19")
|
||||
;
|
||||
|
||||
h01
|
||||
.init(11)
|
||||
.name("Histogram01")
|
||||
@@ -361,18 +368,18 @@ StatTest::init()
|
||||
.desc("this is formula 4")
|
||||
;
|
||||
|
||||
s19
|
||||
.init(2)
|
||||
.name("Stat19")
|
||||
.desc("this is statistic 19 for vector op testing")
|
||||
.flags(total | nozero | nonan)
|
||||
;
|
||||
s20
|
||||
.init(2)
|
||||
.name("Stat20")
|
||||
.desc("this is statistic 20 for vector op testing")
|
||||
.flags(total | nozero | nonan)
|
||||
;
|
||||
s21
|
||||
.init(2)
|
||||
.name("Stat21")
|
||||
.desc("this is statistic 21 for vector op testing")
|
||||
.flags(total | nozero | nonan)
|
||||
;
|
||||
|
||||
f6
|
||||
.name("vector_op_test_formula")
|
||||
@@ -386,7 +393,7 @@ StatTest::init()
|
||||
f4 += constant(10.0);
|
||||
f4 += s5[3];
|
||||
f5 = constant(1);
|
||||
f6 = s19/s20;
|
||||
f6 = s20/s21;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -663,10 +670,10 @@ StatTest::run()
|
||||
sh1.sample(random() % 10000);
|
||||
}
|
||||
|
||||
s19[0] = 1;
|
||||
s19[1] = 100000;
|
||||
s20[0] = 100000;
|
||||
s20[1] = 1;
|
||||
s20[0] = 1;
|
||||
s20[1] = 100000;
|
||||
s21[0] = 100000;
|
||||
s21[1] = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user