From b7b4c99bc9a3139d635d705314cc05a984502e13 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 9 Aug 2020 14:12:31 -0600 Subject: [PATCH] Temporal: add new arithmetic operators allowing more inter-operability of int64_t/int62_t; make operator int64_t explicit to avoid hidden use --- libs/pbd/pbd/int62.h | 81 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/libs/pbd/pbd/int62.h b/libs/pbd/pbd/int62.h index 490312384f..2cfb57f6cf 100644 --- a/libs/pbd/pbd/int62.h +++ b/libs/pbd/pbd/int62.h @@ -72,17 +72,17 @@ class alignas(16) int62_t { int62_t operator- () const { int64_t tmp = v; return int62_t (flagged (tmp), -int62(tmp)); } - int62_t operator+ (int n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) + n); } - int62_t operator- (int n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) - n); } - int62_t operator* (int n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) * n); } - int62_t operator/ (int n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) / n); } - int62_t operator% (int n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) % n); } + int62_t operator+ (int64_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) + n); } + int62_t operator- (int64_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) - n); } + int62_t operator* (int64_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) * n); } + int62_t operator/ (int64_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) / n); } + int62_t operator% (int64_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) % n); } - int62_t operator+ (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) + n); } - int62_t operator- (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) - n); } - int62_t operator* (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) * n); } - int62_t operator/ (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) / n); } - int62_t operator% (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) % n); } + int62_t operator+ (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) + n.val()); } + int62_t operator- (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) - n.val()); } + int62_t operator* (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) * n.val()); } + int62_t operator/ (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) / n.val()); } + int62_t operator% (int62_t n) const { int64_t tmp = v; return int62_t (flagged (tmp), int62 (tmp) % n.val()); } /* comparison operators .. will throw if the two objects have different * flag settings (which is assumed to indicate that they differ in some @@ -101,7 +101,14 @@ class alignas(16) int62_t { bool operator!= (int62_t const & other) const { if (flagged() != other.flagged()) throw flag_mismatch(); return val() != other.val(); } bool operator== (int62_t const & other) const { if (flagged() != other.flagged()) throw flag_mismatch(); return val() == other.val(); } - operator int64_t() const { return int62(v); } + explicit operator int64_t() const { return int62(v); } + + bool operator< (int64_t n) const { return val() < n; } + bool operator<= (int64_t n) const { return val() <= n; } + bool operator> (int64_t n) const { return val() > n; } + bool operator>= (int64_t n) const { return val() >= n; } + bool operator!= (int64_t n) const { return val() != n; } + bool operator== (int64_t n) const { return val() == n; } int62_t abs() const { int64_t tmp = v; return int62_t (flagged(tmp), ::abs(int62(tmp))); } @@ -156,7 +163,57 @@ class alignas(16) int62_t { return *this; } - bool operator== (int64_t vv) const { return val() == v; } + int62_t& operator+= (int62_t n) { + while (1) { + int64_t oldval (v); + int64_t newval = build (flagged (oldval), int62 (oldval) + n.val()); + if (v.compare_exchange_strong (oldval, newval)) { + break; + } + } + return *this; + } + int62_t& operator-= (int62_t n) { + while (1) { + int64_t oldval (v); + int64_t newval = build (flagged (oldval), int62 (oldval) - n.val()); + if (v.compare_exchange_strong (oldval, newval)) { + break; + } + } + return *this; + } + int62_t& operator*= (int62_t n) { + while (1) { + int64_t oldval (v); + int64_t newval = build (flagged (oldval), int62 (oldval) * n.val()); + if (v.compare_exchange_strong (oldval, newval)) { + break; + } + } + return *this; + } + int62_t& operator/= (int62_t n) { + while (1) { + int64_t oldval (v); + int64_t newval = build (flagged (oldval), int62 (oldval) / n.val()); + if (v.compare_exchange_strong (oldval, newval)) { + break; + } + } + return *this; + } + int62_t& operator%= (int62_t n) { + while (1) { + int64_t oldval (v); + int64_t newval = build (flagged (oldval), int62 (oldval) % n.val()); + if (v.compare_exchange_strong (oldval, newval)) { + break; + } + } + return *this; + } + }; namespace std {