OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | |
scottmg
2015/12/04 19:58:51
I'm surprised we don't have this in base. I guess
| |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #ifndef CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_ | |
16 #define CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_ | |
17 | |
18 #include <stddef.h> | |
19 | |
20 #include <limits> | |
21 #include <memory> | |
22 #include <new> | |
23 #include <utility> | |
24 #include <vector> | |
25 | |
26 #include "base/compiler_specific.h" | |
27 #include "build/build_config.h" | |
28 | |
29 #if defined(COMPILER_MSVC) && _MSC_VER < 1900 | |
30 #define NOEXCEPT _NOEXCEPT | |
31 #else | |
32 #define NOEXCEPT noexcept | |
33 #endif | |
34 | |
35 namespace crashpad { | |
36 namespace internal { | |
37 | |
38 //! \brief Allocates memory with the specified alignment constraint. | |
39 //! | |
40 //! This function wraps `posix_memalign()` or `_aligned_malloc()`. Memory | |
41 //! allocated by this function must be released by AlignFree(). | |
42 void* AlignedAllocate(size_t alignment, size_t size); | |
43 | |
44 //! \brief Frees memory allocated by AlignedAllocate(). | |
45 //! | |
46 //! This function wraps `free()` or `_aligned_free()`. | |
47 void AlignedFree(void* pointer); | |
48 | |
49 } // namespace internal | |
50 | |
51 //! \brief A standard allocator that aligns its allocations as requested, | |
52 //! suitable for use as an allocator in standard containers. | |
53 //! | |
54 //! This is similar to `std::allocator<T>`, with the addition of an alignment | |
55 //! guarantee. \a Alignment must be a power of 2. If \a Alignment is not | |
56 //! specified, the default alignment for type \a T is used. | |
57 template <class T, size_t Alignment = ALIGNOF(T)> | |
58 struct AlignedAllocator { | |
59 public: | |
60 using value_type = T; | |
61 using pointer = T*; | |
62 using const_pointer = const T*; | |
63 using reference = T&; | |
64 using const_reference = const T&; | |
65 using size_type = size_t; | |
66 using difference_type = ptrdiff_t; | |
67 | |
68 template <class U> | |
69 struct rebind { | |
70 using other = AlignedAllocator<U, Alignment>; | |
71 }; | |
72 | |
73 AlignedAllocator() NOEXCEPT {} | |
74 AlignedAllocator(const AlignedAllocator& other) NOEXCEPT {} | |
75 | |
76 template <typename U> | |
77 AlignedAllocator(const AlignedAllocator<U, Alignment>& other) NOEXCEPT {} | |
78 | |
79 ~AlignedAllocator() {} | |
80 | |
81 pointer address(reference x) NOEXCEPT { return &x; } | |
82 const_pointer address(const_reference x) { return &x; } | |
83 | |
84 pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0) { | |
85 return reinterpret_cast<pointer>( | |
86 internal::AlignedAllocate(Alignment, sizeof(value_type) * n)); | |
87 } | |
88 | |
89 void deallocate(pointer p, size_type n) { internal::AlignedFree(p); } | |
90 | |
91 size_type max_size() const NOEXCEPT { | |
92 return std::numeric_limits<size_type>::max() / sizeof(value_type); | |
93 } | |
94 | |
95 template <class U, class... Args> | |
96 void construct(U* p, Args&&... args) { | |
97 new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...); | |
98 } | |
99 | |
100 template <class U> | |
101 void destroy(U* p) { | |
102 p->~U(); | |
103 } | |
104 }; | |
105 | |
106 template <class T, class U, size_t Alignment> | |
107 bool operator==(const AlignedAllocator<T, Alignment>& lhs, | |
108 const AlignedAllocator<U, Alignment>& rhs) { | |
109 return true; | |
110 } | |
111 | |
112 template <class T, class U, size_t Alignment> | |
113 bool operator!=(const AlignedAllocator<T, Alignment>& lhs, | |
114 const AlignedAllocator<U, Alignment>& rhs) { | |
115 return false; | |
116 } | |
117 | |
118 //! \brief A `std::vector` using AlignedAllocator. | |
119 //! | |
120 //! This is similar to `std::vector<T>`, with the addition of an alignment | |
121 //! guarantee. \a Alignment must be a power of 2. If \a Alignment is not | |
122 //! specified, the default alignment for type \a T is used. | |
123 template <typename T, size_t Alignment = ALIGNOF(T)> | |
124 using AlignedVector = std::vector<T, AlignedAllocator<T, Alignment>>; | |
125 | |
126 } // namespace crashpad | |
127 | |
128 #undef NOEXCEPT | |
129 | |
130 #endif // CRASHPAD_UTIL_STDLIB_ALIGNED_ALLOCATOR_H_ | |
OLD | NEW |