/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // 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_FUNCTIONAL_PIPEABLE_HPP #define RANGES_V3_FUNCTIONAL_PIPEABLE_HPP #include #include #include #include #include #include namespace ranges { /// \addtogroup group-functional /// @{ struct pipeable_base; template RANGES_INLINE_VAR constexpr bool is_pipeable_v = META_IS_BASE_OF(pipeable_base, T); template RANGES_INLINE_VAR constexpr bool is_pipeable_v = META_IS_BASE_OF(pipeable_base, T); template RANGES_INLINE_VAR constexpr bool is_pipeable_v = META_IS_BASE_OF(pipeable_base, T); template using is_pipeable = meta::bool_>; struct make_pipeable_fn { template constexpr auto operator()(Fun fun) const { struct local : Fun , PipeableBase { constexpr explicit local(Fun && f) : Fun(static_cast(f)) {} }; return local{static_cast(fun)}; } }; /// \ingroup group-functional /// \sa `make_pipeable_fn` RANGES_INLINE_VARIABLE(make_pipeable_fn, make_pipeable) struct pipeable_access { template struct impl : Pipeable { using Pipeable::pipe; }; }; struct pipeable_base { private: friend pipeable_access; // Evaluate the pipe with an argument template(typename Arg, typename Pipe)( requires (!is_pipeable_v) AND is_pipeable_v AND invocable) // clang-format off friend constexpr auto operator|(Arg &&arg, Pipe pipe) // clang-format off { return static_cast(pipe)(static_cast(arg)); } // Compose two pipes template(typename Pipe0, typename Pipe1)( requires is_pipeable_v AND is_pipeable_v) // clang-format off friend constexpr auto operator|(Pipe0 pipe0, Pipe1 pipe1) // clang-format on { return make_pipeable(compose(detail::move(pipe1), detail::move(pipe0))); } template friend auto operator|=(Arg & arg, Pipe pipe) // -> CPP_broken_friend_ret(Arg &)( requires (is_pipeable_v) && (!is_pipeable_v) && invocable) { static_cast(pipe)(arg); return arg; } // Default Pipe behavior just passes the argument to the pipe's function call // operator // clang-format off template static constexpr auto CPP_auto_fun(pipe)(Arg && arg, Pipe p) ( return static_cast(p)(static_cast(arg)) ) // clang-format on }; template using pipeable RANGES_DEPRECATED("Please use pipeable_base instead") = pipeable_base; /// \endcond /// @} } // namespace ranges #include #endif