diff options
Diffstat (limited to 'lib/nes/common')
| -rw-r--r-- | lib/nes/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/nes/common/box.hh | 55 | ||||
| -rw-r--r-- | lib/nes/common/list.hh | 2 |
3 files changed, 57 insertions, 1 deletions
diff --git a/lib/nes/common/CMakeLists.txt b/lib/nes/common/CMakeLists.txt index 553d468..1a66929 100644 --- a/lib/nes/common/CMakeLists.txt +++ b/lib/nes/common/CMakeLists.txt @@ -4,4 +4,5 @@ target_sources( debug.hh rgb.hh list.hh + box.hh display.hh)
\ No newline at end of file diff --git a/lib/nes/common/box.hh b/lib/nes/common/box.hh new file mode 100644 index 0000000..442d60f --- /dev/null +++ b/lib/nes/common/box.hh @@ -0,0 +1,55 @@ +#pragma once + +namespace nes +{ + /// Wrapper around an object, allowing for it to be uninitialized or reassigned even if the object type doesn't + /// support it. + /// + /// Basically a std::unique_ptr but stored in-place (and thus not movable). + template<typename T> + class box + { + bool initialized_{ false }; + alignas(T) unsigned char buffer_[sizeof(T)]; + + public: + /// Create an empty box. + explicit box() = default; + + ~box() + { + clear(); + } + + box(box const&) = delete; + box(box&&) = delete; + auto operator=(box const&) -> box& = delete; + auto operator=(box&&) -> box& = delete; + + auto operator*() -> T& { return *get(); } + auto operator*() const -> T const& { return *get(); } + auto operator->() -> T* { return get(); } + auto operator->() const -> T const* { return get(); } + operator bool() const { return has_value(); } + + auto has_value() const -> bool { return initialized_; } + auto get() -> T* { return has_value() ? std::launder(reinterpret_cast<T*>(buffer_)) : nullptr; } + auto get() const -> T const* { return has_value() ? std::launder(reinterpret_cast<T const *>(buffer_)) : nullptr; } + + /// Construct a new value in-place, potentially replacing the old value. + template<typename... Args> + auto emplace(Args&&... args) -> void + { + clear(); + new (buffer_) T(std::forward<Args>(args)...); + initialized_ = true; + } + + /// Clear the boxed value. + auto clear() -> void + { + if (initialized_) { (*this)->~T(); } + initialized_ = false; + } + }; +} // namespace nes
\ No newline at end of file diff --git a/lib/nes/common/list.hh b/lib/nes/common/list.hh index 5f0d258..d7a7d9b 100644 --- a/lib/nes/common/list.hh +++ b/lib/nes/common/list.hh @@ -39,7 +39,7 @@ namespace nes auto operator==(iterator const& other) -> bool { return current_ == other.current_; } auto operator!=(iterator const& other) -> bool { return current_ != other.current_; } - auto operator*() -> T* { return current_; } + auto operator*() const -> T* { return current_; } auto operator++() -> iterator& { |
