Boost logo

Boost :

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




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk