1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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
16 #ifndef LIBPANDABASE_MEM_ARENA_ALLOCATOR_STL_ADAPTER_H
17 #define LIBPANDABASE_MEM_ARENA_ALLOCATOR_STL_ADAPTER_H
18
19 #include "arena_allocator.h"
20
21 namespace panda {
22
23 // Adapter for use of ArenaAllocator in STL containers.
24 template <typename T, bool use_oom_handler>
25 class ArenaAllocatorAdapter;
26
27 template <bool use_oom_handler>
28 class ArenaAllocatorAdapter<void, use_oom_handler> {
29 public:
30 using value_type = void;
31 using pointer = void *;
32 using const_pointer = const void *;
33
34 template <typename U>
35 struct Rebind {
36 using other = ArenaAllocatorAdapter<U, use_oom_handler>;
37 };
38
39 template <typename U>
40 using rebind = Rebind<U>;
41
ArenaAllocatorAdapter(ArenaAllocatorT<use_oom_handler> * allocator)42 explicit ArenaAllocatorAdapter(ArenaAllocatorT<use_oom_handler> *allocator) : allocator_(allocator) {}
43 template <typename U>
44 // NOLINTNEXTLINE(google-explicit-constructor)
ArenaAllocatorAdapter(const ArenaAllocatorAdapter<U,use_oom_handler> & other)45 ArenaAllocatorAdapter(const ArenaAllocatorAdapter<U, use_oom_handler> &other) : allocator_(other.allocator_)
46 {
47 }
48 ArenaAllocatorAdapter(const ArenaAllocatorAdapter &) = default;
49 ArenaAllocatorAdapter &operator=(const ArenaAllocatorAdapter &) = default;
50 ArenaAllocatorAdapter(ArenaAllocatorAdapter &&) = default;
51 ArenaAllocatorAdapter &operator=(ArenaAllocatorAdapter &&) = default;
52 ~ArenaAllocatorAdapter() = default;
53
54 private:
55 ArenaAllocatorT<use_oom_handler> *allocator_;
56
57 template <typename U, bool use_oom_handle>
58 friend class ArenaAllocatorAdapter;
59 };
60
61 template <typename T, bool use_oom_handler = false>
62 class ArenaAllocatorAdapter {
63 public:
64 using value_type = T;
65 using pointer = T *;
66 using reference = T &;
67 using const_pointer = const T *;
68 using const_reference = const T &;
69 using size_type = size_t;
70 using difference_type = ptrdiff_t;
71
72 template <typename U>
73 struct Rebind {
74 using other = ArenaAllocatorAdapter<U, use_oom_handler>;
75 };
76
77 template <typename U>
78 using rebind = Rebind<U>;
79
ArenaAllocatorAdapter(ArenaAllocatorT<use_oom_handler> * allocator)80 explicit ArenaAllocatorAdapter(ArenaAllocatorT<use_oom_handler> *allocator) : allocator_(allocator) {}
81 template <typename U>
82 // NOLINTNEXTLINE(google-explicit-constructor)
ArenaAllocatorAdapter(const ArenaAllocatorAdapter<U,use_oom_handler> & other)83 ArenaAllocatorAdapter(const ArenaAllocatorAdapter<U, use_oom_handler> &other) : allocator_(other.allocator_)
84 {
85 }
86 ArenaAllocatorAdapter(const ArenaAllocatorAdapter &) = default;
87 ArenaAllocatorAdapter &operator=(const ArenaAllocatorAdapter &) = default;
ArenaAllocatorAdapter(ArenaAllocatorAdapter && other)88 ArenaAllocatorAdapter(ArenaAllocatorAdapter &&other) noexcept
89 {
90 allocator_ = other.allocator_;
91 other.allocator_ = nullptr;
92 }
93 ArenaAllocatorAdapter &operator=(ArenaAllocatorAdapter &&other) noexcept
94 {
95 allocator_ = other.allocator_;
96 other.allocator_ = nullptr;
97 return *this;
98 }
99 ~ArenaAllocatorAdapter() = default;
100
101 // NOLINTNEXTLINE(readability-identifier-naming)
max_size()102 size_type max_size() const
103 {
104 return static_cast<size_type>(-1) / sizeof(T);
105 }
106
107 // NOLINTNEXTLINE(readability-identifier-naming)
address(reference x)108 pointer address(reference x) const
109 {
110 return &x;
111 }
112 // NOLINTNEXTLINE(readability-identifier-naming)
address(const_reference x)113 const_pointer address(const_reference x) const
114 {
115 return &x;
116 }
117
118 // NOLINTNEXTLINE(readability-identifier-naming)
119 pointer allocate(size_type n,
120 [[maybe_unused]] typename ArenaAllocatorAdapter<void, use_oom_handler>::pointer ptr = nullptr)
121 {
122 ASSERT(n <= max_size());
123 return allocator_->template AllocArray<T>(n);
124 }
125
126 // NOLINTNEXTLINE(readability-identifier-naming)
deallocate(pointer p,size_type n)127 void deallocate([[maybe_unused]] pointer p, [[maybe_unused]] size_type n) {}
128
129 template <typename U, typename... Args>
construct(U * p,Args &&...args)130 void construct(U *p, Args &&... args) // NOLINT(readability-identifier-naming)
131 {
132 ::new (static_cast<void *>(p)) U(std::forward<Args>(args)...);
133 }
134 template <typename U>
destroy(U * p)135 void destroy(U *p) // NOLINT(readability-identifier-naming)
136 {
137 p->~U();
138 }
139
140 private:
141 ArenaAllocatorT<use_oom_handler> *allocator_ {nullptr};
142
143 template <typename U, bool use_oom_handle>
144 friend class ArenaAllocatorAdapter;
145
146 template <typename U, bool use_oom_handle>
147 // NOLINTNEXTLINE(readability-redundant-declaration)
148 friend inline bool operator==(const ArenaAllocatorAdapter<U, use_oom_handle> &lhs,
149 const ArenaAllocatorAdapter<U, use_oom_handle> &rhs);
150 };
151
152 template <typename T, bool use_oom_handle>
153 inline bool operator==(const ArenaAllocatorAdapter<T, use_oom_handle> &lhs,
154 const ArenaAllocatorAdapter<T, use_oom_handle> &rhs)
155 {
156 return lhs.allocator_ == rhs.allocator_;
157 }
158
159 template <typename T, bool use_oom_handle>
160 inline bool operator!=(const ArenaAllocatorAdapter<T, use_oom_handle> &lhs,
161 const ArenaAllocatorAdapter<T, use_oom_handle> &rhs)
162 {
163 return !(lhs == rhs);
164 }
165
166 template <bool use_oom_handler>
Adapter()167 inline ArenaAllocatorAdapter<void, use_oom_handler> ArenaAllocatorT<use_oom_handler>::Adapter()
168 {
169 return ArenaAllocatorAdapter<void, use_oom_handler>(this);
170 }
171
172 } // namespace panda
173
174 #endif // LIBPANDABASE_MEM_ARENA_ALLOCATOR_STL_ADAPTER_H
175