unpack.hpp 3.7 KB

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