distance_impl.hpp 3.1 KB

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