esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
region.hpp
Go to the documentation of this file.
1#ifndef NDNPH_CORE_REGION_HPP
2#define NDNPH_CORE_REGION_HPP
3
4#include "common.hpp"
5
6namespace ndnph {
7
9class Region {
10public:
11 enum {
12 ALIGNMENT = sizeof(void*),
13 };
14
15 template<typename T>
16 static constexpr T sizeofAligned(T size) {
17 return size % ALIGNMENT == 0 ? size : (size | (ALIGNMENT - 1)) + 1;
18 }
19
20 explicit Region(uint8_t* buf, size_t cap)
21 : m_begin(buf)
22 , m_end(buf + cap) {
23 reset();
24 }
25
27 uint8_t* alloc(size_t size) {
28 if (available() < size) {
29 return nullptr;
30 }
31 m_right -= size;
32 return m_right;
33 }
34
36 uint8_t* allocA(size_t size) {
37 uint8_t* room = alignUp(m_left);
38 if (m_right - room < static_cast<ssize_t>(size)) {
39 return nullptr;
40 }
41 m_left = room + size;
42 return room;
43 }
44
51 bool free(const uint8_t* first, const uint8_t* last) {
52 if (first == m_right && last <= m_end) {
53 m_right = const_cast<uint8_t*>(last);
54 return true;
55 }
56 if (last == m_left && first >= m_begin) {
57 m_left = const_cast<uint8_t*>(first);
58 return true;
59 }
60 return false;
61 }
62
63 bool free(const uint8_t* ptr, size_t size) {
64 return free(ptr, ptr + size);
65 }
66
68 template<typename T, typename... Arg>
69 T* make(Arg&&... arg) {
70 // Region allocator would not `delete` created objects, so it's safe to
71 // create trivially destructible objects only.
72 static_assert(std::is_trivially_destructible<T>::value, "");
73
74 uint8_t* ptr = this->allocA(sizeof(T));
75 if (ptr == nullptr) {
76 return nullptr;
77 }
78 return new (ptr) T(std::forward<Arg>(arg)...);
79 }
80
89 template<typename RefType, typename... Arg>
90 RefType create(Arg&&... arg) {
91 using ObjType = typename RefType::ObjType;
92 auto obj = make<ObjType>(*this, std::forward<Arg>(arg)...);
93 return obj == nullptr ? RefType() : RefType(obj);
94 }
95
100 void reset() {
101 m_left = m_begin;
102 m_right = m_end;
103 }
104
106 size_t available() const {
107 return m_right - m_left;
108 }
109
111 size_t availableA() const {
112 return std::max<ssize_t>(0, m_right - alignUp(m_left));
113 }
114
116 size_t size() const {
117 return m_end - m_begin - available();
118 }
119
120protected:
121 uint8_t* getArray() {
122 return m_begin;
123 }
124
125private:
126 static uint8_t* alignUp(uint8_t* ptr) {
127 return reinterpret_cast<uint8_t*>(
128 sizeofAligned(reinterpret_cast<uintptr_t>(reinterpret_cast<void*>(ptr))));
129 }
130
131private:
132 uint8_t* const m_begin;
133 uint8_t* const m_end;
134 uint8_t* m_left;
135 uint8_t* m_right;
136};
137
142template<int C>
143class StaticRegion : public Region {
144public:
146 : Region(m_array, sizeof(m_array)) {}
147
148 ~StaticRegion() = default;
149
150private:
151 uint8_t m_array[C];
152};
153
155class DynamicRegion : public Region {
156public:
157 DynamicRegion(size_t capacity)
158 : Region(new uint8_t[capacity], capacity) {}
159
161 delete[] getArray();
162 }
163};
164
166constexpr size_t
167sizeofSubRegions(size_t capacity, size_t count = 1) {
168 return count * (Region::sizeofAligned(capacity) + Region::sizeofAligned(sizeof(Region)));
169}
170
172inline Region*
173makeSubRegion(Region& parent, size_t capacity) {
174 uint8_t* room = parent.allocA(capacity);
175 if (room == nullptr) {
176 return nullptr;
177 }
178 return parent.make<Region>(room, capacity);
179}
180
183public:
184 WithRegion(WithRegion&&) = default;
185
186protected:
188 : region(region) {}
189
190 WithRegion(const WithRegion&) = delete;
191 WithRegion& operator=(const WithRegion&) = delete;
192
193protected:
195
196 friend Region& regionOf(const WithRegion* obj) {
197 return obj->region;
198 }
199};
200
202class InRegion : public WithRegion {
203protected:
205 : WithRegion(region) {}
206};
207
209template<typename Obj>
211public:
212 using ObjType = Obj;
213 static_assert(std::is_base_of<InRegion, ObjType>::value, "");
214
215 explicit RefRegion(ObjType* obj = nullptr)
216 : obj(obj) {}
217
218 explicit operator bool() const {
219 return obj != nullptr;
220 }
221
222protected:
223 ~RefRegion() = default;
224
225protected:
226 ObjType* obj = nullptr;
227
228 friend Region& regionOf(const RefRegion<Obj>& ref) {
229 return regionOf(ref.obj);
230 }
231};
232
233} // namespace ndnph
234
235#endif // NDNPH_CORE_REGION_HPP
Region with dynamically allocated memory.
Definition region.hpp:155
DynamicRegion(size_t capacity)
Definition region.hpp:157
~DynamicRegion()
Definition region.hpp:160
Base class of an object allocated in a Region.
Definition region.hpp:202
InRegion(Region &region)
Definition region.hpp:204
Base class of an object referencing an InRegion object.
Definition region.hpp:210
friend Region & regionOf(const RefRegion< Obj > &ref)
Definition region.hpp:228
Obj ObjType
Definition region.hpp:212
~RefRegion()=default
ObjType * obj
Definition region.hpp:226
RefRegion(ObjType *obj=nullptr)
Definition region.hpp:215
Region-based memory allocator thats owns memory of NDNph objects.
Definition region.hpp:9
size_t available() const
Compute remaining space for alloc().
Definition region.hpp:106
RefType create(Arg &&... arg)
Allocate and create an object, and return its reference.
Definition region.hpp:90
size_t availableA() const
Compute remaining space for allocA().
Definition region.hpp:111
static constexpr T sizeofAligned(T size)
Definition region.hpp:16
uint8_t * alloc(size_t size)
Allocate a buffer with no alignment requirement.
Definition region.hpp:27
T * make(Arg &&... arg)
Allocate and create an item, and return its pointer.
Definition region.hpp:69
bool free(const uint8_t *ptr, size_t size)
Definition region.hpp:63
size_t size() const
Compute utilized space.
Definition region.hpp:116
uint8_t * getArray()
Definition region.hpp:121
Region(uint8_t *buf, size_t cap)
Definition region.hpp:20
void reset()
Discard allocated items.
Definition region.hpp:100
@ ALIGNMENT
Definition region.hpp:12
uint8_t * allocA(size_t size)
Allocate a region aligned to multiple of sizeof(void*).
Definition region.hpp:36
bool free(const uint8_t *first, const uint8_t *last)
Deallocate (part of) last allocated buffer.
Definition region.hpp:51
Region with statically allocated memory.
Definition region.hpp:143
~StaticRegion()=default
StaticRegion()
Definition region.hpp:145
Base class of an object associated with a Region.
Definition region.hpp:182
friend Region & regionOf(const WithRegion *obj)
Definition region.hpp:196
WithRegion(WithRegion &&)=default
WithRegion & operator=(const WithRegion &)=delete
Region & region
Definition region.hpp:194
WithRegion(const WithRegion &)=delete
WithRegion(Region &region)
Definition region.hpp:187
Definition fs.hpp:33
Region * makeSubRegion(Region &parent, size_t capacity)
Create Region inside a parent Region.
Definition region.hpp:173
constexpr size_t sizeofSubRegions(size_t capacity, size_t count=1)
Compute total size of several sub Regions of given capacity.
Definition region.hpp:167