• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_DETAIL_ARRAY_PROPERTY_H
17 #define META_INTERFACE_DETAIL_ARRAY_PROPERTY_H
18 
19 #include <meta/interface/detail/any.h>
20 #include <meta/interface/detail/property.h>
21 
META_BEGIN_NAMESPACE()22 META_BEGIN_NAMESPACE()
23 
24 template<typename Base>
25 class ConstTypelessArrayPropertyInterfaceImpl : public Base {
26 public:
27     using IndexType = IArrayAny::IndexType;
28 
29     template<typename Prop>
30     explicit ConstTypelessArrayPropertyInterfaceImpl(Prop* p) : Base(p)
31     {}
32 
33     IndexType GetSize() const
34     {
35         if (auto arr = interface_cast<IArrayAny>(&this->GetValueAny())) {
36             return arr->GetSize();
37         }
38         return {};
39     }
40     AnyReturnValue GetAnyAt(IndexType index, IAny& any) const
41     {
42         if (auto arr = interface_cast<IArrayAny>(&this->GetValueAny())) {
43             return arr->GetAnyAt(index, any);
44         }
45         return AnyReturn::INCOMPATIBLE_TYPE;
46     }
47     IAny::Ptr GetAnyAt(IndexType index) const
48     {
49         IAny::Ptr res = ConstructItemAny();
50         if (res) {
51             if (!GetAnyAt(index, *res)) {
52                 res.reset();
53             }
54         }
55         return res;
56     }
57     IAny::Ptr ConstructItemAny() const
58     {
59         IAny::Ptr res;
60         if (auto i = interface_cast<IPropertyInternalAny>(this->p_)) {
61             if (auto internal = i->GetInternalAny()) {
62                 res = internal->Clone({ CloneValueType::DEFAULT_VALUE, TypeIdRole::ITEM });
63             }
64         }
65         return res;
66     }
67 };
68 
69 using ConstTypelessArrayPropertyInterface = ConstTypelessArrayPropertyInterfaceImpl<ConstTypelessPropertyInterface>;
70 
71 class TypelessArrayPropertyInterface : public ConstTypelessArrayPropertyInterfaceImpl<TypelessPropertyInterface> {
72 public:
73     using PropertyType = IProperty*;
74     using IndexType = IArrayAny::IndexType;
75 
TypelessArrayPropertyInterface(PropertyType p)76     TypelessArrayPropertyInterface(PropertyType p)
77         : ConstTypelessArrayPropertyInterfaceImpl<TypelessPropertyInterface>(p)
78     {}
79 
SetAnyAt(IndexType index,const IAny & any)80     AnyReturnValue SetAnyAt(IndexType index, const IAny& any)
81     {
82         if (auto c = this->GetValueAny().Clone(true)) {
83             if (auto arr = interface_cast<IArrayAny>(c)) {
84                 auto res = arr->SetAnyAt(index, any);
85                 return res ? this->SetValueAny(*arr) : res;
86             }
87         }
88         return AnyReturn::INCOMPATIBLE_TYPE;
89     }
AddAny(const IAny & any)90     AnyReturnValue AddAny(const IAny& any)
91     {
92         return InsertAnyAt(-1, any);
93     }
InsertAnyAt(IndexType index,const IAny & v)94     AnyReturnValue InsertAnyAt(IndexType index, const IAny& v)
95     {
96         if (auto c = this->GetValueAny().Clone(true)) {
97             if (auto arr = interface_cast<IArrayAny>(c)) {
98                 auto res = arr->InsertAnyAt(index, v);
99                 return res ? this->SetValueAny(*arr) : res;
100             }
101         }
102         return AnyReturn::INCOMPATIBLE_TYPE;
103     }
RemoveAt(IndexType index)104     bool RemoveAt(IndexType index)
105     {
106         if (auto c = this->GetValueAny().Clone(true)) {
107             if (auto arr = interface_cast<IArrayAny>(c)) {
108                 return arr->RemoveAt(index) && this->SetValueAny(*arr);
109             }
110         }
111         return false;
112     }
113 };
114 
115 template<typename Type>
116 using ArrayPropertyBaseType = BASE_NS::conditional_t<BASE_NS::is_const_v<Type>, ConstTypelessArrayPropertyInterface,
117     TypelessArrayPropertyInterface>;
118 
119 template<typename Type>
120 class ArrayPropertyInterface : public ArrayPropertyBaseType<Type> {
121     using Super = ArrayPropertyBaseType<Type>;
122 
123 public:
124     using ValueType = BASE_NS::remove_const_t<Type>;
125     using PropertyType = typename PropertyBaseType<Type>::PropertyType;
126     using IndexType = IArrayAny::IndexType;
127 
ArrayPropertyInterface(PropertyType p)128     explicit ArrayPropertyInterface(PropertyType p) : Super(p) {}
129 
GetValueAt(IndexType index)130     ValueType GetValueAt(IndexType index) const
131     {
132         Any<ValueType> any;
133         if (auto arr = interface_cast<IArrayAny>(&this->GetValueAny())) {
134             arr->GetAnyAt(index, any);
135         }
136         return any.InternalGetValue();
137     }
SetValueAt(IndexType index,const Type & v)138     bool SetValueAt(IndexType index, const Type& v)
139     {
140         return this->SetAnyAt(index, Any<ValueType> { v });
141     }
AddValue(const Type & v)142     bool AddValue(const Type& v)
143     {
144         return InsertValueAt(-1, v);
145     }
InsertValueAt(IndexType index,const Type & v)146     bool InsertValueAt(IndexType index, const Type& v)
147     {
148         return this->InsertAnyAt(index, Any<ValueType> { v });
149     }
GetDefaultValue()150     BASE_NS::vector<ValueType> GetDefaultValue() const
151     {
152         BASE_NS::vector<ValueType> v;
153         this->GetDefaultValueAny().GetValue(v);
154         return v;
155     }
156 
SetDefaultValue(BASE_NS::array_view<const ValueType> value)157     AnyReturnValue SetDefaultValue(BASE_NS::array_view<const ValueType> value)
158     {
159         return this->SetDefaultValueAny(ArrayAny<ValueType>(value));
160     }
161 
162     template<typename T, typename = BASE_NS::enable_if_t<BASE_NS::is_same_v<T, ValueType>>>
SetDefaultValue(BASE_NS::vector<T> value)163     AnyReturnValue SetDefaultValue(BASE_NS::vector<T> value)
164     {
165         return this->SetDefaultValueAny(ArrayAny<ValueType>(BASE_NS::move(value)));
166     }
167 
SetDefaultValue(BASE_NS::vector<ValueType> value,bool resetToDefault)168     AnyReturnValue SetDefaultValue(BASE_NS::vector<ValueType> value, bool resetToDefault)
169     {
170         auto ret = this->SetDefaultValueAny(ArrayAny<ValueType>(BASE_NS::move(value)));
171         if (resetToDefault && ret) {
172             this->ResetValue();
173         }
174         return ret;
175     }
176 
GetValue()177     BASE_NS::vector<ValueType> GetValue() const
178     {
179         BASE_NS::vector<ValueType> v {};
180         this->GetValueAny().GetValue(v);
181         return v;
182     }
183 
SetValue(BASE_NS::array_view<const ValueType> value)184     AnyReturnValue SetValue(BASE_NS::array_view<const ValueType> value)
185     {
186         return this->SetValueAny(ArrayAny<ValueType>(value));
187     }
188 
189     template<typename T, typename = BASE_NS::enable_if_t<BASE_NS::is_same_v<T, ValueType>>>
SetValue(BASE_NS::vector<T> value)190     AnyReturnValue SetValue(BASE_NS::vector<T> value)
191     {
192         return this->SetValueAny(ArrayAny<ValueType>(BASE_NS::move(value)));
193     }
194 
FindFirstValueOf(const Type & v)195     IndexType FindFirstValueOf(const Type& v) const
196     {
197         for (IndexType i = 0; i != this->GetSize(); ++i) {
198             if (GetValueAt(i) == v) {
199                 return i;
200             }
201         }
202         return -1;
203     }
204 };
205 
206 template<typename Type>
207 class TypedArrayPropertyLock final : public ArrayPropertyInterface<Type> {
208     using PropertyType = typename ArrayPropertyInterface<Type>::PropertyType;
209     using IT = ArrayPropertyInterface<Type>;
210     using InterfaceType = BASE_NS::conditional_t<BASE_NS::is_const_v<Type>, const IT*, IT*>;
211 
META_NO_COPY_MOVE(TypedArrayPropertyLock)212     META_NO_COPY_MOVE(TypedArrayPropertyLock)
213 
214     bool CanConstructFrom(PropertyType p) const
215     {
216         return p && p->IsCompatible(META_NS::GetArrayTypeId<BASE_NS::remove_const_t<Type>>());
217     }
218 public:
TypedArrayPropertyLock(NoCheckT,PropertyType p)219     TypedArrayPropertyLock(NoCheckT, PropertyType p) : ArrayPropertyInterface<Type>(p)
220     {
221         if (auto i = interface_cast<ILockable>(this->GetProperty())) {
222             i->Lock();
223         }
224     }
TypedArrayPropertyLock(PropertyType p)225     explicit TypedArrayPropertyLock(PropertyType p) : TypedArrayPropertyLock(NOCHECK, CanConstructFrom(p) ? p : nullptr)
226     {}
TypedArrayPropertyLock(const IProperty::Ptr & p)227     explicit TypedArrayPropertyLock(const IProperty::Ptr& p) : TypedArrayPropertyLock(p.get()) {}
TypedArrayPropertyLock(const IProperty::ConstPtr & p)228     explicit TypedArrayPropertyLock(const IProperty::ConstPtr& p) : TypedArrayPropertyLock(p.get()) {}
~TypedArrayPropertyLock()229     ~TypedArrayPropertyLock()
230     {
231         if (auto i = interface_cast<ILockable>(this->GetProperty())) {
232             i->Unlock();
233         }
234     }
235 
236     InterfaceType operator->() const
237     {
238         return const_cast<TypedArrayPropertyLock*>(this);
239     }
IsValid()240     bool IsValid() const
241     {
242         return this->GetProperty() != nullptr;
243     }
244     explicit operator bool() const
245     {
246         return IsValid();
247     }
248 };
249 
250 template<typename Property>
251 class ArrayPropertyLock final : public ArrayPropertyBaseType<Property> {
252     using InterfaceType = ArrayPropertyBaseType<Property>*;
253 
META_NO_COPY_MOVE(ArrayPropertyLock)254     META_NO_COPY_MOVE(ArrayPropertyLock)
255 
256     bool CanConstructFrom(Property* p) const
257     {
258         auto i = interface_cast<IPropertyInternalAny>(p);
259         return i && IsArray(i->GetInternalAny());
260     }
261 public:
ArrayPropertyLock(NoCheckT,Property * p)262     ArrayPropertyLock(NoCheckT, Property* p) : ArrayPropertyBaseType<Property>(p)
263     {
264         if (auto i = interface_cast<ILockable>(this->GetProperty())) {
265             i->Lock();
266         }
267     }
ArrayPropertyLock(Property * p)268     explicit ArrayPropertyLock(Property* p) : ArrayPropertyLock(NOCHECK, CanConstructFrom(p) ? p : nullptr) {}
ArrayPropertyLock(BASE_NS::shared_ptr<Property> p)269     explicit ArrayPropertyLock(BASE_NS::shared_ptr<Property> p) : ArrayPropertyLock(p.get()) {}
~ArrayPropertyLock()270     ~ArrayPropertyLock()
271     {
272         if (auto i = interface_cast<ILockable>(this->GetProperty())) {
273             i->Unlock();
274         }
275     }
276 
277     InterfaceType operator->() const
278     {
279         return const_cast<ArrayPropertyLock*>(this);
280     }
IsValid()281     bool IsValid() const
282     {
283         return this->GetProperty() != nullptr;
284     }
285     explicit operator bool() const
286     {
287         return IsValid();
288     }
289 };
290 
291 META_END_NAMESPACE()
292 
293 #endif
294