nngn
Loading...
Searching...
No Matches
tagging.h
Go to the documentation of this file.
1#ifndef NNGN_UTILS_ALLOC_TAGGED_H
2#define NNGN_UTILS_ALLOC_TAGGED_H
3
4#include "utils/utils.h"
5
6#include "base.h"
7
8namespace nngn {
9
15template<typename T>
16concept tagging_descriptor = requires(T t) {
17 // Type exposed in the allocator interface.
18 typename T::value_type;
19 // Allocated type.
20 typename T::block_type;
21};
22
39template<
41 typename A = std::allocator<typename D::block_type::value_type>>
43 public stateless_allocator<tagging_allocator<D, A>>
44{
45public:
46 using block_type = typename D::block_type;
47 using value_type = typename D::value_type;
49 using allocator =
50 typename std::allocator_traits<A>::template rebind_alloc<char>;
51 template<typename U>
52 struct rebind {
53 using other =
55 typename D::template rebind<U>::other,
56 typename std::allocator_traits<allocator>
57 ::template rebind_alloc<U>>;
58 };
59 // Construction, assignment
60 tagging_allocator(void) = default;
63 template<tagging_descriptor D1, typename A1>
65 explicit tagging_allocator(const allocator &a) : alloc{a} {}
66 tagging_allocator(tagging_allocator&&) noexcept = default;
67 tagging_allocator &operator=(tagging_allocator&&) noexcept = default;
68 ~tagging_allocator(void) = default;
69 // Allocator API
71 pointer allocate(std::size_t n) noexcept;
73 template<typename I>
74 pointer allocate(std::size_t n, I i) noexcept
75 requires(detail::has_typed_alloc<allocator, I>);
76 pointer reallocate(pointer p, std::size_t n) noexcept
77 requires(detail::has_realloc<A>);
78 void deallocate(pointer p, std::size_t n) noexcept;
79 const allocator &get_allocator(void) const { return this->alloc; }
80private:
81 static pointer to_ptr(char *p);
82 static char *raw_from_ptr(pointer p);
83 static auto alloc_size(std::size_t n) { return block_type::alloc_size(n); }
84 [[no_unique_address]] allocator alloc = {};
85};
86
87template<tagging_descriptor D, typename A>
89 auto b = block_type::from_storage_ptr(p);
90 new (b.header()) typename block_type::header_type;
91 return b.get();
92}
93
94template<tagging_descriptor D, typename A>
96 return nngn::byte_cast<char*>(block_type::from_ptr(p).data());
97}
98
99template<tagging_descriptor D, typename A>
102{
103 this->alloc = rhs.alloc;
104 return *this;
105}
106
107template<tagging_descriptor D, typename A>
108template<tagging_descriptor D1, typename A1>
110 : alloc{rhs.get_allocator()} {}
111
112template<tagging_descriptor D, typename A>
113auto tagging_allocator<D, A>::allocate(std::size_t n) noexcept -> pointer {
115 this->alloc.allocate(this->alloc_size(n)));
116}
117
118template<tagging_descriptor D, typename A>
119template<typename I>
120auto tagging_allocator<D, A>::allocate(std::size_t n, I i)
121 noexcept -> pointer
122 requires(detail::has_typed_alloc<allocator, I>)
123{
125 this->alloc.allocate(this->alloc_size(n), i));
126}
127
128template<tagging_descriptor D, typename A>
130 noexcept -> pointer requires(detail::has_realloc<A>)
131{
132 return block_type::from_storage_ptr(
133 this->alloc.reallocate(this->raw_from_ptr(p), this->alloc_size(n))
134 ).get();
135}
136
137template<tagging_descriptor D, typename A>
138void tagging_allocator<D, A>::deallocate(pointer p, std::size_t n) noexcept {
139 this->alloc.deallocate(this->raw_from_ptr(p), this->alloc_size(n));
140}
141
142}
143
144#endif
Generic implementation of a malloc(3)-style allocator with headers.
Definition: tagging.h:44
typename D::block_type block_type
Definition: tagging.h:46
static auto alloc_size(std::size_t n)
Definition: tagging.h:83
tagging_allocator(const allocator &a)
Definition: tagging.h:65
static pointer to_ptr(char *p)
Definition: tagging.h:88
void deallocate(pointer p, std::size_t n) noexcept
Definition: tagging.h:138
typename D::value_type value_type
Definition: tagging.h:47
tagging_allocator(void)=default
pointer allocate(std::size_t n) noexcept
Allocates n objects (n.b.: only one header is added).
Definition: tagging.h:113
tagging_allocator(tagging_allocator &&) noexcept=default
tagging_allocator & operator=(const tagging_allocator &rhs)
Definition: tagging.h:100
pointer reallocate(pointer p, std::size_t n) noexcept
Definition: tagging.h:129
tagging_allocator(const tagging_allocator &rhs)
Definition: tagging.h:61
typename std::allocator_traits< A >::template rebind_alloc< char > allocator
Definition: tagging.h:50
static char * raw_from_ptr(pointer p)
Definition: tagging.h:95
allocator alloc
Definition: tagging.h:84
const allocator & get_allocator(void) const
Definition: tagging.h:79
Definition: fundamental.h:41
Associates a block type with an allocator.
Definition: tagging.h:16
#define D(x)
Definition: math_test.cpp:256
Definition: debug.h:45
Definition: debug.h:13
Base class for allocators, implements a few basic operations.
Definition: base.h:49
Definition: tagging.h:52