summaryrefslogtreecommitdiffhomepage
path: root/src/handle-page.hpp
blob: 7afad5f8a6cbde266699f011b52c8ef342df4d5e (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
#pragma once
#include "handle-fwd.hpp"
#include "compat/defs.hpp"
#include <array>
#include <cr/BitArray.h>

namespace floormat::impl_handle {

template<typename Obj, uint32_t PageSize>
struct Item
{
    fm_DECLARE_DELETED_COPY_MOVE_ASSIGNMENTS(Item);
    Item();
    ~Item() noexcept;

    union { char empty = {}; Obj object; };
    Handle<Obj, PageSize> handle;
    uint32_t next;
};

template<typename Obj, uint32_t PageSize>
class Page
{
    friend struct Handle<Obj, PageSize>;

    std::array<Item<Obj, PageSize>, PageSize> storage;
    BitArray used_map; // todo replace with a rewrite of std::bitset
    uint32_t start_index;
    uint32_t used_count;
    uint32_t first_free;
    bool locked;

    static void do_deallocate(Item<Obj, PageSize>& item);

public:
    fm_DECLARE_DELETED_COPY_MOVE_ASSIGNMENTS(Page);

    explicit Page(uint32_t start_index);
    ~Page() noexcept;

    template<typename... Xs>
    requires requires (Xs&&... xs) {
        Obj{forward<Xs>(xs)...};
    }
    [[nodiscard]] Item<Obj, PageSize>& allocate(Xs&&... xs);
    void deallocate(Handle<Obj, PageSize> obj);
    void deallocate_all();
    bool is_empty();
    bool is_full();
    uint32_t use_count() const;
};

} // namespace floormat::impl_handle