File indexing completed on 2025-01-18 10:09:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_TRIM_HPP
0015 #define RANGES_V3_VIEW_TRIM_HPP
0016
0017 #include <utility>
0018
0019 #include <concepts/concepts.hpp>
0020
0021 #include <range/v3/algorithm/find_if_not.hpp>
0022 #include <range/v3/detail/config.hpp>
0023 #include <range/v3/functional/bind_back.hpp>
0024 #include <range/v3/functional/compose.hpp>
0025 #include <range/v3/functional/invoke.hpp>
0026 #include <range/v3/iterator/concepts.hpp>
0027 #include <range/v3/range/access.hpp>
0028 #include <range/v3/range/concepts.hpp>
0029 #include <range/v3/range/primitives.hpp>
0030 #include <range/v3/utility/optional.hpp>
0031 #include <range/v3/utility/semiregular_box.hpp>
0032 #include <range/v3/view/all.hpp>
0033 #include <range/v3/view/interface.hpp>
0034 #include <range/v3/view/view.hpp>
0035
0036 #include <range/v3/detail/prologue.hpp>
0037
0038 namespace ranges
0039 {
0040
0041
0042 template<typename Rng, typename Pred>
0043 struct trim_view : view_interface<trim_view<Rng, Pred>>
0044 {
0045 private:
0046 Rng rng_;
0047 semiregular_box_t<Pred> pred_;
0048 detail::non_propagating_cache<iterator_t<Rng>> begin_;
0049 detail::non_propagating_cache<iterator_t<Rng>> end_;
0050
0051 public:
0052 CPP_assert(bidirectional_range<Rng> && view_<Rng> && indirect_unary_predicate<
0053 Pred, iterator_t<Rng>> && common_range<Rng>);
0054
0055 trim_view() = default;
0056 constexpr trim_view(Rng rng, Pred pred)
0057 : rng_(std::move(rng))
0058 , pred_(std::move(pred))
0059 {}
0060
0061 iterator_t<Rng> begin()
0062 {
0063 if(!begin_)
0064 begin_ = find_if_not(rng_, std::ref(pred_));
0065 return *begin_;
0066 }
0067 iterator_t<Rng> end()
0068 {
0069 if(!end_)
0070 {
0071 const auto first = begin();
0072 auto last = ranges::end(rng_);
0073 while(last != first)
0074 if(!invoke(pred_, *--last))
0075 {
0076 ++last;
0077 break;
0078 }
0079 end_ = std::move(last);
0080 }
0081 return *end_;
0082 }
0083
0084 Rng base() const
0085 {
0086 return rng_;
0087 }
0088 };
0089
0090 template<typename Rng, typename Pred>
0091 RANGES_INLINE_VAR constexpr bool enable_borrowed_range<trim_view<Rng, Pred>> =
0092 enable_borrowed_range<Rng>;
0093
0094 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0095 template<typename Rng, typename Pred>
0096 trim_view(Rng &&, Pred)
0097 -> trim_view<views::all_t<Rng>, Pred>;
0098 #endif
0099
0100 template<typename Rng, typename Pred>
0101 RANGES_INLINE_VAR constexpr bool disable_sized_range<trim_view<Rng, Pred>> = true;
0102
0103 namespace views
0104 {
0105 struct trim_base_fn
0106 {
0107 template(typename Rng, typename Pred)(
0108 requires viewable_range<Rng> AND bidirectional_range<Rng> AND
0109 indirect_unary_predicate<Pred, iterator_t<Rng>> AND
0110 common_range<Rng>)
0111 constexpr trim_view<all_t<Rng>, Pred>
0112 operator()(Rng && rng, Pred pred) const
0113 {
0114 return {all(static_cast<Rng &&>(rng)), std::move(pred)};
0115 }
0116 template(typename Rng, typename Pred, typename Proj)(
0117 requires viewable_range<Rng> AND bidirectional_range<Rng> AND
0118 indirect_unary_predicate<composed<Pred, Proj>, iterator_t<Rng>> AND
0119 common_range<Rng>)
0120 constexpr trim_view<all_t<Rng>, composed<Pred, Proj>>
0121 operator()(Rng && rng, Pred pred, Proj proj) const
0122 {
0123 return {all(static_cast<Rng &&>(rng)),
0124 compose(std::move(pred), std::move(proj))};
0125 }
0126 };
0127
0128 struct trim_bind_fn
0129 {
0130 template<typename Pred>
0131 constexpr auto operator()(Pred pred) const
0132 {
0133 return make_view_closure(bind_back(trim_base_fn{}, std::move(pred)));
0134 }
0135 template(typename Pred, typename Proj)(
0136 requires (!range<Pred>))
0137 constexpr auto operator()(Pred && pred, Proj proj) const
0138 {
0139 return make_view_closure(bind_back(
0140 trim_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
0141 }
0142 };
0143
0144 struct RANGES_EMPTY_BASES trim_fn
0145 : trim_base_fn, trim_bind_fn
0146 {
0147 using trim_base_fn::operator();
0148 using trim_bind_fn::operator();
0149 };
0150
0151
0152
0153 RANGES_INLINE_VARIABLE(trim_fn, trim)
0154 }
0155
0156 }
0157
0158 #include <range/v3/detail/epilogue.hpp>
0159 #include <range/v3/detail/satisfy_boost_range.hpp>
0160 RANGES_SATISFY_BOOST_RANGE(::ranges::trim_view)
0161
0162 #endif