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 
6 namespace ndnph {
7 
9 class Region {
10 public:
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 
120 protected:
121  uint8_t* getArray() {
122  return m_begin;
123  }
124 
125 private:
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 
131 private:
132  uint8_t* const m_begin;
133  uint8_t* const m_end;
134  uint8_t* m_left;
135  uint8_t* m_right;
136 };
137 
142 template<int C>
143 class StaticRegion : public Region {
144 public:
146  : Region(m_array, sizeof(m_array)) {}
147 
148  ~StaticRegion() = default;
149 
150 private:
151  uint8_t m_array[C];
152 };
153 
155 class DynamicRegion : public Region {
156 public:
157  DynamicRegion(size_t capacity)
158  : Region(new uint8_t[capacity], capacity) {}
159 
161  delete[] getArray();
162  }
163 };
164 
166 constexpr size_t
167 sizeofSubRegions(size_t capacity, size_t count = 1) {
168  return count * (Region::sizeofAligned(capacity) + Region::sizeofAligned(sizeof(Region)));
169 }
170 
172 inline Region*
173 makeSubRegion(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 
182 class WithRegion {
183 public:
184  WithRegion(WithRegion&&) = default;
185 
186 protected:
188  : region(region) {}
189 
190  WithRegion(const WithRegion&) = delete;
191  WithRegion& operator=(const WithRegion&) = delete;
192 
193 protected:
195 
196  friend Region& regionOf(const WithRegion* obj) {
197  return obj->region;
198  }
199 };
200 
202 class InRegion : public WithRegion {
203 protected:
204  explicit InRegion(Region& region)
205  : WithRegion(region) {}
206 };
207 
209 template<typename Obj>
210 class RefRegion {
211 public:
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 
222 protected:
223  ~RefRegion() = default;
224 
225 protected:
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
Obj ObjType
Definition: region.hpp:212
~RefRegion()=default
ObjType * obj
Definition: region.hpp:226
friend Region & regionOf(const RefRegion< Obj > &ref)
Definition: region.hpp:228
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
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
uint8_t * allocA(size_t size)
Allocate a region aligned to multiple of sizeof(void*).
Definition: region.hpp:36
size_t size() const
Compute utilized space.
Definition: region.hpp:116
uint8_t * alloc(size_t size)
Allocate a buffer with no alignment requirement.
Definition: region.hpp:27
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 * getArray()
Definition: region.hpp:121
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
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
friend Region & regionOf(const WithRegion *obj)
Definition: region.hpp:196
Definition: fs.hpp:33
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
Region * makeSubRegion(Region &parent, size_t capacity)
Create Region inside a parent Region.
Definition: region.hpp:173