From 3e26756f1dfe1ddd1d7f5e458771c9bf79acb09a Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Fri, 7 Aug 2015 09:59:12 +0100 Subject: 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. --- src/base/types.hh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src') 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 #include #include +#include #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); -- cgit v1.2.3