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_BASE_INTERFACE_UTILS_H
17 #define META_BASE_INTERFACE_UTILS_H
18
19 #include <base/containers/vector.h>
20 #include <core/plugin/intf_interface.h>
21
22 #include <meta/base/ids.h>
23 #include <meta/base/shared_ptr.h>
24
META_BEGIN_NAMESPACE()25 META_BEGIN_NAMESPACE()
26
27 /**
28 * @brief Checks if object implements any of the given interfaces.
29 * @note The function returns false for a null object, regardless of uids.
30 * @note If the object is valid but the uid list is empty, the function returns true.
31 * @param object The object to check.
32 * @param uids The uids to check against.
33 * @return True if the object implements any of the uids.
34 */
35 static inline bool ObjectImplementsAny(
36 const BASE_NS::shared_ptr<const CORE_NS::IInterface>& object, const BASE_NS::array_view<const TypeId>& ids) noexcept
37 {
38 if (object) {
39 for (const auto& id : ids) {
40 if (object->GetInterface(id.ToUid())) {
41 return true;
42 }
43 }
44 return ids.empty();
45 }
46 return false;
47 }
48
49 /**
50 * @brief Checks if object implements all of the given interfaces.
51 * @note The function returns false for a null object, regardless of uids.
52 * @note If the object is valid but the uid list is empty, the function returns true.
53 * @param object The object to check.
54 * @param uids The uids to check against.
55 * @return True if the object implements all of the uids.
56 */
ObjectImplementsAll(const BASE_NS::shared_ptr<const CORE_NS::IInterface> & object,const BASE_NS::array_view<const TypeId> & ids)57 static inline bool ObjectImplementsAll(
58 const BASE_NS::shared_ptr<const CORE_NS::IInterface>& object, const BASE_NS::array_view<const TypeId>& ids) noexcept
59 {
60 if (object) {
61 for (const auto& id : ids) {
62 if (!object->GetInterface(id.ToUid())) {
63 return false;
64 }
65 }
66 return true;
67 }
68 return false;
69 }
70
71 /**
72 * @brief Checks whether a given object implements one/all of a given set of interface UIDs.
73 * @note The function returns false for a null object, regardless of uids.
74 * @note If the object is valid but the uid list is empty, the function returns true.
75 * @param object The object to check.
76 * @param uids A list of Uids to check against.
77 * @param strict If true, the object must implement all listed Uids. If false, it is enough to implement one.
78 * @return True if object implements given requirements, false otherwise.
79 */
CheckInterfaces(const BASE_NS::shared_ptr<const CORE_NS::IInterface> & object,const BASE_NS::array_view<const TypeId> & ids,bool strict)80 static inline bool CheckInterfaces(const BASE_NS::shared_ptr<const CORE_NS::IInterface>& object,
81 const BASE_NS::array_view<const TypeId>& ids, bool strict) noexcept
82 {
83 return strict ? ObjectImplementsAll(object, ids) : ObjectImplementsAny(object, ids);
84 }
85
86 /**
87 * @brief Checks if a list of uids matches a given set of requirements.
88 * @param uids The uid list to check against.
89 * @param reqs A uid list which must be found from <param>uids</param>.
90 * @param strict If true, all of reqs must be found from uids. If false, one match is enough.
91 * @return True if uids fulfills reqs, false otherwise.
92 */
CheckInterfaces(const BASE_NS::vector<BASE_NS::Uid> & uids,const BASE_NS::vector<BASE_NS::Uid> & reqs,bool strict)93 static bool CheckInterfaces(
94 const BASE_NS::vector<BASE_NS::Uid>& uids, const BASE_NS::vector<BASE_NS::Uid>& reqs, bool strict) noexcept
95 {
96 if (uids.empty() && !reqs.empty()) {
97 return false;
98 }
99 if (reqs.empty()) {
100 return true;
101 }
102 size_t matches = strict ? reqs.size() : 1;
103 for (auto&& uid : uids) {
104 for (auto&& req : reqs) {
105 if (req == uid) {
106 if (--matches == 0) {
107 return true;
108 }
109 break;
110 }
111 }
112 }
113 return false;
114 }
115
116 /**
117 * @brief Returns a vector containing all of the source vector objects which implement To::UID casted
118 * to To::Ptr.
119 * @note The result can contain less items than the input if all items of input do not implement To::UID.
120 * The result will never contain more items than input.
121 * @param from The vector to convert from.
122 */
123 template<class To, class From>
PtrArrayCast(BASE_NS::vector<From> && from)124 BASE_NS::vector<typename To::Ptr> PtrArrayCast(BASE_NS::vector<From>&& from)
125 {
126 static_assert(IsKindOfPointer_v<From>, "Conversion source array must contain shared_ptrs.");
127 static_assert(IsKindOfInterface_v<To>, "Conversion target type must be an IInterface.");
128 using ToPtr = typename To::Ptr;
129 if constexpr (BASE_NS::is_same_v<ToPtr, From>) {
130 return BASE_NS::move(from);
131 }
132 BASE_NS::vector<ToPtr> converted;
133 converted.reserve(from.size());
134 for (auto&& obj : from) {
135 if (auto t = interface_pointer_cast<To>(obj)) {
136 converted.emplace_back(BASE_NS::move(t));
137 }
138 }
139 return converted;
140 }
141
142 META_END_NAMESPACE()
143
144 #endif // META_BASE_INTERFACE_UTILS_H
145