Skip to content

Commit 616c3e9

Browse files
make Address Allocators report extra_ctor_param_types and add to traits
1 parent 9ea0d94 commit 616c3e9

9 files changed

Lines changed: 576 additions & 598 deletions
Lines changed: 141 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,154 @@
1-
// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
1+
// Copyright (C) 2018-2026 - DevSH Graphics Programming Sp. z O.O.
22
// This file is part of the "Nabla Engine".
33
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#ifndef _NBL_CORE_ADDRESS_ALLOCATOR_BASE_H_INCLUDED_
5+
#define _NBL_CORE_ADDRESS_ALLOCATOR_BASE_H_INCLUDED_
46

5-
#ifndef __NBL_CORE_ADDRESS_ALLOCATOR_BASE_H_INCLUDED__
6-
#define __NBL_CORE_ADDRESS_ALLOCATOR_BASE_H_INCLUDED__
77

88
#include "nbl/core/memory/memory.h"
99
#include "nbl/core/alloc/address_allocator_traits.h"
1010

11-
namespace nbl
12-
{
13-
namespace core
11+
12+
namespace nbl::core
1413
{
1514

16-
#define _NBL_DECLARE_ADDRESS_ALLOCATOR_TYPEDEFS(SIZE_TYPE) \
17-
using size_type = SIZE_TYPE;\
18-
using difference_type = typename std::make_signed<size_type>::type;\
19-
using ubyte_pointer = uint8_t*;\
20-
static constexpr size_type invalid_address = nbl::core::address_type_traits<size_type>::invalid_address
21-
22-
template<typename CRTP, typename _size_type>
23-
class AddressAllocatorBase
24-
{
25-
public:
26-
_NBL_DECLARE_ADDRESS_ALLOCATOR_TYPEDEFS(_size_type);
27-
28-
AddressAllocatorBase() { invalidate(); }
29-
30-
inline _size_type max_alignment() const noexcept
31-
{
32-
return maxRequestableAlignment;
33-
}
34-
35-
inline _size_type get_align_offset() const noexcept
36-
{
37-
return alignOffset;
38-
}
39-
40-
inline _size_type get_combined_offset() const noexcept
41-
{
42-
return combinedOffset;
43-
}
44-
45-
// usage: for resizeable allocators built on top of non-resizeable ones (that resize via the CRTP constructor)
46-
// we usually call this before attempting to create the memory for the resized allocator,
47-
// so we don't know exactly what the addressOffset or alignOffset will be
48-
inline _size_type safe_shrink_size(_size_type sizeBound, _size_type newBuffAlignmentWeCanGuarantee=1u) const noexcept
49-
{
50-
if (newBuffAlignmentWeCanGuarantee<maxRequestableAlignment)
51-
return sizeBound+maxRequestableAlignment-newBuffAlignmentWeCanGuarantee;
52-
else if (sizeBound)
53-
return sizeBound;
54-
else
55-
return std::max(maxRequestableAlignment,newBuffAlignmentWeCanGuarantee);
56-
}
57-
protected:
58-
virtual ~AddressAllocatorBase() {}
59-
60-
AddressAllocatorBase(void* reservedSpc, _size_type addressOffsetToApply, _size_type alignOffsetNeeded, _size_type maxAllocatableAlignment) :
61-
reservedSpace(reservedSpc), addressOffset(addressOffsetToApply), alignOffset(alignOffsetNeeded),
62-
maxRequestableAlignment(maxAllocatableAlignment), combinedOffset(addressOffset+alignOffset)
63-
{
64-
#ifdef _NBL_DEBUG
65-
// pointer to reserved memory has to be aligned to SIMD types!
66-
assert((reinterpret_cast<size_t>(reservedSpace)&(_NBL_SIMD_ALIGNMENT-1u))==0ull);
67-
assert(maxAllocatableAlignment);
68-
assert(core::isPoT(maxRequestableAlignment)); // this is not a proper alignment value
69-
#endif // _NBL_DEBUG
70-
}
71-
AddressAllocatorBase(CRTP&& other, void* newReservedSpc)
72-
{
73-
operator=(std::move(other));
74-
reservedSpace = newReservedSpc;
75-
#ifdef _NBL_DEBUG
76-
// reserved space has to be aligned at least to SIMD
77-
assert((reinterpret_cast<size_t>(reservedSpace)&(_NBL_SIMD_ALIGNMENT-1u))==0ull);
78-
#endif // _NBL_DEBUG
79-
}
80-
AddressAllocatorBase(CRTP&& other, void* newReservedSpc, _size_type newAddressOffset, _size_type newAlignOffset) :
81-
AddressAllocatorBase(std::move(other),newReservedSpc)
82-
{
83-
addressOffset = newAddressOffset;
84-
alignOffset = newAlignOffset;
85-
combinedOffset = addressOffset+alignOffset;
86-
}
87-
AddressAllocatorBase(const CRTP& other, void* newReservedSpc) :
88-
reservedSpace(newReservedSpc), addressOffset(other.addressOffset), alignOffset(other.alignOffset),
89-
maxRequestableAlignment(other.maxRequestableAlignment), combinedOffset(other.combinedOffset)
90-
{
91-
#ifdef _NBL_DEBUG
92-
// reserved space has to be aligned at least to SIMD
93-
assert((reinterpret_cast<size_t>(reservedSpace)&(_NBL_SIMD_ALIGNMENT-1u))==0ull);
94-
#endif // _NBL_DEBUG
95-
}
96-
AddressAllocatorBase(const CRTP& other, void* newReservedSpc, _size_type newAddressOffset, _size_type newAlignOffset) :
97-
AddressAllocatorBase(other, newReservedSpc)
98-
{
99-
addressOffset = newAddressOffset;
100-
alignOffset = newAlignOffset;
101-
combinedOffset = addressOffset+alignOffset;
102-
}
103-
104-
inline bool checkResize(_size_type newBuffSz, _size_type newAlignOffset)
105-
{
106-
// cannot reallocate the data into smaller storage than is necessary
107-
if (newBuffSz<safe_shrink_size(0u,maxRequestableAlignment)) return false;
108-
// need enough space for the new alignment
109-
if (newAlignOffset>newBuffSz) return false;
110-
111-
return true;
112-
}
113-
114-
inline _size_type getAddressOffset() const noexcept {return addressOffset;}
115-
116-
inline const void* getReservedSpacePtr() const noexcept {return reservedSpace;}
117-
118-
AddressAllocatorBase& operator=(AddressAllocatorBase&& other)
119-
{
120-
reservedSpace = other.reservedSpace;
121-
addressOffset = other.addressOffset;
122-
alignOffset = other.alignOffset;
123-
maxRequestableAlignment = other.maxRequestableAlignment;
124-
combinedOffset = other.combinedOffset;
125-
other.invalidate();
126-
return *this;
127-
}
128-
129-
void invalidate()
130-
{
131-
reservedSpace = nullptr;
132-
addressOffset = invalid_address;
133-
alignOffset = invalid_address;
134-
maxRequestableAlignment = invalid_address;
135-
combinedOffset = invalid_address;
136-
}
137-
138-
// pointer to allocator specific state-keeping data, please note that irrBaW address allocators were designed to allocate memory they can't actually access
139-
void* reservedSpace;
140-
// automatic offset to be added to generated addresses
141-
_size_type addressOffset;
142-
// the positive offset that would have to be applied to `addressOffset` to make it `maxRequestableAlignment`-aligned to some unknown value
143-
_size_type alignOffset;
144-
// this cannot be deduced from the `addressOffset` , so we let the user specify it
145-
_size_type maxRequestableAlignment;
146-
147-
//internal usage
148-
_size_type combinedOffset;
149-
};
15+
#define _NBL_DECLARE_ADDRESS_ALLOCATOR_TYPEDEFS(SIZE_TYPE) \
16+
using size_type = SIZE_TYPE;\
17+
using difference_type = typename std::make_signed<size_type>::type;\
18+
using ubyte_pointer = uint8_t*;\
19+
static constexpr size_type invalid_address = nbl::core::address_type_traits<size_type>::invalid_address
15020

151-
}
152-
}
21+
template<typename CRTP, typename _size_type>
22+
class AddressAllocatorBase
23+
{
24+
public:
25+
_NBL_DECLARE_ADDRESS_ALLOCATOR_TYPEDEFS(_size_type);
26+
27+
AddressAllocatorBase() { invalidate(); }
28+
29+
inline _size_type max_alignment() const noexcept
30+
{
31+
return maxRequestableAlignment;
32+
}
33+
34+
inline _size_type get_align_offset() const noexcept
35+
{
36+
return alignOffset;
37+
}
38+
39+
inline _size_type get_combined_offset() const noexcept
40+
{
41+
return combinedOffset;
42+
}
43+
44+
// usage: for resizeable allocators built on top of non-resizeable ones (that resize via the CRTP constructor)
45+
// we usually call this before attempting to create the memory for the resized allocator,
46+
// so we don't know exactly what the addressOffset or alignOffset will be
47+
inline _size_type safe_shrink_size(_size_type sizeBound, _size_type newBuffAlignmentWeCanGuarantee=1u) const noexcept
48+
{
49+
if (newBuffAlignmentWeCanGuarantee<maxRequestableAlignment)
50+
return sizeBound+maxRequestableAlignment-newBuffAlignmentWeCanGuarantee;
51+
else if (sizeBound)
52+
return sizeBound;
53+
else
54+
return std::max(maxRequestableAlignment,newBuffAlignmentWeCanGuarantee);
55+
}
56+
protected:
57+
virtual ~AddressAllocatorBase() {}
58+
59+
inline AddressAllocatorBase(void* reservedSpc, _size_type addressOffsetToApply, _size_type alignOffsetNeeded, _size_type maxAllocatableAlignment) :
60+
reservedSpace(reservedSpc), addressOffset(addressOffsetToApply), alignOffset(alignOffsetNeeded),
61+
maxRequestableAlignment(maxAllocatableAlignment), combinedOffset(addressOffset+alignOffset)
62+
{
63+
#ifdef _NBL_DEBUG
64+
// pointer to reserved memory has to be aligned to SIMD types!
65+
assert((reinterpret_cast<size_t>(reservedSpace)&(_NBL_SIMD_ALIGNMENT-1u))==0ull);
66+
assert(maxAllocatableAlignment);
67+
assert(core::isPoT(maxRequestableAlignment)); // this is not a proper alignment value
68+
#endif // _NBL_DEBUG
69+
}
70+
inline AddressAllocatorBase(CRTP&& other, void* newReservedSpc)
71+
{
72+
operator=(std::move(other));
73+
reservedSpace = newReservedSpc;
74+
#ifdef _NBL_DEBUG
75+
// reserved space has to be aligned at least to SIMD
76+
assert((reinterpret_cast<size_t>(reservedSpace)&(_NBL_SIMD_ALIGNMENT-1u))==0ull);
77+
#endif // _NBL_DEBUG
78+
}
79+
// TODO: list of extra parameter types for move and copy ctors, and utilities to static assert them
80+
// NOTE: there's only one move ctor, so maybe all the base classes shouldn't perfectly forward it anymore?
81+
inline AddressAllocatorBase(CRTP&& other, void* newReservedSpc, _size_type newAddressOffset, _size_type newAlignOffset) :
82+
AddressAllocatorBase(std::move(other),newReservedSpc)
83+
{
84+
addressOffset = newAddressOffset;
85+
alignOffset = newAlignOffset;
86+
combinedOffset = addressOffset+alignOffset;
87+
}
88+
inline AddressAllocatorBase(const CRTP& other, void* newReservedSpc) :
89+
reservedSpace(newReservedSpc), addressOffset(other.addressOffset), alignOffset(other.alignOffset),
90+
maxRequestableAlignment(other.maxRequestableAlignment), combinedOffset(other.combinedOffset)
91+
{
92+
#ifdef _NBL_DEBUG
93+
// reserved space has to be aligned at least to SIMD
94+
assert((reinterpret_cast<size_t>(reservedSpace)&(_NBL_SIMD_ALIGNMENT-1u))==0ull);
95+
#endif // _NBL_DEBUG
96+
}
97+
inline AddressAllocatorBase(const CRTP& other, void* newReservedSpc, _size_type newAddressOffset, _size_type newAlignOffset) :
98+
AddressAllocatorBase(other, newReservedSpc)
99+
{
100+
addressOffset = newAddressOffset;
101+
alignOffset = newAlignOffset;
102+
combinedOffset = addressOffset+alignOffset;
103+
}
104+
105+
inline bool checkResize(_size_type newBuffSz, _size_type newAlignOffset)
106+
{
107+
// cannot reallocate the data into smaller storage than is necessary
108+
if (newBuffSz<safe_shrink_size(0u,maxRequestableAlignment)) return false;
109+
// need enough space for the new alignment
110+
if (newAlignOffset>newBuffSz) return false;
111+
112+
return true;
113+
}
114+
115+
inline _size_type getAddressOffset() const noexcept {return addressOffset;}
116+
117+
inline const void* getReservedSpacePtr() const noexcept {return reservedSpace;}
118+
119+
inline AddressAllocatorBase& operator=(AddressAllocatorBase&& other)
120+
{
121+
reservedSpace = other.reservedSpace;
122+
addressOffset = other.addressOffset;
123+
alignOffset = other.alignOffset;
124+
maxRequestableAlignment = other.maxRequestableAlignment;
125+
combinedOffset = other.combinedOffset;
126+
other.invalidate();
127+
return *this;
128+
}
129+
130+
inline void invalidate()
131+
{
132+
reservedSpace = nullptr;
133+
addressOffset = invalid_address;
134+
alignOffset = invalid_address;
135+
maxRequestableAlignment = invalid_address;
136+
combinedOffset = invalid_address;
137+
}
138+
139+
// pointer to allocator specific state-keeping data, please note that irrBaW address allocators were designed to allocate memory they can't actually access
140+
void* reservedSpace;
141+
// automatic offset to be added to generated addresses
142+
_size_type addressOffset;
143+
// the positive offset that would have to be applied to `addressOffset` to make it `maxRequestableAlignment`-aligned to some unknown value
144+
_size_type alignOffset;
145+
// this cannot be deduced from the `addressOffset` , so we let the user specify it
146+
_size_type maxRequestableAlignment;
147+
148+
//internal usage
149+
_size_type combinedOffset;
150+
};
153151

152+
}
154153
#endif
155154

0 commit comments

Comments
 (0)