mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-01 23:33:22 +02:00
Update to v106r83 release.
byuu says: Changelog: - reverted nall/inline-if.hpp usage for now, since the nall/primitives.hpp math operators still cast to (u)int64_t - improved nall/primitives.hpp more; integer8 x = -128; print(-x) will now print 128 (unary operator+ and - cast to (u)int64_t) - renamed processor/lr35902 to processor/sm83; after the Sharp SM83 CPU core [gekkio discovered the name] - a few bugfixes to the TLCS900H CPU core - completed the disassembler for the TLCS900H core As a result of reverting most of the inline if stuff, I guess the testing priority has been reduced. Which is probably a good thing, considering I seem to have a smaller pool of testers these days. Indeed, the TLCS900H core has ended up at 131KiB compared to the M68000 core at 128KiB. So it's now the largest CPU core in all of higan. It's even more ridiculous because the M68000 core would ordinarily be quite a bit smaller, had I not gone overboard with the extreme templating to reduce instruction decoding overhead (you kind of have to do this for RISC CPUs, and the inverted design of the TLCS900H kind of makes it infeasible to do the same there.) This CPU core is bound to have dozens of extremely difficult CPU bugs, and there's no easy way for me to test them. I would greatly appreciate any help in looking over the core for bugs. A fresh pair of eyes to spot a mistake could save me up to several days of tedious debugging work. The core still isn't ready to actually be tested: I have to hook up cartridge loading, a memory bus, interrupts, timers, and the micro DMA controller before it's likely that anything happens at all.
This commit is contained in:
@@ -63,4 +63,22 @@ private:
|
||||
T values[Size];
|
||||
};
|
||||
|
||||
template<typename T, T... p> auto from_array(uint index) -> T {
|
||||
static const array<T[sizeof...(p)]> table{p...};
|
||||
struct out_of_bounds {};
|
||||
#if defined(DEBUG)
|
||||
if(index >= sizeof...(p)) throw out_of_bounds{};
|
||||
#endif
|
||||
return table[index];
|
||||
}
|
||||
|
||||
template<int64_t... p> auto from_array(uint index) -> int64_t {
|
||||
static const array<int64_t[sizeof...(p)]> table{p...};
|
||||
struct out_of_bounds {};
|
||||
#if defined(DEBUG)
|
||||
if(index >= sizeof...(p)) throw out_of_bounds{};
|
||||
#endif
|
||||
return table[index];
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#warning "these defines break if statements with multiple parameters to templates"
|
||||
|
||||
#define if1(statement) if(statement)
|
||||
#define if2(condition, false) ([](auto&& value) -> decltype(condition) { \
|
||||
|
@@ -5,8 +5,8 @@
|
||||
|
||||
namespace nall {
|
||||
struct Boolean;
|
||||
template<int Precision> struct Natural;
|
||||
template<int Precision> struct Integer;
|
||||
template<uint Precision> struct Natural;
|
||||
template<uint Precision> struct Integer;
|
||||
}
|
||||
|
||||
#include <nall/primitives/bit-range.hpp>
|
||||
@@ -18,6 +18,6 @@ namespace nall {
|
||||
#include <nall/primitives/literals.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<int Bits> auto Natural<Bits>::integer() const -> Integer<Bits> { return Integer<Bits>(*this); }
|
||||
template<int Bits> auto Integer<Bits>::natural() const -> Natural<Bits> { return Natural<Bits>(*this); }
|
||||
template<uint Bits> auto Natural<Bits>::integer() const -> Integer<Bits> { return Integer<Bits>(*this); }
|
||||
template<uint Bits> auto Integer<Bits>::natural() const -> Natural<Bits> { return Natural<Bits>(*this); }
|
||||
}
|
||||
|
@@ -2,18 +2,18 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<int Requested> struct BitRange {
|
||||
enum : uint { Precision = Requested < 1 ? 1 : Requested > 64 ? 64 : Requested };
|
||||
template<int Precision> struct BitRange {
|
||||
static_assert(Precision >= 1 && Precision <= 64);
|
||||
static inline constexpr auto bits() -> uint { return Precision; }
|
||||
using type =
|
||||
using utype =
|
||||
typename conditional<bits() <= 8, uint8_t,
|
||||
typename conditional<bits() <= 16, uint16_t,
|
||||
typename conditional<bits() <= 32, uint32_t,
|
||||
typename conditional<bits() <= 64, uint64_t,
|
||||
void>::type>::type>::type>::type;
|
||||
static inline constexpr auto mask() -> type { return ~0ull >> 64 - bits(); }
|
||||
static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); }
|
||||
|
||||
inline BitRange(type& source, int lo, int hi) : source(source) {
|
||||
inline BitRange(utype& source, int lo, int hi) : source(source) {
|
||||
if(lo < 0) lo = Precision + lo;
|
||||
if(hi < 0) hi = Precision + hi;
|
||||
if(lo > hi) swap(lo, hi);
|
||||
@@ -28,7 +28,7 @@ template<int Requested> struct BitRange {
|
||||
inline auto& operator++() { return set(get() + 1); }
|
||||
inline auto& operator--() { return set(get() - 1); }
|
||||
|
||||
inline operator type() const { return get(); }
|
||||
inline operator utype() const { return get(); }
|
||||
template<typename T> inline auto& operator =(const T& value) { return set( value); }
|
||||
template<typename T> inline auto& operator *=(const T& value) { return set(get() * value); }
|
||||
template<typename T> inline auto& operator /=(const T& value) { return set(get() / value); }
|
||||
@@ -42,20 +42,20 @@ template<int Requested> struct BitRange {
|
||||
template<typename T> inline auto& operator |=(const T& value) { return set(get() | value); }
|
||||
|
||||
private:
|
||||
inline auto get() const -> type {
|
||||
const type rangeBits = hi - lo + 1;
|
||||
const type rangeMask = (1ull << rangeBits) - 1 << lo & mask();
|
||||
inline auto get() const -> utype {
|
||||
const utype rangeBits = hi - lo + 1;
|
||||
const utype rangeMask = (1ull << rangeBits) - 1 << lo & mask();
|
||||
return (source & rangeMask) >> lo;
|
||||
}
|
||||
|
||||
inline auto& set(const type& value) {
|
||||
const type rangeBits = hi - lo + 1;
|
||||
const type rangeMask = (1ull << rangeBits) - 1 << lo & mask();
|
||||
inline auto& set(const utype& value) {
|
||||
const utype rangeBits = hi - lo + 1;
|
||||
const utype rangeMask = (1ull << rangeBits) - 1 << lo & mask();
|
||||
source = source & ~rangeMask | value << lo & rangeMask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
type& source;
|
||||
utype& source;
|
||||
uint lo;
|
||||
uint hi;
|
||||
};
|
||||
|
@@ -2,15 +2,15 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<int Precision> struct Integer {
|
||||
template<uint Precision = 64> struct Integer {
|
||||
static_assert(Precision >= 1 && Precision <= 64);
|
||||
static inline constexpr auto bits() -> uint { return Precision; }
|
||||
using stype =
|
||||
typename conditional<bits() <= 8, int8_t,
|
||||
typename conditional<bits() <= 16, int16_t,
|
||||
typename conditional<bits() <= 32, int32_t,
|
||||
typename conditional<bits() <= 64, int64_t,
|
||||
void>::type>::type>::type>::type;
|
||||
conditional_t<bits() <= 8, int8_t,
|
||||
conditional_t<bits() <= 16, int16_t,
|
||||
conditional_t<bits() <= 32, int32_t,
|
||||
conditional_t<bits() <= 64, int64_t,
|
||||
void>>>>;
|
||||
using utype = typename Natural<Precision>::utype;
|
||||
static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); }
|
||||
static inline constexpr auto sign() -> utype { return 1ull << Precision - 1; }
|
||||
@@ -30,8 +30,8 @@ template<int Precision> struct Integer {
|
||||
|
||||
inline auto operator!() const { return Integer{!data}; }
|
||||
inline auto operator~() const { return Integer{~data}; }
|
||||
inline auto operator+() const { return Integer{+data}; }
|
||||
inline auto operator-() const { return Integer{-data}; }
|
||||
inline auto operator+() const { return Integer<>{+(int64_t)data}; }
|
||||
inline auto operator-() const { return Integer<>{-(int64_t)data}; }
|
||||
|
||||
#define lhs data
|
||||
#define rhs value
|
||||
@@ -54,6 +54,9 @@ template<int Precision> struct Integer {
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
//warning: this does not and cannot short-circuit; value is always evaluated
|
||||
template<typename T> inline auto orElse(const T& value) { return Integer<>{data ? data : value}; }
|
||||
|
||||
inline auto bits(int lo, int hi) -> BitRange<Precision> { return {(utype&)data, lo, hi}; }
|
||||
inline auto bit(int index) -> BitRange<Precision> { return {(utype&)data, index, index}; }
|
||||
inline auto byte(int index) -> BitRange<Precision> { return {(utype&)data, index * 8 + 0, index * 8 + 7}; }
|
||||
@@ -62,16 +65,19 @@ template<int Precision> struct Integer {
|
||||
inline auto bit(int index) const -> const BitRange<Precision> { return {(utype&)*this, index, index}; }
|
||||
inline auto byte(int index) const -> const BitRange<Precision> { return {(utype&)*this, index * 8 + 0, index * 8 + 7}; }
|
||||
|
||||
inline auto slice(int index) const { return Natural<>{bit(index)}; }
|
||||
inline auto slice(int lo, int hi) const { return Natural<>{bit(lo, hi)}; }
|
||||
|
||||
inline auto clamp(uint bits) {
|
||||
const intmax b = 1ull << (bits - 1);
|
||||
const intmax m = b - 1;
|
||||
return Integer<64>{data > m ? m : data < -b ? -b : data};
|
||||
const int64_t b = 1ull << (bits - 1);
|
||||
const int64_t m = b - 1;
|
||||
return Integer<>{data > m ? m : data < -b ? -b : data};
|
||||
}
|
||||
|
||||
inline auto clip(uint bits) {
|
||||
const uintmax b = 1ull << (bits - 1);
|
||||
const uintmax m = b * 2 - 1;
|
||||
return Integer<64>{(data & m ^ b) - b};
|
||||
const uint64_t b = 1ull << (bits - 1);
|
||||
const uint64_t m = b * 2 - 1;
|
||||
return Integer<>{(data & m ^ b) - b};
|
||||
}
|
||||
|
||||
inline auto serialize(serializer& s) { s(data); }
|
||||
@@ -87,16 +93,16 @@ private:
|
||||
|
||||
#define lhs (int64_t)l
|
||||
#define rhs r
|
||||
template<int LHS, int RHS> inline auto operator *(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator /(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator %(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator +(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator -(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs - rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator<<(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs << rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator>>(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs >> rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator &(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs & rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator ^(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs ^ rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator |(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs | rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator *(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator /(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator %(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator +(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator -(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs - rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator<<(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs << rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator>>(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs >> rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator &(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs & rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator ^(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs ^ rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator |(Integer<LHS> l, Integer<RHS> r) { return Integer{lhs | rhs}; }
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
|
@@ -2,15 +2,15 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<int Precision> struct Natural {
|
||||
template<uint Precision = 64> struct Natural {
|
||||
static_assert(Precision >= 1 && Precision <= 64);
|
||||
static inline constexpr auto bits() -> uint { return Precision; }
|
||||
using utype =
|
||||
typename conditional<bits() <= 8, uint8_t,
|
||||
typename conditional<bits() <= 16, uint16_t,
|
||||
typename conditional<bits() <= 32, uint32_t,
|
||||
typename conditional<bits() <= 64, uint64_t,
|
||||
void>::type>::type>::type>::type;
|
||||
conditional_t<bits() <= 8, uint8_t,
|
||||
conditional_t<bits() <= 16, uint16_t,
|
||||
conditional_t<bits() <= 32, uint32_t,
|
||||
conditional_t<bits() <= 64, uint64_t,
|
||||
void>>>>;
|
||||
static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); }
|
||||
|
||||
inline Natural() : data(0) {}
|
||||
@@ -28,8 +28,8 @@ template<int Precision> struct Natural {
|
||||
|
||||
inline auto operator!() const { return Natural{!data}; }
|
||||
inline auto operator~() const { return Natural{~data}; }
|
||||
inline auto operator+() const { return Natural{+data}; }
|
||||
inline auto operator-() const { return Natural{-data}; }
|
||||
inline auto operator+() const { return Natural<>{+(uint64_t)data}; }
|
||||
inline auto operator-() const { return Natural<>{-(uint64_t)data}; }
|
||||
|
||||
#define lhs data
|
||||
#define rhs value
|
||||
@@ -47,40 +47,8 @@ template<int Precision> struct Natural {
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
//work in progress: we want natural<op>primitive and primitive<op>natural to result in natural<64> ...
|
||||
//however, these operators will create ambiguous overloads unless operator uint64_t() is explicit.
|
||||
//a large volume of existing code will need to be updated before this will be possible.
|
||||
#if 0
|
||||
#define lhs (uint64_t)data
|
||||
#define rhs value
|
||||
template<typename T> inline auto operator *(const T& value) { return Natural<64>{lhs * rhs}; }
|
||||
template<typename T> inline auto operator /(const T& value) { return Natural<64>{lhs / rhs}; }
|
||||
template<typename T> inline auto operator %(const T& value) { return Natural<64>{lhs % rhs}; }
|
||||
template<typename T> inline auto operator +(const T& value) { return Natural<64>{lhs + rhs}; }
|
||||
template<typename T> inline auto operator -(const T& value) { return Natural<64>{lhs - rhs}; }
|
||||
template<typename T> inline auto operator<<(const T& value) { return Natural<64>{lhs << rhs}; }
|
||||
template<typename T> inline auto operator>>(const T& value) { return Natural<64>{lhs >> rhs}; }
|
||||
template<typename T> inline auto operator &(const T& value) { return Natural<64>{lhs & rhs}; }
|
||||
template<typename T> inline auto operator ^(const T& value) { return Natural<64>{lhs ^ rhs}; }
|
||||
template<typename T> inline auto operator |(const T& value) { return Natural<64>{lhs | rhs}; }
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
#define lhs l
|
||||
#define rhs (uint64_t)r
|
||||
template<typename T> friend inline auto operator *(const T& l, Natural r) { return Natural<64>{lhs * rhs}; }
|
||||
template<typename T> friend inline auto operator %(const T& l, Natural r) { return Natural<64>{lhs / rhs}; }
|
||||
template<typename T> friend inline auto operator /(const T& l, Natural r) { return Natural<64>{lhs % rhs}; }
|
||||
template<typename T> friend inline auto operator +(const T& l, Natural r) { return Natural<64>{lhs + rhs}; }
|
||||
template<typename T> friend inline auto operator -(const T& l, Natural r) { return Natural<64>{lhs - rhs}; }
|
||||
template<typename T> friend inline auto operator<<(const T& l, Natural r) { return Natural<64>{lhs << rhs}; }
|
||||
template<typename T> friend inline auto operator>>(const T& l, Natural r) { return Natural<64>{lhs >> rhs}; }
|
||||
template<typename T> friend inline auto operator &(const T& l, Natural r) { return Natural<64>{lhs & rhs}; }
|
||||
template<typename T> friend inline auto operator ^(const T& l, Natural r) { return Natural<64>{lhs ^ rhs}; }
|
||||
template<typename T> friend inline auto operator |(const T& l, Natural r) { return Natural<64>{lhs | rhs}; }
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
#endif
|
||||
//warning: this does not and cannot short-circuit; value is always evaluated
|
||||
template<typename T> inline auto orElse(const T& value) { return Natural<>{data ? data : value}; }
|
||||
|
||||
inline auto bits(int lo, int hi) -> BitRange<Precision> { return {(utype&)data, lo, hi}; }
|
||||
inline auto bit(int index) -> BitRange<Precision> { return {(utype&)data, index, index}; }
|
||||
@@ -90,16 +58,19 @@ template<int Precision> struct Natural {
|
||||
inline auto bit(int index) const -> const BitRange<Precision> { return {(utype&)data, index, index}; }
|
||||
inline auto byte(int index) const -> const BitRange<Precision> { return {(utype&)data, index * 8 + 0, index * 8 + 7}; }
|
||||
|
||||
inline auto slice(int index) const { return Natural<>{bit(index)}; }
|
||||
inline auto slice(int lo, int hi) const { return Natural<>{bits(lo, hi)}; }
|
||||
|
||||
inline auto clamp(uint bits) {
|
||||
const uintmax b = 1ull << (bits - 1);
|
||||
const uintmax m = b * 2 - 1;
|
||||
return Natural<64>{data < m ? data : m};
|
||||
const uint64_t b = 1ull << (bits - 1);
|
||||
const uint64_t m = b * 2 - 1;
|
||||
return Natural<>{data < m ? data : m};
|
||||
}
|
||||
|
||||
inline auto clip(uint bits) {
|
||||
const uintmax b = 1ull << (bits - 1);
|
||||
const uintmax m = b * 2 - 1;
|
||||
return Natural<64>{data & m};
|
||||
const uint64_t b = 1ull << (bits - 1);
|
||||
const uint64_t m = b * 2 - 1;
|
||||
return Natural<>{data & m};
|
||||
}
|
||||
|
||||
inline auto serialize(serializer& s) { s(data); }
|
||||
@@ -114,17 +85,17 @@ private:
|
||||
};
|
||||
|
||||
#define lhs (uint64_t)l
|
||||
#define rhs (uint64_t)r
|
||||
template<int LHS, int RHS> inline auto operator *(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator /(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator %(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator +(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator -(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs - rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator<<(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs << rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator>>(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs >> rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator &(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs & rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator ^(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs ^ rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator |(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs | rhs}; }
|
||||
#define rhs r
|
||||
template<int LHS, int RHS> inline auto operator *(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator /(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator %(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator +(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator -(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs - rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator<<(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs << rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator>>(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs >> rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator &(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs & rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator ^(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs ^ rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator |(Natural<LHS> l, Natural<RHS> r) { return Natural{lhs | rhs}; }
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
|
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<int Precision> struct Real {
|
||||
template<uint Precision = 64> struct Real {
|
||||
static_assert(Precision == 32 || Precision == 64);
|
||||
static inline constexpr auto bits() -> uint { return Precision; }
|
||||
using ftype =
|
||||
typename conditional<bits() == 32, float32_t,
|
||||
typename conditional<bits() == 64, float64_t,
|
||||
void>::type>::type;
|
||||
conditional_t<bits() == 32, float32_t,
|
||||
conditional_t<bits() == 64, float64_t,
|
||||
void>>;
|
||||
|
||||
inline Real() : data(0.0) {}
|
||||
template<int Bits> inline Real(Real<Bits> value) : data((ftype)value) {}
|
||||
@@ -38,11 +38,11 @@ private:
|
||||
|
||||
#define lhs (float64_t)(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}; }
|
||||
template<int LHS, int RHS> inline auto operator*(Real<LHS> l, Real<RHS> r) { return Real<>{lhs * rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator/(Real<LHS> l, Real<RHS> r) { return Real<>{lhs / rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator%(Real<LHS> l, Real<RHS> r) { return Real<>{lhs % rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator+(Real<LHS> l, Real<RHS> r) { return Real<>{lhs + rhs}; }
|
||||
template<int LHS, int RHS> inline auto operator-(Real<LHS> l, Real<RHS> r) { return Real<>{lhs - rhs}; }
|
||||
#undef lhs
|
||||
#undef rhs
|
||||
|
||||
|
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace nall {
|
||||
using boolean = Boolean;
|
||||
using natural = Natural<64>;
|
||||
using integer = Integer<64>;
|
||||
using real = Real<64>;
|
||||
using natural = Natural<>;
|
||||
using integer = Integer<>;
|
||||
using real = Real<>;
|
||||
|
||||
using natural1 = Natural< 1>; using natural2 = Natural< 2>; using natural3 = Natural< 3>; using natural4 = Natural< 4>;
|
||||
using natural5 = Natural< 5>; using natural6 = Natural< 6>; using natural7 = Natural< 7>; using natural8 = Natural< 8>;
|
||||
|
@@ -76,7 +76,7 @@ template<> struct stringify<int128_t> {
|
||||
};
|
||||
#endif
|
||||
|
||||
template<int Bits> struct stringify<Integer<Bits>> {
|
||||
template<uint Bits> struct stringify<Integer<Bits>> {
|
||||
stringify(Integer<Bits> source) { fromInteger(_data, source); }
|
||||
auto data() const -> const char* { return _data; }
|
||||
auto size() const -> uint { return strlen(_data); }
|
||||
@@ -129,7 +129,7 @@ template<> struct stringify<uint128_t> {
|
||||
};
|
||||
#endif
|
||||
|
||||
template<int Bits> struct stringify<Natural<Bits>> {
|
||||
template<uint Bits> struct stringify<Natural<Bits>> {
|
||||
stringify(Natural<Bits> source) { fromNatural(_data, source); }
|
||||
auto data() const -> const char* { return _data; }
|
||||
auto size() const -> uint { return strlen(_data); }
|
||||
|
@@ -9,6 +9,7 @@
|
||||
namespace nall {
|
||||
using std::add_const;
|
||||
using std::conditional;
|
||||
using std::conditional_t;
|
||||
using std::decay;
|
||||
using std::declval;
|
||||
using std::enable_if;
|
||||
|
Reference in New Issue
Block a user