X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FForeach.h;h=84663ef363604da9fb23f059ed4c0565abe3cb0d;hb=d2c8a36b6b96eea44e9e92fa6946d607f8530b07;hp=f5fed8bd3fa9202407729adb91e29da91906ed68;hpb=fe41434ed66e679162423eb608df857d844013b8;p=folly.git diff --git a/folly/Foreach.h b/folly/Foreach.h index f5fed8bd..84663ef3 100644 --- a/folly/Foreach.h +++ b/folly/Foreach.h @@ -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 @@ -30,13 +29,13 @@ * 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 @@ -47,20 +46,26 @@ * generates code 100% identical to the handwritten loop. */ -#include #include +#include + +/* + * 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