Compile RangeSse42.cpp with -msse4.2
[folly.git] / folly / Foreach.h
index f5fed8bd3fa9202407729adb91e29da91906ed68..84663ef363604da9fb23f059ed4c0565abe3cb0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2016 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
  * generates code 100% identical to the handwritten loop.
  */
 
-#include <boost/type_traits/remove_cv.hpp>
 #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
@@ -228,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