
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