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_ITERATION_H
17 #define META_API_ITERATION_H
18 
19 #include <meta/api/internal/iteration.h>
20 #include <meta/interface/intf_lockable.h>
21 
22 META_BEGIN_NAMESPACE()
23 
24 /// Create suitable callable for iteration from lambda (or alike)
25 using Internal::MakeIterationCallable;
26 
27 /// Create suitable const callable for iteration from lambda (or alike)
28 using Internal::MakeIterationConstCallable;
29 
30 /**
31  * @brief Iterate over sequence of elements (e.g. container) and call function for each element.
32  *        Takes unique lock over the sequence of elements if it is ILockable
33  * @param c Sequence of elements, must implement IIterable
34  * @param func Function that is called for each element, can mutate the element value
35  * @param traversal Control how to iterate over elements
36  * @return True if the iteration did not fail
37  */
38 template<typename Iterable, typename Func>
39 bool ForEachUnique(
40     const BASE_NS::shared_ptr<Iterable>& c, Func&& func, TraversalType traversal = TraversalType::NO_HIERARCHY)
41 {
42     return Internal::Iterate(
43         c,
44         [f = BASE_NS::forward<Func>(func)](Internal::IterationArgType<Func>& arg) {
45             f(arg);
46             return true;
47         },
48         IterateStrategy { traversal, LockType::UNIQUE_LOCK });
49 }
50 
51 /**
52  * @brief Iterate over sequence of elements (e.g. container) and call function for each element.
53  *        Takes shared lock over the sequence of elements if it is IReadWriteLockable
54  * @param c Sequence of elements, must implement IIterable
55  * @param func Function that is called for each element, cannot mutate the element value
56  * @param traversal Control how to iterate over elements
57  * @return True if the iteration did not fail
58  */
59 template<typename Iterable, typename Func>
60 bool ForEachShared(
61     const BASE_NS::shared_ptr<Iterable>& c, Func&& func, TraversalType traversal = TraversalType::NO_HIERARCHY)
62 {
63     return Internal::ConstIterate(
64         c,
65         [f = BASE_NS::forward<Func>(func)](const Internal::IterationArgType<Func>& arg) {
66             f(arg);
67             return true;
68         },
69         IterateStrategy { traversal, LockType::SHARED_LOCK });
70 }
71 
72 /**
73  * @brief Iterate over sequence of elements (e.g. container) and call function for each element
74  *        as long as the function returns true. If it returns false, stop iteration.
75  *        Takes unique lock over the sequence of elements if it is ILockable
76  * @param c Sequence of elements, must implement IIterable
77  * @param func Function that is called for each element, can mutate the element value
78  * @param traversal Control how to iterate over elements
79  * @return True if the iteration was stopped (this usually indicates the user function returned false)
80  */
81 template<typename Iterable, typename Func>
82 bool IterateUnique(
83     const BASE_NS::shared_ptr<Iterable>& c, Func&& func, TraversalType traversal = TraversalType::NO_HIERARCHY)
84 {
85     return Internal::Iterate(c, BASE_NS::forward<Func>(func), IterateStrategy { traversal, LockType::UNIQUE_LOCK })
86                .value == IterationResult::STOP;
87 }
88 
89 /**
90  * @brief Iterate over sequence of elements (e.g. container) and call function for each element
91  *        as long as the function returns true. If it returns false, stop iteration.
92  *        Takes shared lock over the sequence of elements if it is IReadWriteLockable
93  * @param c Sequence of elements, must implement IIterable
94  * @param func Function that is called for each element, cannot mutate the element value
95  * @param traversal Control how to iterate over elements
96  * @return True if the iteration was stopped (this usually indicates the user function returned false)
97  */
98 template<typename Iterable, typename Func>
99 bool IterateShared(
100     const BASE_NS::shared_ptr<Iterable>& c, Func&& func, TraversalType traversal = TraversalType::NO_HIERARCHY)
101 {
102     return Internal::ConstIterate(c, BASE_NS::forward<Func>(func), IterateStrategy { traversal, LockType::SHARED_LOCK })
103                .value == IterationResult::STOP;
104 }
105 
106 /**
107  * @brief Iterate over sequence of elements (e.g. container) and call function for each element
108  *        as long as the function returns true. If it returns false, stop iteration.
109  *        Takes unique lock over the sequence of elements if it is ILockable
110  * @param c Sequence of elements, must implement IIterable
111  * @param func Function that is called for each element, can mutate the element value
112  * @param is Strategy how to iterate over elements
113  * @return True if the iteration was stopped (this usually indicates the user function returned false)
114  */
115 template<typename Iterable, typename Func>
Iterate(const BASE_NS::shared_ptr<Iterable> & c,Func && func,IterateStrategy is)116 bool Iterate(const BASE_NS::shared_ptr<Iterable>& c, Func&& func, IterateStrategy is)
117 {
118     return Internal::Iterate(c, BASE_NS::forward<Func>(func), is).value == IterationResult::STOP;
119 }
120 
121 /**
122  * @brief Iterate over sequence of elements (e.g. container) and call function for each element
123  *        as long as the function returns true. If it returns false, stop iteration.
124  *        Takes shared lock over the sequence of elements if it is IReadWriteLockable
125  * @param c Sequence of elements, must implement IIterable
126  * @param func Function that is called for each element, cannot mutate the element value
127  * @param is Strategy how to iterate over elements
128  * @return True if the iteration was stopped (this usually indicates the user function returned false)
129  */
130 template<typename Iterable, typename Func>
ConstIterate(const BASE_NS::shared_ptr<Iterable> & c,Func && func,IterateStrategy is)131 bool ConstIterate(const BASE_NS::shared_ptr<Iterable>& c, Func&& func, IterateStrategy is)
132 {
133     return Internal::ConstIterate(c, BASE_NS::forward<Func>(func), is).value == IterationResult::STOP;
134 }
135 
136 META_END_NAMESPACE()
137 
138 #endif
139