X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FForeach.h;h=5cc075c7e6aeeeeeb4a476a091da42bfa72e734a;hb=9783dc4e7cfa938f1c33666ec0a31c204dff60ed;hp=d362c0bab2b3378bddb0637c11287c8a007838ca;hpb=dee8a5180aa542d98d1b71c74f83a006e4627952;p=folly.git diff --git a/folly/Foreach.h b/folly/Foreach.h index d362c0ba..5cc075c7 100644 --- a/folly/Foreach.h +++ b/folly/Foreach.h @@ -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. @@ -29,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,29 +47,36 @@ */ #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 * 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 @@ -81,13 +88,13 @@ * } */ #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 @@ -97,19 +104,19 @@ * 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 {