1 /* 2 * Copyright (c) 2021 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 PANDA_RUNTIME_INCLUDE_MEM_PANDA_SMART_POINTERS_H_ 17 #define PANDA_RUNTIME_INCLUDE_MEM_PANDA_SMART_POINTERS_H_ 18 19 #include <memory> 20 21 #include "libpandabase/concepts.h" 22 #include "runtime/include/mem/allocator.h" 23 24 namespace panda { 25 26 template <class T> 27 struct DefaultPandaDelete { 28 constexpr DefaultPandaDelete() noexcept = default; 29 30 template <class U, std::enable_if_t<std::is_convertible_v<U *, T *>, void *> = nullptr> 31 // NOLINTNEXTLINE(google-explicit-constructor, readability-named-parameter) DefaultPandaDeleteDefaultPandaDelete32 DefaultPandaDelete(const DefaultPandaDelete<U> &) noexcept 33 { 34 } 35 operatorDefaultPandaDelete36 void operator()(T *ptr) const noexcept 37 { 38 static_assert(!std::is_void_v<T>, "Incorrect (void) type for DefaultPandaDelete"); 39 static_assert(sizeof(T) > 0, "Incorrect (incomplete) type for DefaultPandaDelete"); 40 mem::InternalAllocator<>::GetInternalAllocatorFromRuntime()->Delete(ptr); 41 } 42 }; 43 44 template <class T> 45 // NOLINTNEXTLINE(modernize-avoid-c-arrays) 46 struct DefaultPandaDelete<T[]> { 47 constexpr DefaultPandaDelete() noexcept = default; 48 49 // NOLINTNEXTLINE(modernize-avoid-c-arrays) 50 template <class U, std::enable_if_t<std::is_convertible_v<U (*)[], T (*)[]>, void *> = nullptr> 51 // NOLINTNEXTLINE(google-explicit-constructor, readability-named-parameter, modernize-avoid-c-arrays) 52 DefaultPandaDelete(const DefaultPandaDelete<U[]> &) noexcept 53 { 54 } 55 56 template <class U> 57 // NOLINTNEXTLINE(google-explicit-constructor, readability-named-parameter, modernize-avoid-c-arrays) 58 std::enable_if_t<std::is_convertible_v<U (*)[], T (*)[]>> operator()(U *ptr) const noexcept 59 { 60 static_assert(!std::is_void_v<T>, "Incorrect (void) type for DefaultPandaDelete"); 61 static_assert(sizeof(T) > 0, "Incorrect (incomplete) type for DefaultPandaDelete"); 62 mem::InternalAllocator<>::GetInternalAllocatorFromRuntime()->DeleteArray(ptr); 63 } 64 }; 65 66 template <typename T, typename Deleter = DefaultPandaDelete<T>> 67 using PandaUniquePtr = std::unique_ptr<T, Deleter>; 68 69 template <class T, bool cond> 70 using PandaUniquePtrIf = std::enable_if_t<cond, PandaUniquePtr<T>>; 71 72 template <class T, class... Args> 73 inline PandaUniquePtrIf<T, !std::is_array_v<T>> MakePandaUnique(Args &&... args) 74 { 75 return PandaUniquePtr<T> { 76 mem::InternalAllocator<>::GetInternalAllocatorFromRuntime()->New<T>(std::forward<Args>(args)...)}; 77 } 78 79 template <class T> 80 inline PandaUniquePtrIf<T, is_unbounded_array_v<T>> MakePandaUnique(size_t size) 81 { 82 return PandaUniquePtr<T> {mem::InternalAllocator<>::GetInternalAllocatorFromRuntime()->New<T>(size)}; 83 } 84 85 template <class T, class... Args> 86 inline PandaUniquePtrIf<T, is_bounded_array_v<T>> MakePandaUnique(Args &&... args) = delete; 87 88 } // namespace panda 89 90 #endif // PANDA_RUNTIME_INCLUDE_MEM_PANDA_SMART_POINTERS_H_ 91