Re-work the OpenSSL portability header to be a portability header
[folly.git] / folly / Foreach.h
index c6e45835bf471f9ab1bd3958e9d6db15720cc784..5cc075c7e6aeeeeeb4a476a091da42bfa72e734a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef FOLLY_BASE_FOREACH_H_
-#define FOLLY_BASE_FOREACH_H_
+#pragma once
 
 /*
  * Iterim macros (until we have C++0x range-based for) that simplify
  * and everything is taken care of.
  *
  * The implementation is a bit convoluted to make sure the container is
- * only evaluated once (however, keep in mind that c.end() is evaluated
+ * evaluated only once (however, keep in mind that c.end() is evaluated
  * at every pass through the loop). To ensure the container is not
  * evaluated multiple times, the macro defines one do-nothing if
  * statement to inject the Boolean variable FOR_EACH_state1, and then a
  * for statement that is executed only once, which defines the variable
- * FOR_EACH_state2 holding a rvalue reference to the container being
- * iterated. The workhorse is the last loop, which uses the just defined
+ * FOR_EACH_state2 holding an rvalue reference to the container being
+ * iterated. The workhorse is the last loop, which uses the just-defined
  * rvalue reference FOR_EACH_state2.
  *
  * The state variables are nested so they don't interfere; you can use
  */
 
 #include <type_traits>
+#include <folly/Preprocessor.h>
+
+/*
+ * Form a local variable name from "FOR_EACH_" x __LINE__, so that
+ * FOR_EACH can be nested without creating shadowed declarations.
+ */
+#define _FE_ANON(x) FB_CONCATENATE(FOR_EACH_, FB_CONCATENATE(x, __LINE__))
 
 /*
  * Shorthand for:
  *   for (auto i = c.begin(); i != c.end(); ++i)
- * except that c is only evaluated once.
+ * except that c is evaluated only once.
  */
-#define FOR_EACH(i, c)                              \
-  if (bool FOR_EACH_state1 = false) {} else         \
-    for (auto && FOR_EACH_state2 = (c);             \
-         !FOR_EACH_state1; FOR_EACH_state1 = true)  \
-      for (auto i = FOR_EACH_state2.begin();        \
-           i != FOR_EACH_state2.end(); ++i)
+#define FOR_EACH(i, c)                                  \
+  if (bool _FE_ANON(s1_) = false) {} else               \
+    for (auto && _FE_ANON(s2_) = (c);                   \
+         !_FE_ANON(s1_); _FE_ANON(s1_) = true)          \
+      for (auto i = _FE_ANON(s2_).begin();              \
+           i != _FE_ANON(s2_).end(); ++i)
 
 /*
  * Similar to FOR_EACH, but iterates the container backwards by
  * using rbegin() and rend().
  */
 #define FOR_EACH_R(i, c)                                \
-  if (bool FOR_EACH_R_state1 = false) {} else           \
-    for (auto && FOR_EACH_R_state2 = (c);               \
-         !FOR_EACH_R_state1; FOR_EACH_R_state1 = true)  \
-      for (auto i = FOR_EACH_R_state2.rbegin();         \
-           i != FOR_EACH_R_state2.rend(); ++i)
+  if (bool _FE_ANON(s1_) = false) {} else               \
+    for (auto && _FE_ANON(s2_) = (c);                   \
+         !_FE_ANON(s1_); _FE_ANON(s1_) = true)          \
+      for (auto i = _FE_ANON(s2_).rbegin();             \
+           i != _FE_ANON(s2_).rend(); ++i)
 
 /*
  * Similar to FOR_EACH but also allows client to specify a 'count' variable
  * }
  */
 #define FOR_EACH_ENUMERATE(count, i, c)                                \
-  if (bool FOR_EACH_state1 = false) {} else                            \
+  if (bool _FE_ANON(s1_) = false) {} else                            \
     for (auto && FOR_EACH_state2 = (c);                                \
-         !FOR_EACH_state1; FOR_EACH_state1 = true)                     \
-      if (size_t FOR_EACH_privateCount = 0) {} else                    \
-        if (const size_t& count = FOR_EACH_privateCount) {} else       \
+         !_FE_ANON(s1_); _FE_ANON(s1_) = true)                     \
+      if (size_t _FE_ANON(n1_) = 0) {} else                            \
+        if (const size_t& count = _FE_ANON(n1_)) {} else               \
           for (auto i = FOR_EACH_state2.begin();                       \
-               i != FOR_EACH_state2.end(); ++FOR_EACH_privateCount, ++i)
+               i != FOR_EACH_state2.end(); ++_FE_ANON(n1_), ++i)
 
 /**
  * Similar to FOR_EACH, but gives the user the key and value for each entry in
  *      cout << key << " " << value;
  *   }
  */
-#define FOR_EACH_KV(k, v, c)                                    \
-  if (unsigned int FOR_EACH_state1 = 0) {} else                 \
-    for (auto && FOR_EACH_state2 = (c);                         \
-         !FOR_EACH_state1; FOR_EACH_state1 = 1)                 \
-      for (auto FOR_EACH_state3 = FOR_EACH_state2.begin();      \
-           FOR_EACH_state3 != FOR_EACH_state2.end();            \
-           FOR_EACH_state1 == 2                                 \
-             ? ((FOR_EACH_state1 = 0), ++FOR_EACH_state3)       \
-             : (FOR_EACH_state3 = FOR_EACH_state2.end()))       \
-        for (auto &k = FOR_EACH_state3->first;                  \
-             !FOR_EACH_state1; ++FOR_EACH_state1)               \
-          for (auto &v = FOR_EACH_state3->second;               \
-               !FOR_EACH_state1; ++FOR_EACH_state1)
+#define FOR_EACH_KV(k, v, c)                                  \
+  if (unsigned int _FE_ANON(s1_) = 0) {} else                 \
+    for (auto && _FE_ANON(s2_) = (c);                         \
+         !_FE_ANON(s1_); _FE_ANON(s1_) = 1)                   \
+      for (auto _FE_ANON(s3_) = _FE_ANON(s2_).begin();        \
+           _FE_ANON(s3_) != _FE_ANON(s2_).end();              \
+           _FE_ANON(s1_) == 2                                 \
+             ? ((_FE_ANON(s1_) = 0), ++_FE_ANON(s3_))         \
+             : (_FE_ANON(s3_) = _FE_ANON(s2_).end()))         \
+        for (auto &k = _FE_ANON(s3_)->first;                  \
+             !_FE_ANON(s1_); ++_FE_ANON(s1_))                 \
+          for (auto &v = _FE_ANON(s3_)->second;               \
+               !_FE_ANON(s1_); ++_FE_ANON(s1_))
 
 namespace folly { namespace detail {
 
@@ -227,5 +233,3 @@ downTo(T& iter, const U& begin) {
  */
 #define FOR_EACH_RANGE_R(i, begin, end) \
   for (auto i = (false ? (begin) : (end)); ::folly::detail::downTo(i, (begin));)
-
-#endif