Home | History | Annotate | Download | only in utils
      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