Warning, file /include/boost/hana/functional/infix.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_FUNCTIONAL_INFIX_HPP
0011 #define BOOST_HANA_FUNCTIONAL_INFIX_HPP
0012
0013 #include <boost/hana/config.hpp>
0014 #include <boost/hana/detail/decay.hpp>
0015 #include <boost/hana/functional/partial.hpp>
0016 #include <boost/hana/functional/reverse_partial.hpp>
0017
0018 #include <type_traits>
0019 #include <utility>
0020
0021
0022 namespace boost { namespace hana {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0079 constexpr auto infix = [](auto f) {
0080 return unspecified;
0081 };
0082 #else
0083 namespace infix_detail {
0084
0085
0086 template <bool left, bool right, typename F>
0087 struct infix_t {
0088 F f;
0089
0090 template <typename ...X>
0091 constexpr decltype(auto) operator()(X&& ...x) const&
0092 { return f(static_cast<X&&>(x)...); }
0093
0094 template <typename ...X>
0095 constexpr decltype(auto) operator()(X&& ...x) &
0096 { return f(static_cast<X&&>(x)...); }
0097
0098 template <typename ...X>
0099 constexpr decltype(auto) operator()(X&& ...x) &&
0100 { return std::move(f)(static_cast<X&&>(x)...); }
0101 };
0102
0103 template <bool left, bool right>
0104 struct make_infix {
0105 template <typename F>
0106 constexpr infix_t<left, right, typename detail::decay<F>::type>
0107 operator()(F&& f) const { return {static_cast<F&&>(f)}; }
0108 };
0109
0110 template <bool left, bool right>
0111 struct Infix;
0112 struct Object;
0113
0114 template <typename T>
0115 struct dispatch { using type = Object; };
0116
0117 template <bool left, bool right, typename F>
0118 struct dispatch<infix_t<left, right, F>> {
0119 using type = Infix<left, right>;
0120 };
0121
0122 template <typename, typename>
0123 struct bind_infix;
0124
0125
0126 template <>
0127 struct bind_infix<Infix<false, false>, Object> {
0128 template <typename F, typename Y>
0129 static constexpr decltype(auto) apply(F&& f, Y&& y) {
0130 return make_infix<false, true>{}(
0131 hana::reverse_partial(
0132 static_cast<F&&>(f), static_cast<Y&&>(y)
0133 )
0134 );
0135 }
0136 };
0137
0138
0139 template <>
0140 struct bind_infix<Infix<true, false>, Object> {
0141 template <typename F, typename Y>
0142 static constexpr decltype(auto) apply(F&& f, Y&& y) {
0143 return static_cast<F&&>(f)(static_cast<Y&&>(y));
0144 }
0145 };
0146
0147
0148 template <>
0149 struct bind_infix<Object, Infix<false, false>> {
0150 template <typename X, typename F>
0151 static constexpr decltype(auto) apply(X&& x, F&& f) {
0152 return make_infix<true, false>{}(
0153 hana::partial(static_cast<F&&>(f), static_cast<X&&>(x))
0154 );
0155 }
0156 };
0157
0158
0159 template <>
0160 struct bind_infix<Object, Infix<false, true>> {
0161 template <typename X, typename F>
0162 static constexpr decltype(auto) apply(X&& x, F&& f) {
0163 return static_cast<F&&>(f)(static_cast<X&&>(x));
0164 }
0165 };
0166
0167 template <typename T>
0168 using strip = typename std::remove_cv<
0169 typename std::remove_reference<T>::type
0170 >::type;
0171
0172 template <typename X, typename Y>
0173 constexpr decltype(auto) operator^(X&& x, Y&& y) {
0174 return bind_infix<
0175 typename dispatch<strip<X>>::type,
0176 typename dispatch<strip<Y>>::type
0177 >::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
0178 }
0179 }
0180
0181 BOOST_HANA_INLINE_VARIABLE constexpr infix_detail::make_infix<false, false> infix{};
0182 #endif
0183 }}
0184
0185 #endif