/// \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_; } }; #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_fn { private: friend view_access; template static constexpr auto bind(trim_fn trim, Pred pred) { return make_pipeable(bind_back(trim, std::move(pred))); } template static constexpr auto bind(trim_fn trim, Pred pred, Proj proj) { return make_pipeable(bind_back(trim, std::move(pred), std::move(proj))); } public: template constexpr auto operator()(Rng && rng, Pred pred) const -> CPP_ret( trim_view, Pred>)( // requires viewable_range && bidirectional_range && indirect_unary_predicate> && common_range) { return {all(static_cast(rng)), std::move(pred)}; } template constexpr auto operator()(Rng && rng, Pred pred, Proj proj) const -> CPP_ret(trim_view, composed>)( // requires viewable_range && bidirectional_range && indirect_unary_predicate, iterator_t> && common_range) { return {all(static_cast(rng)), compose(std::move(pred), std::move(proj))}; } }; /// \relates trim_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(view, trim) } // namespace views /// @} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::trim_view) #endif // RANGES_V3_VIEW_TRIM_HPP