Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
several.hpp
Go to the documentation of this file.
1/*
2 SEVERAL.hpp - abstraction providing a limited fixed number of elements
3
4 Copyright (C)
5 2008, Hermann Vosseler <Ichthyostega@web.de>
6 2024, Hermann Vosseler <Ichthyostega@web.de>
7
8  **Lumiera** is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by the
10  Free Software Foundation; either version 2 of the License, or (at your
11  option) any later version. See the file COPYING for further details.
12
13*/
14
15
54#ifndef LIB_SEVERAL_H
55#define LIB_SEVERAL_H
56
57
58#include "lib/nocopy.hpp"
59#include "lib/index-iter.hpp"
60
61#include <cstddef>
62#include <functional>
63
64namespace util {
65 template<class COLL>
66 std::string toStringBracket (COLL&& coll);
67}
68
69namespace lib {
70
71 namespace several {// Storage header implementation details
72
78 template<class TAR>
80 {
81 std::function<void(TAR*)> dtor_{};
82
83 public:
84 template<class FUN>
85 void
86 installDestructor (FUN&& dtor)
87 {
88 dtor_ = std::forward<FUN> (dtor);
89 }
90
92 {
93 if (isArmed())
94 {
95 auto destructionFun = std::move(dtor_);
96 ENSURE (not dtor_);
97 destructionFun (target());
98 }
99 }
100
101 bool isArmed() const { return bool(dtor_); }
102 auto getDtor() const { return dtor_; }
103 void destroy() { target()->~TAR(); }
104 TAR* target() { return static_cast<TAR*>(this); }
105 };
106
112 template<class I>
114 : SelfDestructor<ArrayBucket<I>>
115 {
116 ArrayBucket (size_t storageSize, size_t buffStart, size_t elmSize = sizeof(I))
117 : cnt{0}
118 , spread{elmSize}
119 , buffSiz{storageSize - buffStart}
120 , buffOffset{buffStart}
121 { }
122
123 using Deleter = std::function<void(ArrayBucket*)>;
124
125 size_t cnt;
126 size_t spread;
127 size_t buffSiz;
129
130 static constexpr size_t storageOffset = sizeof(ArrayBucket);
131 size_t getAllocSize() const { return buffOffset +buffSiz; }
132
133
135 std::byte*
137 {
138 return reinterpret_cast<std::byte*>(this) + buffOffset;
139 }
140
142 I&
143 subscript (size_t idx)
144 {
145 std::byte* elm = storage() + (idx * spread);
146 ENSURE (storage() <= elm and elm < storage()+buffSiz);
147 return * std::launder (reinterpret_cast<I*> (elm));
148 }
149
150 };
151
152 }//(End)implementation details
153
154
155
156 /************************************************/
163 template<class I>
166 {
167 protected:
169
170 Bucket data_{nullptr};
171
172 public:
173 Several() =default;
174
175 ~Several() noexcept
176 try { if (data_) data_->destroy(); }
177 ERROR_LOG_AND_IGNORE (progress, "clean-up Several data")
178
179
181 {
182 std::swap (data_, rr.data_);
183 }
185 {
186 std::swap (data_, rr.data_);
187 return *this;
188 }
189
190 explicit
191 operator std::string() const;
192
193 size_t
194 size() const
195 {
196 return data_? data_->cnt : 0;
197 }
198
199 bool
200 empty() const
201 {
202 return not data_;
203 }
204
205 I&
206 operator[] (size_t idx)
207 {
208 REQUIRE (data_);
209 return data_->subscript (idx);
210 }
211
212 I const&
213 operator[] (size_t idx) const
214 {
215 return const_cast<Several&>(*this).operator[] (idx);
216 }
217
218 I& front() { return operator[] (0); }
219 I& back() { return operator[] (data_? data_->cnt-1 : 0); }
220
223
224 iterator begin() { return iterator{*this}; }
225 iterator end() { return iterator{}; }
226 const_iterator begin() const { return const_iterator{*this};}
227 const_iterator end() const { return const_iterator{}; }
228
229 friend auto begin (Several& svl) { return svl.begin();}
230 friend auto end (Several& svl) { return svl.end(); }
231 friend auto begin (Several const& svl) { return svl.begin();}
232 friend auto end (Several const& svl) { return svl.end(); }
233
237
238
239 protected:
240 size_t
241 spread() const
242 {
243 return data_? data_->spread : sizeof(I);
244 }
245
246 size_t
248 {
249 return data_? data_->buffSiz : 0;
250 }
251
252 bool
253 hasReserve (size_t requiredSize, size_t newElms =1) const
254 {
255 if (requiredSize < spread())
256 requiredSize = spread();
257 size_t extraSize{requiredSize * newElms};
258 if (requiredSize > spread())
259 extraSize += (requiredSize - spread())*size();
260 return data_
261 and data_->buffSiz >= size()*spread() + extraSize;
262 }
263 };
264
265
267 template<class I>
268 inline
269 Several<I>::operator std::string() const
270 {
271 return util::toStringBracket (*this);
272 }
273
274} // namespace lib
275#endif
Subscript-index based access to a container, packaged as iterator.
Abstraction: Fixed array of elements.
Definition several.hpp:166
meta::RefTraits< I >::Value value_type
Definition several.hpp:234
friend auto end(Several const &svl)
Definition several.hpp:232
size_t storageBuffSiz() const
Definition several.hpp:247
size_t size() const
Definition several.hpp:194
const_iterator begin() const
Definition several.hpp:226
friend auto begin(Several const &svl)
Definition several.hpp:231
~Several() noexcept
Definition several.hpp:175
value_type const & const_reference
Definition several.hpp:236
bool hasReserve(size_t requiredSize, size_t newElms=1) const
Definition several.hpp:253
bool empty() const
Definition several.hpp:200
I & operator[](size_t idx)
Definition several.hpp:206
friend auto end(Several &svl)
Definition several.hpp:230
size_t spread() const
Definition several.hpp:241
Several()=default
usually to be created through SeveralBuilder
Bucket data_
Definition several.hpp:170
iterator end()
Definition several.hpp:225
const_iterator end() const
Definition several.hpp:227
iterator begin()
Definition several.hpp:224
Several & operator=(Several &&rr)
Definition several.hpp:184
meta::RefTraits< I >::Reference reference
Definition several.hpp:235
friend auto begin(Several &svl)
Definition several.hpp:229
void installDestructor(FUN &&dtor)
Definition several.hpp:86
std::function< void(TAR *)> dtor_
Definition several.hpp:81
Types marked with this mix-in may be moved and move-assigned.
Definition nocopy.hpp:64
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error.
Definition error.hpp:267
Iterator-style access handle to a referred container with subscript index.
Implementation namespace for support and library code.
string toStringBracket(COLL &&coll)
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Metadata record placed immediately before the data storage.
Definition several.hpp:115
static constexpr size_t storageOffset
Definition several.hpp:130
std::byte * storage()
data storage area starts immediately behind the ArrayBucket
Definition several.hpp:136
std::function< void(ArrayBucket *)> Deleter
Definition several.hpp:123
ArrayBucket(size_t storageSize, size_t buffStart, size_t elmSize=sizeof(I))
Definition several.hpp:116
I & subscript(size_t idx)
perform unchecked access into the storage area
Definition several.hpp:143
size_t getAllocSize() const
Definition several.hpp:131