LeviLamina
Loading...
Searching...
No Matches
Alias.h
1#pragma once
2
3#include <bit>
4#include <cstddef>
5#include <memory>
6#include <type_traits>
7#include <utility>
8
9#include "gsl/pointers"
10
11namespace ll {
12
13template <size_t Align, size_t Size>
15 alignas(Align) std::byte data[Size];
16
17 template <class T>
18 [[nodiscard]] T& as() & {
19 if constexpr (std::is_reference_v<T>) {
20 return **reinterpret_cast<std::remove_reference_t<T>**>(data);
21 } else {
22 return *reinterpret_cast<T*>(data);
23 }
24 }
25 template <class T>
26 [[nodiscard]] T const& as() const& {
27 if constexpr (std::is_reference_v<T>) {
28 return **reinterpret_cast<std::remove_reference_t<T> const**>(data);
29 } else {
30 return *reinterpret_cast<T const*>(data);
31 }
32 }
33 template <class T>
34 [[nodiscard]] T&& as() && {
35 if constexpr (std::is_reference_v<T>) {
36 return std::move(**reinterpret_cast<std::remove_reference_t<T>**>(data));
37 } else {
38 return std::move(*reinterpret_cast<T*>(data));
39 }
40 }
41 template <class T>
42 [[nodiscard]] T const&& as() const&& {
43 if constexpr (std::is_reference_v<T>) {
44 return std::move(**reinterpret_cast<std::remove_reference_t<T> const**>(data));
45 } else {
46 return std::move(*reinterpret_cast<T const*>(data));
47 }
48 }
49};
50
51template <size_t Align, size_t Size, class T>
53 alignas(Align) std::byte data[Size];
54
55 template <class... Args>
56 constexpr TypedStorageImpl(Args&&... args) {
57 std::construct_at(this->operator->(), std::forward<Args>(args)...);
58 }
59
60 TypedStorageImpl(TypedStorageImpl const& other) { std::construct_at(this->operator->(), other.get()); }
61
62 TypedStorageImpl(TypedStorageImpl&& other) { std::construct_at(this->operator->(), std::move(other.get())); }
63
64 template <class U>
65 constexpr T& operator=(U&& u) {
66 get().operator=(std::forward<U>(u));
67 return get();
68 }
69
70 T& operator=(TypedStorageImpl const& u) {
71 get().operator=(u.get());
72 return get();
73 }
74
75 T& operator=(TypedStorageImpl&& u) {
76 get().operator=(std::move(u.get()));
77 return get();
78 }
79
80 constexpr ~TypedStorageImpl() { std::destroy_at(this->operator->()); }
81
82 [[nodiscard]] T* operator->() { return reinterpret_cast<T*>(data); }
83 [[nodiscard]] T const* operator->() const { return reinterpret_cast<T const*>(data); }
84 [[nodiscard]] T& get() & { return *reinterpret_cast<T*>(data); }
85 [[nodiscard]] T const& get() const& { return *reinterpret_cast<T const*>(data); }
86 [[nodiscard]] T&& get() && { return std::move(*reinterpret_cast<T*>(data)); }
87 [[nodiscard]] T const&& get() const&& { return std::move(*reinterpret_cast<T const*>(data)); }
88 [[nodiscard]] T& operator*() & { return get(); }
89 [[nodiscard]] T const& operator*() const& { return get(); }
90 [[nodiscard]] T&& operator*() && { return std::move(get()); }
91 [[nodiscard]] T const&& operator*() const&& { return std::move(get()); }
92 [[nodiscard]] operator T&() { return get(); }
93 [[nodiscard]] operator T const&() const { return get(); }
94};
95
96template <size_t A, size_t S, class T>
100template <size_t A, size_t S, class T>
101 requires(std::is_reference_v<T> || std::is_scalar_v<T>)
103 using Type = T;
104};
105template <size_t A, size_t S, class T>
106struct TypedStorageType<A, S, gsl::not_null<T>> {
107 using Type = gsl::not_null<T>;
108};
109template <size_t A, size_t S, class T>
110struct TypedStorageType<A, S, std::unique_ptr<T>> {
111 using Type = std::unique_ptr<T>;
112};
113template <size_t A, size_t S, class T>
114struct TypedStorageType<A, S, std::shared_ptr<T>> {
115 using Type = std::shared_ptr<T>;
116};
117template <size_t A, size_t S, class T>
118struct TypedStorageType<A, S, std::weak_ptr<T>> {
119 using Type = std::weak_ptr<T>;
120};
121template <size_t A, size_t S, class T, size_t N>
122struct TypedStorageType<A, S, T[N]> {
123 using Type = TypedStorageType<A, S / N, T>::Type[N];
124};
125
126template <size_t A, size_t S, class T>
127using TypedStorage = TypedStorageType<A, S, T>::Type;
128
129} // namespace ll
STL namespace.
Definition Alias.h:52
Definition Alias.h:97
Definition Alias.h:14