summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2015-08-07 09:59:12 +0100
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2015-08-07 09:59:12 +0100
commit3e26756f1dfe1ddd1d7f5e458771c9bf79acb09a (patch)
tree6d189d36689d70e7ce905492af89c8d7d43673e2 /src
parent83a668ad2564d1231f59f130c81cab6e7e31c364 (diff)
downloadgem5-3e26756f1dfe1ddd1d7f5e458771c9bf79acb09a.tar.xz
base: Use constexpr in Cycles
Declare the constructor and all of the operators that don't change the state of a Cycles instance as constexpr. This makes it possible to use Cycles as a static constant and allows the compiler to evaulate simple expressions at compile time. An unfortunate side-effect of this is that we cannot use assertions since C++11 doesn't support them in constexpr functions. As a workaround, we throw an invalid_argument exception when the assert would have triggered. A nice side-effect of this is that the compiler will evaluate the "assertion" at compile time when an expression involving Cycles can be statically evaluated.
Diffstat (limited to 'src')
-rw-r--r--src/base/types.hh24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/base/types.hh b/src/base/types.hh
index 2b6e3f11b..3d53e6ba0 100644
--- a/src/base/types.hh
+++ b/src/base/types.hh
@@ -42,6 +42,7 @@
#include <cassert>
#include <memory>
#include <ostream>
+#include <stdexcept>
#include "base/refcnt.hh"
@@ -90,8 +91,12 @@ class Cycles
public:
+#ifndef SWIG // SWIG gets confused by constexpr
/** Explicit constructor assigning a value. */
+ explicit constexpr Cycles(uint64_t _c) : c(_c) { }
+#else
explicit Cycles(uint64_t _c) : c(_c) { }
+#endif
/** Default constructor for parameter classes. */
Cycles() : c(0) { }
@@ -99,7 +104,7 @@ class Cycles
#ifndef SWIG // keep the operators away from SWIG
/** Converting back to the value type. */
- operator uint64_t() const { return c; }
+ constexpr operator uint64_t() const { return c; }
/** Prefix increment operator. */
Cycles& operator++()
@@ -110,23 +115,26 @@ class Cycles
{ assert(c != 0); --c; return *this; }
/** In-place addition of cycles. */
- const Cycles& operator+=(const Cycles& cc)
+ Cycles& operator+=(const Cycles& cc)
{ c += cc.c; return *this; }
/** Greater than comparison used for > Cycles(0). */
- bool operator>(const Cycles& cc) const
+ constexpr bool operator>(const Cycles& cc) const
{ return c > cc.c; }
- const Cycles operator +(const Cycles& b) const
+ constexpr Cycles operator +(const Cycles& b) const
{ return Cycles(c + b.c); }
- const Cycles operator -(const Cycles& b) const
- { assert(c >= b.c); return Cycles(c - b.c); }
+ constexpr Cycles operator -(const Cycles& b) const
+ {
+ return c >= b.c ? Cycles(c - b.c) :
+ throw std::invalid_argument("RHS cycle value larger than LHS");
+ }
- const Cycles operator <<(const int32_t shift)
+ constexpr Cycles operator <<(const int32_t shift) const
{ return Cycles(c << shift); }
- const Cycles operator >>(const int32_t shift)
+ constexpr Cycles operator >>(const int32_t shift) const
{ return Cycles(c >> shift); }
friend std::ostream& operator<<(std::ostream &out, const Cycles & cycles);