erase.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(FUSION_ERASE_07232005_0534)
  7. #define FUSION_ERASE_07232005_0534
  8. #include <boost/fusion/iterator/equal_to.hpp>
  9. #include <boost/fusion/iterator/mpl/convert_iterator.hpp>
  10. #include <boost/fusion/container/vector/vector10.hpp>
  11. #include <boost/fusion/view/joint_view/joint_view.hpp>
  12. #include <boost/fusion/view/iterator_range/iterator_range.hpp>
  13. #include <boost/fusion/support/detail/as_fusion_element.hpp>
  14. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  15. #include <boost/fusion/sequence/intrinsic/end.hpp>
  16. #include <boost/fusion/adapted/mpl/mpl_iterator.hpp>
  17. #include <boost/fusion/support/is_sequence.hpp>
  18. #include <boost/utility/enable_if.hpp>
  19. #include <boost/mpl/if.hpp>
  20. namespace boost { namespace fusion
  21. {
  22. namespace result_of
  23. {
  24. template <typename Sequence, typename First>
  25. struct compute_erase_last // put this in detail!!!
  26. {
  27. typedef typename result_of::end<Sequence>::type seq_last_type;
  28. typedef typename convert_iterator<First>::type first_type;
  29. typedef typename
  30. mpl::if_<
  31. result_of::equal_to<first_type, seq_last_type>
  32. , first_type
  33. , typename result_of::next<first_type>::type
  34. >::type
  35. type;
  36. static type
  37. call(First const& first, mpl::false_)
  38. {
  39. return fusion::next(convert_iterator<First>::call(first));
  40. }
  41. static type
  42. call(First const& first, mpl::true_)
  43. {
  44. return convert_iterator<First>::call(first);
  45. }
  46. static type
  47. call(First const& first)
  48. {
  49. return call(first, result_of::equal_to<first_type, seq_last_type>());
  50. }
  51. };
  52. struct use_default;
  53. template <class T, class Default>
  54. struct fusion_default_help
  55. : mpl::if_<
  56. is_same<T, use_default>
  57. , Default
  58. , T
  59. >
  60. {
  61. };
  62. template <
  63. typename Sequence
  64. , typename First
  65. , typename Last = use_default>
  66. struct erase
  67. {
  68. typedef typename result_of::begin<Sequence>::type seq_first_type;
  69. typedef typename result_of::end<Sequence>::type seq_last_type;
  70. BOOST_STATIC_ASSERT((!result_of::equal_to<seq_first_type, seq_last_type>::value));
  71. typedef First FirstType;
  72. typedef typename
  73. fusion_default_help<
  74. Last
  75. , typename compute_erase_last<Sequence, First>::type
  76. >::type
  77. LastType;
  78. typedef typename convert_iterator<FirstType>::type first_type;
  79. typedef typename convert_iterator<LastType>::type last_type;
  80. typedef iterator_range<seq_first_type, first_type> left_type;
  81. typedef iterator_range<last_type, seq_last_type> right_type;
  82. typedef joint_view<left_type, right_type> type;
  83. };
  84. }
  85. template <typename Sequence, typename First>
  86. typename
  87. lazy_enable_if<
  88. traits::is_sequence<Sequence>
  89. , typename result_of::erase<Sequence const, First>
  90. >::type
  91. erase(Sequence const& seq, First const& first)
  92. {
  93. typedef result_of::erase<Sequence const, First> result_of;
  94. typedef typename result_of::left_type left_type;
  95. typedef typename result_of::right_type right_type;
  96. typedef typename result_of::type result_type;
  97. left_type left(
  98. fusion::begin(seq)
  99. , convert_iterator<First>::call(first));
  100. right_type right(
  101. fusion::result_of::compute_erase_last<Sequence const, First>::call(first)
  102. , fusion::end(seq));
  103. return result_type(left, right);
  104. }
  105. template <typename Sequence, typename First, typename Last>
  106. typename result_of::erase<Sequence const, First, Last>::type
  107. erase(Sequence const& seq, First const& first, Last const& last)
  108. {
  109. typedef result_of::erase<Sequence const, First, Last> result_of;
  110. typedef typename result_of::left_type left_type;
  111. typedef typename result_of::right_type right_type;
  112. typedef typename result_of::type result_type;
  113. left_type left(fusion::begin(seq), first);
  114. right_type right(last, fusion::end(seq));
  115. return result_type(left, right);
  116. }
  117. }}
  118. #endif