/// \file // Range v3 library // // Copyright Johel Guerrero 2019 // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_VIEW_TRIM_HPP #define RANGES_V3_VIEW_TRIM_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-views /// @{ template struct trim_view : view_interface> { private: Rng rng_; semiregular_box_t pred_; detail::non_propagating_cache> begin_; detail::non_propagating_cache> end_; public: CPP_assert(bidirectional_range && view_ && indirect_unary_predicate< Pred, iterator_t> && common_range); trim_view() = default; constexpr trim_view(Rng rng, Pred pred) : rng_(std::move(rng)) , pred_(std::move(pred)) {} iterator_t begin() { if(!begin_) begin_ = find_if_not(rng_, std::ref(pred_)); return *begin_; } iterator_t end() { if(!end_) { const auto first = begin(); auto last = ranges::end(rng_); while(last != first) if(!invoke(pred_, *--last)) { ++last; break; } end_ = std::move(last); } return *end_; } Rng base() const { return rng_; } }; template RANGES_INLINE_VAR constexpr bool enable_borrowed_range> = // enable_borrowed_range; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template trim_view(Rng &&, Pred) // -> trim_view, Pred>; #endif template RANGES_INLINE_VAR constexpr bool disable_sized_range> = true; namespace views { struct trim_base_fn { template(typename Rng, typename Pred)( requires viewable_range AND bidirectional_range AND indirect_unary_predicate> AND common_range) constexpr trim_view, Pred> // operator()(Rng && rng, Pred pred) const // { return {all(static_cast(rng)), std::move(pred)}; } template(typename Rng, typename Pred, typename Proj)( requires viewable_range AND bidirectional_range AND indirect_unary_predicate, iterator_t> AND common_range) constexpr trim_view, composed> // operator()(Rng && rng, Pred pred, Proj proj) const { return {all(static_cast(rng)), compose(std::move(pred), std::move(proj))}; } }; struct trim_bind_fn { template constexpr auto operator()(Pred pred) const // TODO: underconstrained { return make_view_closure(bind_back(trim_base_fn{}, std::move(pred))); } template(typename Pred, typename Proj)( requires (!range)) // TODO: underconstrained constexpr auto operator()(Pred && pred, Proj proj) const { return make_view_closure(bind_back( trim_base_fn{}, static_cast(pred), std::move(proj))); } }; struct RANGES_EMPTY_BASES trim_fn : trim_base_fn, trim_bind_fn { using trim_base_fn::operator(); using trim_bind_fn::operator(); }; /// \relates trim_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(trim_fn, trim) } // namespace views /// @} } // namespace ranges #include #include RANGES_SATISFY_BOOST_RANGE(::ranges::trim_view) #endif // RANGES_V3_VIEW_TRIM_HPP