File indexing completed on 2025-12-15 10:26:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
0063
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
0081 template(typename Arg, typename Pipe)(
0082 requires (!is_pipeable_v<Arg>) AND is_pipeable_v<Pipe> AND
0083 invocable<Pipe, Arg>)
0084 friend constexpr auto operator|(Arg &&arg, Pipe pipe)
0085 {
0086 return static_cast<Pipe &&>(pipe)(static_cast<Arg &&>(arg));
0087 }
0088
0089
0090 template(typename Pipe0, typename Pipe1)(
0091 requires is_pipeable_v<Pipe0> AND is_pipeable_v<Pipe1>)
0092 friend constexpr auto operator|(Pipe0 pipe0, Pipe1 pipe1)
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
0108
0109
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
0116 };
0117
0118 template<typename>
0119 using pipeable RANGES_DEPRECATED("Please use pipeable_base instead") = pipeable_base;
0120
0121
0122
0123
0124 }
0125
0126 #include <range/v3/detail/epilogue.hpp>
0127
0128 #endif