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