1 /*
2 * Copyright (c) 2024 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 META_INTERFACE_TYPED_PROPERTY_H
17 #define META_INTERFACE_TYPED_PROPERTY_H
18
19 #include <meta/base/types.h>
20 #include <meta/interface/detail/property.h>
21
META_BEGIN_NAMESPACE()22 META_BEGIN_NAMESPACE()
23
24 template<typename Type>
25 class Property {
26 public:
27 using ValueType = BASE_NS::remove_const_t<Type>;
28 using PropertyInterfaceType = BASE_NS::conditional_t<BASE_NS::is_const_v<Type>, const IProperty, IProperty>;
29 using PropertyType = BASE_NS::shared_ptr<PropertyInterfaceType>;
30
31 Property() = default;
32 Property(nullptr_t) {}
33
34 template<typename Prop, typename = BASE_NS::enable_if_t<BASE_NS::is_convertible_v<Prop*, PropertyInterfaceType*>>>
35 Property(BASE_NS::shared_ptr<Prop> p) : p_(BASE_NS::move(p))
36 {
37 if (p_ && !p_->IsCompatible(UidFromType<ValueType>())) {
38 CORE_LOG_W("Not compatible any for given property type [%s]", p_->GetName().c_str());
39 p_ = nullptr;
40 }
41 }
42 template<typename Prop, typename = BASE_NS::enable_if_t<BASE_NS::is_convertible_v<Prop*, PropertyInterfaceType*>>>
43 Property(NoCheckT, BASE_NS::shared_ptr<Prop> p) : p_(p)
44 {}
45
46 template<typename PType,
47 typename = BASE_NS::enable_if_t<BASE_NS::is_const_v<Type> && BASE_NS::is_same_v<PType, ValueType>>>
48 Property(const Property<PType>& p) : Property(p.GetProperty())
49 {}
50
51 bool IsValid() const
52 {
53 return p_ != nullptr;
54 }
55
56 explicit operator bool() const
57 {
58 return IsValid();
59 }
60
61 TypedPropertyLock<Type> operator->() const
62 {
63 return GetLockedAccess();
64 }
65
66 TypedPropertyLock<Type> GetLockedAccess() const
67 {
68 return TypedPropertyLock<Type>(p_.get());
69 }
70
71 PropertyInterface<Type> GetUnlockedAccess() const
72 {
73 return PropertyInterface<Type>(p_.get());
74 }
75
76 operator IProperty::ConstPtr() const
77 {
78 return p_;
79 }
80
81 operator IProperty::Ptr()
82 {
83 return p_;
84 }
85
86 operator IProperty::ConstWeakPtr() const
87 {
88 return p_;
89 }
90
91 operator IProperty::WeakPtr()
92 {
93 return p_;
94 }
95
96 PropertyType GetProperty() const
97 {
98 return p_;
99 }
100
101 private:
102 PropertyType p_;
103 };
104
105 template<typename T>
106 using ConstProperty = Property<const T>;
107
108 template<typename T>
109 inline bool operator==(const Property<T>& l, const Property<T>& r)
110 {
111 return l.GetProperty() == r.GetProperty();
112 }
113
114 template<typename T>
115 inline bool operator!=(const Property<T>& l, const Property<T>& r)
116 {
117 return !(l == r);
118 }
119
META_END_NAMESPACE()120 META_END_NAMESPACE()
121
122 // NOLINTBEGIN(readability-identifier-naming) to keep std like syntax
123
124 template<typename T, typename S>
125 BASE_NS::shared_ptr<T> interface_pointer_cast(const META_NS::Property<S>& p)
126 {
127 static_assert(META_NS::HasGetInterfaceMethod_v<T>, "T::GetInterface not defined");
128 return interface_pointer_cast<T>(p.GetProperty());
129 }
130
131 template<typename T, typename S>
interface_cast(const META_NS::Property<S> & p)132 T* interface_cast(const META_NS::Property<S>& p)
133 {
134 static_assert(META_NS::HasGetInterfaceMethod_v<T>, "T::GetInterface not defined");
135 return interface_cast<T>(p.GetProperty());
136 }
137
138 // NOLINTEND(readability-identifier-naming) to keep std like syntax
139
140 #endif
141