bit::memory
allocator_reference.hpp
1 /*****************************************************************************
2  * \file
3  * \brief This header contains the implementation of a type-erased allocator
4  *****************************************************************************/
5 
6 /*
7  The MIT License (MIT)
8 
9  Copyright (c) 2018 Matthew Rodusek
10 
11  Permission is hereby granted, free of charge, to any person obtaining a copy
12  of this software and associated documentation files (the "Software"), to deal
13  in the Software without restriction, including without limitation the rights
14  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  copies of the Software, and to permit persons to whom the Software is
16  furnished to do so, subject to the following conditions:
17 
18  The above copyright notice and this permission notice shall be included in
19  all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  SOFTWARE.
28 */
29 #ifndef BIT_MEMORY_ALLOCATORS_ALLOCATOR_REFERENCE_HPP
30 #define BIT_MEMORY_ALLOCATORS_ALLOCATOR_REFERENCE_HPP
31 
32 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
33 # pragma once
34 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
35 
36 #include "../utilities/owner.hpp" // owner
37 #include "../utilities/allocator_info.hpp" // allocator_info
38 #include "../utilities/macros.hpp" // BIT_MEMORY_UNUSED
39 
40 #include "../concepts/Allocator.hpp" // is_allocator
41 #include "../concepts/Stateless.hpp" // is_stateless
42 
43 #include "../traits/allocator_traits.hpp" // allocator_traits
44 
45 #include <cstddef> // std::size_t, std::ptrdiff_t
46 #include <type_traits> // std::integral_constant, std::is_same, etc
47 #include <memory> // std::addressof
48 
49 namespace bit {
50  namespace memory {
51  namespace detail {
52  struct allocator_vtable;
53  } // namespace detail
54 
71  {
72  //----------------------------------------------------------------------
73  // Public Member Types
74  //----------------------------------------------------------------------
75  public:
76 
77  using default_alignment = std::integral_constant<std::size_t,1>;
78 
79  //----------------------------------------------------------------------
80  // Constructor / Assignment
81  //----------------------------------------------------------------------
82  public:
83 
88  template<typename Allocator,
89  typename = std::enable_if_t<is_allocator<std::decay_t<Allocator>>::value &&
90  !std::is_same<allocator_reference,std::decay_t<Allocator>>::value>>
91  allocator_reference( Allocator& allocator ) noexcept;
92 
96  allocator_reference( const allocator_reference& other ) noexcept = default;
97 
101  allocator_reference( allocator_reference&& other ) noexcept = default;
102 
103  //----------------------------------------------------------------------
104 
109  allocator_reference& operator = ( const allocator_reference& other ) noexcept = default;
110 
115  allocator_reference& operator = ( allocator_reference&& other ) noexcept = default;
116 
117  //----------------------------------------------------------------------
118  // Allocation / Deallocation
119  //----------------------------------------------------------------------
120  public:
121 
127  owner<void*> try_allocate( std::size_t size, std::size_t align ) noexcept;
128 
134  owner<void*> allocate( std::size_t size, std::size_t align );
135 
141  void deallocate( owner<void*> p, std::size_t n );
142 
143  //----------------------------------------------------------------------
144  // Observers
145  //----------------------------------------------------------------------
146  public:
147 
151  allocator_info info() const noexcept;
152 
153  //----------------------------------------------------------------------
154  // Private Member Types
155  //----------------------------------------------------------------------
156  private:
157 
158  using vtable_type = detail::allocator_vtable;
159 
160  template<typename Allocator>
161  struct stateless_type;
162 
163  //----------------------------------------------------------------------
164  // Private Constructor
165  //----------------------------------------------------------------------
166  private:
167 
172  template<typename Allocator>
173  explicit allocator_reference( stateless_type<Allocator> ) noexcept;
174 
175  //----------------------------------------------------------------------
176  // Private Members
177  //----------------------------------------------------------------------
178  private:
179 
180  void* m_ptr;
181  const vtable_type* m_vtable;
182 
183  friend bool operator==( const allocator_reference&, const allocator_reference& ) noexcept;
184 
185  template<typename>
186  friend allocator_reference make_stateless_allocator_reference() noexcept;
187  };
188 
189  //-------------------------------------------------------------------------
190  // Equality Comparison
191  //-------------------------------------------------------------------------
192 
193  bool operator==( const allocator_reference& lhs, const allocator_reference& rhs ) noexcept;
194  bool operator!=( const allocator_reference& lhs, const allocator_reference& rhs ) noexcept;
195 
196  //-------------------------------------------------------------------------
197  // Utility
198  //-------------------------------------------------------------------------
199 
206  template<typename StatelessAllocator>
207  allocator_reference make_stateless_allocator_reference() noexcept;
208 
209  } // namespace memory
210 } // namespace bit
211 
212 #include "detail/allocator_reference.inl"
213 
214 #endif /* BIT_MEMORY_ALLOCATORS_ALLOCATOR_REFERENCE_HPP */
This type is used to hold the generic information for a given allocator.
A non-owning allocator type that type-erases an underlying allocator.