summaryrefslogtreecommitdiff
path: root/deimos/core/temp_allocator.h
blob: 6d93a7708f23bc9dbed8cc675ad6fb0a65b3a6ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#pragma once

#include "deimos/core/base.h"
#include "deimos/core/id_name.h"
#include "deimos/core/allocator.h"

namespace deimos
{

struct TempAllocatorTag { uintptr_t tag; };

class TempAllocatorApi;

class ITempAllocator
{
public:
    ITempAllocator() = default;
    deimos_NO_COPY_MOVE(ITempAllocator);
    virtual ~ITempAllocator() = default;
    
    virtual gsl::owner<void*> Reallocate(TempAllocatorTag tag,
        gsl::owner<void*> old_ptr, int64_t old_size, int64_t new_size) = 0;
    
    virtual void Release(TempAllocatorTag tag) = 0;
};

class TempAllocator : public IAllocator
{
    ITempAllocator* m_inner;
    TempAllocatorTag m_tag;

public:
    TempAllocator(ITempAllocator* inner, TempAllocatorTag tag) :
        m_inner{inner}, m_tag{tag}
    {}
    
    deimos_NO_COPY_MOVE(TempAllocator);

    ~TempAllocator() override;
    
    [[nodiscard]]
    gsl::owner<void*> Reallocate(
        gsl::owner<void*> old_ptr, int64_t old_size, int64_t new_size,
        MemoryScope scope, const SourceLocation& source_location = {}) override;

    constexpr Allocator allocator() { return Allocator(this, MemoryScope{0}); }
};

class TempAllocatorApi
{
public:
    TempAllocatorApi() = default;
    deimos_NO_COPY_MOVE(TempAllocatorApi);
    virtual ~TempAllocatorApi() = default;

    static constexpr IdName kApiName{"deimos::TempAllocatorApi"};

    [[nodiscard]] virtual TempAllocator Acquire() = 0;
};

[[nodiscard]]
inline gsl::owner<void*> TempAllocator::Reallocate(
    gsl::owner<void*> old_ptr, int64_t old_size, int64_t new_size,
    MemoryScope, const SourceLocation&)
{
    return m_inner->Reallocate(m_tag, old_ptr, old_size, new_size);
}

inline TempAllocator::~TempAllocator()
{
    m_inner->Release(m_tag);
}

} // namespace deimos