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_ANY_H
17 #define META_INTERFACE_ANY_H
18
19 #include <core/plugin/intf_interface.h>
20
21 #include <meta/base/expected.h>
22 #include <meta/base/ids.h>
23 #include <meta/base/interface_macros.h>
24 #include <meta/base/namespace.h>
25 #include <meta/base/types.h>
26
27 META_BEGIN_NAMESPACE()
28
29 META_REGISTER_INTERFACE(IAny, "9e6d554e-3647-4040-a5c4-ea299fa85b8f")
30 META_REGISTER_INTERFACE(IArrayAny, "d3c49aa9-9314-4680-b23a-7d2a24a0af30")
31
32 enum class AnyReturn {
33 NOTHING_TO_DO = 2,
34 SUCCESS = 1,
35 UNUSED = 0,
36 FAIL = -1,
37 INVALID_ARGUMENT = -2,
38 INCOMPATIBLE_TYPE = -3,
39 NOT_SUPPORTED = -4,
40 RECURSIVE_CALL = -5
41 };
42 inline bool operator<(AnyReturn l, AnyReturn r)
43 {
44 return int64_t(l) < int64_t(r);
45 }
46 inline bool operator>(AnyReturn l, AnyReturn r)
47 {
48 return int64_t(l) > int64_t(r);
49 }
50
51 using AnyReturnValue = ReturnValue<AnyReturn>;
52
53 enum class CompatibilityDirection { GET, SET, BOTH };
54 enum class TypeIdRole { CURRENT, ITEM, ARRAY };
55 enum class CloneValueType { COPY_VALUE, DEFAULT_VALUE };
56
57 struct AnyCloneOptions {
58 /** Should value be cloned. Ignored if role != TypeIdRole::CURRENT */
59 CloneValueType value { CloneValueType::COPY_VALUE };
60 /** Type of Any (same as source, item or array type) the clone should be. */
61 TypeIdRole role { TypeIdRole::CURRENT };
62 };
63
64 class IAny : public CORE_NS::IInterface {
65 META_INTERFACE(CORE_NS::IInterface, IAny)
66 public:
67 virtual ObjectId GetClassId() const = 0;
68 virtual const BASE_NS::array_view<const TypeId> GetCompatibleTypes(CompatibilityDirection) const = 0;
69 virtual AnyReturnValue GetData(const TypeId& id, void* data, size_t size) const = 0;
70 virtual AnyReturnValue SetData(const TypeId& id, const void* data, size_t size) = 0;
71 virtual AnyReturnValue CopyFrom(const IAny& any) = 0;
72 virtual AnyReturnValue ResetValue() = 0;
73 virtual IAny::Ptr Clone(const AnyCloneOptions& options) const = 0;
74 virtual TypeId GetTypeId(TypeIdRole role) const = 0;
75 virtual BASE_NS::string GetTypeIdString() const = 0;
76
GetTypeId()77 TypeId GetTypeId() const
78 {
79 return GetTypeId(TypeIdRole::CURRENT);
80 }
IsArray()81 bool IsArray() const
82 {
83 return GetTypeId(TypeIdRole::CURRENT) == GetTypeId(TypeIdRole::ARRAY);
84 }
Clone()85 IAny::Ptr Clone() const
86 {
87 return Clone({ CloneValueType::COPY_VALUE });
88 }
Clone(bool withValue)89 IAny::Ptr Clone(bool withValue) const
90 {
91 return Clone({ withValue ? CloneValueType::COPY_VALUE : CloneValueType::DEFAULT_VALUE });
92 }
93 template<typename T>
GetValue(T & value)94 AnyReturnValue GetValue(T& value) const
95 {
96 return GetData(UidFromType<T>(), &value, sizeof(T)); /*NOLINT(bugprone-sizeof-expression)*/
97 }
98 template<typename T>
SetValue(const T & value)99 AnyReturnValue SetValue(const T& value)
100 {
101 return SetData(UidFromType<T>(), &value, sizeof(T)); /*NOLINT(bugprone-sizeof-expression)*/
102 }
103 };
104
105 class IArrayAny : public IAny {
106 META_INTERFACE(IAny, IArrayAny)
107 public:
108 using IndexType = size_t;
109
110 virtual const BASE_NS::array_view<const TypeId> GetItemCompatibleTypes(CompatibilityDirection) const = 0;
111 virtual AnyReturnValue GetDataAt(size_t index, const TypeId& id, void* data, size_t size) const = 0;
112 virtual AnyReturnValue SetDataAt(size_t index, const TypeId& id, const void* data, size_t size) = 0;
113 virtual AnyReturnValue SetAnyAt(IndexType index, const IAny& value) = 0;
114 virtual AnyReturnValue GetAnyAt(IndexType index, IAny& value) const = 0;
115 virtual AnyReturnValue InsertAnyAt(IndexType index, const IAny& value) = 0;
116 virtual AnyReturnValue RemoveAt(IndexType index) = 0;
117 virtual void RemoveAll() = 0;
118
119 virtual IndexType GetSize() const = 0;
120
121 template<typename T>
GetValueAt(IndexType index,T & value)122 AnyReturnValue GetValueAt(IndexType index, T& value) const
123 {
124 return GetDataAt(index, UidFromType<T>(), &value, sizeof(T)); /*NOLINT(bugprone-sizeof-expression)*/
125 }
126 template<typename T>
SetValueAt(IndexType index,const T & value)127 AnyReturnValue SetValueAt(IndexType index, const T& value)
128 {
129 return SetDataAt(index, UidFromType<T>(), &value, sizeof(T)); /*NOLINT(bugprone-sizeof-expression)*/
130 }
131 };
132
IsArray(const IAny & any)133 inline bool IsArray(const IAny& any)
134 {
135 return any.GetInterface<IArrayAny>() != nullptr;
136 }
137
IsArray(const IAny::ConstPtr & any)138 inline bool IsArray(const IAny::ConstPtr& any)
139 {
140 return any && any->GetInterface<IArrayAny>() != nullptr;
141 }
142
143 template<typename T>
144 inline T GetValue(const IAny& any, NonDeduced_t<T> defaultValue = {})
145 {
146 T t;
147 if (!any.GetValue(t)) {
148 t = defaultValue;
149 }
150 return t;
151 }
152
153 template<typename T>
154 inline T GetValueAt(const IArrayAny& array, IArrayAny::IndexType index, NonDeduced_t<T> defaultValue = {})
155 {
156 T t;
157 if (!array.GetValueAt(index, t)) {
158 t = defaultValue;
159 }
160 return t;
161 }
162
163 inline bool IsCompatible(const IAny& any, const TypeId& uid, CompatibilityDirection dir = CompatibilityDirection::BOTH)
164 {
165 for (auto&& v : any.GetCompatibleTypes(dir)) {
166 if (uid == v) {
167 return true;
168 }
169 }
170 return false;
171 }
172
173 inline bool IsItemCompatible(
174 const IArrayAny& array, const TypeId& uid, CompatibilityDirection dir = CompatibilityDirection::BOTH)
175 {
176 for (auto&& v : array.GetItemCompatibleTypes(dir)) {
177 if (uid == v) {
178 return true;
179 }
180 }
181 return false;
182 }
183 inline bool IsCompatibleWith(
184 const IAny& any, const IAny& other, CompatibilityDirection dir = CompatibilityDirection::BOTH)
185 {
186 for (auto&& v : other.GetCompatibleTypes(dir)) {
187 if (IsCompatible(any, v, dir)) {
188 return true;
189 }
190 }
191 return false;
192 }
193
194 template<typename T>
195 inline bool IsCompatibleWith(const IAny& any, CompatibilityDirection dir = CompatibilityDirection::BOTH)
196 {
197 return IsCompatible(any, UidFromType<BASE_NS::remove_const_t<BASE_NS::remove_reference_t<T>>>(), dir);
198 }
199
IsSetCompatible(const IAny & any,const TypeId & uid)200 inline bool IsSetCompatible(const IAny& any, const TypeId& uid)
201 {
202 return IsCompatible(any, uid, CompatibilityDirection::SET);
203 }
204
IsGetCompatible(const IAny & any,const TypeId & uid)205 inline bool IsGetCompatible(const IAny& any, const TypeId& uid)
206 {
207 return IsCompatible(any, uid, CompatibilityDirection::GET);
208 }
209
210 template<typename T>
IsSetCompatibleWith(const IAny & any)211 inline bool IsSetCompatibleWith(const IAny& any)
212 {
213 return IsCompatibleWith<T>(any, CompatibilityDirection::SET);
214 }
215
216 template<typename T>
IsGetCompatibleWith(const IAny & any)217 inline bool IsGetCompatibleWith(const IAny& any)
218 {
219 return IsCompatibleWith<T>(any, CompatibilityDirection::GET);
220 }
221
222 META_END_NAMESPACE()
223
224 META_INTERFACE_TYPE(META_NS::IAny)
225 META_INTERFACE_TYPE(META_NS::IArrayAny)
226
227 #endif
228