diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-09-06 23:22:18 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-09-06 23:22:18 +0200 |
commit | def67bba57e7cfdf9942bc2c88a4ce484963f9d2 (patch) | |
tree | a0c2024343151166bebc70440e2adb58c611d409 /asl | |
parent | aa427cb5fe7564a85703f14f76f854419274decc (diff) |
maybe_uninit
Diffstat (limited to 'asl')
-rw-r--r-- | asl/BUILD.bazel | 5 | ||||
-rw-r--r-- | asl/annotations.hpp | 11 | ||||
-rw-r--r-- | asl/layout.hpp | 29 | ||||
-rw-r--r-- | asl/maybe_uninit.hpp | 44 | ||||
-rw-r--r-- | asl/maybe_uninit_tests.cpp | 7 | ||||
-rw-r--r-- | asl/memory.hpp | 8 |
6 files changed, 103 insertions, 1 deletions
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel index e5d5eb3..d7371c1 100644 --- a/asl/BUILD.bazel +++ b/asl/BUILD.bazel @@ -3,6 +3,9 @@ cc_library( hdrs = [
"annotations.hpp",
"integers.hpp",
+ "layout.hpp",
+ "maybe_uninit.hpp",
+ "memory.hpp",
"meta.hpp",
"option.hpp",
"utility.hpp",
@@ -19,4 +22,4 @@ cc_library( deps = [
":asl",
],
-) for name in ["integers", "meta", "option", "utility"]]
+) for name in ["integers", "maybe_uninit", "meta", "option", "utility"]]
diff --git a/asl/annotations.hpp b/asl/annotations.hpp index a94834d..c0d8f20 100644 --- a/asl/annotations.hpp +++ b/asl/annotations.hpp @@ -10,3 +10,14 @@ #define ASL_NO_UNIQUE_ADDRESS [[no_unique_address]]
#endif
+namespace asl
+{
+
+struct unsafe
+{
+ unsafe() = delete;
+ explicit unsafe(auto&&) {}
+};
+
+} // namespace asl
+
diff --git a/asl/layout.hpp b/asl/layout.hpp new file mode 100644 index 0000000..5141456 --- /dev/null +++ b/asl/layout.hpp @@ -0,0 +1,29 @@ +#pragma once
+
+#include "asl/integers.hpp"
+#include "asl/meta.hpp"
+
+namespace asl
+{
+
+template<typename T>
+inline constexpr int64_t size_of = static_cast<int64_t>(sizeof(T));
+
+template<typename T>
+inline constexpr int64_t align_of = static_cast<int64_t>(alignof(T));
+
+struct layout
+{
+ int64_t size;
+ int64_t align;
+
+ constexpr bool operator==(const layout&) const = default;
+
+ template<is_object T>
+ static constexpr layout of()
+ {
+ return layout{ size_of<T>, align_of<T> };
+ }
+};
+
+} // namespace asl
diff --git a/asl/maybe_uninit.hpp b/asl/maybe_uninit.hpp new file mode 100644 index 0000000..ffbbb1c --- /dev/null +++ b/asl/maybe_uninit.hpp @@ -0,0 +1,44 @@ +#pragma once
+
+#include "asl/annotations.hpp"
+#include "asl/layout.hpp"
+#include "asl/memory.hpp"
+#include "asl/meta.hpp"
+
+namespace asl
+{
+
+template<is_object T>
+class alignas(align_of<T>) maybe_uninit
+{
+ char m_storage[size_of<T>];
+
+public:
+ constexpr void* uninit_ptr() const { return m_storage; }
+
+ // @Safety Pointer must only be accessed when in initialized state.
+ constexpr const T* init_ptr(unsafe) const { return reinterpret_cast<const T*>(m_storage); }
+ constexpr T* init_ptr(unsafe) { return reinterpret_cast< T*>(m_storage); }
+
+ // @Safety Reference must only be accessed when in initialized state.
+ constexpr const T& as_init(unsafe) const { return *reinterpret_cast<const T*>(m_storage); }
+ constexpr T& as_init(unsafe) { return *reinterpret_cast< T*>(m_storage); }
+
+ // @Safety Must be called only when in uninitialized state.
+ template<typename... Args>
+ inline void init(unsafe, Args&&... args)
+ {
+ new(uninit_ptr()) T(ASL_FWD(args)...);
+ }
+
+ // @Safety Must be called only when in initialized state.
+ inline void uninit(unsafe)
+ {
+ if constexpr (!trivially_destructible<T>)
+ {
+ init_ptr(unsafe("Caller has checked init state"))->~T();
+ }
+ }
+};
+
+} // namespace asl
diff --git a/asl/maybe_uninit_tests.cpp b/asl/maybe_uninit_tests.cpp new file mode 100644 index 0000000..7efeff0 --- /dev/null +++ b/asl/maybe_uninit_tests.cpp @@ -0,0 +1,7 @@ +#include "asl/maybe_uninit.hpp"
+
+static_assert(asl::layout::of<int>() == asl::layout::of<asl::maybe_uninit<int>>());
+static_assert(asl::size_of<int> == asl::size_of<asl::maybe_uninit<int>>);
+static_assert(asl::align_of<int> == asl::align_of<asl::maybe_uninit<int>>);
+
+int main() { return 0; }
diff --git a/asl/memory.hpp b/asl/memory.hpp new file mode 100644 index 0000000..33fa819 --- /dev/null +++ b/asl/memory.hpp @@ -0,0 +1,8 @@ +#pragma once
+
+#include "asl/integers.hpp"
+
+constexpr void* operator new(uint64_t, void* ptr)
+{
+ return ptr;
+}
|