From 10af4fc1e091e7f9402e40bcfb3130cb2a6f6629 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Tue, 29 Mar 2011 10:27:00 +0000 Subject: [PATCH] [boost][range] - Improve the forwarding of the functor, and provide a work-around for the breaking changes in VC10 for_each. [SVN r70690] --- include/boost/range/algorithm/for_each.hpp | 67 +++++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/include/boost/range/algorithm/for_each.hpp b/include/boost/range/algorithm/for_each.hpp index 714a06f..dc2221d 100755 --- a/include/boost/range/algorithm/for_each.hpp +++ b/include/boost/range/algorithm/for_each.hpp @@ -13,13 +13,52 @@ #include #include #include +#include #include +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) +#include +#endif + namespace boost { namespace range { +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + namespace for_each_detail + { + template + inline UnaryFunction + for_each_impl(Iterator first, Iterator last, UnaryFunction fun, + typename enable_if< + is_reference_wrapper, + void + >::type* = 0) + { + typedef typename std::_Get_unchecked_type::type + unchecked_iterator; + + unchecked_iterator unchecked_last = std::_Unchecked(last); + for (unchecked_iterator unchecked_first = std::_Unchecked(first); first != last; ++first) + fun.get()(*unchecked_first); + + return fun; + } + + template + inline UnaryFunction + for_each_impl(Iterator first, Iterator last, UnaryFunction fn, + typename disable_if< + is_reference_wrapper, + void + >::type* = 0) + { + return std::for_each(first, last, fn); + } + } +#endif + /// \brief template function for_each /// /// range-based version of the for_each std algorithm @@ -30,7 +69,18 @@ template< class SinglePassRange, class UnaryFunction > inline UnaryFunction for_each(SinglePassRange & rng, UnaryFunction fun) { BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - return std::for_each(boost::begin(rng),boost::end(rng),fun); + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + return for_each_detail::for_each_impl< + typename range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#else + return std::for_each< + BOOST_DEDUCED_TYPENAME range_iterator::type, + UnaryFunction + >(boost::begin(rng),boost::end(rng),fun); +#endif } /// \overload @@ -38,11 +88,22 @@ template< class SinglePassRange, class UnaryFunction > inline UnaryFunction for_each(const SinglePassRange& rng, UnaryFunction fun) { BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - return std::for_each(boost::begin(rng), boost::end(rng), fun); + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1600) + return for_each_detail::for_each_impl< + typename range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#else + return std::for_each< + BOOST_DEDUCED_TYPENAME range_iterator::type, + UnaryFunction + >(boost::begin(rng), boost::end(rng), fun); +#endif } } // namespace range using range::for_each; } // namespace boost -#endif // include guard +#endif // include guard \ No newline at end of file