1 /*! 2 @file 3 Defines `boost::hana::flip`. 4 5 @copyright Louis Dionne 2013-2017 6 Distributed under the Boost Software License, Version 1.0. 7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 10 #ifndef BOOST_HANA_FUNCTIONAL_FLIP_HPP 11 #define BOOST_HANA_FUNCTIONAL_FLIP_HPP 12 13 #include <boost/hana/config.hpp> 14 #include <boost/hana/detail/create.hpp> 15 16 #include <utility> 17 18 19 BOOST_HANA_NAMESPACE_BEGIN 20 //! @ingroup group-functional 21 //! Invoke a function with its two first arguments reversed. 22 //! 23 //! Specifically, `flip(f)` is a function such that 24 //! @code 25 //! flip(f)(x, y, z...) == f(y, x, z...) 26 //! @endcode 27 //! 28 //! ### Example 29 //! @include example/functional/flip.cpp 30 #ifdef BOOST_HANA_DOXYGEN_INVOKED __anon0aef5bd60102(auto&& f) 31 constexpr auto flip = [](auto&& f) { 32 return [perfect-capture](auto&& x, auto&& y, auto&& ...z) -> decltype(auto) { 33 return forwarded(f)(forwarded(y), forwarded(x), forwarded(z)...); 34 }; 35 }; 36 #else 37 template <typename F> 38 struct flip_t { 39 F f; 40 41 template <typename X, typename Y, typename ...Z> 42 constexpr decltype(auto) operator()(X&& x, Y&& y, Z&& ...z) const& { 43 return f( 44 static_cast<Y&&>(y), 45 static_cast<X&&>(x), 46 static_cast<Z&&>(z)... 47 ); 48 } 49 50 template <typename X, typename Y, typename ...Z> 51 constexpr decltype(auto) operator()(X&& x, Y&& y, Z&& ...z) & { 52 return f( 53 static_cast<Y&&>(y), 54 static_cast<X&&>(x), 55 static_cast<Z&&>(z)... 56 ); 57 } 58 59 template <typename X, typename Y, typename ...Z> 60 constexpr decltype(auto) operator()(X&& x, Y&& y, Z&& ...z) && { 61 return std::move(f)( 62 static_cast<Y&&>(y), 63 static_cast<X&&>(x), 64 static_cast<Z&&>(z)... 65 ); 66 } 67 }; 68 69 constexpr detail::create<flip_t> flip{}; 70 #endif 71 BOOST_HANA_NAMESPACE_END 72 73 #endif // !BOOST_HANA_FUNCTIONAL_FLIP_HPP 74