/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2007 Dan Marsden Copyright (c) 2009 Christopher Schmidt 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) ==============================================================================*/ #if !defined(FUSION_FIND_IF_05052005_1107) #define FUSION_FIND_IF_05052005_1107 #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace fusion { struct random_access_traversal_tag; namespace detail { template struct apply_filter { typedef typename mpl::apply1< Pred, Iterator>::type type; BOOST_STATIC_CONSTANT(int, value = type::value); }; template struct main_find_if; template struct recursive_find_if { typedef typename main_find_if< typename result_of::next::type, Last, Pred >::type type; }; template struct main_find_if { typedef mpl::or_< result_of::equal_to , apply_filter > filter; typedef typename mpl::eval_if< filter , mpl::identity , recursive_find_if >::type type; }; template< typename First, typename Last, typename Pred, bool> struct choose_find_if; template struct choose_find_if : main_find_if {}; template struct unroll_again; template struct apply_offset_filter { typedef typename result_of::advance_c::type Shifted; typedef typename mpl::apply1< Pred , Shifted >::type type; BOOST_STATIC_CONSTANT(int, value = type::value); }; template struct unrolled_find_if { typedef typename mpl::eval_if< apply_filter, mpl::identity, mpl::eval_if< apply_offset_filter, result_of::advance_c, mpl::eval_if< apply_offset_filter, result_of::advance_c, mpl::eval_if< apply_offset_filter, result_of::advance_c, unroll_again< Iter, Pred, n, 4> > > > >::type type; }; template struct unrolled_find_if { typedef typename mpl::eval_if< apply_filter, mpl::identity, mpl::eval_if< apply_offset_filter, result_of::advance_c, mpl::eval_if< apply_offset_filter, result_of::advance_c, result_of::advance_c > > >::type type; }; template struct unrolled_find_if { typedef typename mpl::eval_if< apply_filter, mpl::identity, mpl::eval_if< apply_offset_filter, result_of::advance_c, result_of::advance_c > >::type type; }; template struct unrolled_find_if { typedef typename mpl::eval_if< apply_filter, mpl::identity, result_of::advance_c >::type type; }; template struct unroll_again { typedef typename unrolled_find_if< typename result_of::advance_c::type, Pred, n-unrolling>::type type; }; template struct unrolled_find_if { typedef Iter type; }; template struct choose_find_if { typedef typename result_of::distance::type N; typedef typename unrolled_find_if::type type; }; template struct static_find_if { typedef typename choose_find_if< First , Last , typename mpl::lambda::type , is_base_of::type>::value >::type type; template static type recursive_call(Iterator const& iter, mpl::true_) { return iter; } template static type recursive_call(Iterator const& iter, mpl::false_) { return recursive_call(fusion::next(iter)); } template static type recursive_call(Iterator const& iter) { typedef result_of::equal_to found; return recursive_call(iter, found()); } template static type choose_call(Iterator const& iter, Tag) { return recursive_call(iter); } template static type choose_call(Iterator const& iter, random_access_traversal_tag) { typedef typename result_of::distance::type N; return fusion::advance(iter); } template static type iter_call(Iterator const& iter) { return choose_call(iter, typename traits::category_of::type()); } template static type call(Sequence& seq) { return iter_call(fusion::begin(seq)); } }; template struct result_of_find_if { typedef static_find_if< typename result_of::begin::type , typename result_of::end::type , Pred > filter; typedef typename filter::type type; }; }}} #endif