delimit.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. #include <range/v3/detail/prologue.hpp>
  27. namespace ranges
  28. {
  29. /// \addtogroup group-views
  30. /// @{
  31. template<typename Rng, typename Val>
  32. struct delimit_view
  33. : view_adaptor<delimit_view<Rng, Val>, Rng,
  34. is_finite<Rng>::value ? finite : unknown>
  35. {
  36. private:
  37. friend range_access;
  38. Val value_;
  39. struct sentinel_adaptor : adaptor_base
  40. {
  41. sentinel_adaptor() = default;
  42. sentinel_adaptor(Val value)
  43. : value_(std::move(value))
  44. {}
  45. template<class I, class S>
  46. bool empty(I const & it, S const & last) const
  47. {
  48. return it == last || *it == value_;
  49. }
  50. Val value_;
  51. };
  52. sentinel_adaptor end_adaptor() const
  53. {
  54. return {value_};
  55. }
  56. public:
  57. delimit_view() = default;
  58. constexpr delimit_view(Rng rng, Val value)
  59. : delimit_view::view_adaptor{std::move(rng)}
  60. , value_(std::move(value))
  61. {}
  62. };
  63. // the begin iterator will be an iterator into the underlying view (conditionally
  64. // borrowed) and the end iterator owns the value to be compared against (borrowed)
  65. template<typename Rng, typename Val>
  66. RANGES_INLINE_VAR constexpr bool enable_borrowed_range<delimit_view<Rng, Val>> = //
  67. enable_borrowed_range<Rng>;
  68. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  69. template(typename Rng, typename Val)(
  70. requires copy_constructible<Val>)
  71. delimit_view(Rng &&, Val)
  72. -> delimit_view<views::all_t<Rng>, Val>;
  73. #endif
  74. namespace views
  75. {
  76. struct delimit_base_fn
  77. {
  78. template(typename I_, typename Val, typename I = detail::decay_t<I_>)(
  79. requires (!range<I_>) AND convertible_to<I_, I> AND input_iterator<I> AND
  80. semiregular<Val> AND
  81. equality_comparable_with<Val, iter_reference_t<I>>)
  82. constexpr auto operator()(I_ && begin_, Val value) const
  83. -> delimit_view<subrange<I, unreachable_sentinel_t>, Val>
  84. {
  85. return {{static_cast<I_ &&>(begin_), {}}, std::move(value)};
  86. }
  87. template(typename Rng, typename Val)(
  88. requires viewable_range<Rng> AND input_range<Rng> AND semiregular<
  89. Val> AND equality_comparable_with<Val, range_reference_t<Rng>>)
  90. constexpr auto operator()(Rng && rng, Val value) const //
  91. -> delimit_view<all_t<Rng>, Val>
  92. {
  93. return {all(static_cast<Rng &&>(rng)), std::move(value)};
  94. }
  95. };
  96. struct delimit_fn : delimit_base_fn
  97. {
  98. using delimit_base_fn::operator();
  99. template<typename Val>
  100. constexpr auto operator()(Val value) const
  101. {
  102. return make_view_closure(bind_back(delimit_base_fn{}, std::move(value)));
  103. }
  104. };
  105. /// \relates delimit_fn
  106. /// \ingroup group-views
  107. RANGES_INLINE_VARIABLE(delimit_fn, delimit)
  108. } // namespace views
  109. /// @}
  110. } // namespace ranges
  111. #include <range/v3/detail/epilogue.hpp>
  112. #include <range/v3/detail/satisfy_boost_range.hpp>
  113. RANGES_SATISFY_BOOST_RANGE(::ranges::delimit_view)
  114. #endif