Lumiera  0.pre.03
»edit your freedom«
util-foreach.hpp
Go to the documentation of this file.
1 /*
2  UTIL-FOREACH.hpp - helpers for doing something for each element
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
51 #ifndef UTIL_FOREACH_H
52 #define UTIL_FOREACH_H
53 
54 #include "lib/util.hpp"
55 #include "lib/meta/trait.hpp"
56 
57 #include <functional>
58 #include <algorithm>
59 
60 
61 
62 namespace util {
63 
65  using lib::meta::disable_if;
66 
69 
70 
71 
76  template <typename IT, typename FUN>
77  inline bool
78  and_all (IT i, IT end, FUN predicate)
79  {
80  for ( ; i!=end; ++i )
81  if (!predicate(*i))
82  return false;
83 
84  return true;
85  }
86 
87 
92  template <typename IT, typename FUN>
93  inline bool
94  has_any (IT i, IT end, FUN predicate)
95  {
96  for ( ; i!=end; ++i )
97  if (predicate(*i))
98  return true;
99 
100  return false;
101  }
102 
103 
104  /* === specialisations for STL containers and Lumiera Forward Iterators === */
105 
117  template <typename Container
118  ,typename FUN
119  >
120  inline disable_if< can_IterForEach<Container>,
121  FUN >
122  for_each (Container const& coll, FUN doIt)
123  {
124  using lib::meta::unwrap;
125 
126  return std::for_each (unwrap(coll).begin()
127  ,unwrap(coll).end()
128  , doIt);
129  }
130 
131 
133  template <typename IT
134  ,typename FUN
135  >
136  inline enable_if< can_IterForEach<IT>,
137  FUN >
138  for_each (IT const& ii, FUN doIt)
139  {
140  return std::for_each (ii, IT(), doIt);
141  }
142 
143 
144 
145 
146  template <typename Container
147  ,typename FUN
148  >
149  inline enable_if< can_STL_ForEach<Container>,
150  bool >
151  and_all (Container const& coll, FUN predicate)
152  {
153  using lib::meta::unwrap;
154 
155  return and_all (unwrap(coll).begin()
156  ,unwrap(coll).end()
157  , predicate);
158  }
159 
160 
161  template <typename IT
162  ,typename FUN
163  >
164  inline enable_if< can_IterForEach<IT>,
165  bool >
166  and_all (IT const& ii, FUN predicate)
167  {
168  return and_all (ii, IT(), predicate);
169  }
170 
171 
172 
173  template <typename Container
174  ,typename FUN
175  >
176  inline enable_if< can_STL_ForEach<Container>,
177  bool >
178  has_any (Container const& coll, FUN predicate)
179  {
180  using lib::meta::unwrap;
181 
182  return has_any (unwrap(coll).begin()
183  ,unwrap(coll).end()
184  , predicate);
185  }
186 
187 
188  template <typename IT
189  ,typename FUN
190  >
191  inline enable_if< can_IterForEach<IT>,
192  bool >
193  has_any (IT const& ii, FUN predicate)
194  {
195  return has_any (ii, IT(), predicate);
196  }
197 
198 
199 
200 
201  /* === allow creating argument binders on-the-fly === */
202 
203 
206  template <typename CON, typename FUN, typename P1, typename...ARGS>
207  inline void
208  for_each (CON const& elements, FUN function, P1&& bind1, ARGS&& ...args)
209  {
210  for_each (elements, std::bind (function, std::forward<P1>(bind1), std::forward<ARGS> (args)...));
211  }
212 
213 
214 
215 
216 
219  template <typename CON, typename FUN, typename P1, typename...ARGS>
220  inline bool
221  and_all (CON const& elements, FUN function, P1&& bind1, ARGS&& ...args)
222  {
223  return and_all (elements, std::bind<bool> (function, std::forward<P1>(bind1), std::forward<ARGS> (args)...));
224  }
225 
226 
227 
228 
229 
232  template <typename CON, typename FUN, typename P1, typename...ARGS>
233  inline bool
234  has_any (CON const& elements, FUN function, P1&& bind1, ARGS&& ...args)
235  {
236  return has_any (elements, std::bind<bool> (function, std::forward<P1>(bind1), std::forward<ARGS> (args)...));
237  }
238 
239 
240 
241 } // namespace util
242 #endif /*UTIL_FOREACH_H*/
IterQueue< T > elements(T const &elm)
convenience free function to build an iterable sequence
Definition: iter-stack.hpp:301
Trait template to detect a type usable with the STL for-each loop.
Definition: trait.hpp:550
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:92
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Trait template to detect a type usable immediately as "Lumiera Forward Iterator" in a specialised for...
Definition: trait.hpp:505
disable_if< can_IterForEach< Container >, FUN > for_each(Container const &coll, FUN doIt)
operate on all elements of a STL container.
Helpers for type detection, type rewriting and metaprogramming.
bool has_any(IT i, IT end, FUN predicate)
Existential quantification: check if any element of a collection satisfies the given predicate...
bool and_all(IT i, IT end, FUN predicate)
All quantification: check if all elements of a collection satisfy the given predicate.