Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
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_FILTER_HPP
0015 #define RANGES_V3_VIEW_FILTER_HPP
0016 
0017 #include <range/v3/range_fwd.hpp>
0018 
0019 #include <range/v3/functional/bind_back.hpp>
0020 #include <range/v3/functional/compose.hpp>
0021 #include <range/v3/functional/not_fn.hpp>
0022 #include <range/v3/utility/static_const.hpp>
0023 #include <range/v3/view/remove_if.hpp>
0024 
0025 #include <range/v3/detail/prologue.hpp>
0026 
0027 namespace ranges
0028 {
0029     /// \addtogroup group-views
0030     /// @{
0031     template<typename Rng, typename Pred>
0032     struct filter_view : remove_if_view<Rng, logical_negate<Pred>>
0033     {
0034         filter_view() = default;
0035         constexpr filter_view(Rng rng, Pred pred)
0036           : filter_view::remove_if_view{std::move(rng), not_fn(std::move(pred))}
0037         {}
0038     };
0039 
0040 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0041     template(typename Rng, typename Pred)(
0042         requires input_range<Rng> AND indirect_unary_predicate<Pred, iterator_t<Rng>> AND
0043             view_<Rng> AND std::is_object<Pred>::value) //
0044         filter_view(Rng &&, Pred)
0045             ->filter_view<views::all_t<Rng>, Pred>;
0046 #endif
0047 
0048     namespace views
0049     {
0050         struct filter_fn;
0051 
0052         /// Given a source range and a unary predicate,
0053         /// present a view of the elements that satisfy the predicate.
0054         struct cpp20_filter_base_fn
0055         {
0056             template(typename Rng, typename Pred)(
0057                 requires viewable_range<Rng> AND input_range<Rng> AND
0058                     indirect_unary_predicate<Pred, iterator_t<Rng>>)
0059             constexpr filter_view<all_t<Rng>, Pred> operator()(Rng && rng, Pred pred) //
0060                 const
0061             {
0062                 return filter_view<all_t<Rng>, Pred>{all(static_cast<Rng &&>(rng)),
0063                                                      std::move(pred)};
0064             }
0065         };
0066 
0067         struct cpp20_filter_fn : cpp20_filter_base_fn
0068         {
0069             using cpp20_filter_base_fn::operator();
0070 
0071             template<typename Pred>
0072             constexpr auto operator()(Pred pred) const
0073             {
0074                 return make_view_closure(
0075                     bind_back(cpp20_filter_base_fn{}, std::move(pred)));
0076             }
0077         };
0078 
0079         /// Given a source range, unary predicate, and optional projection,
0080         /// present a view of the elements that satisfy the predicate.
0081         struct filter_base_fn : cpp20_filter_base_fn
0082         {
0083             using cpp20_filter_base_fn::operator();
0084 
0085             template(typename Rng, typename Pred, typename Proj)(
0086                 requires viewable_range<Rng> AND input_range<Rng> AND
0087                     indirect_unary_predicate<Pred, projected<iterator_t<Rng>, Proj>>)
0088             constexpr filter_view<all_t<Rng>, composed<Pred, Proj>> //
0089             operator()(Rng && rng, Pred pred, Proj proj) const
0090             {
0091                 return filter_view<all_t<Rng>, composed<Pred, Proj>>{
0092                     all(static_cast<Rng &&>(rng)),
0093                     compose(std::move(pred), std::move(proj))};
0094             }
0095         };
0096 
0097         /// # ranges::views::filter
0098         /// The filter view takes in a predicate function `T -> bool` and converts an
0099         /// input range of `T` into an output range of `T` by keeping all elements for
0100         /// which the predicate returns true.
0101         ///
0102         /// ## Example
0103         /// \snippet example/view/filter.cpp filter example
0104         ///
0105         /// ### Output
0106         /// \include example/view/filter_golden.txt
0107         ///
0108         /// ## Syntax
0109         /// ```cpp
0110         /// auto output_range = input_range | ranges::views::filter(filter_func);
0111         /// ```
0112         ///
0113         /// ## Parameters
0114         /// <pre><b>filter_func</b></pre>
0115         ///   - Called once for each element of the input range
0116         ///   - Returns true for elements that should present in the output range
0117         ///
0118         /// <pre><b>input_range</b></pre>
0119         ///   - The range of elements to filter
0120         ///   - Reference type: `T`
0121         ///
0122         /// <pre><b>output_range</b></pre>
0123         ///   - The range of filtered values
0124         ///     - Is either a `forward_range` or the concept satisfied by the input
0125         ///     - Is a `common_range` if the input is a `common_range`
0126         ///     - Is not a `sized_range` or `borrowed_range`
0127         ///   - Reference type: `T`
0128         ///
0129         struct filter_fn : filter_base_fn
0130         {
0131             using filter_base_fn::operator();
0132 
0133             template<typename Pred>
0134             constexpr auto operator()(Pred pred) const
0135             {
0136                 return make_view_closure(bind_back(filter_base_fn{}, std::move(pred)));
0137             }
0138 
0139             template(typename Pred, typename Proj)(
0140                 requires (!range<Pred>))
0141             constexpr auto operator()(Pred pred, Proj proj) const
0142             {
0143                 return make_view_closure(
0144                     bind_back(filter_base_fn{}, std::move(pred), std::move(proj)));
0145             }
0146         };
0147 
0148         /// \relates filter_fn
0149         /// \ingroup group-views
0150         RANGES_INLINE_VARIABLE(filter_fn, filter)
0151     } // namespace views
0152 
0153     namespace cpp20
0154     {
0155         namespace views
0156         {
0157             RANGES_INLINE_VARIABLE(ranges::views::cpp20_filter_fn, filter)
0158         }
0159         template(typename V, typename Pred)(
0160             requires input_range<V> AND indirect_unary_predicate<Pred, iterator_t<V>> AND
0161                 view_<V> AND std::is_object<Pred>::value) //
0162             using filter_view = ranges::filter_view<V, Pred>;
0163     } // namespace cpp20
0164     /// @}
0165 } // namespace ranges
0166 
0167 #include <range/v3/detail/epilogue.hpp>
0168 #include <range/v3/detail/satisfy_boost_range.hpp>
0169 RANGES_SATISFY_BOOST_RANGE(::ranges::filter_view)
0170 
0171 #endif