// 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 #include #if defined(_MSC_VER) & _MSC_VER <= 1400 #error Sorry, this doesn''t work on VC++. Try gcc. #endif /////////////////////////////////////////////////////////////////////////////// // ENCODED_TYPEOF template struct type2type {}; template type2type encode_type(T const&) { return type2type(); } struct any_type { template operator type2type () const { return type2type(); } }; #define ENCODED_TYPEOF(expr) (true? any_type() : encode_type(expr)) /////////////////////////////////////////////////////////////////////////////// // EVAL struct rvalue_probe { template rvalue_probe(T const& t, bool& b) : ptemp(const_cast(&t)) , is_rvalue(b) {} template operator R() { is_rvalue = true; return *static_cast(ptemp); } template operator L&() const { is_rvalue = false; return *static_cast(ptemp); } void* ptemp; bool& is_rvalue; }; #define EVAL(expr,is_rvalue) (true? rvalue_probe(expr,is_rvalue) : (expr)) /////////////////////////////////////////////////////////////////////////////// // 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 > contain(T const& t, bool const& is_rvalue) { typedef boost::variant variant_t; return is_rvalue ? variant_t(t) : variant_t(&t); } template auto_any begin(auto_any_base const& container, bool is_rvalue, type2type) { typedef boost::variant variant_t; variant_t& var = auto_any_cast(container); T const& t = is_rvalue ? boost::get(var) : *boost::get(var); return t.begin(); } template auto_any end(auto_any_base const& container, bool is_rvalue, type2type) { typedef boost::variant variant_t; variant_t& var = auto_any_cast(container); T const& t = is_rvalue ? boost::get(var) : *boost::get(var); return t.end(); } template bool done(auto_any_base const& cur, auto_any_base const& end, type2type) { typedef typename T::const_iterator iter_type; return auto_any_cast(cur) == auto_any_cast(end); } template void next(auto_any_base const& cur, type2type) { typedef typename T::const_iterator iter_type; ++auto_any_cast(cur); } template typename T::const_reference deref(auto_any_base const& cur, type2type) { typedef typename T::const_iterator iter_type; return *auto_any_cast(cur); } /////////////////////////////////////////////////////////////////////////////// // FOREACH #define FOREACH(item, container) \ if(bool is_rvalue = false) {} else \ if(auto_any_base const& c = contain(EVAL(container,is_rvalue),is_rvalue)) {} else \ if(auto_any_base const& b = begin(c,is_rvalue,ENCODED_TYPEOF(container))) {} else \ if(auto_any_base const& e = end(c,is_rvalue,ENCODED_TYPEOF(container))) {} else \ for(bool more = true; \ more && !done(b,e,ENCODED_TYPEOF(container)); \ more ? next(b,ENCODED_TYPEOF(container)) : (void)0) \ if (more = false) {} else \ for(item = deref(b,ENCODED_TYPEOF(container)); !more; more = true) std::vector get_cont() { std::cout << "here\n"; return std::vector(3,1.0); } int main() { FOREACH(double d, get_cont()) { std::cout << d << '\n'; } return 0; }