mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
6871e0e32a
commit
17fc6d8d51
|
@ -30,7 +30,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "106.78";
|
||||
static const string Version = "106.79";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "https://byuu.org/";
|
||||
|
|
|
@ -171,9 +171,10 @@ auto TLCS900H::instructionLoadCarry(Source source, Offset offset) -> void {
|
|||
//note: an 8-bit lookup table is faster (when in L1/L2 cache), but much more code
|
||||
auto TLCS900H::instructionMirror(Register<uint16> register) -> void {
|
||||
auto data = load(register);
|
||||
uint8 lo = (data.byte(0) * 0x80200802ull & 0x884422110ull) * 0x101010101ull >> 32;
|
||||
uint8 hi = (data.byte(1) * 0x80200802ull & 0x884422110ull) * 0x101010101ull >> 32;
|
||||
store(register, lo << 8 | hi << 0);
|
||||
data = data << 1 & 0xaaaa | data >> 1 & 0x5555;
|
||||
data = data << 2 & 0xcccc | data >> 2 & 0x3333;
|
||||
data = data << 4 & 0xf0f0 | data >> 4 & 0x0f0f;
|
||||
store(register, data << 8 | data >> 8);
|
||||
}
|
||||
|
||||
template<typename Target, typename Source>
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace nall {
|
|||
#include <nall/primitives/integer.hpp>
|
||||
#include <nall/primitives/real.hpp>
|
||||
#include <nall/primitives/types.hpp>
|
||||
//#include <nall/primitives/operators.hpp>
|
||||
#include <nall/primitives/literals.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<int Bits> auto Natural<Bits>::integer() const -> Integer<Bits> { return Integer<Bits>(*this); }
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#pragma once
|
||||
|
||||
namespace nall {
|
||||
|
||||
inline auto operator"" _b(unsigned long long value) { return boolean{value}; }
|
||||
inline auto operator"" _n(unsigned long long value) { return natural{value}; }
|
||||
inline auto operator"" _i(unsigned long long value) { return integer{value}; }
|
||||
inline auto operator"" _r(long double value) { return real{value}; }
|
||||
|
||||
inline auto operator"" _n1(unsigned long long value) { return natural1{value}; }
|
||||
inline auto operator"" _n2(unsigned long long value) { return natural2{value}; }
|
||||
inline auto operator"" _n3(unsigned long long value) { return natural3{value}; }
|
||||
inline auto operator"" _n4(unsigned long long value) { return natural4{value}; }
|
||||
inline auto operator"" _n5(unsigned long long value) { return natural5{value}; }
|
||||
inline auto operator"" _n6(unsigned long long value) { return natural6{value}; }
|
||||
inline auto operator"" _n7(unsigned long long value) { return natural7{value}; }
|
||||
inline auto operator"" _n8(unsigned long long value) { return natural8{value}; }
|
||||
inline auto operator"" _n9(unsigned long long value) { return natural9{value}; }
|
||||
inline auto operator"" _n10(unsigned long long value) { return natural10{value}; }
|
||||
inline auto operator"" _n11(unsigned long long value) { return natural11{value}; }
|
||||
inline auto operator"" _n12(unsigned long long value) { return natural12{value}; }
|
||||
inline auto operator"" _n13(unsigned long long value) { return natural13{value}; }
|
||||
inline auto operator"" _n14(unsigned long long value) { return natural14{value}; }
|
||||
inline auto operator"" _n15(unsigned long long value) { return natural15{value}; }
|
||||
inline auto operator"" _n16(unsigned long long value) { return natural16{value}; }
|
||||
inline auto operator"" _n17(unsigned long long value) { return natural17{value}; }
|
||||
inline auto operator"" _n18(unsigned long long value) { return natural18{value}; }
|
||||
inline auto operator"" _n19(unsigned long long value) { return natural19{value}; }
|
||||
inline auto operator"" _n20(unsigned long long value) { return natural20{value}; }
|
||||
inline auto operator"" _n21(unsigned long long value) { return natural21{value}; }
|
||||
inline auto operator"" _n22(unsigned long long value) { return natural22{value}; }
|
||||
inline auto operator"" _n23(unsigned long long value) { return natural23{value}; }
|
||||
inline auto operator"" _n24(unsigned long long value) { return natural24{value}; }
|
||||
inline auto operator"" _n25(unsigned long long value) { return natural25{value}; }
|
||||
inline auto operator"" _n26(unsigned long long value) { return natural26{value}; }
|
||||
inline auto operator"" _n27(unsigned long long value) { return natural27{value}; }
|
||||
inline auto operator"" _n28(unsigned long long value) { return natural28{value}; }
|
||||
inline auto operator"" _n29(unsigned long long value) { return natural29{value}; }
|
||||
inline auto operator"" _n30(unsigned long long value) { return natural30{value}; }
|
||||
inline auto operator"" _n31(unsigned long long value) { return natural31{value}; }
|
||||
inline auto operator"" _n32(unsigned long long value) { return natural32{value}; }
|
||||
inline auto operator"" _n33(unsigned long long value) { return natural33{value}; }
|
||||
inline auto operator"" _n34(unsigned long long value) { return natural34{value}; }
|
||||
inline auto operator"" _n35(unsigned long long value) { return natural35{value}; }
|
||||
inline auto operator"" _n36(unsigned long long value) { return natural36{value}; }
|
||||
inline auto operator"" _n37(unsigned long long value) { return natural37{value}; }
|
||||
inline auto operator"" _n38(unsigned long long value) { return natural38{value}; }
|
||||
inline auto operator"" _n39(unsigned long long value) { return natural39{value}; }
|
||||
inline auto operator"" _n40(unsigned long long value) { return natural40{value}; }
|
||||
inline auto operator"" _n41(unsigned long long value) { return natural41{value}; }
|
||||
inline auto operator"" _n42(unsigned long long value) { return natural42{value}; }
|
||||
inline auto operator"" _n43(unsigned long long value) { return natural43{value}; }
|
||||
inline auto operator"" _n44(unsigned long long value) { return natural44{value}; }
|
||||
inline auto operator"" _n45(unsigned long long value) { return natural45{value}; }
|
||||
inline auto operator"" _n46(unsigned long long value) { return natural46{value}; }
|
||||
inline auto operator"" _n47(unsigned long long value) { return natural47{value}; }
|
||||
inline auto operator"" _n48(unsigned long long value) { return natural48{value}; }
|
||||
inline auto operator"" _n49(unsigned long long value) { return natural49{value}; }
|
||||
inline auto operator"" _n50(unsigned long long value) { return natural50{value}; }
|
||||
inline auto operator"" _n51(unsigned long long value) { return natural51{value}; }
|
||||
inline auto operator"" _n52(unsigned long long value) { return natural52{value}; }
|
||||
inline auto operator"" _n53(unsigned long long value) { return natural53{value}; }
|
||||
inline auto operator"" _n54(unsigned long long value) { return natural54{value}; }
|
||||
inline auto operator"" _n55(unsigned long long value) { return natural55{value}; }
|
||||
inline auto operator"" _n56(unsigned long long value) { return natural56{value}; }
|
||||
inline auto operator"" _n57(unsigned long long value) { return natural57{value}; }
|
||||
inline auto operator"" _n58(unsigned long long value) { return natural58{value}; }
|
||||
inline auto operator"" _n59(unsigned long long value) { return natural59{value}; }
|
||||
inline auto operator"" _n60(unsigned long long value) { return natural60{value}; }
|
||||
inline auto operator"" _n61(unsigned long long value) { return natural61{value}; }
|
||||
inline auto operator"" _n62(unsigned long long value) { return natural62{value}; }
|
||||
inline auto operator"" _n63(unsigned long long value) { return natural63{value}; }
|
||||
inline auto operator"" _n64(unsigned long long value) { return natural64{value}; }
|
||||
|
||||
inline auto operator"" _i1(unsigned long long value) { return integer1{value}; }
|
||||
inline auto operator"" _i2(unsigned long long value) { return integer2{value}; }
|
||||
inline auto operator"" _i3(unsigned long long value) { return integer3{value}; }
|
||||
inline auto operator"" _i4(unsigned long long value) { return integer4{value}; }
|
||||
inline auto operator"" _i5(unsigned long long value) { return integer5{value}; }
|
||||
inline auto operator"" _i6(unsigned long long value) { return integer6{value}; }
|
||||
inline auto operator"" _i7(unsigned long long value) { return integer7{value}; }
|
||||
inline auto operator"" _i8(unsigned long long value) { return integer8{value}; }
|
||||
inline auto operator"" _i9(unsigned long long value) { return integer9{value}; }
|
||||
inline auto operator"" _i10(unsigned long long value) { return integer10{value}; }
|
||||
inline auto operator"" _i11(unsigned long long value) { return integer11{value}; }
|
||||
inline auto operator"" _i12(unsigned long long value) { return integer12{value}; }
|
||||
inline auto operator"" _i13(unsigned long long value) { return integer13{value}; }
|
||||
inline auto operator"" _i14(unsigned long long value) { return integer14{value}; }
|
||||
inline auto operator"" _i15(unsigned long long value) { return integer15{value}; }
|
||||
inline auto operator"" _i16(unsigned long long value) { return integer16{value}; }
|
||||
inline auto operator"" _i17(unsigned long long value) { return integer17{value}; }
|
||||
inline auto operator"" _i18(unsigned long long value) { return integer18{value}; }
|
||||
inline auto operator"" _i19(unsigned long long value) { return integer19{value}; }
|
||||
inline auto operator"" _i20(unsigned long long value) { return integer20{value}; }
|
||||
inline auto operator"" _i21(unsigned long long value) { return integer21{value}; }
|
||||
inline auto operator"" _i22(unsigned long long value) { return integer22{value}; }
|
||||
inline auto operator"" _i23(unsigned long long value) { return integer23{value}; }
|
||||
inline auto operator"" _i24(unsigned long long value) { return integer24{value}; }
|
||||
inline auto operator"" _i25(unsigned long long value) { return integer25{value}; }
|
||||
inline auto operator"" _i26(unsigned long long value) { return integer26{value}; }
|
||||
inline auto operator"" _i27(unsigned long long value) { return integer27{value}; }
|
||||
inline auto operator"" _i28(unsigned long long value) { return integer28{value}; }
|
||||
inline auto operator"" _i29(unsigned long long value) { return integer29{value}; }
|
||||
inline auto operator"" _i30(unsigned long long value) { return integer30{value}; }
|
||||
inline auto operator"" _i31(unsigned long long value) { return integer31{value}; }
|
||||
inline auto operator"" _i32(unsigned long long value) { return integer32{value}; }
|
||||
inline auto operator"" _i33(unsigned long long value) { return integer33{value}; }
|
||||
inline auto operator"" _i34(unsigned long long value) { return integer34{value}; }
|
||||
inline auto operator"" _i35(unsigned long long value) { return integer35{value}; }
|
||||
inline auto operator"" _i36(unsigned long long value) { return integer36{value}; }
|
||||
inline auto operator"" _i37(unsigned long long value) { return integer37{value}; }
|
||||
inline auto operator"" _i38(unsigned long long value) { return integer38{value}; }
|
||||
inline auto operator"" _i39(unsigned long long value) { return integer39{value}; }
|
||||
inline auto operator"" _i40(unsigned long long value) { return integer40{value}; }
|
||||
inline auto operator"" _i41(unsigned long long value) { return integer41{value}; }
|
||||
inline auto operator"" _i42(unsigned long long value) { return integer42{value}; }
|
||||
inline auto operator"" _i43(unsigned long long value) { return integer43{value}; }
|
||||
inline auto operator"" _i44(unsigned long long value) { return integer44{value}; }
|
||||
inline auto operator"" _i45(unsigned long long value) { return integer45{value}; }
|
||||
inline auto operator"" _i46(unsigned long long value) { return integer46{value}; }
|
||||
inline auto operator"" _i47(unsigned long long value) { return integer47{value}; }
|
||||
inline auto operator"" _i48(unsigned long long value) { return integer48{value}; }
|
||||
inline auto operator"" _i49(unsigned long long value) { return integer49{value}; }
|
||||
inline auto operator"" _i50(unsigned long long value) { return integer50{value}; }
|
||||
inline auto operator"" _i51(unsigned long long value) { return integer51{value}; }
|
||||
inline auto operator"" _i52(unsigned long long value) { return integer52{value}; }
|
||||
inline auto operator"" _i53(unsigned long long value) { return integer53{value}; }
|
||||
inline auto operator"" _i54(unsigned long long value) { return integer54{value}; }
|
||||
inline auto operator"" _i55(unsigned long long value) { return integer55{value}; }
|
||||
inline auto operator"" _i56(unsigned long long value) { return integer56{value}; }
|
||||
inline auto operator"" _i57(unsigned long long value) { return integer57{value}; }
|
||||
inline auto operator"" _i58(unsigned long long value) { return integer58{value}; }
|
||||
inline auto operator"" _i59(unsigned long long value) { return integer59{value}; }
|
||||
inline auto operator"" _i60(unsigned long long value) { return integer60{value}; }
|
||||
inline auto operator"" _i61(unsigned long long value) { return integer61{value}; }
|
||||
inline auto operator"" _i62(unsigned long long value) { return integer62{value}; }
|
||||
inline auto operator"" _i63(unsigned long long value) { return integer63{value}; }
|
||||
inline auto operator"" _i64(unsigned long long value) { return integer64{value}; }
|
||||
|
||||
inline auto operator"" _r32(long double value) { return real32{value}; }
|
||||
inline auto operator"" _r64(long double value) { return real32{value}; }
|
||||
|
||||
}
|
|
@ -14,8 +14,10 @@ template<int Requested> struct Natural {
|
|||
static inline constexpr auto mask() -> type { return ~0ull >> 64 - bits(); }
|
||||
|
||||
inline Natural() : data(0) {}
|
||||
template<int Bits> inline Natural(Natural<Bits> value) { data = mask(value); }
|
||||
template<typename T> inline Natural(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; }
|
||||
|
@ -76,4 +78,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 (uint64_t)(typename Natural<LHS>::type)l
|
||||
#define rhs (typename Natural<RHS>::type)r
|
||||
template<int LHS, int RHS> inline auto operator *(Natural<LHS> l, Natural<RHS> r) { return Natural<ADD>{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator /(Natural<LHS> l, Natural<RHS> r) { return Natural<LHS>{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator %(Natural<LHS> l, Natural<RHS> r) { return Natural<LHS>{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator +(Natural<LHS> l, Natural<RHS> r) { return Natural<INC>{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator -(Natural<LHS> l, Natural<RHS> r) { return Natural<INC>{lhs - rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator<<(Natural<LHS> l, Natural<RHS> r) { return Natural<ALL>{lhs << rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator>>(Natural<LHS> l, Natural<RHS> r) { return Natural<LHS>{lhs >> rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator &(Natural<LHS> l, Natural<RHS> r) { return Natural<MAX>{lhs & rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator ^(Natural<LHS> l, Natural<RHS> r) { return Natural<MAX>{lhs ^ rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator |(Natural<LHS> l, Natural<RHS> r) { return Natural<MAX>{lhs | rhs}; }
|
||||
#undef ALL
|
||||
#undef ADD
|
||||
#undef INC
|
||||
#undef MAX
|
||||
#undef MIN
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
}
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace nall {
|
||||
|
||||
//attempt to keep Natural / Integer types when performing a math operation against another Natural / Integer or primitive type
|
||||
//try not to lose any data through truncation (eg Natural<32> + Natural<32> -> Natural<64>)
|
||||
//complex SFINAE is needed to prevent the creation of ambiguous operator overloads
|
||||
|
||||
#define Type PrimitiveType
|
||||
#define Compatible PrimitiveCompatible
|
||||
#define CastExpand PrimitiveCastExpand
|
||||
#define CastShrink PrimitiveCastShrink
|
||||
#define CastDouble PrimitiveCastDouble
|
||||
#define CastLarger PrimitiveCastLarger
|
||||
#define CastLesser PrimitiveCastLesser
|
||||
|
||||
template<typename T> struct Type {
|
||||
using type = T;
|
||||
static inline constexpr uint bits = 8 * sizeof(T);
|
||||
};
|
||||
|
||||
template<> struct Type<Boolean> {
|
||||
using type = typename Boolean::type;
|
||||
static inline constexpr uint bits = Boolean::bits();
|
||||
};
|
||||
|
||||
template<int Precision> struct Type<Natural<Precision>> {
|
||||
using type = typename Natural<Precision>::type;
|
||||
static inline constexpr uint bits = Natural<Precision>::bits();
|
||||
};
|
||||
|
||||
template<int Precision> struct Type<Integer<Precision>> {
|
||||
using type = typename Integer<Precision>::type;
|
||||
static inline constexpr uint bits = Integer<Precision>::bits();
|
||||
};
|
||||
|
||||
template<int Precision> struct Type<Real<Precision>> {
|
||||
using type = typename Real<Precision>::type;
|
||||
static inline constexpr uint bits = Real<Precision>::bits();
|
||||
};
|
||||
|
||||
//compatible: SFINAE operator enable
|
||||
|
||||
template<typename LHS, typename RHS, typename = void> struct Compatible { static const bool value = false; };
|
||||
|
||||
template<int LHS, typename RHS> struct Compatible<Natural<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { static const bool value = true; };
|
||||
template<typename LHS, int RHS> struct Compatible<LHS, Natural<RHS>, enable_if_t<is_integral_v<LHS>>> { static const bool value = true; };
|
||||
template<int LHS, int RHS> struct Compatible<Natural<LHS>, Natural<RHS>> { static const bool value = true; };
|
||||
|
||||
template<int LHS, typename RHS> struct Compatible<Integer<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { static const bool value = true; };
|
||||
template<typename LHS, int RHS> struct Compatible<LHS, Integer<RHS>, enable_if_t<is_integral_v<LHS>>> { static const bool value = true; };
|
||||
template<int LHS, int RHS> struct Compatible<Integer<LHS>, Integer<RHS>> { static const bool value = true; };
|
||||
|
||||
//expand: LHS+RHS bits
|
||||
|
||||
template<typename LHS, typename RHS, typename = void> struct CastExpand { using type = void; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastExpand<Natural<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Natural<LHS + Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastExpand<LHS, Natural<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Natural<Type<LHS>::bits + RHS>; };
|
||||
template<int LHS, int RHS> struct CastExpand<Natural<LHS>, Natural<RHS>> { using type = Natural<LHS + RHS>; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastExpand<Integer<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Integer<LHS + Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastExpand<LHS, Integer<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Integer<Type<LHS>::bits + RHS>; };
|
||||
template<int LHS, int RHS> struct CastExpand<Integer<LHS>, Integer<RHS>> { using type = Integer<LHS + RHS>; };
|
||||
|
||||
//shrink: LHS-RHS bits
|
||||
|
||||
template<typename LHS, typename RHS, typename = void> struct CastShrink { using type = void; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastShrink<Natural<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Natural<LHS - Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastShrink<LHS, Natural<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Natural<Type<LHS>::bits - RHS>; };
|
||||
template<int LHS, int RHS> struct CastShrink<Natural<LHS>, Natural<RHS>> { using type = Natural<LHS - RHS>; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastShrink<Integer<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Integer<LHS - Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastShrink<LHS, Integer<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Integer<Type<LHS>::bits - RHS>; };
|
||||
template<int LHS, int RHS> struct CastShrink<Integer<LHS>, Integer<RHS>> { using type = Integer<LHS - RHS>; };
|
||||
|
||||
//double: 1+max(LHS,RHS) bits
|
||||
|
||||
template<typename LHS, typename RHS, typename = void> struct CastDouble { using type = void; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastDouble<Natural<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Natural<1 + (LHS >= Type<RHS>::bits ? LHS : Type<RHS>::bits)>; };
|
||||
template<typename LHS, int RHS> struct CastDouble<LHS, Natural<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Natural<1 + (Type<LHS>::bits >= RHS ? Type<LHS>::bits : RHS)>; };
|
||||
template<int LHS, int RHS> struct CastDouble<Natural<LHS>, Natural<RHS>> { using type = Natural<1 + (LHS >= RHS ? LHS : RHS)>; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastDouble<Integer<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Integer<1 + (LHS >= Type<RHS>::bits ? LHS : Type<RHS>::bits)>; };
|
||||
template<typename LHS, int RHS> struct CastDouble<LHS, Integer<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Integer<1 + (Type<LHS>::bits >= RHS ? Type<LHS>::bits : RHS)>; };
|
||||
template<int LHS, int RHS> struct CastDouble<Integer<LHS>, Integer<RHS>> { using type = Integer<1 + (LHS >= RHS ? LHS : RHS)>; };
|
||||
|
||||
//larger: max(LHS,RHS) bits
|
||||
|
||||
template<typename LHS, typename RHS, typename = void> struct CastLarger { using type = void; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastLarger<Natural<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Natural<LHS >= Type<RHS>::bits ? LHS : Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastLarger<LHS, Natural<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Natural<Type<LHS>::bits >= RHS ? Type<LHS>::bits : RHS>; };
|
||||
template<int LHS, int RHS> struct CastLarger<Natural<LHS>, Natural<RHS>> { using type = Natural<LHS >= RHS ? LHS : RHS>; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastLarger<Integer<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Integer<LHS >= Type<RHS>::bits ? LHS : Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastLarger<LHS, Integer<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Integer<Type<LHS>::bits >= RHS ? Type<LHS>::bits : RHS>; };
|
||||
template<int LHS, int RHS> struct CastLarger<Integer<LHS>, Integer<RHS>> { using type = Integer<LHS >= RHS ? LHS : RHS>; };
|
||||
|
||||
//lesser: min(LHS,RHS) bits
|
||||
|
||||
template<typename LHS, typename RHS, typename = void> struct CastLesser { using type = void; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastLesser<Natural<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Natural<LHS <= Type<RHS>::bits ? LHS : Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastLesser<LHS, Natural<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Natural<Type<LHS>::bits <= RHS ? Type<LHS>::bits : RHS>; };
|
||||
template<int LHS, int RHS> struct CastLesser<Natural<LHS>, Natural<RHS>> { using type = Natural<LHS <= RHS ? LHS : RHS>; };
|
||||
|
||||
template<int LHS, typename RHS> struct CastLesser<Integer<LHS>, RHS, enable_if_t<is_integral_v<RHS>>> { using type = Integer<LHS <= Type<RHS>::bits ? LHS : Type<RHS>::bits>; };
|
||||
template<typename LHS, int RHS> struct CastLesser<LHS, Integer<RHS>, enable_if_t<is_integral_v<LHS>>> { using type = Integer<Type<LHS>::bits <= RHS ? Type<LHS>::bits : RHS>; };
|
||||
template<int LHS, int RHS> struct CastLesser<Integer<LHS>, Integer<RHS>> { using type = Integer<LHS <= RHS ? LHS : RHS>; };
|
||||
|
||||
#define TP template<typename LHS, typename RHS, typename = enable_if_t<Compatible<LHS, RHS>::value>>
|
||||
|
||||
#define Source typename Type<LHS>::type
|
||||
#define Expand typename CastExpand<LHS, RHS>::type
|
||||
#define Shrink typename CastShrink<LHS, RHS>::type
|
||||
#define Double typename CastDouble<LHS, RHS>::type
|
||||
#define Larger typename CastLarger<LHS, RHS>::type
|
||||
#define Lesser typename CastLesser<LHS, RHS>::type
|
||||
|
||||
#define TLE typename Type<typename CastExpand<LHS, RHS>::type>::type
|
||||
#define TLN typename Type<LHS>::type
|
||||
#define TRN typename Type<RHS>::type
|
||||
|
||||
#if 1
|
||||
TP inline auto operator *(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs * (TRN)rhs}; }
|
||||
TP inline auto operator /(const LHS& lhs, const RHS& rhs) -> Source { return {(TLN)lhs / (TRN)rhs}; }
|
||||
TP inline auto operator %(const LHS& lhs, const RHS& rhs) -> Source { return {(TLN)lhs % (TRN)rhs}; }
|
||||
TP inline auto operator +(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs + (TRN)rhs}; }
|
||||
TP inline auto operator -(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs - (TRN)rhs}; }
|
||||
TP inline auto operator<<(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs << (TRN)rhs}; }
|
||||
TP inline auto operator>>(const LHS& lhs, const RHS& rhs) -> Source { return {(TLN)lhs >> (TRN)rhs}; }
|
||||
TP inline auto operator &(const LHS& lhs, const RHS& rhs) -> Lesser { return {(TLN)lhs & (TRN)rhs}; }
|
||||
TP inline auto operator ^(const LHS& lhs, const RHS& rhs) -> Larger { return {(TLN)lhs ^ (TRN)rhs}; }
|
||||
TP inline auto operator |(const LHS& lhs, const RHS& rhs) -> Larger { return {(TLN)lhs | (TRN)rhs}; }
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TP inline auto operator *(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs * (TRN)rhs}; }
|
||||
TP inline auto operator /(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs / (TRN)rhs}; }
|
||||
TP inline auto operator %(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs % (TRN)rhs}; }
|
||||
TP inline auto operator +(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs + (TRN)rhs}; }
|
||||
TP inline auto operator -(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs - (TRN)rhs}; }
|
||||
TP inline auto operator<<(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs << (TRN)rhs}; }
|
||||
TP inline auto operator>>(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs >> (TRN)rhs}; }
|
||||
TP inline auto operator &(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs & (TRN)rhs}; }
|
||||
TP inline auto operator ^(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs ^ (TRN)rhs}; }
|
||||
TP inline auto operator |(const LHS& lhs, const RHS& rhs) -> Expand { return {(TLE)lhs | (TRN)rhs}; }
|
||||
#endif
|
||||
|
||||
#undef TP
|
||||
|
||||
#undef Source
|
||||
#undef Expand
|
||||
#undef Shrink
|
||||
#undef Double
|
||||
#undef Larger
|
||||
#undef Lesser
|
||||
|
||||
#undef TLE
|
||||
#undef TLN
|
||||
#undef TRN
|
||||
|
||||
#undef Type
|
||||
#undef Compatible
|
||||
#undef CastExpand
|
||||
#undef CastShrink
|
||||
#undef CastDouble
|
||||
#undef CastLarger
|
||||
#undef CastLesser
|
||||
|
||||
}
|
|
@ -34,4 +34,14 @@ private:
|
|||
type data;
|
||||
};
|
||||
|
||||
#define lhs (long double)(typename Real<LHS>::type)l
|
||||
#define rhs (typename Real<RHS>::type)r
|
||||
template<int LHS, int RHS> inline auto operator*(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator/(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator%(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator+(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator-(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs - rhs}; }
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
}
|
||||
|
|
|
@ -329,6 +329,8 @@ struct string_format : vector<string> {
|
|||
inline auto append() -> type&;
|
||||
};
|
||||
|
||||
inline auto operator"" _s(const char* value, std::size_t) -> string { return {value}; }
|
||||
|
||||
}
|
||||
|
||||
#include <nall/string/view.hpp>
|
||||
|
@ -360,4 +362,4 @@ struct string_format : vector<string> {
|
|||
#include <nall/string/markup/xml.hpp>
|
||||
|
||||
#include <nall/string/transform/cml.hpp>
|
||||
#include <nall/string/transform/dml.hpp>
|
||||
//#include <nall/string/transform/dml.hpp>
|
||||
|
|
|
@ -41,4 +41,7 @@ enum XlibConstants : int {
|
|||
#undef None
|
||||
#undef True
|
||||
|
||||
#undef MAX
|
||||
#undef MIN
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue