SeqAn3  3.2.0
The Modern C++ library for sequence analysis.
aligned_allocator.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <limits>
16 #include <memory>
17 #include <type_traits>
18 
19 #include <seqan3/core/platform.hpp>
20 
21 // __cpp_aligned_new is a C++17 feature that we use in this allocator and we require it.
22 #if __cpp_aligned_new < 201606
23 # pragma GCC warning "Non-C++17 compliant compiler! Please open an issue with your compiler and platform!"
24 #endif // __cpp_aligned_new < 201606
25 
26 namespace seqan3
27 {
28 
75 template <typename value_t, size_t alignment_v = __STDCPP_DEFAULT_NEW_ALIGNMENT__>
77 {
78 public:
80  static constexpr size_t alignment = alignment_v;
81 
83  using value_type = value_t;
85  using pointer = value_type *;
90 
93 
97  aligned_allocator() = default;
98  aligned_allocator(aligned_allocator const &) = default;
102  ~aligned_allocator() = default;
103 
105  template <class other_value_type, size_t other_alignment>
107  {}
109 
141  [[nodiscard]] pointer allocate(size_type const n) const
142  {
143  constexpr size_type max_size = std::numeric_limits<size_type>::max() / sizeof(value_type);
144  if (n > max_size)
145  throw std::bad_alloc{};
146 
147  size_t bytes_to_allocate = n * sizeof(value_type);
148  if constexpr (alignment <= __STDCPP_DEFAULT_NEW_ALIGNMENT__)
149  return static_cast<pointer>(::operator new(bytes_to_allocate));
150  else // Use alignment aware allocator function.
151  return static_cast<pointer>(::operator new(bytes_to_allocate, static_cast<std::align_val_t>(alignment)));
152  }
153 
180  void deallocate(pointer const p, size_type const n) const noexcept
181  {
182  size_t bytes_to_deallocate = n * sizeof(value_type);
183 
184  // Clang doesn't have __cpp_sized_deallocation defined by default even though this is a C++14! feature
185  // > In Clang 3.7 and later, sized deallocation is only enabled if the user passes the `-fsized-deallocation`
186  // > flag.
187  // see also https://clang.llvm.org/cxx_status.html#n3778
188 #if __cpp_sized_deallocation >= 201309
189  // gcc
190  if constexpr (alignment <= __STDCPP_DEFAULT_NEW_ALIGNMENT__)
191  ::operator delete(p, bytes_to_deallocate);
192  else // Use alignment aware deallocator function.
193  ::operator delete(p, bytes_to_deallocate, static_cast<std::align_val_t>(alignment));
194 #else /*__cpp_sized_deallocation >= 201309*/
195  // e.g. clang++
196  if constexpr (alignment <= __STDCPP_DEFAULT_NEW_ALIGNMENT__)
197  ::operator delete(p);
198  else // Use alignment aware deallocator function.
199  ::operator delete(p, static_cast<std::align_val_t>(alignment));
200 #endif // __cpp_sized_deallocation >= 201309
201  }
202 
213  template <typename new_value_type>
214  struct rebind
215  {
217  static constexpr size_t other_alignment = std::max(alignof(new_value_type), alignment);
220  };
221 
226  template <class value_type2, size_t alignment2>
228  {
229  return alignment == alignment2;
230  }
231 
233  template <class value_type2, size_t alignment2>
235  {
236  return alignment != alignment2;
237  }
239 };
240 
241 } // namespace seqan3
Allocates uninitialized storage whose memory-alignment is specified by alignment.
Definition: aligned_allocator.hpp:77
value_t value_type
The value type of the allocation.
Definition: aligned_allocator.hpp:83
void deallocate(pointer const p, size_type const n) const noexcept
Deallocates the storage referenced by the pointer p, which must be a pointer obtained by an earlier c...
Definition: aligned_allocator.hpp:180
constexpr bool operator==(aligned_allocator< value_type2, alignment2 > const &) noexcept
Returns true if the memory-alignment matches.
Definition: aligned_allocator.hpp:227
pointer allocate(size_type const n) const
Allocates sufficiently large memory to hold n many elements of value_type.
Definition: aligned_allocator.hpp:141
value_type * pointer
The pointer type of the allocation.
Definition: aligned_allocator.hpp:85
constexpr aligned_allocator(aligned_allocator< other_value_type, other_alignment > const &) noexcept
Copy constructor with different value type and alignment.
Definition: aligned_allocator.hpp:106
~aligned_allocator()=default
Defaulted.
constexpr bool operator!=(aligned_allocator< value_type2, alignment2 > const &) noexcept
Returns false if the memory-alignment mismatches.
Definition: aligned_allocator.hpp:234
aligned_allocator & operator=(aligned_allocator &&)=default
Defaulted.
aligned_allocator & operator=(aligned_allocator const &)=default
Defaulted.
aligned_allocator(aligned_allocator const &)=default
Defaulted.
static constexpr size_t alignment
The memory-alignment of the allocation.
Definition: aligned_allocator.hpp:80
aligned_allocator(aligned_allocator &&)=default
Defaulted.
aligned_allocator()=default
Defaulted.
typename std::pointer_traits< pointer >::difference_type difference_type
The difference type of the allocation.
Definition: aligned_allocator.hpp:87
T max(T... args)
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Provides platform and dependency checks.
The aligned_allocator member template class aligned_allocator::rebind provides a way to obtain an all...
Definition: aligned_allocator.hpp:215
static constexpr size_t other_alignment
The alignment for the rebound allocator.
Definition: aligned_allocator.hpp:217