9 #ifndef EAGINE_MEMORY_FALLBACK_ALLOC_HPP
10 #define EAGINE_MEMORY_FALLBACK_ALLOC_HPP
12 #include "../assert.hpp"
16 namespace eagine::memory {
18 template <
typename Policy = default_
byte_allocator_policy>
19 class byte_allocator_with_fallback
20 :
public byte_allocator_impl<Policy, byte_allocator_with_fallback> {
24 shared_byte_allocator _dft;
25 shared_byte_allocator _fbk;
28 byte_allocator_with_fallback(
29 shared_byte_allocator&& dft,
30 shared_byte_allocator&& fbk = default_byte_allocator())
33 , _dft(std::move(dft))
34 , _fbk(std::move(fbk)) {}
38 auto equal(byte_allocator* a)
const noexcept ->
bool override {
39 auto* pa =
dynamic_cast<byte_allocator_with_fallback*
>(a);
42 return (_dft == pa->_dft) && (_fbk == pa->_fbk);
47 auto max_size(
span_size_t a) noexcept -> size_type
override {
48 size_type mdft = _dft.max_size(a);
49 size_type mfbk = _fbk.max_size(a);
51 return (mfbk > mdft) ? mfbk : mdft;
54 auto has_allocated(
const owned_block& b,
span_size_t a) noexcept
56 return _dft.has_allocated(b, a) || _fbk.has_allocated(b, a);
59 auto allocate(size_type n, size_type a) noexcept -> owned_block
override {
60 if(n <= _dft.max_size(a)) {
61 if(owned_block b = _dft.allocate(n, a)) {
67 if(_fbk_max < _fbk_size) {
70 return _fbk.allocate(n, a);
73 void deallocate(owned_block&& b, size_type a) noexcept
override {
74 if(_dft.has_allocated(b, a)) {
75 _dft.deallocate(std::move(b), a);
76 }
else if(!!_fbk.has_allocated(b, a)) {
77 _fbk_size -= b.size();
78 _fbk.deallocate(std::move(b), a);
80 EAGINE_ABORT(
"Pointer not allocated by this allocator!");
87 #endif // EAGINE_MEMORY_FALLBACK_ALLOC_HPP