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 Eric Niebler 2014-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_VIEW_HPP
0015 #define RANGES_V3_VIEW_VIEW_HPP
0016 
0017 #include <type_traits>
0018 #include <utility>
0019 
0020 #include <meta/meta.hpp>
0021 
0022 #include <range/v3/range_fwd.hpp>
0023 
0024 #include <range/v3/functional/compose.hpp>
0025 #include <range/v3/functional/concepts.hpp>
0026 #include <range/v3/functional/pipeable.hpp>
0027 #include <range/v3/functional/reference_wrapper.hpp>
0028 #include <range/v3/range/concepts.hpp>
0029 #include <range/v3/range/traits.hpp>
0030 #include <range/v3/utility/static_const.hpp>
0031 
0032 #include <range/v3/detail/prologue.hpp>
0033 
0034 namespace ranges
0035 {
0036     /// \addtogroup group-views
0037     /// @{
0038 
0039     /// \cond
0040     namespace detail
0041     {
0042         struct dereference_fn
0043         {
0044             // clang-format off
0045             template<typename I>
0046             constexpr auto CPP_auto_fun(operator())(I &&i) (const)
0047             (
0048                 return *(I &&) i
0049             )
0050             // clang-format on
0051         };
0052 
0053         struct view_closure_base_
0054         {};
0055     } // namespace detail
0056       /// \endcond
0057 
0058     // clang-format off
0059     /// \concept simple_view_impl_
0060     /// \brief The \c simple_view_impl_ concept
0061     template(typename Rng)(
0062     concept (simple_view_impl_)(Rng),
0063         same_as<iterator_t<Rng>, iterator_t<Rng const>> AND
0064         same_as<sentinel_t<Rng>, sentinel_t<Rng const>>);
0065 
0066     /// \concept simple_view_
0067     /// \brief The \c simple_view_ concept
0068     template<typename Rng>
0069     CPP_concept simple_view_ =
0070         view_<Rng> &&
0071         range<Rng const> &&
0072         CPP_concept_ref(ranges::simple_view_impl_, Rng);
0073 
0074     /// \concept invocable_view_closure_
0075     /// \brief The \c invocable_view_closure_ concept
0076     template(typename ViewFn, typename Rng)(
0077     concept (invocable_view_closure_)(ViewFn, Rng),
0078         !derived_from<invoke_result_t<ViewFn, Rng>, detail::view_closure_base_>);
0079 
0080     /// \concept invocable_view_closure
0081     /// \brief The \c invocable_view_closure concept
0082     template<typename ViewFn, typename Rng>
0083     CPP_concept invocable_view_closure =
0084         invocable<ViewFn, Rng> &&
0085         CPP_concept_ref(ranges::invocable_view_closure_, ViewFn, Rng);
0086     // clang-format on
0087 
0088     template<typename Rng>
0089     constexpr bool simple_view() noexcept
0090     {
0091         return (bool)simple_view_<Rng>;
0092     }
0093 
0094     struct make_view_closure_fn
0095     {
0096         template<typename Fun>
0097         constexpr views::view_closure<Fun> operator()(Fun fun) const
0098         {
0099             return views::view_closure<Fun>{static_cast<Fun &&>(fun)};
0100         }
0101     };
0102 
0103     /// \ingroup group-views
0104     /// \sa make_view_closure_fn
0105     RANGES_INLINE_VARIABLE(make_view_closure_fn, make_view_closure)
0106 
0107     namespace views
0108     {
0109         struct RANGES_STRUCT_WITH_ADL_BARRIER(view_closure_base)
0110           : detail::view_closure_base_
0111         {
0112             // Piping requires viewable_ranges. Pipeing a value into a closure
0113             // should not yield another closure.
0114             template(typename Rng, typename ViewFn)(
0115                 requires viewable_range<Rng> AND
0116                     invocable_view_closure<ViewFn, Rng>)
0117             friend constexpr auto operator|(Rng && rng, view_closure<ViewFn> vw)
0118             {
0119                 return static_cast<ViewFn &&>(vw)(static_cast<Rng &&>(rng));
0120             }
0121 
0122 #ifndef RANGES_WORKAROUND_CLANG_43400
0123             // This overload is deleted because when piping a range into an
0124             // view, it must be moved in.
0125             template<typename Rng, typename ViewFn>         // **************************
0126             friend constexpr auto                           // **************************
0127             operator|(Rng &&, view_closure<ViewFn> const &) // ******* READ THIS ********
0128                                                             // **** IF YOUR COMPILE *****
0129                 -> CPP_broken_friend_ret(Rng)(              // ****** BREAKS HERE *******
0130                     requires range<Rng> &&                  // **************************
0131                     (!viewable_range<Rng>)) = delete;       // **************************
0132             // **************************************************************************
0133             // *    When piping a range into an adaptor, the range must satisfy the     *
0134             // *    "viewable_range" concept. A range is viewable when either or both   *
0135             // *    of these things are true:                                           *
0136             // *      - The range is an lvalue (not a temporary object), OR             *
0137             // *      - The range is a view (not a container).                          *
0138             // **************************************************************************
0139 #endif
0140 
0141             template<typename ViewFn, typename Pipeable>
0142             friend constexpr auto operator|(view_closure<ViewFn> vw, Pipeable pipe)
0143                 -> CPP_broken_friend_ret(view_closure<composed<Pipeable, ViewFn>>)(
0144                     requires (is_pipeable_v<Pipeable>))
0145             {
0146                 return make_view_closure(
0147                     compose(static_cast<Pipeable &&>(pipe), static_cast<ViewFn &&>(vw)));
0148             }
0149         };
0150 
0151 #ifdef RANGES_WORKAROUND_CLANG_43400
0152         namespace RANGES_ADL_BARRIER_FOR(view_closure_base)
0153         {
0154             // This overload is deleted because when piping a range into an
0155             // view, it must be moved in.
0156             template(typename Rng, typename ViewFn)(           // ************************
0157                 requires range<Rng> AND (!viewable_range<Rng>))// ************************
0158             constexpr Rng                                      // ************************
0159             operator|(Rng &&, view_closure<ViewFn> const &)    // ****** READ THIS *******
0160                 = delete;                                      // *** IF YOUR COMPILE ****
0161                                                                // ***** BREAKS HERE ******
0162                                                                // ************************
0163                                                                // ************************
0164             // ***************************************************************************
0165             // *    When piping a range into an adaptor, the range must satisfy the      *
0166             // *    "viewable_range" concept. A range is viewable when either or both    *
0167             // *    of these things are true:                                            *
0168             // *      - The range is an lvalue (not a temporary object), OR              *
0169             // *      - The range is a view (not a container).                           *
0170             // ***************************************************************************
0171         } // namespace )
0172 #endif    // RANGES_WORKAROUND_CLANG_43400
0173 
0174         template<typename ViewFn>
0175         struct RANGES_EMPTY_BASES view_closure
0176           : view_closure_base
0177           , ViewFn
0178         {
0179             view_closure() = default;
0180 
0181             constexpr explicit view_closure(ViewFn fn)
0182               : ViewFn(static_cast<ViewFn &&>(fn))
0183             {}
0184         };
0185 
0186         /// \cond
0187         /// DEPRECATED STUFF
0188         struct view_access_
0189         {
0190             template<typename ViewFn>
0191             struct impl
0192             {
0193                 // clang-format off
0194                 template<typename... Ts, typename V = ViewFn>
0195                 static constexpr auto CPP_auto_fun(bind)(Ts &&... ts)
0196                 (
0197                     return V::bind(static_cast<Ts &&>(ts)...)
0198                 )
0199                 // clang-format on
0200             };
0201         };
0202 
0203         using view_access RANGES_DEPRECATED(
0204             "view_access and views::view<> are deprecated. Please "
0205             "replace view<> with view_closure<> and discontinue use of view_access.") =
0206             view_access_;
0207 
0208         template<typename>
0209         struct old_view_;
0210 
0211         struct make_view_fn_
0212         {
0213             template<typename Fun>
0214             constexpr old_view_<Fun> operator()(Fun fun) const
0215             {
0216                 return old_view_<Fun>{static_cast<Fun &&>(fun)};
0217             }
0218         };
0219         using make_view_fn RANGES_DEPRECATED(
0220             "make_view_fn is deprecated. Please use "
0221             "make_view_closure instead.") = make_view_fn_;
0222 
0223         namespace
0224         {
0225             RANGES_DEPRECATED(
0226                 "make_view and views::view<> has been deprecated. Please switch to "
0227                 "make_view_closure and views::view_closure.")
0228             RANGES_INLINE_VAR constexpr auto & make_view =
0229                 static_const<make_view_fn_>::value;
0230         } // namespace
0231 
0232         template<typename ViewFn>
0233         struct old_view_ : pipeable_base
0234         {
0235         private:
0236             ViewFn vw_;
0237             friend pipeable_access;
0238 
0239             // Piping requires range arguments or lvalue containers.
0240             template(typename Rng, typename Vw)(
0241                 requires viewable_range<Rng> AND invocable<ViewFn &, Rng>)
0242             static constexpr auto pipe(Rng && rng, Vw && v)
0243             {
0244                 return v.vw_(static_cast<Rng &&>(rng));
0245             }
0246 
0247         public:
0248             old_view_() = default;
0249 
0250             constexpr explicit old_view_(ViewFn a) noexcept(
0251                 std::is_nothrow_move_constructible<ViewFn>::value)
0252               : vw_(std::move(a))
0253             {}
0254 
0255             // Calling directly requires a viewable_range.
0256             template(typename Rng, typename... Rest)(
0257                 requires viewable_range<Rng> AND invocable<ViewFn const &, Rng, Rest...>)
0258             constexpr invoke_result_t<ViewFn const &, Rng, Rest...> //
0259             operator()(Rng && rng, Rest &&... rest) const
0260             {
0261                 return vw_(static_cast<Rng &&>(rng), static_cast<Rest &&>(rest)...);
0262             }
0263 
0264             // Currying overload.
0265             // clang-format off
0266             template<typename... Ts, typename V = ViewFn>
0267             constexpr auto CPP_auto_fun(operator())(Ts &&... ts)(const)
0268             (
0269                 return make_view_fn_{}(
0270                     view_access_::impl<V>::bind(vw_, static_cast<Ts &&>(ts)...))
0271             )
0272             // clang-format on
0273         };
0274 
0275         template<typename ViewFn>
0276         using view RANGES_DEPRECATED(
0277             "The views::view<> template is deprecated. Please switch to view_closure") =
0278             old_view_<ViewFn>;
0279         /// \endcond
0280     } // namespace views
0281 
0282     template<typename ViewFn>
0283     RANGES_INLINE_VAR constexpr bool is_pipeable_v<views::view_closure<ViewFn>> = true;
0284     /// @}
0285 } // namespace ranges
0286 
0287 #include <range/v3/detail/epilogue.hpp>
0288 
0289 #endif