]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/fwd/unpack.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / hana / fwd / unpack.hpp
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 BOOST_HANA_NAMESPACE_BEGIN
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 constexpr unpack_t unpack{};
92 #endif
93 BOOST_HANA_NAMESPACE_END
94
95 #endif // !BOOST_HANA_FWD_UNPACK_HPP