summaryrefslogtreecommitdiff
path: root/lib/nes/common
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2025-02-01 00:38:55 +0100
committerHannes Schulze <haschu0103@outlook.de>2025-02-01 00:38:55 +0100
commit1d5f5482f91391a6dfee9ec0e7cb0a22ee5f0464 (patch)
tree80e1dff12390aa36ec532da655136e4b83b6ccf3 /lib/nes/common
parentccb81b60dac888e44079fb0228c1d5d8542ceade (diff)
implement screens
Diffstat (limited to 'lib/nes/common')
-rw-r--r--lib/nes/common/CMakeLists.txt1
-rw-r--r--lib/nes/common/box.hh55
-rw-r--r--lib/nes/common/list.hh2
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&
{