Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:59

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Johel Guerrero 2019
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-views
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 // TODO: underconstrained
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>)) // TODO: underconstrained
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         /// \relates trim_fn
0152         /// \ingroup group-views
0153         RANGES_INLINE_VARIABLE(trim_fn, trim)
0154     } // namespace views
0155     /// @}
0156 } // namespace ranges
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 // RANGES_V3_VIEW_TRIM_HPP