bit::memory
block_allocator_reference.hpp
1 /*****************************************************************************
2  * \file
3  * \brief This header contains a type-erased view of a BlockAllocator concept
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_BLOCK_ALLOCATORS_BLOCK_ALLOCATOR_REFERENCE_HPP
30 #define BIT_MEMORY_BLOCK_ALLOCATORS_BLOCK_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/memory_block.hpp" // memory_block
39 #include "../utilities/macros.hpp" // BIT_MEMORY_UNUSED
40 
41 #include "../concepts/BlockAllocator.hpp" // is_block_allocator
42 #include "../concepts/Stateless.hpp" // is_stateless
43 
44 #include "../traits/block_allocator_traits.hpp" // block_allocator_traits
45 
46 #include <cstddef> // std::size_t, std::ptrdiff_t
47 #include <type_traits> // std::integral_constant, std::is_same, etc
48 #include <memory> // std::addressof
49 
50 namespace bit {
51  namespace memory {
52  namespace detail {
53  struct block_allocator_reference_vtable;
54  } // namespace detail
55 
66  {
67  //----------------------------------------------------------------------
68  // Constructor / Assignment
69  //----------------------------------------------------------------------
70  public:
71 
76  template<typename BlockAllocator,
77  typename = std::enable_if_t<is_block_allocator<BlockAllocator>::value &&
78  !std::is_same<block_allocator_reference,BlockAllocator>::value>>
79  block_allocator_reference( BlockAllocator& allocator ) noexcept;
80 
84  block_allocator_reference( block_allocator_reference&& other ) noexcept = default;
85 
89  block_allocator_reference( const block_allocator_reference& other ) noexcept = default;
90 
91  //----------------------------------------------------------------------
92 
97  block_allocator_reference& operator = ( block_allocator_reference&& other ) noexcept = default;
98 
103  block_allocator_reference& operator = ( const block_allocator_reference& other ) noexcept = default;
104 
105  //----------------------------------------------------------------------
106  // Block Allocations
107  //----------------------------------------------------------------------
108  public:
109 
113  owner<memory_block> allocate_block();
114 
118  void deallocate_block( owner<memory_block> block );
119 
120  //----------------------------------------------------------------------
121  // Observers
122  //----------------------------------------------------------------------
123  public:
124 
128  allocator_info info() const noexcept;
129 
133  std::size_t next_block_size() const noexcept;
134 
135  //----------------------------------------------------------------------
136  // Private Member Types
137  //----------------------------------------------------------------------
138  private:
139 
140  using vtable_type = detail::block_allocator_reference_vtable;
141 
142  template<typename Allocator>
143  struct stateless_type;
144 
145  //-----------------------------------------------------------------------
146  // Private Constructor
147  //-----------------------------------------------------------------------
148  private:
149 
155  template<typename BlockAllocator>
156  explicit block_allocator_reference( stateless_type<BlockAllocator> ) noexcept;
157 
158  //----------------------------------------------------------------------
159  // Private Members
160  //----------------------------------------------------------------------
161  private:
162 
163  void* m_ptr;
164  const vtable_type* m_vtable;
165 
166  template<typename>
167  friend block_allocator_reference make_stateless_block_allocator_reference()
168  noexcept;
169  };
170 
171  //-------------------------------------------------------------------------
172  // Utility
173  //-------------------------------------------------------------------------
174 
182  template<typename StatelessBlockAllocator>
183  block_allocator_reference make_stateless_block_allocator_reference() noexcept;
184 
185  } // namespace memory
186 } // namespace bit
187 
188 #include "detail/block_allocator_reference.inl"
189 
190 #endif /* BIT_MEMORY_BLOCK_ALLOCATORS_BLOCK_ALLOCATOR_REFERENCE_HPP */
A type erased view of allocators that satisfy the BlockAllocator concept.
This type is used to hold the generic information for a given allocator.