• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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