diff options
Diffstat (limited to 'boost/hana/fwd/unpack.hpp')
-rw-r--r-- | boost/hana/fwd/unpack.hpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/boost/hana/fwd/unpack.hpp b/boost/hana/fwd/unpack.hpp new file mode 100644 index 0000000000..43a4941f3e --- /dev/null +++ b/boost/hana/fwd/unpack.hpp @@ -0,0 +1,103 @@ +/*! +@file +Forward declares `boost::hana::unpack`. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_FWD_UNPACK_HPP +#define BOOST_HANA_FWD_UNPACK_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> + + +BOOST_HANA_NAMESPACE_BEGIN + //! Invoke a function with the elements of a Foldable as arguments. + //! @ingroup group-Foldable + //! + //! Given a function and a foldable structure whose length can be known at + //! compile-time, `unpack` invokes the function with the contents of that + //! structure. In other words, `unpack(xs, f)` is equivalent to `f(x...)`, + //! where `x...` are the elements of the structure. The length of the + //! structure must be known at compile-time, because the version of `f`'s + //! `operator()` that will be compiled depends on the number of arguments + //! it is called with, which has to be known at compile-time. + //! + //! To create a function that accepts a foldable instead of variadic + //! arguments, see `fuse` instead. + //! + //! + //! @param xs + //! The structure to expand into the function. + //! + //! @param f + //! A function to be invoked as `f(x...)`, where `x...` are the elements + //! of the structure as-if they had been linearized with `to<tuple_tag>`. + //! + //! + //! Example + //! ------- + //! @include example/unpack.cpp + //! + //! + //! Benchmarks + //! ---------- + //! <div class="benchmark-chart" + //! style="min-width: 310px; height: 400px; margin: 0 auto" + //! data-dataset="benchmark.unpack.compile.json"> + //! </div> + //! + //! + //! Rationale: `unpack`'s name and parameter order + //! ---------------------------------------------- + //! It has been suggested a couple of times that `unpack` be called + //! `apply` instead, and that the parameter order be reversed to match + //! that of the [proposed std::apply function][1]. However, the name + //! `apply` is already used to denote normal function application, an use + //! which is consistent with the Boost MPL library and with the rest of + //! the world, especially the functional programming community. + //! Furthermore, the author of this library considers the proposed + //! `std::apply` to have both an unfortunate name and an unfortunate + //! parameter order. Indeed, taking the function as the first argument + //! means that using `std::apply` with a lambda function looks like + //! @code + //! std::apply([](auto ...args) { + //! use(args...); + //! }, tuple); + //! @endcode + //! + //! which is undeniably ugly because of the trailing `, tuple)` part + //! on the last line. On the other hand, taking the function as a + //! second argument allows one to write + //! @code + //! hana::unpack(tuple, [](auto ...args) { + //! use(args...); + //! }); + //! @endcode + //! + //! which looks much nicer. Because of these observations, the author + //! of this library feels justified to use `unpack` instead of `apply`, + //! and to use a sane parameter order. + //! + //! [1]: http://en.cppreference.com/w/cpp/experimental/apply +#ifdef BOOST_HANA_DOXYGEN_INVOKED + constexpr auto unpack = [](auto&& xs, auto&& f) -> decltype(auto) { + return tag-dispatched; + }; +#else + template <typename T, typename = void> + struct unpack_impl : unpack_impl<T, when<true>> { }; + + struct unpack_t { + template <typename Xs, typename F> + constexpr decltype(auto) operator()(Xs&& xs, F&& f) const; + }; + + constexpr unpack_t unpack{}; +#endif +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_FWD_UNPACK_HPP |