#include #include #include #include template< bool C_ > struct bool_ { enum { value = C_ }; operator bool() const { return this->value; } }; typedef bool_ true_; typedef bool_ false_; //-------------------- struct auto_any_base { operator bool() const { return false; } }; template struct auto_any : auto_any_base { explicit auto_any(T const &t) : item(t) { } mutable T item; }; typedef auto_any_base const &auto_any_t; template inline T &auto_any_cast1(auto_any_t a) { return static_cast const &>(a).item; } template inline T *&to_ptr2(T const &) { static T *t = 0; return t; } template inline false_ * boost_foreach_is_lightweight_proxy1(T *&) { return 0; } template inline true_ * boost_foreach_is_lightweight_proxy1(T **&) { return 0; } # define BOOST_FOREACH_SHOULD_COPY2(COL) (true ? 0 : boost_foreach_is_lightweight_proxy1(to_ptr2(COL))) // 不理解,但确实用这个方法,就区分了数组与字串 namespace boka { template< typename C > struct iterator1 { typedef typename C::iterator type; }; template< typename T > struct iterator1 { typedef T* type; }; template< typename T, std::size_t sz > struct iterator1< T[sz] > { typedef T* type; }; namespace range_detail { template< typename C > inline typename iterator1::type range_begin1( C& c ) { return c.begin(); } template< typename T, std::size_t sz > inline T* range_begin1( T (&a)[sz] ) { return a; } template< typename C > inline typename iterator1::type range_end1( C& c ) { return c.end(); } template< typename T, std::size_t sz > inline T* range_end1( T (&a)[sz] ) { return a + sz; } } template< class T > inline typename iterator1::type begin1( T& r ) { return range_detail::range_begin1( r ); } template< class T > inline typename iterator1::type end1( T& r ) { return range_detail::range_end1( r ); } namespace foreach_detail_ { template inline auto_any begin5(T* t, true_*) { return auto_any(t); // null-terminated C-style strings } template inline auto_any::type> begin5(T &t, false_*) { typename iterator1::type y = begin1(t); return auto_any::type>(y); } template inline auto_any end5(T*, true_*) { return auto_any(0); // null-terminated C-style strings } template inline auto_any::type> end5(T &t, false_*) { typename iterator1::type y = end1(t); return auto_any::type>(y); } template inline bool done(auto_any_t cur, auto_any_t end, T*, true_*) { return ! *auto_any_cast1(cur); // null-terminated C-style strings } template inline bool done(auto_any_t cur, auto_any_t end, T&, false_*) { typedef typename iterator1::type type; return auto_any_cast1(cur) == auto_any_cast1(end); } template struct reference2 { typedef typename T::reference type; }; template struct reference2 { typedef typename T type; }; template< typename T, std::size_t sz > struct reference2< T[sz] > { typedef T type; }; template inline typename reference2::type deref1(auto_any_t cur, T&) { return *auto_any_cast1::type>(cur); } template inline void next(auto_any_t cur, T&) { ++auto_any_cast1::type>(cur); } }} inline bool set_false(bool &b) { b = false; return false; } #define BEGIN5(COL) BAIL::begin5(COL, BOOST_FOREACH_SHOULD_COPY2(COL)) #define END5(COL) BAIL::end5(COL, BOOST_FOREACH_SHOULD_COPY2(COL)) #define DONE5(COL) BAIL::done(_cur, _end, COL, BOOST_FOREACH_SHOULD_COPY2(COL)) #define BAIL boka::foreach_detail_ #define FOR_EACH(VAR, COL) \ if (auto_any_t _cur = BEGIN5( COL )){} else \ if (auto_any_t _end = END5( COL )) {} else \ for (bool _conti = true; \ _conti && !DONE5(COL); \ _conti ? BAIL::next( _cur, COL) : (void)0) \ if (set_false(_conti)){} else \ for (VAR = BAIL::deref1(_cur, COL); !_conti; _conti = true) void testa() { int tbl[] = {1,2,3,4,5,6,7}; if (1) FOR_EACH( int i, tbl ) { std::cout << i << ' '; } std::cout << std::endl; std::vector m; // also support std::list, std::deque m.push_back(10); m.push_back(20); m.push_back(30); FOR_EACH( int i, m ) { std::cout << i << ' '; } std::cout << std::endl; const char * hello = "hello, world\n"; FOR_EACH( char ch, hello ) { std::cout << ch; } } /* 第五章 支持C++字串 继续修改,支持 null-terminated C-style strings,最后,我们的宏支持所有以下情况: void test() { int tbl[] = {1,2,3,4,5,6,7}; if (1) FOR_EACH( int i, tbl ) { std::cout << i << ' '; } std::cout << std::endl; std::vector m; // also support std::list, std::deque m.push_back(10); m.push_back(20); m.push_back(30); FOR_EACH( int i, m ) { std::cout << i << ' '; } std::cout << std::endl; const char * hello = "hello, world\n"; FOR_EACH( char ch, hello ) { std::cout << ch; } } 代码见附件,不知道还能不能更简单地实现。 关注的人太少了,不再更新.... */