mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-23 22:52:34 +01:00
byuu says: Changelog: - NES PPU core updated to use BitFields (absolutely massive improvement in code readability) - NES APU core updated to new coding style - NES cartridge/board and cartridge/chip updated to new coding style - pushed NES PPU rendering one dot forward (doesn't fix King's Quest V yet, sadly) - fixed SNES PPU BG tilemask for 128KiB VRAM mode (doesn't fix Yoshi's Island, though) So ... I kind of went overboard with the fc/cartridge changes. This WIP diff is 185KiB >_> I didn't realize it was going to be as big a task as it was, but once I started everything broke in a chain reaction, so I had to do it all at once. There's a massive chance we've broken a bunch of NES things. Any typos in this WIP are going to be absolutely insidious to track down =( But ... supposing I pulled it off, this means the Famicom core is now fully converted to the new coding style as well. That leaves only the GB and GBA cores. Once those are finished, then we'll finally be free of these gigantic hellspawn diffs.
91 lines
3.3 KiB
C++
91 lines
3.3 KiB
C++
#pragma once
|
|
|
|
namespace nall {
|
|
|
|
struct nothing_t {};
|
|
static nothing_t nothing;
|
|
|
|
template<typename T>
|
|
struct maybe {
|
|
inline maybe() {}
|
|
inline maybe(nothing_t) {}
|
|
inline maybe(const T& source) { operator=(source); }
|
|
inline maybe(T&& source) { operator=(move(source)); }
|
|
inline maybe(const maybe& source) { operator=(source); }
|
|
inline maybe(maybe&& source) { operator=(move(source)); }
|
|
inline ~maybe() { reset(); }
|
|
|
|
inline auto operator=(nothing_t) -> maybe& { reset(); return *this; }
|
|
inline auto operator=(const T& source) -> maybe& { reset(); _valid = true; new(&_value.t) T(source); return *this; }
|
|
inline auto operator=(T&& source) -> maybe& { reset(); _valid = true; new(&_value.t) T(move(source)); return *this; }
|
|
|
|
inline auto operator=(const maybe& source) -> maybe& {
|
|
if(this == &source) return *this;
|
|
reset();
|
|
if(_valid = source._valid) new(&_value.t) T(source.get());
|
|
return *this;
|
|
}
|
|
|
|
inline auto operator=(maybe&& source) -> maybe& {
|
|
if(this == &source) return *this;
|
|
reset();
|
|
if(_valid = source._valid) new(&_value.t) T(move(source.get()));
|
|
return *this;
|
|
}
|
|
|
|
inline explicit operator bool() const { return _valid; }
|
|
inline auto reset() -> void { if(_valid) { _value.t.~T(); _valid = false; } }
|
|
inline auto data() -> T* { return _valid ? &_value.t : nullptr; }
|
|
inline auto get() -> T& { assert(_valid); return _value.t; }
|
|
|
|
inline auto data() const -> const T* { return ((maybe*)this)->data(); }
|
|
inline auto get() const -> const T& { return ((maybe*)this)->get(); }
|
|
inline auto operator->() -> T* { return data(); }
|
|
inline auto operator->() const -> const T* { return data(); }
|
|
inline auto operator*() -> T& { return get(); }
|
|
inline auto operator*() const -> const T& { return get(); }
|
|
inline auto operator()() -> T& { return get(); }
|
|
inline auto operator()() const -> const T& { return get(); }
|
|
inline auto operator()(const T& invalid) const -> const T& { return _valid ? get() : invalid; }
|
|
|
|
private:
|
|
union U {
|
|
T t;
|
|
U() {}
|
|
~U() {}
|
|
} _value;
|
|
bool _valid = false;
|
|
};
|
|
|
|
template<typename T>
|
|
struct maybe<T&> {
|
|
inline maybe() : _value(nullptr) {}
|
|
inline maybe(nothing_t) : _value(nullptr) {}
|
|
inline maybe(const T& source) : _value((T*)&source) {}
|
|
inline maybe(const maybe& source) : _value(source._value) {}
|
|
|
|
inline auto operator=(nothing_t) -> maybe& { _value = nullptr; return *this; }
|
|
inline auto operator=(const T& source) -> maybe& { _value = (T*)&source; return *this; }
|
|
inline auto operator=(const maybe& source) -> maybe& { _value = source._value; return *this; }
|
|
|
|
inline explicit operator bool() const { return _value; }
|
|
inline auto reset() -> void { _value = nullptr; }
|
|
inline auto data() -> T* { return _value; }
|
|
inline auto get() -> T& { assert(_value); return *_value; }
|
|
|
|
inline auto data() const -> const T* { return ((maybe*)this)->data(); }
|
|
inline auto get() const -> const T& { return ((maybe*)this)->get(); }
|
|
inline auto operator->() -> T* { return data(); }
|
|
inline auto operator->() const -> const T* { return data(); }
|
|
inline auto operator*() -> T& { return get(); }
|
|
inline auto operator*() const -> const T& { return get(); }
|
|
inline auto operator()() -> T& { return get(); }
|
|
inline auto operator()() const -> const T& { return get(); }
|
|
inline auto operator()(const T& invalid) const -> const T& { return _value ? get() : invalid; }
|
|
|
|
private:
|
|
T* _value;
|
|
};
|
|
|
|
}
|