Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
uninitialised-storage.hpp
Go to the documentation of this file.
1/*
2 UNINITIALISED-STORAGE.hpp - array-like container with raw storage
3
4 Copyright (C)
5 2023, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
61#ifndef LIB_UNINITIALISED_STORAGE_H
62#define LIB_UNINITIALISED_STORAGE_H
63
64
65#include <cstddef>
66#include <utility>
67#include <array>
68#include <new>
69
70
71namespace lib {
72
78 template<typename T, size_t cnt =1>
80 {
81 using _Arr = std::array<T,cnt>;
82 alignas(T) std::byte buffer_[sizeof(_Arr)];
83
84 public:
85 _Arr&
87 {
88 return * std::launder (reinterpret_cast<_Arr* > (&buffer_));
89 }
90
91 _Arr const&
92 array() const
93 {
94 return * std::launder (reinterpret_cast<_Arr const*> (&buffer_));
95 }
96
97
98 operator _Arr&() { return array(); }
99 operator _Arr const&() const { return array(); }
100
101 T & operator[] (size_t idx) { return array()[idx]; }
102 T const& operator[] (size_t idx) const { return array()[idx]; }
103
104
105 template<typename...Args>
106 T&
107 createAt (size_t idx, Args&& ...args)
108 {
109 return *new(&operator[](idx)) T{std::forward<Args>(args)...};
110 }
111
112 void
113 destroyAt (size_t idx)
114 {
115 operator[](idx).~T();
116 }
117
118 static constexpr size_t size() { return cnt; }
119 };
120
121
122
123
128 template<typename T>
130 {
131 using _Arr = T[];
132
133 void* buff_{nullptr};
134 size_t size_{0};
135
136 public:
137 T*
138 allocate(size_t cnt)
139 {
140 if (buff_) discard();
141 size_ = cnt;
142 buff_ = cnt? std::aligned_alloc (std::alignment_of<T>(), cnt * sizeof(T))
143 : nullptr;
144 return front();
145 }
146
147 void
149 {
150 std::free (buff_);
151 buff_ = nullptr;
152 size_ = 0;
153 }
154
155
158 {
159 if (buff_)
160 discard();
161 }
162 explicit
164 {
165 if (cnt)
166 allocate(cnt);
167 }
168
170 {
171 if (this != &rr)
172 swap (*this, rr);
173 }
174
178
179 friend void
181 {
182 using std::swap;
183 swap (u1.size_, u2.size_);
184 swap (u1.buff_, u2.buff_);
185 }
186
187 explicit
188 operator bool() const
189 {
190 return bool(buff_);
191 }
192
193 size_t
194 size() const
195 {
196 return size_;
197 }
198
199
200 _Arr&
202 {
203 return * std::launder (reinterpret_cast<_Arr* > (buff_));
204 }
205
206 _Arr const&
207 array() const
208 {
209 return * std::launder (reinterpret_cast<_Arr const*> (buff_));
210 }
211
212
213 T * front() { return &array()[0]; }
214 T const* front() const { return &array()[0]; }
215 T * after() { return &array()[size_];}
216 T const* after() const { return &array()[size_];}
217 T * back () { return after() - 1; }
218 T const* back () const { return after() - 1; }
219
220 T & operator[] (size_t idx) { return array()[idx]; }
221 T const& operator[] (size_t idx) const { return array()[idx]; }
222
223
224 template<typename...Args>
225 T&
226 createAt (size_t idx, Args&& ...args)
227 {
228 return *new(&operator[](idx)) T{std::forward<Args>(args)...};
229 }
230
231 void
232 destroyAt (size_t idx)
233 {
234 operator[](idx).~T();
235 }
236 };
237
238
239} // namespace lib
240#endif /*LIB_UNINITIALISED_STORAGE_H*/
Managed uninitialised Heap-allocated storage with array like access.
UninitialisedDynBlock(UninitialisedDynBlock const &)=delete
T & createAt(size_t idx, Args &&...args)
UninitialisedDynBlock & operator=(UninitialisedDynBlock &&)=delete
UninitialisedDynBlock(UninitialisedDynBlock &&rr)
friend void swap(UninitialisedDynBlock &u1, UninitialisedDynBlock &u2)
Block of raw uninitialised storage with array like access.
static constexpr size_t size()
T & createAt(size_t idx, Args &&...args)
std::byte buffer_[sizeof(_Arr)]
Implementation namespace for support and library code.