Zserio C++17 runtime library  0.5.0
Built for Zserio 2.17.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 
8 #include "zserio/RebindAlloc.h"
9 
10 namespace zserio
11 {
12 
13 namespace detail
14 {
15 
19 template <class ALLOC_T>
20 struct UniquePtrDeleter : public AllocatorHolder<ALLOC_T>
21 {
22  using allocator_type = ALLOC_T;
23  using T = typename allocator_type::value_type;
24 
27  ~UniquePtrDeleter() = default;
28 
29  UniquePtrDeleter(UniquePtrDeleter&& other) = default;
30  UniquePtrDeleter& operator=(UniquePtrDeleter&& other) = default;
39  UniquePtrDeleter(const UniquePtrDeleter& other) = delete;
40  UniquePtrDeleter& operator=(const UniquePtrDeleter& other) = delete;
48  UniquePtrDeleter() :
49  UniquePtrDeleter(ALLOC_T())
50  {}
51 
55  UniquePtrDeleter(const ALLOC_T& allocator) :
56  AllocatorHolder<ALLOC_T>(allocator)
57  {}
58 
59  void operator()(T* ptr)
60  {
61  allocator_type alloc = this->get_allocator();
62  using AllocTraits = std::allocator_traits<allocator_type>;
63  AllocTraits::destroy(alloc, std::addressof(*ptr));
64  AllocTraits::deallocate(alloc, ptr, 1);
65  }
66 };
67 
68 } // namespace detail
69 
75 template <typename T, typename ALLOC = std::allocator<T>>
76 using UniquePtr = std::unique_ptr<T, detail::UniquePtrDeleter<ALLOC>>;
77 
87 template <typename T, typename ALLOC, class... Args>
88 UniquePtr<T, RebindAlloc<ALLOC, T>> allocate_unique(const ALLOC& allocator, Args&&... args)
89 {
90  using Allocator = RebindAlloc<ALLOC, T>;
91  using AllocTraits = std::allocator_traits<Allocator>;
92 
93  Allocator typedAllocator = allocator;
94  typename AllocTraits::pointer ptr = AllocTraits::allocate(typedAllocator, 1);
95  try
96  {
97  AllocTraits::construct(typedAllocator, std::addressof(*ptr), std::forward<Args>(args)...);
98  return UniquePtr<T, Allocator>(std::addressof(*ptr), typedAllocator);
99  }
100  catch (...)
101  {
102  AllocTraits::deallocate(typedAllocator, ptr, 1);
103  throw;
104  }
105 }
106 
107 } // namespace zserio
108 
109 #endif // ZSERIO_UNIQUE_PTR_H_INC
allocator_type get_allocator() const
AllocatorHolder & operator=(const AllocatorHolder &other)=default
std::unique_ptr< T, detail::UniquePtrDeleter< ALLOC > > UniquePtr
Definition: UniquePtr.h:76
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
Definition: RebindAlloc.h:10
UniquePtr< T, RebindAlloc< ALLOC, T > > allocate_unique(const ALLOC &allocator, Args &&... args)
Definition: UniquePtr.h:88