Zserio C++ runtime library  1.1.0
Built for Zserio 2.15.0
PolymorphicAllocator.h
Go to the documentation of this file.
1 #ifndef ZSERIO_PMR_POLYMORPHIC_ALLOCATOR_H_INC
2 #define ZSERIO_PMR_POLYMORPHIC_ALLOCATOR_H_INC
3 
4 #include <cstddef>
5 #include <limits>
6 #include <type_traits>
7 #include <utility>
8 
9 #include "zserio/Types.h"
11 
12 namespace zserio
13 {
14 namespace pmr
15 {
16 namespace detail
17 {
18 
22 template <class T = uint8_t>
23 class PolymorphicAllocatorBase
24 {
25 public:
26  using value_type = T;
27 
28  // Following typedefs are only present for compatibility with older std. libraries, that does not fully
29  // conform to C++11. [old-compiler-support]
30  using pointer = value_type*;
31  using const_pointer = const value_type*;
32  using size_type = std::size_t;
33  using difference_type = std::ptrdiff_t;
34  using reference = value_type&;
35  using const_reference = const value_type&;
36 
47  PolymorphicAllocatorBase(MemoryResource* resource = getDefaultResource()) noexcept :
48  m_resource(resource != nullptr ? resource : getDefaultResource()) // non-standard extension
49  {}
50 
55  ~PolymorphicAllocatorBase() = default;
56 
57  PolymorphicAllocatorBase(const PolymorphicAllocatorBase& other) noexcept = default;
58  PolymorphicAllocatorBase& operator=(const PolymorphicAllocatorBase& other) noexcept = default;
59 
60  PolymorphicAllocatorBase(PolymorphicAllocatorBase&& other) noexcept = default;
61  PolymorphicAllocatorBase& operator=(PolymorphicAllocatorBase&& other) noexcept = default;
71  template <class U>
72  PolymorphicAllocatorBase(const PolymorphicAllocatorBase<U>& other) noexcept :
73  m_resource(other.resource())
74  {}
75 
81  template <class U>
82  PolymorphicAllocatorBase& operator=(const PolymorphicAllocatorBase<U>& other) noexcept
83  {
84  m_resource = other.resource();
85  return *this;
86  }
87 
93  value_type* allocate(std::size_t size)
94  {
95  return static_cast<value_type*>(m_resource->allocate(size * sizeof(value_type), alignof(value_type)));
96  }
97 
105  void deallocate(value_type* memory, std::size_t size) noexcept
106  {
107  m_resource->deallocate(memory, size * sizeof(value_type), alignof(value_type));
108  }
109 
113  MemoryResource* resource() const noexcept
114  {
115  return m_resource;
116  }
117 
126  template <typename U, typename... Args>
127  void construct(U* ptr, Args&&... args) noexcept(
128  noexcept(new (static_cast<void*>(ptr)) U(std::forward<Args>(args)...)))
129  {
130  new (static_cast<void*>(ptr)) U(std::forward<Args>(args)...);
131  }
132 
140  template <typename U>
141  void destroy(U* ptr) noexcept(noexcept(ptr->~U()))
142  {
143  ptr->~U();
144  }
145 
153  size_type max_size() const noexcept
154  {
155  return std::numeric_limits<size_type>::max() / sizeof(value_type);
156  }
157 
158 private:
159  MemoryResource* m_resource;
160 };
161 
162 template <class T, class U>
163 bool operator==(const PolymorphicAllocatorBase<T>& lhs, const PolymorphicAllocatorBase<U>& rhs) noexcept
164 {
165  return *lhs.resource() == *rhs.resource();
166 }
167 
168 template <class T, class U>
169 bool operator!=(const PolymorphicAllocatorBase<T>& lhs, const PolymorphicAllocatorBase<U>& rhs) noexcept
170 {
171  return !(lhs == rhs);
172 }
173 
174 } // namespace detail
175 
180 template <class T = uint8_t>
181 class PolymorphicAllocator : public detail::PolymorphicAllocatorBase<T>
182 {
183 public:
184  using detail::PolymorphicAllocatorBase<T>::PolymorphicAllocatorBase;
185 
186  using propagate_on_container_copy_assignment = std::false_type;
187  using propagate_on_container_move_assignment = std::false_type;
188  using propagate_on_container_swap = std::false_type;
189 
194  {
195  return PolymorphicAllocator();
196  }
197 
203  template <typename U>
204  struct rebind
205  {
207  };
208 };
209 
213 template <class T = uint8_t>
214 class PropagatingPolymorphicAllocator : public detail::PolymorphicAllocatorBase<T>
215 {
216 public:
217  using detail::PolymorphicAllocatorBase<T>::PolymorphicAllocatorBase;
218 
221  using propagate_on_container_swap = std::true_type;
222 
227  {
228  return *this;
229  }
230 
236  template <typename U>
237  struct rebind
238  {
240  };
241 };
242 
243 } // namespace pmr
244 } // namespace zserio
245 
246 #endif // ZSERIO_PMR_POLYMORPHIC_ALLOCATOR_H_INC
std::false_type propagate_on_container_copy_assignment
PolymorphicAllocator select_on_container_copy_construction() const
std::false_type propagate_on_container_move_assignment
PropagatingPolymorphicAllocator select_on_container_copy_construction() const
bool operator==(const MemoryResource &lhs, const MemoryResource &rhs)
MemoryResource * getDefaultResource() noexcept
bool operator!=(const MemoryResource &lhs, const MemoryResource &rhs)