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