maybe_uninit
This commit is contained in:
1
.bazelrc
1
.bazelrc
@ -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
|
||||||
|
30
.clang-tidy
30
.clang-tidy
@ -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"
|
||||||
|
|
||||||
|
@ -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"]]
|
||||||
|
@ -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
29
asl/layout.hpp
Normal 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
44
asl/maybe_uninit.hpp
Normal 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
|
7
asl/maybe_uninit_tests.cpp
Normal file
7
asl/maybe_uninit_tests.cpp
Normal 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
8
asl/memory.hpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "asl/integers.hpp"
|
||||||
|
|
||||||
|
constexpr void* operator new(uint64_t, void* ptr)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
Reference in New Issue
Block a user