File indexing completed on 2025-01-31 09:41:56
0001
0002
0003
0004
0005
0006
0007
0008 #if !defined(FUSION_DISTANCE_IMPL_20060124_2033)
0009 #define FUSION_DISTANCE_IMPL_20060124_2033
0010
0011 #include <boost/fusion/support/config.hpp>
0012 #include <boost/mpl/eval_if.hpp>
0013 #include <boost/mpl/placeholders.hpp>
0014 #include <boost/mpl/assert.hpp>
0015 #include <boost/fusion/iterator/distance.hpp>
0016 #include <boost/fusion/support/category_of.hpp>
0017 #include <boost/fusion/algorithm/query/find_if.hpp>
0018 #include <boost/fusion/sequence/intrinsic/end.hpp>
0019 #include <boost/fusion/sequence/intrinsic/value_at.hpp>
0020 #include <boost/type_traits/is_same.hpp>
0021
0022 namespace boost { namespace fusion {
0023
0024 struct zip_view_iterator_tag;
0025
0026 struct random_access_iterator_tag;
0027
0028 namespace detail
0029 {
0030 template<typename FoundIt, typename SearchIt>
0031 struct best_distance
0032 {
0033 typedef typename result_of::find_if<
0034 typename SearchIt::iterators, is_same<traits::category_of<mpl::_>, random_access_iterator_tag> > finder;
0035
0036 BOOST_MPL_ASSERT_NOT((is_same<typename finder::type, result_of::end<typename SearchIt::iterators> >));
0037
0038 typedef typename result_of::distance<FoundIt, typename finder::type>::type type;
0039 };
0040
0041 template<typename It1, typename It2>
0042 struct default_distance
0043 : result_of::distance<
0044 typename result_of::value_at_c<typename It1::iterators, 0>::type,
0045 typename result_of::value_at_c<typename It2::iterators, 0>::type>
0046 {};
0047
0048 template<typename It1, typename It2>
0049 struct zip_view_iterator_distance
0050 {
0051 typedef typename result_of::find_if<
0052 typename It1::iterators, is_same<traits::category_of<mpl::_>, random_access_iterator_tag> > finder;
0053
0054 typedef typename mpl::eval_if<
0055 is_same<typename finder::type, typename result_of::end<typename It1::iterators>::type>,
0056 detail::default_distance<It1, It2> ,
0057 detail::best_distance<typename finder::type, It2> >::type type;
0058 };
0059 }
0060
0061 namespace extension
0062 {
0063 template<typename Tag>
0064 struct distance_impl;
0065
0066 template<>
0067 struct distance_impl<zip_view_iterator_tag>
0068 {
0069 template<typename It1, typename It2>
0070 struct apply
0071 : detail::zip_view_iterator_distance<It1, It2>::type
0072 {
0073 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
0074 static typename detail::zip_view_iterator_distance<It1, It2>::type
0075 call(It1 const& , It2 const& )
0076 {
0077 return typename detail::zip_view_iterator_distance<It1, It2>::type();
0078 }
0079 };
0080 };
0081 }
0082 }}
0083
0084 #endif