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 #ifndef META_INTERFACE_DETAIL_ANY_POINTER_COMPATIBILITY_H
16 #define META_INTERFACE_DETAIL_ANY_POINTER_COMPATIBILITY_H
17 
18 #include <core/plugin/intf_interface.h>
19 
20 #include <meta/base/interface_traits.h>
21 #include <meta/base/shared_ptr.h>
22 #include <meta/interface/intf_any.h>
23 
24 META_BEGIN_NAMESPACE()
25 
26 // NOLINTBEGIN(readability-identifier-naming)
27 using SharedPtrIInterface = BASE_NS::shared_ptr<CORE_NS::IInterface>;
28 using SharedPtrConstIInterface = BASE_NS::shared_ptr<const CORE_NS::IInterface>;
29 constexpr TypeId SharedPtrIInterfaceId = UidFromType<SharedPtrIInterface>();
30 constexpr TypeId SharedPtrConstIInterfaceId = UidFromType<SharedPtrConstIInterface>();
31 using WeakPtrIInterface = BASE_NS::weak_ptr<CORE_NS::IInterface>;
32 using WeakPtrConstIInterface = BASE_NS::weak_ptr<const CORE_NS::IInterface>;
33 constexpr TypeId WeakPtrIInterfaceId = UidFromType<WeakPtrIInterface>();
34 constexpr TypeId WeakPtrConstIInterfaceId = UidFromType<WeakPtrConstIInterface>();
35 // NOLINTEND(readability-identifier-naming)
36 
37 template<bool IsConst, bool IsWeak>
38 struct AnyPointerCompatibility {
39     using IIType = BASE_NS::conditional_t<IsConst, const CORE_NS::IInterface, CORE_NS::IInterface>;
40     using IIPtrType = BASE_NS::conditional_t<IsConst, SharedPtrConstIInterface, SharedPtrIInterface>;
41 
42     template<typename Type>
GetCompatibleTypesAnyPointerCompatibility43     static BASE_NS::array_view<const TypeId> GetCompatibleTypes(CompatibilityDirection dir)
44     {
45         static constexpr TypeId typeId = UidFromType<Type>();
46         if (dir == CompatibilityDirection::GET) {
47             if constexpr (IsConst) {
48                 static TypeId uids[] = { typeId, SharedPtrConstIInterfaceId };
49                 return uids;
50             }
51             static TypeId uids[] = { typeId, SharedPtrIInterfaceId, SharedPtrConstIInterfaceId };
52             return uids;
53         }
54         if (dir == CompatibilityDirection::SET) {
55             if constexpr (IsConst) {
56                 static TypeId uids[] = { typeId, SharedPtrIInterfaceId, SharedPtrConstIInterfaceId };
57                 return uids;
58             }
59             static TypeId uids[] = { typeId, SharedPtrIInterfaceId };
60             return uids;
61         }
62         if constexpr (IsConst) {
63             static TypeId uids[] = { typeId, SharedPtrConstIInterfaceId };
64             return uids;
65         }
66 
67         static TypeId uids[] = { typeId, SharedPtrIInterfaceId };
68         return uids;
69     }
70 
GetDataAnyPointerCompatibility71     static AnyReturnValue GetData(const TypeId& id, void* data, const IIPtrType& ptr)
72     {
73         if constexpr (!IsConst) {
74             if (id == SharedPtrIInterfaceId) {
75                 *static_cast<SharedPtrIInterface*>(data) = ptr;
76                 return AnyReturn::SUCCESS;
77             }
78         }
79         if (id == SharedPtrConstIInterfaceId) {
80             *static_cast<SharedPtrConstIInterface*>(data) = ptr;
81             return AnyReturn::SUCCESS;
82         }
83         return AnyReturn::INVALID_ARGUMENT;
84     }
85 
SetDataAnyPointerCompatibility86     static bool SetData(const TypeId& id, const void* data, IIPtrType& out)
87     {
88         if constexpr (IsConst) {
89             if (id == SharedPtrConstIInterfaceId) {
90                 out = *static_cast<const SharedPtrConstIInterface*>(data);
91                 return true;
92             }
93         }
94         if (id == SharedPtrIInterfaceId) {
95             out = *static_cast<const SharedPtrIInterface*>(data);
96             return true;
97         }
98         return false;
99     }
IsValidGetArgsAnyPointerCompatibility100     static constexpr bool IsValidGetArgs(const TypeId& uid, const void* data, size_t size)
101     {
102         if constexpr (!IsConst) {
103             if (data && uid == SharedPtrIInterfaceId && sizeof(SharedPtrIInterface) == size) {
104                 return true;
105             }
106         }
107         if (data && uid == SharedPtrConstIInterfaceId && sizeof(SharedPtrConstIInterfaceId) == size) {
108             return true;
109         }
110         return false;
111     }
IsValidSetArgsAnyPointerCompatibility112     static constexpr bool IsValidSetArgs(const TypeId& uid, const void* data, size_t size)
113     {
114         if constexpr (IsConst) {
115             if (data && uid == SharedPtrConstIInterfaceId && sizeof(SharedPtrConstIInterface) == size) {
116                 return true;
117             }
118         }
119         if (data && uid == SharedPtrIInterfaceId && sizeof(SharedPtrIInterfaceId) == size) {
120             return true;
121         }
122         return false;
123     }
124 };
125 
126 template<bool IsConst>
127 struct AnyPointerCompatibility<IsConst, true> {
128     using IIType = BASE_NS::conditional_t<IsConst, const CORE_NS::IInterface, CORE_NS::IInterface>;
129     using IIPtrType = BASE_NS::conditional_t<IsConst, SharedPtrConstIInterface, SharedPtrIInterface>;
130 
131     template<typename Type>
132     static BASE_NS::array_view<const TypeId> GetCompatibleTypes(CompatibilityDirection dir)
133     {
134         static constexpr TypeId typeId = UidFromType<Type>();
135         if (dir == CompatibilityDirection::GET) {
136             if constexpr (IsConst) {
137                 static TypeId uids[] = { typeId, SharedPtrConstIInterfaceId, WeakPtrConstIInterfaceId };
138                 return uids;
139             }
140             static TypeId uids[] = { typeId, SharedPtrIInterfaceId, SharedPtrConstIInterfaceId, WeakPtrIInterfaceId,
141                 WeakPtrConstIInterfaceId };
142             return uids;
143         }
144         if (dir == CompatibilityDirection::SET) {
145             if constexpr (IsConst) {
146                 static TypeId uids[] = { typeId, SharedPtrIInterfaceId, SharedPtrConstIInterfaceId, WeakPtrIInterfaceId,
147                     WeakPtrConstIInterfaceId };
148                 return uids;
149             }
150             static TypeId uids[] = { typeId, SharedPtrIInterfaceId, WeakPtrIInterfaceId };
151             return uids;
152         }
153         if constexpr (IsConst) {
154             static TypeId uids[] = { typeId, SharedPtrConstIInterfaceId, WeakPtrConstIInterfaceId };
155             return uids;
156         }
157 
158         static TypeId uids[] = { typeId, SharedPtrIInterfaceId, WeakPtrIInterfaceId };
159         return uids;
160     }
161 
162     static AnyReturnValue GetData(const TypeId& id, void* data, const IIPtrType& ptr)
163     {
164         if (AnyPointerCompatibility<IsConst, false>::GetData(id, data, ptr)) {
165             return AnyReturn::SUCCESS;
166         }
167         if constexpr (!IsConst) {
168             if (id == WeakPtrIInterfaceId) {
169                 *static_cast<WeakPtrIInterface*>(data) = ptr;
170                 return AnyReturn::SUCCESS;
171             }
172         }
173         if (id == WeakPtrConstIInterfaceId) {
174             *static_cast<WeakPtrConstIInterface*>(data) = ptr;
175             return AnyReturn::SUCCESS;
176         }
177         return AnyReturn::INVALID_ARGUMENT;
178     }
179 
180     static bool SetData(const TypeId& id, const void* data, IIPtrType& out)
181     {
182         if (AnyPointerCompatibility<IsConst, false>::SetData(id, data, out)) {
183             return true;
184         }
185         if constexpr (IsConst) {
186             if (id == WeakPtrConstIInterfaceId) {
187                 out = static_cast<const WeakPtrConstIInterface*>(data)->lock();
188                 return true;
189             }
190         }
191         if (id == WeakPtrIInterfaceId) {
192             out = static_cast<const WeakPtrIInterface*>(data)->lock();
193             return true;
194         }
195         return false;
196     }
197     static constexpr bool IsValidGetArgs(const TypeId& uid, const void* data, size_t size)
198     {
199         if (AnyPointerCompatibility<IsConst, false>::IsValidGetArgs(uid, data, size)) {
200             return true;
201         }
202         if constexpr (!IsConst) {
203             if (data && uid == WeakPtrIInterfaceId && sizeof(WeakPtrIInterface) == size) {
204                 return true;
205             }
206         }
207         if (data && uid == WeakPtrConstIInterfaceId && sizeof(WeakPtrConstIInterface) == size) {
208             return true;
209         }
210         return false;
211     }
212     static constexpr bool IsValidSetArgs(const TypeId& uid, const void* data, size_t size)
213     {
214         if (AnyPointerCompatibility<IsConst, false>::IsValidSetArgs(uid, data, size)) {
215             return true;
216         }
217         if constexpr (IsConst) {
218             if (data && uid == WeakPtrConstIInterfaceId && sizeof(WeakPtrConstIInterface) == size) {
219                 return true;
220             }
221         }
222         if (data && uid == WeakPtrIInterfaceId && sizeof(WeakPtrIInterface) == size) {
223             return true;
224         }
225         return false;
226     }
227 };
228 
229 template<typename Type>
230 using AnyPC = AnyPointerCompatibility<IsConstPtr_v<Type>, IsWeakPtr_v<Type>>;
231 
232 META_END_NAMESPACE()
233 
234 #endif
235