/* * Copyright (c) 2024 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 API_BASE_CONTAINERS_REFCNT_PTR_H #define API_BASE_CONTAINERS_REFCNT_PTR_H #include #include BASE_BEGIN_NAMESPACE() template class refcnt_ptr { public: using pointer = BASE_NS::remove_reference_t*; using element_type = T; constexpr refcnt_ptr() noexcept {} constexpr refcnt_ptr(nullptr_t) noexcept {} explicit constexpr refcnt_ptr(pointer ptr) noexcept : ptr_(ptr) { if (ptr) { ptr->Ref(); } } refcnt_ptr(const refcnt_ptr& ptr) : refcnt_ptr(ptr.get()) {} template refcnt_ptr(const refcnt_ptr& ptr) : refcnt_ptr(static_cast(ptr.get())) {} refcnt_ptr(refcnt_ptr&& ptr) noexcept : ptr_(exchange(ptr.ptr_, nullptr)) {} template refcnt_ptr(refcnt_ptr&& ptr) noexcept : ptr_(static_cast(ptr.release())) {} ~refcnt_ptr() { if (ptr_) { ptr_->Unref(); } } pointer get() const noexcept { return ptr_; } pointer release() noexcept { pointer res = ptr_; ptr_ = nullptr; return res; } void reset(pointer ptr = pointer()) noexcept { if (ptr_ != ptr) { pointer old_ptr = ptr_; ptr_ = ptr; if (ptr_) { ptr_->Ref(); } if (old_ptr) { old_ptr->Unref(); } } } refcnt_ptr& operator=(nullptr_t) noexcept { reset(); return *this; } refcnt_ptr& operator=(const refcnt_ptr& r) noexcept { reset(r.get()); return *this; } template refcnt_ptr& operator=(const refcnt_ptr& r) noexcept { reset(r.get()); return *this; } refcnt_ptr& operator=(refcnt_ptr&& r) noexcept { reset(); ptr_ = exchange(r.ptr_, nullptr); return *this; } template refcnt_ptr& operator=(refcnt_ptr&& r) noexcept { reset(); ptr_ = r.release(); return *this; } void swap(refcnt_ptr& other) noexcept { ptr_ = exchange(other.ptr_, ptr_); } explicit operator bool() const noexcept { return (ptr_ != nullptr); } bool operator==(const refcnt_ptr& other) const noexcept { return (ptr_ == other.ptr_); } bool operator!=(const refcnt_ptr& other) const noexcept { return (ptr_ != other.ptr_); } pointer operator->() const noexcept { return ptr_; } typename BASE_NS::add_lvalue_reference::type operator*() const { return *ptr_; } bool operator!=(nullptr_t) const noexcept { return ptr_ != nullptr; } bool operator==(nullptr_t) const noexcept { return ptr_ == nullptr; } protected: pointer ptr_ { nullptr }; }; BASE_END_NAMESPACE() #endif // API_BASE_CONTAINERS_REFCNT_PTR_H