SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
aligned_allocator.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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 namespace seqan3
22 {
23 
58 template <typename value_t, size_t alignment_v = __STDCPP_DEFAULT_NEW_ALIGNMENT__>
60 {
61 public:
63  static constexpr size_t alignment = alignment_v;
64 
66  using value_type = value_t;
68  using pointer = value_type*;
73 
76 
80  aligned_allocator() = default;
81  aligned_allocator(aligned_allocator const &) = default;
82  aligned_allocator(aligned_allocator &&) = default;
83  aligned_allocator& operator=(aligned_allocator const &) = default;
85  ~aligned_allocator() = default;
86 
88  template <class other_value_type>
90  {}
92 
98  [[nodiscard]]
100  {
101  constexpr size_type max_size = std::numeric_limits<size_type>::max() / sizeof(value_type);
102  if (n > max_size)
103  throw std::bad_alloc();
104 
105  // NOTE: On macOS glibc does not implement aligned_alloc, so we need to fallback to posix_memalign instead.
106 #if defined(__APPLE__) && (!defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) && !defined(_ISOC11_SOURCE))
107  void * p{};
108  if (int res = posix_memalign(&p, alignment, n * sizeof(value_type)); res == 0 && p != nullptr)
109  return static_cast<pointer>(p);
110 #else
111  // NOTE:
112  // Allocate size bytes of uninitialized storage whose alignment is
113  // specified by alignment. The size parameter must be an integral
114  // multiple of alignment.
115  //
116  // Passing a size which is not an integral multiple of alignment or an
117  // alignment which is not valid or not supported by the implementation
118  // causes the function to fail and return a null pointer (C11, as
119  // published, specified undefined behavior in this case, this was
120  // corrected by DR 460).
121  // http://en.cppreference.com/w/cpp/memory/c/aligned_alloc
122  if (auto p = static_cast<pointer>(std::aligned_alloc(alignment, n * sizeof(value_type))))
123  return p;
124 #endif
125 
126  throw std::bad_alloc();
127  }
128 
139  void deallocate(pointer p, size_type) noexcept
140  {
141  std::free(p);
142  }
143 
148  template<typename new_value_type>
149  struct rebind
150  {
153  };
154 
158  template <class value_type2, size_t alignment2>
161  {
162  return alignment == alignment2;
163  }
164 
166  template <class value_type2, size_t alignment2>
168  {
169  return alignment != alignment2;
170  }
172 };
173 
174 } // namespace seqan3
aligned_allocator & operator=(aligned_allocator const &)=default
Defaulted.
Provides platform and dependency checks.
constexpr bool operator==(aligned_allocator< value_type2, alignment2 > const &) noexcept
Returns true if the memory-alignment matches.
Definition: aligned_allocator.hpp:160
The main SeqAn3 namespace.
T free(T... args)
void deallocate(pointer p, size_type) noexcept
Deallocates the storage referenced by the pointer p, which must be a pointer obtained by an earlier c...
Definition: aligned_allocator.hpp:139
static constexpr size_t alignment
The memory-alignment of the allocation.
Definition: aligned_allocator.hpp:63
constexpr bool operator!=(aligned_allocator< value_type2, alignment2 > const &) noexcept
Returns false if the memory-alignment mismatches.
Definition: aligned_allocator.hpp:167
typename std::pointer_traits< pointer >::difference_type difference_type
The difference type of the allocation.
Definition: aligned_allocator.hpp:70
The aligned_allocator member template class aligned_allocator::rebind provides a way to obtain an all...
Definition: aligned_allocator.hpp:149
T max(T... args)
pointer allocate(size_type n)
Allocates n * sizeof(T) bytes of uninitialized storage by calling std::aligned_alloc, but it is unspecified when and how this function is called.
Definition: aligned_allocator.hpp:99
value_t value_type
The value type of the allocation.
Definition: aligned_allocator.hpp:66
Allocates uninitialized storage whose memory-alignment is specified by alignment. ...
Definition: aligned_allocator.hpp:59
constexpr aligned_allocator(aligned_allocator< other_value_type, alignment > const &) noexcept
Copy constructor with different value type.
Definition: aligned_allocator.hpp:89
~aligned_allocator()=default
Defaulted.
T aligned_alloc(T... args)
value_type * pointer
The pointer type of the allocation.
Definition: aligned_allocator.hpp:68
aligned_allocator()=default
Defaulted.