/*
* 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