proxygen
Foreach.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <folly/Portability.h>
20 #include <folly/Preprocessor.h>
21 
22 #include <type_traits>
23 
24 namespace folly {
25 
85 template <typename Range, typename Func>
87 
93 namespace for_each_detail {
94 enum class LoopControl : bool { BREAK, CONTINUE };
95 } // namespace for_each_detail
96 
99 
121 template <typename Sequence, typename Index>
122 FOLLY_CPP14_CONSTEXPR decltype(auto) fetch(Sequence&& sequence, Index&& index);
123 
124 } // namespace folly
125 
130 /*
131  * Form a local variable name from "FOR_EACH_" x __LINE__, so that
132  * FOR_EACH can be nested without creating shadowed declarations.
133  */
134 #define _FE_ANON(x) FB_CONCATENATE(FOR_EACH_, FB_CONCATENATE(x, __LINE__))
135 
136 /*
137  * If you just want the element values, please use:
138  *
139  * for (auto&& element : collection)
140  *
141  * If you need access to the iterators please write an explicit iterator loop
142  */
143 #define FOR_EACH(i, c) \
144  if (bool _FE_ANON(s1_) = false) { \
145  } else \
146  for (auto&& _FE_ANON(s2_) = (c); !_FE_ANON(s1_); _FE_ANON(s1_) = true) \
147  for (auto i = _FE_ANON(s2_).begin(); i != _FE_ANON(s2_).end(); ++i)
148 
149 /*
150  * If you just want the element values, please use this (ranges-v3) construct:
151  *
152  * for (auto&& element : collection | view::reverse)
153  *
154  * If you need access to the iterators please write an explicit iterator loop
155  */
156 #define FOR_EACH_R(i, c) \
157  if (bool _FE_ANON(s1_) = false) { \
158  } else \
159  for (auto&& _FE_ANON(s2_) = (c); !_FE_ANON(s1_); _FE_ANON(s1_) = true) \
160  for (auto i = _FE_ANON(s2_).rbegin(); i != _FE_ANON(s2_).rend(); ++i)
161 
162 /*
163  * If you just want the element values, please use this construct:
164  *
165  * for (auto&& element : folly::enumerate(collection))
166  *
167  * If you need access to the iterators please write an explicit iterator loop
168  * and use a counter variable
169  */
170 #define FOR_EACH_ENUMERATE(count, i, c) \
171  if (bool _FE_ANON(s1_) = false) { \
172  } else \
173  for (auto&& FOR_EACH_state2 = (c); !_FE_ANON(s1_); _FE_ANON(s1_) = true) \
174  if (size_t _FE_ANON(n1_) = 0) { \
175  } else if (const size_t& count = _FE_ANON(n1_)) { \
176  } else \
177  for (auto i = FOR_EACH_state2.begin(); i != FOR_EACH_state2.end(); \
178  ++_FE_ANON(n1_), ++i)
179 
197 #define FOR_EACH_KV(k, v, c) \
198  if (unsigned int _FE_ANON(s1_) = 0) { \
199  } else \
200  for (auto&& _FE_ANON(s2_) = (c); !_FE_ANON(s1_); _FE_ANON(s1_) = 1) \
201  for (auto _FE_ANON(s3_) = _FE_ANON(s2_).begin(); \
202  _FE_ANON(s3_) != _FE_ANON(s2_).end(); \
203  _FE_ANON(s1_) == 2 ? ((_FE_ANON(s1_) = 0), ++_FE_ANON(s3_)) \
204  : (_FE_ANON(s3_) = _FE_ANON(s2_).end())) \
205  for (auto& k = _FE_ANON(s3_)->first; !_FE_ANON(s1_); ++_FE_ANON(s1_)) \
206  for (auto& v = _FE_ANON(s3_)->second; !_FE_ANON(s1_); ++_FE_ANON(s1_))
207 
208 namespace folly {
209 namespace detail {
210 
211 // Boost 1.48 lacks has_less, we emulate a subset of it here.
212 template <typename T, typename U>
213 class HasLess {
214  struct BiggerThanChar {
215  char unused[2];
216  };
217  template <typename C, typename D>
218  static char test(decltype(C() < D())*);
219  template <typename, typename>
220  static BiggerThanChar test(...);
221 
222  public:
223  enum { value = sizeof(test<T, U>(nullptr)) == 1 };
224 };
225 
246 #if 0
247 
248 template <class T, class U>
250 notThereYet(T& iter, const U& end) {
251  return iter < end;
252 }
253 
254 template <class T, class U>
256 notThereYet(T& iter, const U& end) {
257  return iter != end;
258 }
259 
260 #else
261 
262 template <class T, class U>
263 typename std::enable_if<
266  bool>::type
267 notThereYet(T& iter, const U& end) {
268  return iter < end;
269 }
270 
271 template <class T, class U>
272 typename std::enable_if<
275  bool>::type
276 notThereYet(T& iter, const U& end) {
277  return iter != end;
278 }
279 
280 #endif
281 
286 template <class T, class U>
288  T& iter,
289  const U& begin) {
290  return begin < iter--;
291 }
292 
293 template <class T, class U>
295  T& iter,
296  const U& begin) {
297  if (iter == begin) {
298  return false;
299  }
300  --iter;
301  return true;
302 }
303 
304 } // namespace detail
305 } // namespace folly
306 
307 /*
308  * Look at the Ranges-v3 views and you'll probably find an easier way to build
309  * the view you want but the equivalent is roughly:
310  *
311  * for (auto& element : make_iterator_range(begin, end))
312  */
313 #define FOR_EACH_RANGE(i, begin, end) \
314  for (auto i = (true ? (begin) : (end)); \
315  ::folly::detail::notThereYet(i, (end)); \
316  ++i)
317 
318 /*
319  * Look at the Ranges-v3 views and you'll probably find an easier way to build
320  * the view you want but the equivalent is roughly:
321  *
322  * for (auto& element : make_iterator_range(begin, end) | view::reverse)
323  */
324 #define FOR_EACH_RANGE_R(i, begin, end) \
325  for (auto i = (false ? (begin) : (end)); ::folly::detail::downTo(i, (begin));)
326 
constexpr auto loop_continue
Definition: Foreach.h:98
PskType type
#define FOLLY_CPP14_CONSTEXPR
Definition: Portability.h:424
static uint64_t test(std::string name, bool fc_, bool dedicated_, bool tc_, bool syncops_, uint64_t base)
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
Function< void()> Func
Definition: Executor.h:27
#define D(name, bit)
Definition: CpuId.h:145
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
#define C(name, bit)
Definition: CpuId.h:204
static const char *const value
Definition: Conv.cpp:50
std::enable_if< !((std::is_arithmetic< T >::value &&std::is_arithmetic< U >::value)||(std::is_pointer< T >::value &&std::is_pointer< U >::value)), bool >::type notThereYet(T &iter, const U &end)
Definition: Foreach.h:276
std::enable_if<!HasLess< U, T >::value, bool >::type downTo(T &iter, const U &begin)
Definition: Foreach.h:294
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
decltype(auto) FOLLY_CPP14_CONSTEXPR fetch(Sequence &&sequence, Index &&index)
Definition: Foreach-inl.h:322
constexpr auto loop_break
Definition: Foreach.h:97
FOLLY_CPP14_CONSTEXPR Func for_each(Sequence &&sequence, Func func)
Definition: Foreach-inl.h:314