/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MAPLE_UTIL_SAFE_PTR_H #define MAPLE_UTIL_SAFE_PTR_H #include "mpl_logging.h" #include "ptr.h" namespace maple { namespace utils { template inline void AssertNotNull(const T *ptr) { CHECK_FATAL(ptr != nullptr, "nullptr was assigned to SafePtr."); } template class SafePtr { using Base = Ptr>; public: using pointer = typename Base::Pointer; using ElementType = typename Base::ElementType; constexpr SafePtr() noexcept = delete; constexpr SafePtr(std::nullptr_t) noexcept = delete; SafePtr(pointer ptr) : base(ptr) {} SafePtr(T &ref) : base(ref, CheckNothing) {} SafePtr(T &&ref) = delete; template ::value>> SafePtr(U *ptr) : base(ptr) { } template ::value>> SafePtr(U &ref) : base(ref, CheckNothing) { } template ::value>> SafePtr(U &&ref) = delete; SafePtr(const SafePtr &other) : base(other.base) {} SafePtr(SafePtr &&other) noexcept : base(std::move(other.base)) {} template ::value>> explicit SafePtr(const SafePtr &other) : base(other.get(), CheckNothing) { } template ::value>> explicit SafePtr(SafePtr &&other) : base(other.get(), CheckNothing) { } ~SafePtr() = default; SafePtr &operator=(pointer ptr) noexcept { base = ptr; return *this; } SafePtr &operator=(std::nullptr_t) noexcept = delete; SafePtr &operator=(const SafePtr &ptr) noexcept { base = ptr.base; return *this; } SafePtr &operator=(SafePtr &&ptr) noexcept { base = std::move(ptr.base); return *this; } template ::value>> SafePtr &operator=(const SafePtr &ptr) noexcept { base = Base(static_cast(ptr.get()), CheckNothing); return *this; } template ::value>> SafePtr &operator=(SafePtr &&ptr) noexcept { base = Base(static_cast(ptr.get()), CheckNothing); return *this; } pointer release() noexcept = delete; void reset(std::nullptr_t) noexcept = delete; void reset(pointer ptr) noexcept { AssertNotNull(ptr); base.reset(ptr); } void swap(SafePtr &other) noexcept { std::swap(base, other.base); } T *get() const noexcept { return base.get(); } explicit operator bool() const noexcept = delete; T &operator*() const { return *get(); } T *operator->() const noexcept { return get(); } SafePtr &operator++() = delete; const SafePtr operator++(int) = delete; SafePtr &operator--() = delete; const SafePtr operator--(int) = delete; SafePtr &operator+=(std::ptrdiff_t) = delete; SafePtr &operator-=(std::ptrdiff_t) = delete; private: Base base; }; template inline bool operator==(const SafePtr &lhs, const SafePtr &rhs) { return lhs.get() == rhs.get(); } template inline bool operator!=(const SafePtr &lhs, const SafePtr &rhs) { return !(lhs == rhs); } template inline bool operator<(const SafePtr &lhs, const SafePtr &rhs) = delete; template inline bool operator<=(const SafePtr &lhs, const SafePtr &rhs) = delete; template inline bool operator>(const SafePtr &lhs, const SafePtr &rhs) = delete; template inline bool operator>=(const SafePtr &lhs, const SafePtr &rhs) = delete; template inline bool operator==(const SafePtr &lhs, std::nullptr_t) = delete; template inline bool operator==(std::nullptr_t, const SafePtr &rhs) = delete; template inline bool operator!=(const SafePtr &lhs, std::nullptr_t) = delete; template inline bool operator!=(std::nullptr_t, const SafePtr &rhs) = delete; template inline bool operator<(const SafePtr &lhs, std::nullptr_t) = delete; template inline bool operator<(std::nullptr_t, const SafePtr &rhs) = delete; template inline bool operator<=(const SafePtr &lhs, std::nullptr_t) = delete; template inline bool operator<=(std::nullptr_t, const SafePtr &rhs) = delete; template inline bool operator>(const SafePtr &lhs, std::nullptr_t) = delete; template inline bool operator>(std::nullptr_t, const SafePtr &rhs) = delete; template inline bool operator>=(const SafePtr &lhs, std::nullptr_t) = delete; template inline bool operator>=(std::nullptr_t, const SafePtr &rhs) = delete; template inline T &ToRef(SafePtr ptr) { return *ptr; } } // namespace utils } // namespace maple namespace std { template struct hash> { std::size_t operator()(const maple::utils::SafePtr &safePtr) const { return hash::pointer>()(safePtr.get()); } }; } // namespace std #endif // DIY_CPLUSPLUS_SAFE_PTR_H