1 // (C) Copyright Eric Niebler 2004-2005 2 // (C) Copyright Gennadiy Rozental 2005-2008. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 // See http://www.boost.org/libs/test for the library home page. 8 // 9 // File : $RCSfile$ 10 // 11 // Version : $Revision: 54633 $ 12 // 13 // Description : this is an abridged version of an excelent BOOST_FOREACH facility 14 // presented by Eric Niebler. I am so fond of it so I can't wait till it 15 // going to be accepted into Boost. Also I need version with less number of dependencies 16 // and more portable. This version doesn't support rvalues and will reeveluate it's 17 // parameters, but should be good enough for my purposes. 18 // *************************************************************************** 19 20 #ifndef BOOST_TEST_FOREACH_HPP_021005GER 21 #define BOOST_TEST_FOREACH_HPP_021005GER 22 23 // Boost.Test 24 #include <boost/test/detail/config.hpp> 25 26 // Boost 27 #include <boost/type.hpp> 28 #include <boost/mpl/bool.hpp> 29 #include <boost/test/detail/workaround.hpp> 30 31 #include <boost/type_traits/is_const.hpp> 32 33 #include <boost/test/detail/suppress_warnings.hpp> 34 35 //____________________________________________________________________________// 36 37 namespace boost { 38 39 namespace unit_test { 40 41 namespace for_each { 42 43 // ************************************************************************** // 44 // ************** static_any ************** // 45 // ************************************************************************** // 46 47 struct static_any_base 48 { 49 operator bool() const { return false; } 50 }; 51 52 //____________________________________________________________________________// 53 54 template<typename Iter> 55 struct static_any : static_any_base 56 { 57 static_any( Iter const& t ) : m_it( t ) {} 58 59 mutable Iter m_it; 60 }; 61 62 //____________________________________________________________________________// 63 64 typedef static_any_base const& static_any_t; 65 66 //____________________________________________________________________________// 67 68 template<typename Iter> 69 inline Iter& 70 static_any_cast( static_any_t a, Iter* = 0 ) 71 { 72 return static_cast<Iter&>( static_cast<static_any<Iter> const&>( a ).m_it ); 73 } 74 75 //____________________________________________________________________________// 76 77 // ************************************************************************** // 78 // ************** is_const ************** // 79 // ************************************************************************** // 80 81 template<typename C> 82 inline is_const<C> 83 is_const_coll( C& ) 84 { 85 return is_const<C>(); 86 } 87 88 //____________________________________________________________________________// 89 90 // ************************************************************************** // 91 // ************** begin ************** // 92 // ************************************************************************** // 93 94 template<typename C> 95 inline static_any<BOOST_DEDUCED_TYPENAME C::iterator> 96 begin( C& t, mpl::false_ ) 97 { 98 return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.begin() ); 99 } 100 101 //____________________________________________________________________________// 102 103 template<typename C> 104 inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator> 105 begin( C const& t, mpl::true_ ) 106 { 107 return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.begin() ); 108 } 109 110 //____________________________________________________________________________// 111 112 // ************************************************************************** // 113 // ************** end ************** // 114 // ************************************************************************** // 115 116 template<typename C> 117 inline static_any<BOOST_DEDUCED_TYPENAME C::iterator> 118 end( C& t, mpl::false_ ) 119 { 120 return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.end() ); 121 } 122 123 //____________________________________________________________________________// 124 125 template<typename C> 126 inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator> 127 end( C const& t, mpl::true_ ) 128 { 129 return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.end() ); 130 } 131 132 //____________________________________________________________________________// 133 134 // ************************************************************************** // 135 // ************** done ************** // 136 // ************************************************************************** // 137 138 template<typename C> 139 inline bool 140 done( static_any_t cur, static_any_t end, C&, mpl::false_ ) 141 { 142 return static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ) == 143 static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( end ); 144 } 145 146 //____________________________________________________________________________// 147 148 template<typename C> 149 inline bool 150 done( static_any_t cur, static_any_t end, C const&, mpl::true_ ) 151 { 152 return static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ) == 153 static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( end ); 154 } 155 156 //____________________________________________________________________________// 157 158 // ************************************************************************** // 159 // ************** next ************** // 160 // ************************************************************************** // 161 162 template<typename C> 163 inline void 164 next( static_any_t cur, C&, mpl::false_ ) 165 { 166 ++static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); 167 } 168 169 //____________________________________________________________________________// 170 171 template<typename C> 172 inline void 173 next( static_any_t cur, C const&, mpl::true_ ) 174 { 175 ++static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); 176 } 177 178 //____________________________________________________________________________// 179 180 // ************************************************************************** // 181 // ************** deref ************** // 182 // ************************************************************************** // 183 184 template<class RefType,typename C> 185 inline RefType 186 deref( static_any_t cur, C&, ::boost::type<RefType>, mpl::false_ ) 187 { 188 return *static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); 189 } 190 191 //____________________________________________________________________________// 192 193 template<class RefType,typename C> 194 inline RefType 195 deref( static_any_t cur, C const&, ::boost::type<RefType>, mpl::true_ ) 196 { 197 return *static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); 198 } 199 200 //____________________________________________________________________________// 201 202 // ************************************************************************** // 203 // ************** BOOST_TEST_FOREACH ************** // 204 // ************************************************************************** // 205 206 #define BOOST_TEST_FE_ANY ::boost::unit_test::for_each::static_any_t 207 #define BOOST_TEST_FE_IS_CONST( COL ) ::boost::unit_test::for_each::is_const_coll( COL ) 208 209 #define BOOST_TEST_FE_BEG( COL ) \ 210 ::boost::unit_test::for_each::begin( \ 211 COL, \ 212 BOOST_TEST_FE_IS_CONST( COL ) ) \ 213 /**/ 214 215 #define BOOST_TEST_FE_END( COL ) \ 216 ::boost::unit_test::for_each::end( \ 217 COL, \ 218 BOOST_TEST_FE_IS_CONST( COL ) ) \ 219 /**/ 220 221 #define BOOST_TEST_FE_DONE( COL ) \ 222 ::boost::unit_test::for_each::done( \ 223 BOOST_TEST_FE_CUR_VAR, \ 224 BOOST_TEST_FE_END_VAR, \ 225 COL, \ 226 BOOST_TEST_FE_IS_CONST( COL ) ) \ 227 /**/ 228 229 #define BOOST_TEST_FE_NEXT( COL ) \ 230 ::boost::unit_test::for_each::next( \ 231 BOOST_TEST_FE_CUR_VAR, \ 232 COL, \ 233 BOOST_TEST_FE_IS_CONST( COL ) ) \ 234 /**/ 235 236 #define BOOST_FOREACH_NOOP(COL) \ 237 ((void)&(COL)) 238 239 #define BOOST_TEST_FE_DEREF( COL, RefType ) \ 240 ::boost::unit_test::for_each::deref( \ 241 BOOST_TEST_FE_CUR_VAR, \ 242 COL, \ 243 ::boost::type<RefType >(), \ 244 BOOST_TEST_FE_IS_CONST( COL ) ) \ 245 /**/ 246 247 #if BOOST_WORKAROUND( BOOST_MSVC, == 1310 ) 248 #define BOOST_TEST_LINE_NUM 249 #else 250 #define BOOST_TEST_LINE_NUM __LINE__ 251 #endif 252 253 #define BOOST_TEST_FE_CUR_VAR BOOST_JOIN( _fe_cur_, BOOST_TEST_LINE_NUM ) 254 #define BOOST_TEST_FE_END_VAR BOOST_JOIN( _fe_end_, BOOST_TEST_LINE_NUM ) 255 #define BOOST_TEST_FE_CON_VAR BOOST_JOIN( _fe_con_, BOOST_TEST_LINE_NUM ) 256 257 #define BOOST_TEST_FOREACH( RefType, var, COL ) \ 258 if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \ 259 if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_END( COL ) ) {} else \ 260 for( bool BOOST_TEST_FE_CON_VAR = true; \ 261 BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); \ 262 BOOST_TEST_FE_CON_VAR ? BOOST_TEST_FE_NEXT( COL ) : BOOST_FOREACH_NOOP( COL )) \ 263 \ 264 if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \ 265 for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \ 266 !BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \ 267 /**/ 268 269 //____________________________________________________________________________// 270 271 } // namespace for_each 272 273 } // namespace unit_test 274 275 } // namespace boost 276 277 //____________________________________________________________________________// 278 279 #include <boost/test/detail/enable_warnings.hpp> 280 281 #endif // BOOST_TEST_FOREACH_HPP_021005GER 282