Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

126 lines
3.8KB

  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_VIEW_DELIMIT_HPP
  14. #define RANGES_V3_VIEW_DELIMIT_HPP
  15. #include <meta/meta.hpp>
  16. #include <range/v3/range_fwd.hpp>
  17. #include <range/v3/functional/bind_back.hpp>
  18. #include <range/v3/iterator/concepts.hpp>
  19. #include <range/v3/iterator/unreachable_sentinel.hpp>
  20. #include <range/v3/range/concepts.hpp>
  21. #include <range/v3/utility/static_const.hpp>
  22. #include <range/v3/view/adaptor.hpp>
  23. #include <range/v3/view/all.hpp>
  24. #include <range/v3/view/subrange.hpp>
  25. #include <range/v3/view/view.hpp>
  26. namespace ranges
  27. {
  28. /// \addtogroup group-views
  29. /// @{
  30. template<typename Rng, typename Val>
  31. struct delimit_view
  32. : view_adaptor<delimit_view<Rng, Val>, Rng,
  33. is_finite<Rng>::value ? finite : unknown>
  34. {
  35. private:
  36. friend range_access;
  37. Val value_;
  38. struct sentinel_adaptor : adaptor_base
  39. {
  40. sentinel_adaptor() = default;
  41. sentinel_adaptor(Val value)
  42. : value_(std::move(value))
  43. {}
  44. template<class I, class S>
  45. bool empty(I const & it, S const & last) const
  46. {
  47. return it == last || *it == value_;
  48. }
  49. Val value_;
  50. };
  51. sentinel_adaptor end_adaptor() const
  52. {
  53. return {value_};
  54. }
  55. public:
  56. delimit_view() = default;
  57. constexpr delimit_view(Rng rng, Val value)
  58. : delimit_view::view_adaptor{std::move(rng)}
  59. , value_(std::move(value))
  60. {}
  61. };
  62. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  63. CPP_template(typename Rng, typename Val)(requires copy_constructible<Val>)
  64. delimit_view(Rng &&, Val)
  65. ->delimit_view<views::all_t<Rng>, Val>;
  66. #endif
  67. namespace views
  68. {
  69. struct delimit_impl_fn
  70. {
  71. private:
  72. friend view_access;
  73. template<typename Val>
  74. static constexpr auto bind(delimit_impl_fn delimit, Val value)
  75. {
  76. return make_pipeable(bind_back(delimit, std::move(value)));
  77. }
  78. public:
  79. template<typename Rng, typename Val>
  80. constexpr auto operator()(Rng && rng, Val value) const -> CPP_ret(
  81. delimit_view<all_t<Rng>, Val>)( //
  82. requires viewable_range<Rng> && input_range<Rng> && semiregular<Val> &&
  83. equality_comparable_with<Val, range_reference_t<Rng>>)
  84. {
  85. return {all(static_cast<Rng &&>(rng)), std::move(value)};
  86. }
  87. };
  88. struct delimit_fn : view<delimit_impl_fn>
  89. {
  90. using view<delimit_impl_fn>::operator();
  91. template<typename I_, typename Val, typename I = detail::decay_t<I_>>
  92. constexpr auto operator()(I_ && begin_, Val value) const
  93. -> CPP_ret(delimit_view<subrange<I, unreachable_sentinel_t>, Val>)( //
  94. requires(!range<I_> && convertible_to<I_, I> && input_iterator<I> &&
  95. semiregular<Val> &&
  96. equality_comparable_with<Val, iter_reference_t<I>>))
  97. {
  98. return {{static_cast<I_ &&>(begin_), {}}, std::move(value)};
  99. }
  100. };
  101. /// \relates delimit_fn
  102. /// \ingroup group-views
  103. RANGES_INLINE_VARIABLE(delimit_fn, delimit)
  104. } // namespace views
  105. /// @}
  106. } // namespace ranges
  107. #include <range/v3/detail/satisfy_boost_range.hpp>
  108. RANGES_SATISFY_BOOST_RANGE(::ranges::delimit_view)
  109. #endif