1 2 /* 3 * Copyright (c) 2024 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CORE_CORE_PROPERTY_SCOPED_HANDLE_H 18 #define CORE_CORE_PROPERTY_SCOPED_HANDLE_H 19 20 #include <base/containers/type_traits.h> 21 #include <base/namespace.h> 22 #include <core/log.h> 23 #include <core/namespace.h> 24 #include <core/property/intf_property_handle.h> 25 26 BASE_BEGIN_NAMESPACE() 27 template<typename CharT> 28 class basic_string_view; 29 using string_view = basic_string_view<char>; 30 BASE_END_NAMESPACE() 31 32 CORE_BEGIN_NAMESPACE() 33 struct PropertyTypeDecl; 34 template<typename Type, bool readOnly_ = BASE_NS::is_const_v<Type>> 35 class ScopedHandle { 36 public: 37 ScopedHandle() = default; 38 ScopedHandle(IPropertyHandle * handle)39 explicit ScopedHandle(IPropertyHandle* handle) : handle_(handle) 40 { 41 if (handle) { 42 if constexpr (readOnly_) { 43 data_ = static_cast<Type*>(handle->RLock()); 44 } else { 45 data_ = static_cast<Type*>(handle->WLock()); 46 } 47 } 48 } 49 ScopedHandle(const IPropertyHandle * handle)50 explicit ScopedHandle(const IPropertyHandle* handle) 51 { 52 static_assert(readOnly_, "const IPropertyHandle can be used with <const Type>."); 53 if (handle) { 54 if constexpr (readOnly_) { 55 handle_ = handle; 56 data_ = static_cast<Type*>(handle_->RLock()); 57 } 58 } 59 } 60 ScopedHandle(ScopedHandle && other)61 ScopedHandle(ScopedHandle&& other) 62 : handle_(BASE_NS::exchange(other.handle_, nullptr)), data_(BASE_NS::exchange(other.data_, nullptr)) 63 {} 64 65 ScopedHandle& operator=(ScopedHandle&& other) noexcept 66 { 67 if (&other != this) { 68 if (handle_) { 69 if constexpr (readOnly_) { 70 handle_->RUnlock(); 71 } else { 72 handle_->WUnlock(); 73 } 74 } 75 handle_ = BASE_NS::exchange(other.handle_, nullptr); 76 data_ = BASE_NS::exchange(other.data_, nullptr); 77 } 78 return *this; 79 } 80 ~ScopedHandle()81 ~ScopedHandle() 82 { 83 if (handle_) { 84 if constexpr (readOnly_) { 85 handle_->RUnlock(); 86 } else { 87 handle_->WUnlock(); 88 } 89 } 90 } 91 92 Type* operator->() const 93 { 94 return data_; 95 } 96 97 Type& operator*() const 98 { 99 CORE_ASSERT(data_); 100 return *data_; 101 } 102 103 explicit operator bool() const 104 { 105 return data_; 106 } 107 108 private: 109 template<typename T> 110 friend ScopedHandle<T> MakeScopedHandle( 111 IPropertyHandle& handle, BASE_NS::string_view propertyName, const PropertyTypeDecl& propertyType); 112 BASE_NS::conditional_t<readOnly_, const IPropertyHandle*, IPropertyHandle*> handle_ { nullptr }; 113 Type* data_ { nullptr }; 114 }; 115 CORE_END_NAMESPACE() 116 117 #endif // CORE_CORE_PROPERTY_SCOPED_HANDLE_H 118