mCRL2
Loading...
Searching...
No Matches
algorithm_impl.h
Go to the documentation of this file.
1// Author(s): Wieger Wesselink
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
11
12#ifndef MCRL2_ATERMPP_DETAIL_ALGORITHM_IMPL_H
13#define MCRL2_ATERMPP_DETAIL_ALGORITHM_IMPL_H
14
16
17namespace atermpp
18{
19
20namespace detail
21{
26template <typename Function>
27aterm appl_apply(const aterm& a, const Function f)
28{
29 return aterm(a.function(), a.begin(), a.end(), f);
30}
31
32//--- find ----------------------------------------------------------------//
33
34// we need to use our own traits classes to extract the value type from insert iterators
35template <class Iterator>
37{
38 typedef typename std::iterator_traits<Iterator>::value_type type;
39};
40
41template <class Container>
42struct iterator_value<std::insert_iterator<Container> >
43{
44 typedef typename Container::value_type type;
45};
46
47template <class Container>
48struct iterator_value<std::back_insert_iterator<Container> >
49{
50 typedef typename Container::value_type type;
51};
52
53template <class Container>
54struct iterator_value<std::front_insert_iterator<Container> >
55{
56 typedef typename Container::value_type type;
57};
58
60// used to abort the recursive find
62{
64
66 : t(t_)
67 {}
68};
69
74template <typename UnaryFunction>
75UnaryFunction for_each_impl(aterm t, UnaryFunction op)
76{
77 if (t.type_is_list())
78 {
79 const aterm_list& l = down_cast<aterm_list>(t);
80 for (const aterm& x: l)
81 {
82 for_each_impl(x, op);
83 }
84 }
85 else if (t.type_is_appl())
86 {
87 if (op(t))
88 {
89 for (const aterm& x: t)
90 {
91 for_each_impl(x, op);
92 }
93 }
94 }
95 return op;
96}
97
104template <typename MatchPredicate>
105bool find_if_impl(const aterm& t, MatchPredicate match, aterm& output)
106{
107 if (t.type_is_appl())
108 {
109 if (match(t))
110 {
111 output = t;
112 return true;
113 }
114 for (const aterm& x: t)
115 {
116 if (find_if_impl(x, match, output))
117 return true;
118 }
119 }
120 else if (t.type_is_list())
121 {
122 const aterm_list& l = down_cast<aterm_list>(t);
123 for (const aterm& x: l)
124 {
125 if (find_if_impl(x, match, output))
126 {
127 return true;
128 }
129 }
130 }
131 return false;
132}
133
138template <typename MatchPredicate, typename OutputIterator>
139void find_all_if_impl(const aterm& t, MatchPredicate op, OutputIterator& destBegin)
140{
141 typedef typename iterator_value<OutputIterator>::type value_type;
142
143 if (t.type_is_list())
144 {
145 const aterm_list& l = down_cast<aterm_list>(t);
146 for (const aterm& x: l)
147 {
148 find_all_if_impl<MatchPredicate>(x, op, destBegin);
149 }
150 }
151 else if (t.type_is_appl())
152 {
153 if (op(t))
154 {
155 *destBegin++ = vertical_cast<value_type>(t);
156 }
157 for (const aterm& x: t)
158 {
159 find_all_if_impl<MatchPredicate>(x, op, destBegin);
160 }
161 }
162 else
163 {
164 return;
165 }
166}
167
168//--- partial find --------------------------------------------------------//
169
174template <typename MatchPredicate, typename StopPredicate>
175aterm partial_find_if_impl(const aterm& t, MatchPredicate match, StopPredicate stop)
176{
177 if (t.type_is_appl())
178 {
179 if (match(t))
180 {
181 return t; // report the match
182 }
183 if (stop(t))
184 {
185 return aterm(); // nothing was found
186 }
187 for (const aterm& x: t)
188 {
189 aterm result = partial_find_if_impl<MatchPredicate, StopPredicate>(x, match, stop);
190 if (result != aterm())
191 {
192 return result;
193 }
194 }
195 }
196
197 if (t.type_is_list())
198 {
199 const aterm_list& l = down_cast<aterm_list>(t);
200 for (const aterm& x: l)
201 {
202 aterm result = partial_find_if_impl<MatchPredicate, StopPredicate>(x, match, stop);
203 if (result != aterm())
204 {
205 return result;
206 }
207 }
208 }
209 return aterm();
210}
211
217template <typename MatchPredicate, typename StopPredicate, typename OutputIterator>
218void partial_find_all_if_impl(const aterm& t, MatchPredicate match, StopPredicate stop, OutputIterator& destBegin)
219{
220 if (t.type_is_appl())
221 {
222 if (match(t))
223 {
224 *destBegin++ = t;
225 }
226 if (stop(t))
227 {
228 return;
229 }
230 for (const aterm& x: t)
231 {
232 partial_find_all_if_impl<MatchPredicate, StopPredicate>(x, match, stop, destBegin);
233 }
234 }
235
236 if (t.type_is_list())
237 {
238 const aterm_list& l = down_cast<aterm_list>(t);
239 for (const aterm& x: l)
240 {
241 partial_find_all_if_impl<MatchPredicate, StopPredicate>(x, match, stop, destBegin);
242 }
243 }
244}
245
246} // namespace detail
247
248} // namespace atermpp
249
250#endif // MCRL2_ATERMPP_DETAIL_ALGORITHM_IMPL_H
const_iterator end() const
Returns a const_iterator pointing past the last argument.
Definition aterm.h:172
const_iterator begin() const
Returns an iterator pointing to the first argument.
Definition aterm.h:165
const function_symbol & function() const
Returns the function symbol belonging to an aterm.
Definition aterm.h:144
A list of aterm objects.
Definition aterm_list.h:24
bool type_is_list() const noexcept
Dynamic check whether the term is an aterm_list.
Definition aterm_core.h:72
bool type_is_appl() const noexcept
Dynamic check whether the term is an aterm.
Definition aterm_core.h:55
void partial_find_all_if_impl(const aterm &t, MatchPredicate match, StopPredicate stop, OutputIterator &destBegin)
Implements the partial_find_all_if algorithm.
bool find_if_impl(const aterm &t, MatchPredicate match, aterm &output)
Implements the find_if algorithm If the term t is found, it is stored in output and true is returned.
void find_all_if_impl(const aterm &t, MatchPredicate op, OutputIterator &destBegin)
Implements the find_all_if algorithm.
aterm appl_apply(const aterm &a, const Function f)
Applies the function f to all children of a.
UnaryFunction for_each_impl(aterm t, UnaryFunction op)
Implements the for_each algorithm.
aterm partial_find_if_impl(const aterm &t, MatchPredicate match, StopPredicate stop)
Implements the partial_find_if_impl algorithm.
The main namespace for the aterm++ library.
Definition algorithm.h:21
STL namespace.
std::iterator_traits< Iterator >::value_type type