1 /****
2 DIAMOND protein aligner
3 Copyright (C) 2020 Max Planck Society for the Advancement of Science e.V.
4
5 Code developed by Benjamin Buchfink <benjamin.buchfink@tue.mpg.de>
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 ****/
20
21 #pragma once
22 #include <stdlib.h>
23 #include <cstddef>
24 #include <exception>
25
26 namespace Util { namespace Memory {
27
aligned_malloc(size_t n,size_t align)28 static inline void* aligned_malloc(size_t n, size_t align) {
29 #ifdef WIN32
30 void* p = _aligned_malloc(n, align);
31 if (p == nullptr)
32 throw std::bad_alloc();
33 return p;
34 #else
35 void* p;
36 if (posix_memalign(&p, align, n) != 0)
37 throw std::bad_alloc();
38 return p;
39 #endif
40 }
41
aligned_free(void * p)42 static inline void aligned_free(void* p) {
43 #ifdef WIN32
44 _aligned_free(p);
45 #else
46 free(p);
47 #endif
48 }
49
50 template <typename T, std::size_t N = 16>
51 class AlignmentAllocator {
52 public:
53 typedef T value_type;
54 typedef std::size_t size_type;
55 typedef std::ptrdiff_t difference_type;
56
57 typedef T* pointer;
58 typedef const T* const_pointer;
59
60 typedef T& reference;
61 typedef const T& const_reference;
62
63 public:
AlignmentAllocator()64 inline AlignmentAllocator() throw () { }
65
66 template <typename T2>
AlignmentAllocator(const AlignmentAllocator<T2,N> &)67 inline AlignmentAllocator(const AlignmentAllocator<T2, N>&) throw () { }
68
~AlignmentAllocator()69 ~AlignmentAllocator() noexcept { }
70
adress(reference r)71 inline pointer adress(reference r) {
72 return &r;
73 }
74
adress(const_reference r)75 inline const_pointer adress(const_reference r) const {
76 return &r;
77 }
78
allocate(size_type n)79 inline pointer allocate(size_type n) {
80 return (pointer)aligned_malloc(n * sizeof(value_type), N);
81 }
82
deallocate(pointer p,size_type)83 inline void deallocate(pointer p, size_type) {
84 aligned_free(p);
85 }
86
construct(pointer p,const value_type & wert)87 inline void construct(pointer p, const value_type& wert) {
88 new (p) value_type(wert);
89 }
90
destroy(pointer p)91 inline void destroy(pointer p) {
92 p->~value_type();
93 }
94
max_size()95 inline size_type max_size() const throw () {
96 return size_type(-1) / sizeof(value_type);
97 }
98
99 template <typename T2>
100 struct rebind {
101 typedef AlignmentAllocator<T2, N> other;
102 };
103
104 bool operator!=(const AlignmentAllocator<T, N>& other) const {
105 return !(*this == other);
106 }
107
108 // Returns true if and only if storage allocated from *this
109 // can be deallocated from other, and vice versa.
110 // Always returns true for stateless allocators.
111 bool operator==(const AlignmentAllocator<T, N>& other) const {
112 return true;
113 }
114 };
115
116 }}