nngn
Loading...
Searching...
No Matches
tracking.h
Go to the documentation of this file.
1#ifndef NNGN_UTILS_ALLOC_TRACKING_H
2#define NNGN_UTILS_ALLOC_TRACKING_H
3
4#include <memory>
5
6#include "utils/utils.h"
7
8#include "base.h"
9
10namespace nngn {
11
12namespace detail {
13
20template<typename T>
22 requires(T t, typename T::pointer p, std::size_t n) {
23 t.reallocate_pre(p, n);
24 t.reallocate(p, n);
25 };
26
27}
28
34template<typename T>
36 requires(T t, typename T::pointer p, std::size_t n) {
37 // Type used in allocator interface.
38 typename T::value_type;
39 // `value_type` as a pointer.
40 typename T::pointer;
41 typename T::template rebind<empty>;
42 t.allocate(p, n);
43 t.deallocate(p, n);
44 }
45 && (!requires { T::reallocate; } || detail::tracker_with_realloc<T>);
46
73template<alloc_tracker T, typename A = std::allocator<typename T::value_type>>
75 public stateful_allocator<tracking_allocator<T, A>>
76{
77public:
78 using value_type = typename T::value_type;
79 using pointer = typename T::pointer;
80 using allocator =
81 typename std::allocator_traits<A>::template rebind_alloc<value_type>;
82private:
83 template<typename I>
84 static bool constexpr has_typed_alloc =
85 requires(T t, pointer p, std::size_t n, I i) {
86 t.allocate(p, n, i);
87 };
88public:
89 template<typename U>
90 struct rebind {
92 typename T::template rebind<U>::other,
93 allocator>;
94 };
95 // Construction, assignment
96 tracking_allocator(void) = default;
97 explicit tracking_allocator(T t) : m_tracker{std::move(t)} {}
100 template<alloc_tracker T1, typename A1>
104 tracking_allocator &operator=(tracking_allocator&&) noexcept = default;
105 ~tracking_allocator(void) = default;
106 // Accessors
107 const allocator &get_allocator(void) const { return this->alloc; }
108 T &tracker(void) { return this->m_tracker; }
109 const T &tracker(void) const { return this->m_tracker; }
110 // Allocator API
111 pointer allocate(std::size_t n) noexcept;
112 void deallocate(pointer p, std::size_t n) noexcept;
113 // Conditional allocator API
114 pointer reallocate(pointer p, std::size_t n) noexcept
115 requires detail::has_realloc<allocator>
116 /*XXX clang*/ {
117 this->m_tracker.reallocate_pre(p, n);
118 p = this->alloc.reallocate(p, n);
119 this->m_tracker.reallocate(p, n);
120 return p;
121 }
122 template<typename I>
123 pointer allocate(std::size_t n, I i) noexcept
124 requires has_typed_alloc<I>;
125private:
126 [[no_unique_address]] T m_tracker = {};
127 [[no_unique_address]] allocator alloc = {};
128};
129
130template<alloc_tracker T, typename A>
132 : m_tracker{std::move(t)}, alloc{rhs.alloc} {}
133
134template<alloc_tracker T, typename A>
136 : m_tracker{rhs.tracker()}, alloc{rhs.alloc} {}
137
138template<alloc_tracker T, typename A>
139template<alloc_tracker T1, typename A1>
142 : m_tracker{rhs.tracker()}, alloc{rhs.get_allocator()} {}
143
144template<alloc_tracker T, typename A>
147{
148 this->alloc = rhs.alloc;
149 return *this;
150}
151
152template<alloc_tracker T, typename A>
153auto tracking_allocator<T, A>::allocate(std::size_t n) noexcept -> pointer {
154 auto *const ret = this->alloc.allocate(n);
155 this->m_tracker.allocate(ret, n);
156 return ret;
157}
158
159template<alloc_tracker T, typename A>
160template<typename I>
161auto tracking_allocator<T, A>::allocate(std::size_t n, I ti)
162 noexcept -> pointer
163 requires has_typed_alloc<I>
164{
165 auto *const ret = this->alloc.allocate(n);
166 this->m_tracker.allocate(ret, n, ti);
167 return ret;
168}
169
170template<alloc_tracker T, typename A>
172 noexcept
173{
174 this->m_tracker.deallocate(p, n);
175 this->alloc.deallocate(p, n);
176}
177
178}
179
180#endif
Allocator which tracks the amount of memory allocated.
Definition: tracking.h:76
typename T::value_type value_type
Definition: tracking.h:78
static bool constexpr has_typed_alloc
Definition: tracking.h:84
pointer allocate(std::size_t n, I i) noexcept
tracking_allocator(T t)
Definition: tracking.h:97
tracking_allocator & operator=(const tracking_allocator &rhs)
Definition: tracking.h:145
allocator alloc
Definition: tracking.h:127
T m_tracker
Definition: tracking.h:126
const T & tracker(void) const
Definition: tracking.h:109
T & tracker(void)
Definition: tracking.h:108
pointer reallocate(pointer p, std::size_t n) noexcept
Definition: tracking.h:114
typename std::allocator_traits< A >::template rebind_alloc< value_type > allocator
Definition: tracking.h:81
tracking_allocator(void)=default
void deallocate(pointer p, std::size_t n) noexcept
Definition: tracking.h:171
const allocator & get_allocator(void) const
Definition: tracking.h:107
pointer allocate(std::size_t n) noexcept
Definition: tracking.h:153
tracking_allocator(tracking_allocator &&) noexcept=default
Describes how allocations of a particular type are tracked.
Definition: tracking.h:35
Checks whether the tracker object tracks memory relocation.
Definition: tracking.h:21
Definition: fundamental.h:41
Definition: debug.h:45
Definition: debug.h:13
move
Definition: camera.lua:43
Base class for allocators, implements a few basic operations.
Definition: base.h:49
Definition: tracking.h:90