Lumiera  0.pre.03
»edit your freedom«
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) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
70 #ifndef LIB_UNINITIALISED_STORAGE_H
71 #define LIB_UNINITIALISED_STORAGE_H
72 
73 
74 #include <cstddef>
75 #include <utility>
76 #include <array>
77 #include <new>
78 
79 
80 namespace lib {
81 
87  template<typename T, size_t cnt>
89  {
90  using _Arr = std::array<T,cnt>;
91  alignas(T) std::byte buffer_[sizeof(_Arr)];
92 
93  public:
94  _Arr&
95  array()
96  {
97  return * std::launder (reinterpret_cast<_Arr* > (&buffer_));
98  }
99 
100  _Arr const&
101  array() const
102  {
103  return * std::launder (reinterpret_cast<_Arr const*> (&buffer_));
104  }
105 
106 
107  operator _Arr&() { return array(); }
108  operator _Arr const&() const { return array(); }
109 
110  T & operator[] (size_t idx) { return array()[idx]; }
111  T const& operator[] (size_t idx) const { return array()[idx]; }
112 
113 
114  template<typename...Args>
115  T&
116  createAt (size_t idx, Args&& ...args)
117  {
118  return *new(&operator[](idx)) T{std::forward<Args>(args)...};
119  }
120 
121  void
122  destroyAt (size_t idx)
123  {
124  operator[](idx).~T();
125  }
126  };
127 
128 
129 
130 
135  template<typename T>
137  {
138  using _Arr = T[];
139 
140  void* buff_{nullptr};
141  size_t size_{0};
142 
143  public:
144  T*
145  allocate(size_t cnt)
146  {
147  if (buff_) discard();
148  size_ = cnt;
149  buff_ = cnt? std::aligned_alloc (std::alignment_of<T>(), cnt * sizeof(T))
150  : nullptr;
151  return front();
152  }
153 
154  void
155  discard()
156  {
157  std::free (buff_);
158  buff_ = nullptr;
159  size_ = 0;
160  }
161 
162 
163  UninitialisedDynBlock() =default;
165  {
166  if (buff_)
167  discard();
168  }
169  explicit
170  UninitialisedDynBlock (size_t cnt)
171  {
172  if (cnt)
173  allocate(cnt);
174  }
175 
177  {
178  if (this != &rr)
179  swap (*this, rr);
180  }
181 
183  UninitialisedDynBlock& operator= (UninitialisedDynBlock &&) =delete;
184  UninitialisedDynBlock& operator= (UninitialisedDynBlock const&) =delete;
185 
186  friend void
188  {
189  std::swap (u1.size_, u2.size_);
190  std::swap (u1.buff_, u2.buff_);
191  }
192 
193  explicit
194  operator bool() const
195  {
196  return bool(buff_);
197  }
198 
199  size_t
200  size() const
201  {
202  return size_;
203  }
204 
205 
206  _Arr&
207  array()
208  {
209  return * std::launder (reinterpret_cast<_Arr* > (buff_));
210  }
211 
212  _Arr const&
213  array() const
214  {
215  return * std::launder (reinterpret_cast<_Arr const*> (buff_));
216  }
217 
218 
219  T * front() { return &array()[0]; }
220  T const* front() const { return &array()[0]; }
221  T * after() { return &array()[size_];}
222  T const* after() const { return &array()[size_];}
223  T * back () { return after() - 1; }
224  T const* back () const { return after() - 1; }
225 
226  T & operator[] (size_t idx) { return array()[idx]; }
227  T const& operator[] (size_t idx) const { return array()[idx]; }
228 
229 
230  template<typename...Args>
231  T&
232  createAt (size_t idx, Args&& ...args)
233  {
234  return *new(&operator[](idx)) T{std::forward<Args>(args)...};
235  }
236 
237  void
238  destroyAt (size_t idx)
239  {
240  operator[](idx).~T();
241  }
242  };
243 
244 
245 } // namespace lib
246 #endif /*LIB_UNINITIALISED_STORAGE_H*/
Implementation namespace for support and library code.
Block of raw uninitialised storage with array like access.
Managed uninitialised Heap-allocated storage with array like access.