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.
This commit is contained in:
parent
83a668ad25
commit
3e26756f1d
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue