maybe_uninit

This commit is contained in:
2024-09-06 23:22:18 +02:00
parent aa427cb5fe
commit def67bba57
8 changed files with 134 additions and 1 deletions

View File

@ -12,3 +12,4 @@ build --cxxopt=-Wno-c++98-compat-pedantic
build --cxxopt=-Wno-pre-c++17-compat build --cxxopt=-Wno-pre-c++17-compat
build --cxxopt=-Wno-c++20-compat build --cxxopt=-Wno-c++20-compat
build --cxxopt=-Wno-unused-macros build --cxxopt=-Wno-unused-macros
build --cxxopt=-Wno-documentation-unknown-command

View File

@ -1 +1,31 @@
Checks:
- "hicpp-*"
- "cppcoreguidelines-*"
- "misc-*"
- "clang-analyzer-*"
- "-misc-include-cleaner"
- "performance-*"
- "readability-*"
- "-*-named-parameter"
- "-*-avoid-do-while"
- "-*-magic-numbers"
- "-*-identifier-length"
- "-*-union-access"
- "-*-vararg"
- "-*-macro-usage"
- "-*-non-private-member-variables-in-classes"
- "-*-avoid-non-const-global-variables"
- "-*-missing-std-forward"
- "-*-owning-memory"
- "-*-no-malloc"
- "-*-avoid-c-arrays"
- "-*-use-anonymous-namespace"
- "-*-reinterpret-cast"
- "-*-noexcept-move"
- "-*-noexcept-move-constructor"
- "-*-noexcept-move-operations"
- "-*-bounds-array-to-pointer-decay"
- "-*-no-array-decay"
- "-*-signed-bitwise"
- "-readability-use-anyofallof"

View File

@ -3,6 +3,9 @@ cc_library(
hdrs = [ hdrs = [
"annotations.hpp", "annotations.hpp",
"integers.hpp", "integers.hpp",
"layout.hpp",
"maybe_uninit.hpp",
"memory.hpp",
"meta.hpp", "meta.hpp",
"option.hpp", "option.hpp",
"utility.hpp", "utility.hpp",
@ -19,4 +22,4 @@ cc_library(
deps = [ deps = [
":asl", ":asl",
], ],
) for name in ["integers", "meta", "option", "utility"]] ) for name in ["integers", "maybe_uninit", "meta", "option", "utility"]]

View File

@ -10,3 +10,14 @@
#define ASL_NO_UNIQUE_ADDRESS [[no_unique_address]] #define ASL_NO_UNIQUE_ADDRESS [[no_unique_address]]
#endif #endif
namespace asl
{
struct unsafe
{
unsafe() = delete;
explicit unsafe(auto&&) {}
};
} // namespace asl

29
asl/layout.hpp Normal file
View File

@ -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

44
asl/maybe_uninit.hpp Normal file
View File

@ -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

View File

@ -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; }

8
asl/memory.hpp Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include "asl/integers.hpp"
constexpr void* operator new(uint64_t, void* ptr)
{
return ptr;
}