LAPACK++  2022.07.00
LAPACK C++ API
NoConstructAllocator.hh
1 // Copyright (c) 2017-2022, University of Tennessee. All rights reserved.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // This program is free software: you can redistribute it and/or modify it under
4 // the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
5 
6 #ifndef LAPACK_NO_CONSTRUCT_ALLOCATOR_HH
7 #define LAPACK_NO_CONSTRUCT_ALLOCATOR_HH
8 
9 namespace lapack {
10 
11 // No-construct allocator type which allocates / deallocates.
12 template <typename T>
13 struct NoConstructAllocator
14 {
15  using value_type = T;
16 
17  NoConstructAllocator () = default;
18  //template <class U> constexpr NoConstructAllocator (const NoConstructAllocator <U>&) noexcept {}
19 
20  // Construction given an allocated pointer is a null-op.
21  //
22  // @tparam Args Parameter pack which handles all possible calling
23  // signatures of construct outlined in the Allocator concept.
24  //
25  template <typename... Args>
26  void construct( T* ptr, Args&& ... args ) { }
27 
28  // Destruction of an object in allocated memory is a null-op
29  void destroy( T* ptr ) { }
30 
31  T* allocate(std::size_t n)
32  {
33  if (n > std::numeric_limits<std::size_t>::max() / sizeof(T))
34  throw std::bad_array_new_length();
35 
36  void* memPtr = nullptr;
37  #if defined( _WIN32 ) || defined( _WIN64 )
38  memPtr = _aligned_malloc( n*sizeof(T, 64) );
39  if (memPtr != nullptr) {
40  auto p = static_cast<T*>(memPtr);
41  return p;
42  }
43  #else
44  int err = posix_memalign( &memPtr, 64, n*sizeof(T) );
45  if (err == 0) {
46  auto p = static_cast<T*>(memPtr);
47  return p;
48  }
49  #endif
50 
51  throw std::bad_alloc();
52  }
53 
54  void deallocate(T* p, std::size_t n) noexcept
55  {
56  #if defined( _WIN32 ) || defined( _WIN64 )
57  _aligned_free( p );
58  #else
59  free( p );
60  #endif
61  }
62 };
63 
64 template <class T, class U>
65 bool operator==(const NoConstructAllocator <T>&, const NoConstructAllocator <U>&)
66 {
67  return true;
68 }
69 
70 template <class T, class U>
71 bool operator!=(const NoConstructAllocator <T>&, const NoConstructAllocator <U>&)
72 {
73  return false;
74 }
75 
76 template <typename T>
77 using vector = std::vector< T, NoConstructAllocator<T> >;
78 
79 } // namespace lapack
80 
81 #endif // LAPACK_NO_CONSTRUCT_ALLOCATOR_HH