1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 Copyright (c) 2006 Dan Marsden 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #if !defined(FUSION_DISTANCE_IMPL_20060124_2033) 9 #define FUSION_DISTANCE_IMPL_20060124_2033 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/mpl/eval_if.hpp> 13 #include <boost/mpl/placeholders.hpp> 14 #include <boost/mpl/assert.hpp> 15 #include <boost/fusion/iterator/distance.hpp> 16 #include <boost/fusion/support/category_of.hpp> 17 #include <boost/fusion/algorithm/query/find_if.hpp> 18 #include <boost/fusion/sequence/intrinsic/end.hpp> 19 #include <boost/fusion/sequence/intrinsic/value_at.hpp> 20 #include <boost/type_traits/is_same.hpp> 21 22 namespace boost { namespace fusion { 23 24 struct zip_view_iterator_tag; 25 26 struct random_access_iterator_tag; 27 28 namespace detail 29 { 30 template<typename FoundIt, typename SearchIt> 31 struct best_distance 32 { 33 typedef typename result_of::find_if< 34 typename SearchIt::iterators, is_same<traits::category_of<mpl::_>, random_access_iterator_tag> > finder; 35 36 BOOST_MPL_ASSERT_NOT((is_same<typename finder::type, result_of::end<typename SearchIt::iterators> >)); 37 38 typedef typename result_of::distance<FoundIt, typename finder::type>::type type; 39 }; 40 41 template<typename It1, typename It2> 42 struct default_distance 43 : result_of::distance< 44 typename result_of::value_at_c<typename It1::iterators, 0>::type, 45 typename result_of::value_at_c<typename It2::iterators, 0>::type> 46 {}; 47 48 template<typename It1, typename It2> 49 struct zip_view_iterator_distance 50 { 51 typedef typename result_of::find_if< 52 typename It1::iterators, is_same<traits::category_of<mpl::_>, random_access_iterator_tag> > finder; 53 54 typedef typename mpl::eval_if< 55 is_same<typename finder::type, typename result_of::end<typename It1::iterators>::type>, 56 detail::default_distance<It1, It2> , 57 detail::best_distance<typename finder::type, It2> >::type type; 58 }; 59 } 60 61 namespace extension 62 { 63 template<typename Tag> 64 struct distance_impl; 65 66 template<> 67 struct distance_impl<zip_view_iterator_tag> 68 { 69 template<typename It1, typename It2> 70 struct apply 71 : detail::zip_view_iterator_distance<It1, It2>::type 72 { 73 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 74 static typename detail::zip_view_iterator_distance<It1, It2>::type callboost::fusion::extension::distance_impl::apply75 call(It1 const& /*it1*/, It2 const& /*it2*/) 76 { 77 return typename detail::zip_view_iterator_distance<It1, It2>::type(); 78 } 79 }; 80 }; 81 } 82 }} 83 84 #endif 85