/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef META_BASE_INTERFACE_UTILS_H #define META_BASE_INTERFACE_UTILS_H #include #include #include #include META_BEGIN_NAMESPACE() /** * @brief Checks if object implements any of the given interfaces. * @note The function returns false for a null object, regardless of uids. * @note If the object is valid but the uid list is empty, the function returns true. * @param object The object to check. * @param uids The uids to check against. * @return True if the object implements any of the uids. */ static inline bool ObjectImplementsAny( const BASE_NS::shared_ptr& object, const BASE_NS::array_view& ids) noexcept { if (object) { for (const auto& id : ids) { if (object->GetInterface(id.ToUid())) { return true; } } return ids.empty(); } return false; } /** * @brief Checks if object implements all of the given interfaces. * @note The function returns false for a null object, regardless of uids. * @note If the object is valid but the uid list is empty, the function returns true. * @param object The object to check. * @param uids The uids to check against. * @return True if the object implements all of the uids. */ static inline bool ObjectImplementsAll( const BASE_NS::shared_ptr& object, const BASE_NS::array_view& ids) noexcept { if (object) { for (const auto& id : ids) { if (!object->GetInterface(id.ToUid())) { return false; } } return true; } return false; } /** * @brief Checks whether a given object implements one/all of a given set of interface UIDs. * @note The function returns false for a null object, regardless of uids. * @note If the object is valid but the uid list is empty, the function returns true. * @param object The object to check. * @param uids A list of Uids to check against. * @param strict If true, the object must implement all listed Uids. If false, it is enough to implement one. * @return True if object implements given requirements, false otherwise. */ static inline bool CheckInterfaces(const BASE_NS::shared_ptr& object, const BASE_NS::array_view& ids, bool strict) noexcept { return strict ? ObjectImplementsAll(object, ids) : ObjectImplementsAny(object, ids); } /** * @brief Checks if a list of uids matches a given set of requirements. * @param uids The uid list to check against. * @param reqs A uid list which must be found from uids. * @param strict If true, all of reqs must be found from uids. If false, one match is enough. * @return True if uids fulfills reqs, false otherwise. */ static bool CheckInterfaces( const BASE_NS::vector& uids, const BASE_NS::vector& reqs, bool strict) noexcept { if (uids.empty() && !reqs.empty()) { return false; } if (reqs.empty()) { return true; } size_t matches = strict ? reqs.size() : 1; for (auto&& uid : uids) { for (auto&& req : reqs) { if (req == uid) { if (--matches == 0) { return true; } break; } } } return false; } /** * @brief Returns a vector containing all of the source vector objects which implement To::UID casted * to To::Ptr. * @note The result can contain less items than the input if all items of input do not implement To::UID. * The result will never contain more items than input. * @param from The vector to convert from. */ template BASE_NS::vector PtrArrayCast(BASE_NS::vector&& from) { static_assert(IsKindOfPointer_v, "Conversion source array must contain shared_ptrs."); static_assert(IsKindOfInterface_v, "Conversion target type must be an IInterface."); using ToPtr = typename To::Ptr; if constexpr (BASE_NS::is_same_v) { return BASE_NS::move(from); } BASE_NS::vector converted; converted.reserve(from.size()); for (auto&& obj : from) { if (auto t = interface_pointer_cast(obj)) { converted.emplace_back(BASE_NS::move(t)); } } return converted; } META_END_NAMESPACE() #endif // META_BASE_INTERFACE_UTILS_H