// A stripped down version of FOREACH for // illustration purposes. NOT FOR GENERAL USE. // For a complete implementation, see BOOST_FOREACH at // http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler // // Copyright 2004 Eric Niebler. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include /////////////////////////////////////////////////////////////////////////////// // auto_any struct auto_any_base { operator bool() const { return false; } }; template struct auto_any : auto_any_base { auto_any(T const& t) : item(t) {} mutable T item; }; template T& auto_any_cast(auto_any_base const& any) { return static_cast const&>(any).item; } /////////////////////////////////////////////////////////////////////////////// // FOREACH helper function template auto_any begin(T const& t) { return t.begin(); } template auto_any end(T const& t) { return t.end(); } template bool done(auto_any_base const& cur, auto_any_base const& end, T const&) { typedef typename T::const_iterator iter_type; return auto_any_cast(cur) == auto_any_cast(end); } template void next(auto_any_base const& cur, T const&) { typedef typename T::const_iterator iter_type; ++auto_any_cast(cur); } template typename T::const_reference deref(auto_any_base const& cur, T const&) { typedef typename T::const_iterator iter_type; return *auto_any_cast(cur); } /////////////////////////////////////////////////////////////////////////////// // FOREACH #define FOREACH(item, container) \ if(auto_any_base const& b = begin(container)) {} else \ if(auto_any_base const& e = end(container)) {} else \ for(bool more = true; \ more && !done(b,e,container); \ more ? next(b,container) : (void)0) \ if (more = false) {} else \ for(item = deref(b,container); !more; more = true) std::vector const container(3,1.0); std::vector const& get_cont() { std::cout << "here\n"; return container; } int main() { FOREACH(double d, get_cont()) { std::cout << d << '\n'; } return 0; }