bit::memory
static_block_allocator.hpp
1 /*****************************************************************************
2  * \file
3  * \brief This header contains the definition for an allocator that can only
4  * allocate a single static block
5  *****************************************************************************/
6 
7 /*
8  The MIT License (MIT)
9 
10  Copyright (c) 2018 Matthew Rodusek
11 
12  Permission is hereby granted, free of charge, to any person obtaining a copy
13  of this software and associated documentation files (the "Software"), to deal
14  in the Software without restriction, including without limitation the rights
15  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  copies of the Software, and to permit persons to whom the Software is
17  furnished to do so, subject to the following conditions:
18 
19  The above copyright notice and this permission notice shall be included in
20  all copies or substantial portions of the Software.
21 
22  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  SOFTWARE.
29 */
30 #ifndef BIT_MEMORY_BLOCK_ALLOCATORS_STATIC_BLOCK_ALLOCATOR_HPP
31 #define BIT_MEMORY_BLOCK_ALLOCATORS_STATIC_BLOCK_ALLOCATOR_HPP
32 
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
34 # pragma once
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
36 
37 #include "detail/named_block_allocator.hpp" // detail::named_block_allocator
38 
39 #include "../utilities/owner.hpp" // owner
40 #include "../utilities/memory_block.hpp" // memory_block
41 #include "../utilities/memory_block_cache.hpp" // memory_block_cache
42 #include "../utilities/pointer_utilities.hpp" // is_power_of_two
43 
44 #include <cstddef> // std::size_t, std::max_align_t
45 #include <cassert> // assert
46 
47 namespace bit {
48  namespace memory {
49 
69  template<std::size_t BlockSize,
70  std::size_t Blocks = 1,
71  std::size_t Align = alignof(std::max_align_t),
72  typename Tag = void>
74  {
75  static_assert( Blocks > 0,
76  "Must have at least one block" );
77  static_assert( is_power_of_two(Align),
78  "Alignment must be a power of two" );
79  static_assert( Blocks == 1 || BlockSize % Align == 0,
80  "Block size must must be an increment of the alignment" );
81 
82  //-----------------------------------------------------------------------
83  // Public Members
84  //-----------------------------------------------------------------------
85  public:
86 
87  using block_size = std::integral_constant<std::size_t,BlockSize>;
88  using block_alignment = std::integral_constant<std::size_t,Align>;
89 
90  //-----------------------------------------------------------------------
91  // Constructor
92  //-----------------------------------------------------------------------
93  public:
94 
96  static_block_allocator() noexcept = default;
97 
101  static_block_allocator( static_block_allocator&& other ) noexcept = default;
102 
106  static_block_allocator( const static_block_allocator& other ) noexcept = default;
107 
108  //-----------------------------------------------------------------------
109 
114  static_block_allocator& operator=( static_block_allocator&& other ) noexcept = default;
115 
120  static_block_allocator& operator=( const static_block_allocator& other ) noexcept = default;
121 
122  //-----------------------------------------------------------------------
123  // Block Allocations
124  //-----------------------------------------------------------------------
125  public:
126 
130  owner<memory_block> allocate_block() noexcept;
131 
135  void deallocate_block( owner<memory_block> block ) noexcept;
136 
137  //-----------------------------------------------------------------------
138  // Observers
139  //-----------------------------------------------------------------------
140  public:
141 
145  std::size_t next_block_size() const noexcept;
146 
153  allocator_info info() const noexcept;
154 
155  //-----------------------------------------------------------------------
156  // Private Members
157  //-----------------------------------------------------------------------
158  private:
159 
160  static constexpr auto s_storage_size = BlockSize * Blocks;
161  alignas(Align) static char s_storage[s_storage_size];
162 
166  static memory_block_cache& block_cache() noexcept;
167  };
168 
169  //-------------------------------------------------------------------------
170 
171  template<std::size_t BlockSize,
172  std::size_t Blocks = 1,
173  std::size_t Align = alignof(std::max_align_t),
174  typename Tag = void>
175  using named_static_block_allocator
176  = detail::named_block_allocator<static_block_allocator<BlockSize,Blocks,Align,Tag>>;
177 
178  } // namespace memory
179 } // namespace bit
180 
181 #include "detail/static_block_allocator.inl"
182 
183 #endif /* BIT_MEMORY_BLOCK_ALLOCATORS_STATIC_BLOCK_ALLOCATOR_HPP */
A cache containing an intrinsically linked list of memory_blocks.
This type is used to hold the generic information for a given allocator.
This is a block allocator that distributes blocks of memory stored statically.