58 #ifndef LIB_ALLOCATION_CLUSTER_H 59 #define LIB_ALLOCATION_CLUSTER_H 64 #include <type_traits> 71 namespace test {
class AllocationCluster_test; }
98 auto bytePos() {
return static_cast<std::byte*
> (pos); }
101 allot (
size_t bytes,
size_t alignment)
103 void* loc = std::align (alignment, bytes, pos, rest);
106 pos = bytePos() + bytes;
112 void adjustPos (
int offset);
113 bool hasReserve (
int offset)
const;
114 bool matches_last_allocation (
void const* loc,
size_t siz)
const;
124 static size_t constexpr EXTENT_SIZ = 256;
125 static size_t constexpr max_size();
129 size_t numExtents()
const;
130 size_t numBytes()
const;
133 template<
class TY,
typename...ARGS>
134 TY& create (ARGS&& ...);
136 template<
class TY,
typename...ARGS>
137 TY& createDisposable (ARGS&& ...);
143 using value_type = X;
145 [[nodiscard]] X* allocate (
size_t n) {
return mother_->allot<X>(n); }
146 void deallocate (X*,
size_t) noexcept { }
163 bool canAdjust (
void* loc,
size_t oldSiz,
size_t newSiz)
const;
164 void doAdjust (
void* loc,
size_t oldSiz,
size_t newSiz);
174 __enforce_limits (bytes, alignment);
175 void* loc = storage_.allot(bytes, alignment);
177 expandStorage (bytes);
178 return allotMemory (bytes, alignment);
183 allot (
size_t cnt =1)
185 return static_cast<X*
> (allotMemory (cnt *
sizeof(X),
alignof(X)));
206 template<
typename...ARGS>
208 : payload(std::forward<ARGS> (args)...)
212 void expandStorage (
size_t);
214 void __enforce_limits (
size_t,
size_t);
236 size_t ADMIN_OVERHEAD = 2 *
sizeof(
void*);
237 return EXTENT_SIZ - ADMIN_OVERHEAD;
244 template<
class TY,
typename...ARGS>
246 AllocationCluster::createDisposable (ARGS&& ...args)
248 return *
new(allot<TY>()) TY (std::forward<ARGS> (args)...);
256 template<
class TY,
typename...ARGS>
258 AllocationCluster::create (ARGS&& ...args)
260 if constexpr (std::is_trivial_v<TY>)
261 return createDisposable<TY> (std::forward<ARGS> (args)...);
264 auto& frame = createDisposable<Frame> (std::forward<ARGS> (args)...);
265 registerDestructor (frame);
266 return frame.payload;
285 if (not canAdjust (loc,oldSiz,newSiz))
286 throw err::Invalid {
"AllocationCluster: unable to perform this allocation adjustment."};
287 storage_.adjustPos (
int(newSiz) -
int(oldSiz));
291 AllocationCluster::canAdjust(
void* loc,
size_t oldSiz,
size_t newSiz)
const 293 int offset{int(newSiz) - int(oldSiz)};
294 return storage_.matches_last_allocation (loc, oldSiz)
295 and storage_.hasReserve (offset);
302 REQUIRE (hasReserve (offset));
303 pos = bytePos() + offset;
308 AllocationCluster::Storage::hasReserve (
int offset)
const 310 return offset <= int(rest);
314 AllocationCluster::Storage::matches_last_allocation (
void const* loc,
size_t siz)
const 316 return loc ==
static_cast<std::byte const*
> (pos) - siz;
328 template<
class I,
class E,
template<
typename>
class ALO>
331 template<
template<
typename>
class ALO,
typename...ARGS>
350 using Adapter =
typename AllocationCluster::template Allocator<X>;
352 template<
class I,
class E>
357 using Bucket =
typename Base::Bucket;
368 canExpand (Bucket* bucket,
size_t request)
370 if (not bucket)
return false;
371 size_t currSize = bucket->getAllocSize();
372 long delta = long(request) - long(bucket->buffSiz);
373 return this->mother_->canAdjust (bucket,currSize, currSize+delta);
377 realloc (Bucket* bucket,
size_t cnt,
size_t spread)
379 size_t request = cnt*spread;
381 if (not canExpand (bucket,request))
382 return Base::realloc (bucket,cnt,spread);
384 size_t currSize = bucket->getAllocSize();
385 size_t delta = request - bucket->buffSiz;
386 this->mother_->doAdjust (bucket, currSize, currSize+delta);
387 bucket->buffSiz += delta;
388 ENSURE (bucket->buffSiz == request);
std::function< UICoord(UICoord)> Allocator
Allocator is a functor to resolve a given, desired location of a view within the UI, resulting in creation or allocation of the view – which happens as side-effect. The result of this invocation are the UI coordinates of an existing or newly created view.
void doAdjust(void *loc, size_t oldSiz, size_t newSiz)
Adjust the size of the latest raw memory allocation dynamically.
An overlay view for the AllocationCluster to add functionality for adding / clearing extents and regi...
Any copy and copy construction prohibited.
void adjustPos(int offset)
Types marked with this mix-in may be moved but not copied.
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
Extension point: how to configure the SeveralBuilder to use an allocator ALO, initialised by ARGS...
Implementation namespace for support and library code.
void * allotMemory(size_t bytes, size_t alignment)
portion out the requested amount of memory, possibly claiming a new pool block.
Derived specific exceptions within Lumiera's exception hierarchy.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Lumiera error handling (C++ interface).
A pile of objects sharing common allocation and lifecycle.
Policy Mix-In used to adapt to the ElementFactory and Allocator.
maintaining the Allocation
static size_t constexpr max_size()
Maximum individual allocation size that can be handled.