123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #ifndef BOOST_HANA_FUNCTIONAL_INFIX_HPP
- #define BOOST_HANA_FUNCTIONAL_INFIX_HPP
- #include <boost/hana/config.hpp>
- #include <boost/hana/functional/partial.hpp>
- #include <boost/hana/functional/reverse_partial.hpp>
- #include <type_traits>
- #include <utility>
- BOOST_HANA_NAMESPACE_BEGIN
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #ifdef BOOST_HANA_DOXYGEN_INVOKED
- constexpr auto infix = [](auto f) {
- return unspecified;
- };
- #else
- namespace infix_detail {
-
-
- template <bool left, bool right, typename F>
- struct infix_t {
- F f;
- template <typename ...X>
- constexpr decltype(auto) operator()(X&& ...x) const&
- { return f(static_cast<X&&>(x)...); }
- template <typename ...X>
- constexpr decltype(auto) operator()(X&& ...x) &
- { return f(static_cast<X&&>(x)...); }
- template <typename ...X>
- constexpr decltype(auto) operator()(X&& ...x) &&
- { return std::move(f)(static_cast<X&&>(x)...); }
- };
- template <bool left, bool right>
- struct make_infix {
- template <typename F>
- constexpr infix_t<left, right, typename std::decay<F>::type>
- operator()(F&& f) const { return {static_cast<F&&>(f)}; }
- };
- template <bool left, bool right>
- struct Infix;
- struct Object;
- template <typename T>
- struct dispatch { using type = Object; };
- template <bool left, bool right, typename F>
- struct dispatch<infix_t<left, right, F>> {
- using type = Infix<left, right>;
- };
- template <typename, typename>
- struct bind_infix;
-
- template <>
- struct bind_infix<Infix<false, false>, Object> {
- template <typename F, typename Y>
- static constexpr decltype(auto) apply(F&& f, Y&& y) {
- return make_infix<false, true>{}(
- hana::reverse_partial(
- static_cast<F&&>(f), static_cast<Y&&>(y)
- )
- );
- }
- };
-
- template <>
- struct bind_infix<Infix<true, false>, Object> {
- template <typename F, typename Y>
- static constexpr decltype(auto) apply(F&& f, Y&& y) {
- return static_cast<F&&>(f)(static_cast<Y&&>(y));
- }
- };
-
- template <>
- struct bind_infix<Object, Infix<false, false>> {
- template <typename X, typename F>
- static constexpr decltype(auto) apply(X&& x, F&& f) {
- return make_infix<true, false>{}(
- hana::partial(static_cast<F&&>(f), static_cast<X&&>(x))
- );
- }
- };
-
- template <>
- struct bind_infix<Object, Infix<false, true>> {
- template <typename X, typename F>
- static constexpr decltype(auto) apply(X&& x, F&& f) {
- return static_cast<F&&>(f)(static_cast<X&&>(x));
- }
- };
- template <typename T>
- using strip = typename std::remove_cv<
- typename std::remove_reference<T>::type
- >::type;
- template <typename X, typename Y>
- constexpr decltype(auto) operator^(X&& x, Y&& y) {
- return bind_infix<
- typename dispatch<strip<X>>::type,
- typename dispatch<strip<Y>>::type
- >::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
- }
- }
- constexpr infix_detail::make_infix<false, false> infix{};
- #endif
- BOOST_HANA_NAMESPACE_END
- #endif
|