Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.0
UniquePtr.h
Go to the documentation of this file.
1 #ifndef ZSERIO_UNIQUE_PTR_H_INC
2 #define ZSERIO_UNIQUE_PTR_H_INC
3 
4 #include <memory>
5 #include <type_traits>
6 #include "zserio/RebindAlloc.h"
8 
9 namespace zserio
10 {
11 
12 namespace detail
13 {
14 
18 template <class ALLOC_T>
19 struct UniquePtrDeleter : public AllocatorHolder<ALLOC_T>
20 {
21  using allocator_type = ALLOC_T;
22  using T = typename allocator_type::value_type;
23 
26  ~UniquePtrDeleter() = default;
27 
28  UniquePtrDeleter(UniquePtrDeleter&& other) = default;
29  UniquePtrDeleter& operator=(UniquePtrDeleter&& other) = default;
38  UniquePtrDeleter(const UniquePtrDeleter& other) = delete;
39  UniquePtrDeleter& operator=(const UniquePtrDeleter& other) = delete;
47  template <typename ALLOC_U = ALLOC_T>
48  UniquePtrDeleter() :
49  UniquePtrDeleter(ALLOC_U())
50  {
51  }
52 
56  template <typename ALLOC_U = ALLOC_T>
57  UniquePtrDeleter(const ALLOC_U& allocator) :
58  AllocatorHolder<ALLOC_T>(allocator)
59  {
60  static_assert(std::is_same<allocator_type, RebindAlloc<ALLOC_U, T>>::value,
61  "UniquePtrDeleter requires same allocator in constructor!");
62  }
63 
67  template <typename ALLOC_U>
68  UniquePtrDeleter(const UniquePtrDeleter<ALLOC_U>& deleter) :
69  UniquePtrDeleter(deleter.get_allocator())
70  {}
71 
72  void operator()(T* ptr)
73  {
74  allocator_type alloc = this->get_allocator();
75  using AllocTraits = std::allocator_traits<allocator_type>;
76  AllocTraits::destroy(alloc, std::addressof(*ptr));
77  AllocTraits::deallocate(alloc, ptr, 1);
78  }
79 };
80 
81 } // namespace detail
82 
88 template <typename T, typename ALLOC = std::allocator<T>>
89 using unique_ptr = std::unique_ptr<T, detail::UniquePtrDeleter<ALLOC>>;
90 
100 template <typename T, typename ALLOC, class ...Args>
102 allocate_unique(const ALLOC& allocator, Args&& ...args)
103 {
104  using Allocator = RebindAlloc<ALLOC, T>;
105  using AllocTraits = std::allocator_traits<Allocator>;
106 
107  Allocator typedAllocator = allocator;
108  typename AllocTraits::pointer ptr = AllocTraits::allocate(typedAllocator, 1);
109  try
110  {
111  AllocTraits::construct(typedAllocator, std::addressof(*ptr), std::forward<Args>(args)...);
112  return zserio::unique_ptr<T, Allocator>(std::addressof(*ptr), typedAllocator);
113  }
114  catch (...)
115  {
116  AllocTraits::deallocate(typedAllocator, ptr, 1);
117  throw;
118  }
119 }
120 
121 } // namespace zserio
122 
123 #endif // ZSERIO_UNIQUE_PTR_H_INC
std::unique_ptr< T, detail::UniquePtrDeleter< ALLOC >> unique_ptr
Definition: UniquePtr.h:89
AllocatorHolder & operator=(const AllocatorHolder &other)=default
allocator_type get_allocator() const
zserio::unique_ptr< T, RebindAlloc< ALLOC, T > > allocate_unique(const ALLOC &allocator, Args &&...args)
Definition: UniquePtr.h:102
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
Definition: RebindAlloc.h:10