KTL
reference.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../utility/aligned_malloc.h"
4 #include "../utility/alignment.h"
5 #include "../utility/empty_base.h"
6 #include "../utility/meta.h"
7 #include "reference_fwd.h"
8 
9 #include <memory>
10 #include <type_traits>
11 
12 namespace ktl
13 {
14  template<typename Alloc>
15  class reference
16  {
17  private:
18  static_assert(detail::has_no_value_type_v<Alloc>, "Building on top of typed allocators is not allowed. Use allocators without a type");
19 
20  public:
22 
26  explicit reference(Alloc& alloc) noexcept:
27  m_Alloc(&alloc) {}
28 
29  reference(const reference& other) noexcept :
30  m_Alloc(other.m_Alloc) {}
31 
32  reference(reference&& other) noexcept :
33  m_Alloc(other.m_Alloc) {}
34 
35  reference& operator=(const reference& rhs) noexcept
36  {
37  m_Alloc = rhs.m_Alloc;
38 
39  return *this;
40  }
41 
42  reference& operator=(reference&& rhs) noexcept
43  {
44  m_Alloc = rhs.m_Alloc;
45 
46  return *this;
47  }
48 
49  bool operator==(const reference& rhs) const
50  noexcept(detail::has_nothrow_equal_v<Alloc>)
51  {
52  return m_Alloc == rhs.m_Alloc && *m_Alloc == *rhs.m_Alloc;
53  }
54 
55  bool operator!=(const reference& rhs) const
56  noexcept(detail::has_nothrow_not_equal_v<Alloc>)
57  {
58  return m_Alloc != rhs.m_Alloc || *m_Alloc != *rhs.m_Alloc;
59  }
60 
61 #pragma region Allocation
62  void* allocate(size_t n)
63  noexcept(detail::has_nothrow_allocate_v<Alloc>)
64  {
65  return m_Alloc->allocate(n);
66  }
67 
68  void deallocate(void* p, size_t n)
69  noexcept(detail::has_nothrow_deallocate_v<Alloc>)
70  {
71  m_Alloc->deallocate(p, n);
72  }
73 #pragma endregion
74 
75 #pragma region Construction
76  template<typename T, typename... Args>
77  typename std::enable_if<detail::has_construct_v<Alloc, T*, Args...>, void>::type
78  construct(T* p, Args&&... args)
79  noexcept(detail::has_nothrow_construct_v<Alloc, T*, Args...>)
80  {
81  m_Alloc->construct(p, std::forward<Args>(args)...);
82  }
83 
84  template<typename T>
85  typename std::enable_if<detail::has_destroy_v<Alloc, T*>, void>::type
86  destroy(T* p)
87  noexcept(detail::has_nothrow_destroy_v<Alloc, T*>)
88  {
89  m_Alloc->destroy(p);
90  }
91 #pragma endregion
92 
93 #pragma region Utility
94  template<typename A = Alloc>
95  typename std::enable_if<detail::has_max_size_v<A>, size_type>::type
96  max_size() const
97  noexcept(detail::has_nothrow_max_size_v<A>)
98  {
99  return m_Alloc->max_size();
100  }
101 
102  template<typename A = Alloc>
103  typename std::enable_if<detail::has_owns_v<A>, bool>::type
104  owns(void* p) const
105  noexcept(detail::has_nothrow_owns_v<A>)
106  {
107  return m_Alloc->owns(p);
108  }
109 #pragma endregion
110 
111  Alloc& get_allocator() noexcept
112  {
113  return *m_Alloc;
114  }
115 
116  const Alloc& get_allocator() const noexcept
117  {
118  return *m_Alloc;
119  }
120 
121  private:
122  Alloc* m_Alloc;
123  };
124 }
Definition: reference.h:16
void deallocate(void *p, size_t n) noexcept(detail::has_nothrow_deallocate_v< Alloc >)
Definition: reference.h:68
detail::get_size_type_t< Alloc > size_type
Definition: reference.h:18
std::enable_if< detail::has_destroy_v< Alloc, T * >, void >::type destroy(T *p) noexcept(detail::has_nothrow_destroy_v< Alloc, T * >)
Definition: reference.h:86
const Alloc & get_allocator() const noexcept
Definition: reference.h:116
void * allocate(size_t n) noexcept(detail::has_nothrow_allocate_v< Alloc >)
Definition: reference.h:62
std::enable_if< detail::has_owns_v< A >, bool >::type owns(void *p) const noexcept(detail::has_nothrow_owns_v< A >)
Definition: reference.h:104
bool operator==(const reference &rhs) const noexcept(detail::has_nothrow_equal_v< Alloc >)
Definition: reference.h:49
reference & operator=(reference &&rhs) noexcept
Definition: reference.h:42
bool operator!=(const reference &rhs) const noexcept(detail::has_nothrow_not_equal_v< Alloc >)
Definition: reference.h:55
std::enable_if< detail::has_construct_v< Alloc, T *, Args... >, void >::type construct(T *p, Args &&... args) noexcept(detail::has_nothrow_construct_v< Alloc, T *, Args... >)
Definition: reference.h:78
reference(Alloc &alloc) noexcept
Constructor for forwarding any arguments to the underlying allocator.
Definition: reference.h:26
reference(const reference &other) noexcept
Definition: reference.h:29
reference(reference &&other) noexcept
Definition: reference.h:32
std::enable_if< detail::has_max_size_v< A >, size_type >::type max_size() const noexcept(detail::has_nothrow_max_size_v< A >)
Definition: reference.h:96
reference & operator=(const reference &rhs) noexcept
Definition: reference.h:35
Alloc & get_allocator() noexcept
Definition: reference.h:111
constexpr bool has_construct_v
Definition: meta.h:41
typename get_size_type< Alloc, void >::type get_size_type_t
Definition: meta.h:31
constexpr bool has_nothrow_max_size_v
Definition: meta.h:122
Definition: cascading.h:15