mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-20 01:51:26 +02:00
Update to v106r79 release.
byuu says: This WIP is just work on nall/primitives ... Basically, I'm coming to the conclusion that it's just not practical to try and make Natural/Integer implicitly castable to primitive signed and unsigned integers. C++ just has too many edge cases there. I also want to get away from the problem of C++ deciding that all math operations return 32-bit values, unless one of the parameters is 64-bit, in which case you get a 64-bit value. You know, so things like array[-1] won't end up accessing the 4 billionth element of the array. It's nice to be fancy and minimally size operations (eg 32-bit+32-bit = 33-bit), but it's just too unintuitive. I think all Natural<X>+Natural<Y> expessions should result in a Natural<64> (eg natural) type. nall/primitives/operators.hpp has been removed, and new Natural<>Natural / Integer<>Integer casts exist. My feeling is that signed and unsigned types should not be implicitly convertible where data loss can occur. In the future, I think an integer8*natural8 is fine to return an integer64, and the bitwise operators are probably all fine between the two types. I could probably add (Integer,Natural)+Boolean conversions as well. To simplify expressions, there are new user-defined literals for _b (boolean), _n (natural), _i (integer), _r (real), _n# (eg _n8), _i# (eg _i8), _r# (eg _r32), and _s (nall::string). In the long-term, my intention is to make the conversion and cast constructors explicit for primitive types, but obviously that'll shatter most of higan, so for now that won't be the case. Something I can do in the future is allow implicit conversion and casting to (u)int64_t. That may be a nice balance.
This commit is contained in:
@@ -16,8 +16,10 @@ template<int Requested> struct Integer {
|
||||
static inline constexpr auto sign() -> utype { return 1ull << Precision - 1; }
|
||||
|
||||
inline Integer() : data(0) {}
|
||||
template<int Bits> inline Integer(Integer<Bits> value) { data = mask(value); }
|
||||
template<typename T> inline Integer(const T& value) { data = mask(value); }
|
||||
|
||||
explicit inline operator bool() const { return data; }
|
||||
inline operator type() const { return data; }
|
||||
|
||||
inline auto operator++(int) { auto value = *this; data = mask(data + 1); return value; }
|
||||
@@ -45,7 +47,7 @@ template<int Requested> struct Integer {
|
||||
template<typename T> inline auto& operator ^=(const T& value) { lhs = mask(lhs ^ rhs); return *this; }
|
||||
template<typename T> inline auto& operator |=(const T& value) { lhs = mask(lhs | rhs); return *this; }
|
||||
#undef lhs
|
||||
#undef rfs
|
||||
#undef rhs
|
||||
|
||||
inline auto bits(int lo, int hi) -> BitRange<Requested> { return {(utype&)data, lo, hi}; }
|
||||
inline auto bit(int index) -> BitRange<Requested> { return {(utype&)data, index, index}; }
|
||||
@@ -78,4 +80,29 @@ private:
|
||||
type data;
|
||||
};
|
||||
|
||||
#define ALL 64
|
||||
#define ADD 64 //LHS + RHS
|
||||
#define INC 64 //1 + (LHS >= RHS ? LHS : RHS)
|
||||
#define MAX 64 //LHS >= RHS ? LHS : RHS
|
||||
#define MIN 64 //LHS <= RHS ? LHS : RHS
|
||||
#define lhs (int64_t)(typename Integer<LHS>::type)l
|
||||
#define rhs (typename Integer<RHS>::type)r
|
||||
template<int LHS, int RHS> inline auto operator *(Integer<LHS> l, Integer<RHS> r) { return Integer<ADD>{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator /(Integer<LHS> l, Integer<RHS> r) { return Integer<LHS>{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator %(Integer<LHS> l, Integer<RHS> r) { return Integer<LHS>{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator +(Integer<LHS> l, Integer<RHS> r) { return Integer<INC>{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator -(Integer<LHS> l, Integer<RHS> r) { return Integer<INC>{lhs - rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator<<(Integer<LHS> l, Integer<RHS> r) { return Integer<ALL>{lhs << rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator>>(Integer<LHS> l, Integer<RHS> r) { return Integer<LHS>{lhs >> rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator &(Integer<LHS> l, Integer<RHS> r) { return Integer<MAX>{lhs & rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator ^(Integer<LHS> l, Integer<RHS> r) { return Integer<MAX>{lhs ^ rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator |(Integer<LHS> l, Integer<RHS> r) { return Integer<MAX>{lhs | rhs}; }
|
||||
#undef ALL
|
||||
#undef ADD
|
||||
#undef INC
|
||||
#undef MAX
|
||||
#undef MIN
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user