Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace nall {
|
|
|
|
|
2019-01-14 06:16:28 +00:00
|
|
|
template<int Requested> struct Integer {
|
|
|
|
enum : uint { Precision = Requested < 1 ? 1 : Requested > 64 ? 64 : Requested };
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
static inline constexpr auto bits() -> uint { return Precision; }
|
|
|
|
using type =
|
|
|
|
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;
|
2019-01-14 06:16:28 +00:00
|
|
|
using utype = typename Natural<Requested>::type;
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); }
|
|
|
|
static inline constexpr auto sign() -> utype { return 1ull << Precision - 1; }
|
|
|
|
|
|
|
|
inline Integer() : data(0) {}
|
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.
2019-01-15 04:33:20 +00:00
|
|
|
template<int Bits> inline Integer(Integer<Bits> value) { data = mask(value); }
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
template<typename T> inline Integer(const T& value) { data = mask(value); }
|
|
|
|
|
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.
2019-01-15 04:33:20 +00:00
|
|
|
explicit inline operator bool() const { return data; }
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
inline operator type() const { return data; }
|
|
|
|
|
|
|
|
inline auto operator++(int) { auto value = *this; data = mask(data + 1); return value; }
|
|
|
|
inline auto operator--(int) { auto value = *this; data = mask(data - 1); return value; }
|
|
|
|
|
|
|
|
inline auto& operator++() { data = mask(data + 1); return *this; }
|
|
|
|
inline auto& operator--() { data = mask(data - 1); return *this; }
|
|
|
|
|
|
|
|
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}; }
|
|
|
|
|
|
|
|
#define lhs data
|
|
|
|
#define rhs value
|
|
|
|
template<typename T> inline auto& operator =(const T& value) { lhs = mask( rhs); return *this; }
|
|
|
|
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; }
|
|
|
|
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; }
|
|
|
|
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; }
|
|
|
|
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; }
|
|
|
|
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
|
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.
2019-01-15 04:33:20 +00:00
|
|
|
#undef rhs
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-01-14 06:16:28 +00:00
|
|
|
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}; }
|
|
|
|
inline auto byte(int index) -> BitRange<Requested> { return {(utype&)data, index * 8 + 0, index * 8 + 7}; }
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-01-14 06:16:28 +00:00
|
|
|
inline auto bits(int lo, int hi) const -> const BitRange<Requested> { return {(utype&)*this, lo, lo}; }
|
|
|
|
inline auto bit(int index) const -> const BitRange<Requested> { return {(utype&)*this, index, index}; }
|
|
|
|
inline auto byte(int index) const -> const BitRange<Requested> { return {(utype&)*this, index * 8 + 0, index * 8 + 7}; }
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
2019-01-14 06:16:28 +00:00
|
|
|
inline auto clamp(uint bits) -> type {
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
const intmax b = 1ull << (bits - 1);
|
|
|
|
const intmax m = b - 1;
|
|
|
|
return data > m ? m : data < -b ? -b : data;
|
|
|
|
}
|
|
|
|
|
2019-01-14 06:16:28 +00:00
|
|
|
inline auto clip(uint bits) -> type {
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
const uintmax b = 1ull << (bits - 1);
|
|
|
|
const uintmax m = b * 2 - 1;
|
|
|
|
return ((data & m) ^ b) - b;
|
|
|
|
}
|
|
|
|
|
2019-01-14 06:16:28 +00:00
|
|
|
inline auto serialize(serializer& s) { s(data); }
|
|
|
|
inline auto natural() const -> Natural<Requested>;
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
|
|
|
|
private:
|
2019-01-14 06:16:28 +00:00
|
|
|
inline auto mask(type value) const -> type {
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
return (value & mask() ^ sign()) - sign();
|
|
|
|
}
|
|
|
|
|
|
|
|
type data;
|
|
|
|
};
|
|
|
|
|
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.
2019-01-15 04:33:20 +00:00
|
|
|
#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
|
|
|
|
|
Update to v106r77 release.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
|
|
|
}
|