1 /*! 2 @file 3 Forward declares `boost::hana::unpack`. 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_FWD_UNPACK_HPP 11 #define BOOST_HANA_FWD_UNPACK_HPP 12 13 #include <boost/hana/config.hpp> 14 #include <boost/hana/core/when.hpp> 15 16 17 namespace boost { namespace hana { 18 //! Invoke a function with the elements of a Foldable as arguments. 19 //! @ingroup group-Foldable 20 //! 21 //! Given a function and a foldable structure whose length can be known at 22 //! compile-time, `unpack` invokes the function with the contents of that 23 //! structure. In other words, `unpack(xs, f)` is equivalent to `f(x...)`, 24 //! where `x...` are the elements of the structure. The length of the 25 //! structure must be known at compile-time, because the version of `f`'s 26 //! `operator()` that will be compiled depends on the number of arguments 27 //! it is called with, which has to be known at compile-time. 28 //! 29 //! To create a function that accepts a foldable instead of variadic 30 //! arguments, see `fuse` instead. 31 //! 32 //! 33 //! @param xs 34 //! The structure to expand into the function. 35 //! 36 //! @param f 37 //! A function to be invoked as `f(x...)`, where `x...` are the elements 38 //! of the structure as-if they had been linearized with `to<tuple_tag>`. 39 //! 40 //! 41 //! Example 42 //! ------- 43 //! @include example/unpack.cpp 44 //! 45 //! 46 //! Rationale: `unpack`'s name and parameter order 47 //! ---------------------------------------------- 48 //! It has been suggested a couple of times that `unpack` be called 49 //! `apply` instead, and that the parameter order be reversed to match 50 //! that of the [proposed std::apply function][1]. However, the name 51 //! `apply` is already used to denote normal function application, an use 52 //! which is consistent with the Boost MPL library and with the rest of 53 //! the world, especially the functional programming community. 54 //! Furthermore, the author of this library considers the proposed 55 //! `std::apply` to have both an unfortunate name and an unfortunate 56 //! parameter order. Indeed, taking the function as the first argument 57 //! means that using `std::apply` with a lambda function looks like 58 //! @code 59 //! std::apply([](auto ...args) { 60 //! use(args...); 61 //! }, tuple); 62 //! @endcode 63 //! 64 //! which is undeniably ugly because of the trailing `, tuple)` part 65 //! on the last line. On the other hand, taking the function as a 66 //! second argument allows one to write 67 //! @code 68 //! hana::unpack(tuple, [](auto ...args) { 69 //! use(args...); 70 //! }); 71 //! @endcode 72 //! 73 //! which looks much nicer. Because of these observations, the author 74 //! of this library feels justified to use `unpack` instead of `apply`, 75 //! and to use a sane parameter order. 76 //! 77 //! [1]: http://en.cppreference.com/w/cpp/experimental/apply 78 #ifdef BOOST_HANA_DOXYGEN_INVOKED 79 constexpr auto unpack = [](auto&& xs, auto&& f) -> decltype(auto) { 80 return tag-dispatched; 81 }; 82 #else 83 template <typename T, typename = void> 84 struct unpack_impl : unpack_impl<T, when<true>> { }; 85 86 struct unpack_t { 87 template <typename Xs, typename F> 88 constexpr decltype(auto) operator()(Xs&& xs, F&& f) const; 89 }; 90 91 BOOST_HANA_INLINE_VARIABLE constexpr unpack_t unpack{}; 92 #endif 93 }} // end namespace boost::hana 94 95 #endif // !BOOST_HANA_FWD_UNPACK_HPP 96