$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] nested BOOST_FOREACH and -Wshadow
From: Dustin Spicuzza (dustin_at_[hidden])
Date: 2009-02-09 15:29:21
David Abrahams wrote:
> on Sat Feb 07 2009, Sebastian Redl <sebastian.redl-AT-getdesigned.at> wrote:
> 
> F> John Bytheway wrote:
>>> I'd suggest a simpler (from the user perspective) solution would be to
>>> have BOOST_FOREACH paste __LINE__ into its variable names.  Then the
>>> problem would only occur if nested BOOST_FOREACHs were used on the same
>>> line.  Asking users not to do that seems a lot more reasonable than
>>> asking them not to use -Wshadow or not to use nested BOOST_FOREACHs at all.
>>>   
>> I'm pretty sure you'd need a special variant for MS compilers, since
>> their __LINE__ expansion is not cleanly pasteable. (You can use their
>> counting macro instead.)
> 
> Doesn't using BOOST_PP_CAT work?
> 
Ok, so attached is a simple patch to BOOST_FOREACH (v1.37) using the
__LINE__ mechanism suggested. It works for gcc 4.3, but I don't have
access to other compilers at the moment -- and even if I did, I'm not
quite sure of the best way to mix the __LINE__ and __COUNTER__
implementations correctly.
Dustin
-- Innovation is just a problem away
--- foreach-original.hpp	2009-01-23 13:19:15.000000000 -0500
+++ foreach.hpp	2009-02-09 15:18:22.000000000 -0500
@@ -976,58 +976,58 @@
 
 #define BOOST_FOREACH_BEGIN(COL)                                                                \
     boost::foreach_detail_::begin(                                                              \
-        _foreach_col                                                                            \
+        BOOST_PP_CAT(_foreach_col, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL)                                                               \
       , BOOST_FOREACH_SHOULD_COPY(COL))
 
 #define BOOST_FOREACH_END(COL)                                                                  \
     boost::foreach_detail_::end(                                                                \
-        _foreach_col                                                                            \
+        BOOST_PP_CAT(_foreach_col, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL)                                                               \
       , BOOST_FOREACH_SHOULD_COPY(COL))
 
 #define BOOST_FOREACH_DONE(COL)                                                                 \
     boost::foreach_detail_::done(                                                               \
-        _foreach_cur                                                                            \
-      , _foreach_end                                                                            \
+        BOOST_PP_CAT(_foreach_cur, __LINE__)                                                    \
+      , BOOST_PP_CAT(_foreach_end, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL))
 
 #define BOOST_FOREACH_NEXT(COL)                                                                 \
     boost::foreach_detail_::next(                                                               \
-        _foreach_cur                                                                            \
+        BOOST_PP_CAT(_foreach_cur, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL))
 
 #define BOOST_FOREACH_DEREF(COL)                                                                \
     boost::foreach_detail_::deref(                                                              \
-        _foreach_cur                                                                            \
+        BOOST_PP_CAT(_foreach_cur, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL))
 
 #define BOOST_FOREACH_RBEGIN(COL)                                                               \
     boost::foreach_detail_::rbegin(                                                             \
-        _foreach_col                                                                            \
+        BOOST_PP_CAT(_foreach_col, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL)                                                               \
       , BOOST_FOREACH_SHOULD_COPY(COL))
 
 #define BOOST_FOREACH_REND(COL)                                                                 \
     boost::foreach_detail_::rend(                                                               \
-        _foreach_col                                                                            \
+        BOOST_PP_CAT(_foreach_col, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL)                                                               \
       , BOOST_FOREACH_SHOULD_COPY(COL))
 
 #define BOOST_FOREACH_RDONE(COL)                                                                \
     boost::foreach_detail_::rdone(                                                              \
-        _foreach_cur                                                                            \
-      , _foreach_end                                                                            \
+        BOOST_PP_CAT(_foreach_cur, __LINE__)                                                    \
+      , BOOST_PP_CAT(_foreach_end, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL))
 
 #define BOOST_FOREACH_RNEXT(COL)                                                                \
     boost::foreach_detail_::rnext(                                                              \
-        _foreach_cur                                                                            \
+        BOOST_PP_CAT(_foreach_cur, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL))
 
 #define BOOST_FOREACH_RDEREF(COL)                                                               \
     boost::foreach_detail_::rderef(                                                             \
-        _foreach_cur                                                                            \
+        BOOST_PP_CAT(_foreach_cur, __LINE__)                                                    \
       , BOOST_FOREACH_TYPEOF(COL))
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1058,14 +1058,20 @@
 //
 #define BOOST_FOREACH(VAR, COL)                                                                 \
     BOOST_FOREACH_PREAMBLE()                                                                    \
-    if (boost::foreach_detail_::auto_any_t _foreach_col = BOOST_FOREACH_CONTAIN(COL)) {} else   \
-    if (boost::foreach_detail_::auto_any_t _foreach_cur = BOOST_FOREACH_BEGIN(COL)) {} else     \
-    if (boost::foreach_detail_::auto_any_t _foreach_end = BOOST_FOREACH_END(COL)) {} else       \
-    for (bool _foreach_continue = true;                                                         \
-              _foreach_continue && !BOOST_FOREACH_DONE(COL);                                    \
-              _foreach_continue ? BOOST_FOREACH_NEXT(COL) : (void)0)                            \
-        if  (boost::foreach_detail_::set_false(_foreach_continue)) {} else                      \
-        for (VAR = BOOST_FOREACH_DEREF(COL); !_foreach_continue; _foreach_continue = true)
+    if (boost::foreach_detail_::auto_any_t                                                      \
+        BOOST_PP_CAT(_foreach_col , __LINE__ ) = BOOST_FOREACH_CONTAIN(COL)) {} else            \
+    if (boost::foreach_detail_::auto_any_t                                                      \
+        BOOST_PP_CAT(_foreach_cur , __LINE__ ) = BOOST_FOREACH_BEGIN(COL)) {} else              \
+    if (boost::foreach_detail_::auto_any_t                                                      \
+        BOOST_PP_CAT(_foreach_end , __LINE__ ) = BOOST_FOREACH_END(COL)) {} else                \
+    for (bool BOOST_PP_CAT(_foreach_continue , __LINE__ ) = true;                               \
+              BOOST_PP_CAT(_foreach_continue , __LINE__ ) && !BOOST_FOREACH_DONE(COL);          \
+              BOOST_PP_CAT(_foreach_continue , __LINE__ ) ? BOOST_FOREACH_NEXT(COL) : (void)0)  \
+        if  (boost::foreach_detail_::set_false(BOOST_PP_CAT(_foreach_continue , __LINE__ ))) {} \
+        else                                                                                    \
+        for (VAR = BOOST_FOREACH_DEREF(COL);                                                    \
+                  !BOOST_PP_CAT(_foreach_continue , __LINE__ );                                 \
+                   BOOST_PP_CAT(_foreach_continue , __LINE__ ) = true)
 
 ///////////////////////////////////////////////////////////////////////////////
 // BOOST_REVERSE_FOREACH
@@ -1076,13 +1082,19 @@
 //
 #define BOOST_REVERSE_FOREACH(VAR, COL)                                                         \
     BOOST_FOREACH_PREAMBLE()                                                                    \
-    if (boost::foreach_detail_::auto_any_t _foreach_col = BOOST_FOREACH_CONTAIN(COL)) {} else   \
-    if (boost::foreach_detail_::auto_any_t _foreach_cur = BOOST_FOREACH_RBEGIN(COL)) {} else    \
-    if (boost::foreach_detail_::auto_any_t _foreach_end = BOOST_FOREACH_REND(COL)) {} else      \
-    for (bool _foreach_continue = true;                                                         \
-              _foreach_continue && !BOOST_FOREACH_RDONE(COL);                                   \
-              _foreach_continue ? BOOST_FOREACH_RNEXT(COL) : (void)0)                           \
-        if  (boost::foreach_detail_::set_false(_foreach_continue)) {} else                      \
-        for (VAR = BOOST_FOREACH_RDEREF(COL); !_foreach_continue; _foreach_continue = true)
+    if (boost::foreach_detail_::auto_any_t                                                      \
+        BOOST_PP_CAT(_foreach_col , __LINE__ ) = BOOST_FOREACH_CONTAIN(COL)) {} else            \
+    if (boost::foreach_detail_::auto_any_t                                                      \
+        BOOST_PP_CAT(_foreach_cur , __LINE__ ) = BOOST_FOREACH_RBEGIN(COL)) {} else             \
+    if (boost::foreach_detail_::auto_any_t                                                      \
+        BOOST_PP_CAT(_foreach_end , __LINE__ ) = BOOST_FOREACH_REND(COL)) {} else               \
+    for (bool BOOST_PP_CAT(_foreach_continue , __LINE__ ) = true;                               \
+              BOOST_PP_CAT(_foreach_continue , __LINE__ ) && !BOOST_FOREACH_RDONE(COL);         \
+              BOOST_PP_CAT(_foreach_continue , __LINE__ ) ? BOOST_FOREACH_RNEXT(COL) : (void)0) \
+        if  (boost::foreach_detail_::set_false(BOOST_PP_CAT(_foreach_continue , __LINE__ ))) {} \
+        else                                                                                    \
+        for (VAR = BOOST_FOREACH_RDEREF(COL);                                                   \
+                  !BOOST_PP_CAT(_foreach_continue , __LINE__ );                                 \
+                   BOOST_PP_CAT(_foreach_continue , __LINE__ ) = true)
 
 #endif