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_API_INTERNAL_BREADTH_FIRST_ITERATION_H
17 #define META_API_INTERNAL_BREADTH_FIRST_ITERATION_H
18
19 #include <meta/api/internal/iteration_types.h>
20
META_BEGIN_NAMESPACE()21 META_BEGIN_NAMESPACE()
22 namespace Internal {
23
24 template<typename Type>
25 void AddToQueue(BASE_NS::vector<IIterable::ConstPtr>& vec, const Type& t)
26 {
27 if constexpr (IsInterfacePtr_v<PlainType_t<Type>>) {
28 if (auto i = interface_pointer_cast<IIterable>(t)) {
29 vec.push_back(i);
30 }
31 }
32 }
33
34 template<template<typename> class InterableCallable, typename Iterable, typename Func>
35 IterationResult BreadthFirstOrderIterate(const Iterable& i, Func& func, IterateStrategy is)
36 {
37 auto ite = interface_pointer_cast<IIterable>(i);
38 if (!ite) {
39 return IterationResult::CONTINUE;
40 }
41 using ParamType = IterationForwardArgType<Func>;
42
43 BASE_NS::vector<IIterable::ConstPtr> queue;
44 auto f = [&](ParamType arg) {
45 if (!func(arg)) {
46 return IterationResult::STOP;
47 }
48 AddToQueue(queue, arg);
49 return IterationResult::CONTINUE;
50 };
51 IterationCallable<InterableCallable, decltype(f)> ff(BASE_NS::move(f));
52 InterfaceLock lock(is.lock, ite);
53
54 IterationResult res;
55
56 queue.push_back(ite);
57 while (!queue.empty()) {
58 auto i = queue[0];
59 queue.erase(queue.begin());
60 res = i->Iterate(IterationParameters { ff, is });
61 if (res.value != IterationResult::CONTINUE) {
62 return res;
63 }
64 }
65 return res;
66 }
67
68 template<template<typename> class InterableCallable, typename Iterable>
69 IterationResult BreadthFirstOrderIterate(const Iterable& i, ICallable& func, IterateStrategy is)
70 {
71 using CallableType = InterableCallable<IObject::Ptr>;
72 auto f = func.GetInterface<CallableType>();
73 if (!f) {
74 CORE_LOG_W("Incompatible function with Iterate");
75 return IterationResult::FAILED;
76 }
77 auto lf = [&](typename CallableType::ArgType obj) { return f->Invoke(obj); };
78 return BreadthFirstOrderIterate<InterableCallable>(i, lf, is);
79 }
80
81 } // namespace Internal
82 META_END_NAMESPACE()
83
84 #endif
85