Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:58

0001 /*!
0002 @file
0003 Defines `boost::hana::capture`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_FUNCTIONAL_CAPTURE_HPP
0011 #define BOOST_HANA_FUNCTIONAL_CAPTURE_HPP
0012 
0013 #include <boost/hana/basic_tuple.hpp>
0014 #include <boost/hana/config.hpp>
0015 #include <boost/hana/detail/decay.hpp>
0016 #include <boost/hana/functional/partial.hpp>
0017 
0018 #include <cstddef>
0019 #include <utility>
0020 
0021 
0022 namespace boost { namespace hana {
0023     //! @ingroup group-functional
0024     //! Create a function capturing the given variables.
0025     //!
0026     //! Given 0 or more variables, `capture` creates a closure that can be
0027     //! used to partially apply a function. This is very similar to `partial`,
0028     //! except that `capture` allows the partially applied function to be
0029     //! specified later. Specifically, `capture(vars...)` is a function object
0030     //! taking a function `f` and returning `f` partially applied to `vars...`.
0031     //! In other words,
0032     //! @code
0033     //!     capture(vars...)(f)(args...) == f(vars..., args...)
0034     //! @endcode
0035     //!
0036     //! @note
0037     //! The arity of `f` must match the total number of arguments passed to
0038     //! it, i.e. `sizeof...(vars) + sizeof...(args)`.
0039     //!
0040     //!
0041     //! Example
0042     //! -------
0043     //! @include example/functional/capture.cpp
0044 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0045     constexpr auto capture = [](auto&& ...variables) {
0046         return [perfect-capture](auto&& f) {
0047             return [perfect-capture](auto&& ...args) -> decltype(auto) {
0048                 return forwarded(f)(forwarded(variables)..., forwarded(args)...);
0049             };
0050         };
0051     };
0052 #else
0053     namespace detail {
0054         template <typename F, typename Closure, std::size_t ...i>
0055         constexpr auto apply_capture(F&& f, Closure&& closure, std::index_sequence<i...>) {
0056             return hana::partial(static_cast<F&&>(f),
0057                 hana::at_c<i>(static_cast<Closure&&>(closure).storage_)...
0058             );
0059         }
0060     }
0061 
0062     template <typename ...X>
0063     struct capture_t;
0064 
0065     struct make_capture_t {
0066         struct secret { };
0067         template <typename ...X>
0068         constexpr capture_t<typename detail::decay<X>::type...>
0069         operator()(X&& ...x) const {
0070             return {secret{}, static_cast<X&&>(x)...};
0071         }
0072     };
0073 
0074     template <typename ...X>
0075     struct capture_t {
0076         template <typename ...Y>
0077         constexpr capture_t(make_capture_t::secret, Y&& ...y)
0078             : storage_{static_cast<Y&&>(y)...}
0079         { }
0080 
0081         basic_tuple<X...> storage_;
0082 
0083         template <typename F>
0084         constexpr auto operator()(F&& f) const& {
0085             return detail::apply_capture(
0086                 static_cast<F&&>(f), *this,
0087                 std::make_index_sequence<sizeof...(X)>{}
0088             );
0089         }
0090 
0091         template <typename F>
0092         constexpr auto operator()(F&& f) & {
0093             return detail::apply_capture(
0094                 static_cast<F&&>(f), *this,
0095                 std::make_index_sequence<sizeof...(X)>{}
0096             );
0097         }
0098 
0099         template <typename F>
0100         constexpr auto operator()(F&& f) && {
0101             return detail::apply_capture(
0102                 static_cast<F&&>(f), static_cast<capture_t&&>(*this),
0103                 std::make_index_sequence<sizeof...(X)>{}
0104             );
0105         }
0106     };
0107 
0108     BOOST_HANA_INLINE_VARIABLE constexpr make_capture_t capture{};
0109 #endif
0110 }} // end namespace boost::hana
0111 
0112 #endif // !BOOST_HANA_FUNCTIONAL_CAPTURE_HPP