Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:26:40

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 #ifndef RANGES_V3_FUNCTIONAL_PIPEABLE_HPP
0014 #define RANGES_V3_FUNCTIONAL_PIPEABLE_HPP
0015 
0016 #include <concepts/concepts.hpp>
0017 
0018 #include <range/v3/range_fwd.hpp>
0019 
0020 #include <range/v3/functional/compose.hpp>
0021 #include <range/v3/functional/concepts.hpp>
0022 #include <range/v3/utility/static_const.hpp>
0023 
0024 #include <range/v3/detail/prologue.hpp>
0025 
0026 namespace ranges
0027 {
0028     /// \addtogroup group-functional
0029     /// @{
0030 
0031     struct pipeable_base;
0032 
0033     template<typename T>
0034     RANGES_INLINE_VAR constexpr bool is_pipeable_v = META_IS_BASE_OF(pipeable_base, T);
0035 
0036     template<typename T>
0037     RANGES_INLINE_VAR constexpr bool is_pipeable_v<T &> = META_IS_BASE_OF(pipeable_base,
0038                                                                           T);
0039     template<typename T>
0040     RANGES_INLINE_VAR constexpr bool is_pipeable_v<T &&> = META_IS_BASE_OF(pipeable_base,
0041                                                                            T);
0042     template<typename T>
0043     using is_pipeable = meta::bool_<is_pipeable_v<T>>;
0044 
0045     struct make_pipeable_fn
0046     {
0047         template<typename Fun, typename PipeableBase = pipeable_base>
0048         constexpr auto operator()(Fun fun) const
0049         {
0050             struct local
0051               : Fun
0052               , PipeableBase
0053             {
0054                 constexpr explicit local(Fun && f)
0055                   : Fun(static_cast<Fun &&>(f))
0056                 {}
0057             };
0058             return local{static_cast<Fun &&>(fun)};
0059         }
0060     };
0061 
0062     /// \ingroup group-functional
0063     /// \sa `make_pipeable_fn`
0064     RANGES_INLINE_VARIABLE(make_pipeable_fn, make_pipeable)
0065 
0066     struct pipeable_access
0067     {
0068         template<typename Pipeable>
0069         struct impl : Pipeable
0070         {
0071             using Pipeable::pipe;
0072         };
0073     };
0074 
0075     struct pipeable_base
0076     {
0077     private:
0078         friend pipeable_access;
0079 
0080         // Evaluate the pipe with an argument
0081         template(typename Arg, typename Pipe)(
0082             requires (!is_pipeable_v<Arg>) AND is_pipeable_v<Pipe> AND
0083             invocable<Pipe, Arg>) // clang-format off
0084         friend constexpr auto operator|(Arg &&arg, Pipe pipe) // clang-format off
0085         {
0086             return static_cast<Pipe &&>(pipe)(static_cast<Arg &&>(arg));
0087         }
0088 
0089         // Compose two pipes
0090         template(typename Pipe0, typename Pipe1)(
0091             requires is_pipeable_v<Pipe0> AND is_pipeable_v<Pipe1>) // clang-format off
0092         friend constexpr auto operator|(Pipe0 pipe0, Pipe1 pipe1) // clang-format on
0093         {
0094             return make_pipeable(compose(detail::move(pipe1), detail::move(pipe0)));
0095         }
0096 
0097         template<typename Arg, typename Pipe>
0098         friend auto operator|=(Arg & arg, Pipe pipe) //
0099             -> CPP_broken_friend_ret(Arg &)(
0100                 requires (is_pipeable_v<Pipe>) &&
0101                     (!is_pipeable_v<Arg>) && invocable<Pipe, Arg &>)
0102         {
0103             static_cast<Pipe &&>(pipe)(arg);
0104             return arg;
0105         }
0106 
0107         // Default Pipe behavior just passes the argument to the pipe's function call
0108         // operator
0109         // clang-format off
0110         template<typename Arg, typename Pipe>
0111         static constexpr auto CPP_auto_fun(pipe)(Arg && arg, Pipe p)
0112         (
0113             return static_cast<Pipe &&>(p)(static_cast<Arg &&>(arg))
0114         )
0115         // clang-format on
0116     };
0117 
0118     template<typename>
0119     using pipeable RANGES_DEPRECATED("Please use pipeable_base instead") = pipeable_base;
0120 
0121     /// \endcond
0122 
0123     /// @}
0124 } // namespace ranges
0125 
0126 #include <range/v3/detail/epilogue.hpp>
0127 
0128 #endif