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::lockstep`.
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_LOCKSTEP_HPP
0011 #define BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP
0012 
0013 #include <boost/hana/basic_tuple.hpp>
0014 #include <boost/hana/config.hpp>
0015 #include <boost/hana/detail/decay.hpp>
0016 
0017 #include <cstddef>
0018 #include <utility>
0019 
0020 
0021 namespace boost { namespace hana {
0022     //! @ingroup group-functional
0023     //! Invoke a function with the result of invoking other functions on its
0024     //! arguments, in lockstep.
0025     //!
0026     //! Specifically, `lockstep(f)(g1, ..., gN)` is a function such that
0027     //! @code
0028     //!     lockstep(f)(g1, ..., gN)(x1, ..., xN) == f(g1(x1), ..., gN(xN))
0029     //! @endcode
0030     //!
0031     //! Since each `g` is invoked on its corresponding argument in lockstep,
0032     //! the number of arguments must match the number of `g`s.
0033     //!
0034     //!
0035     //! Example
0036     //! -------
0037     //! @include example/functional/lockstep.cpp
0038 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0039     constexpr auto lockstep = [](auto&& f, auto&& ...g) {
0040         return [perfect-capture](auto&& ...x) -> decltype(auto) {
0041             return forwarded(f)(forwarded(g)(forwarded(x))...);
0042         };
0043     };
0044 #else
0045     template <typename Indices, typename F, typename ...G>
0046     struct lockstep_t;
0047 
0048     template <typename F>
0049     struct pre_lockstep_t;
0050 
0051     struct make_pre_lockstep_t {
0052         struct secret { };
0053         template <typename F>
0054         constexpr pre_lockstep_t<typename detail::decay<F>::type> operator()(F&& f) const {
0055             return {static_cast<F&&>(f)};
0056         }
0057     };
0058 
0059     template <std::size_t ...n, typename F, typename ...G>
0060     struct lockstep_t<std::index_sequence<n...>, F, G...> {
0061         template <typename ...T>
0062         constexpr lockstep_t(make_pre_lockstep_t::secret, T&& ...t)
0063             : storage_{static_cast<T&&>(t)...}
0064         { }
0065 
0066         basic_tuple<F, G...> storage_;
0067 
0068         template <typename ...X>
0069         constexpr decltype(auto) operator()(X&& ...x) const& {
0070             return hana::at_c<0>(storage_)(
0071                 hana::at_c<n+1>(storage_)(static_cast<X&&>(x))...
0072             );
0073         }
0074 
0075         template <typename ...X>
0076         constexpr decltype(auto) operator()(X&& ...x) & {
0077             return hana::at_c<0>(storage_)(
0078                 hana::at_c<n+1>(storage_)(static_cast<X&&>(x))...
0079             );
0080         }
0081 
0082         template <typename ...X>
0083         constexpr decltype(auto) operator()(X&& ...x) && {
0084             return static_cast<F&&>(hana::at_c<0>(storage_))(
0085                 static_cast<G&&>(hana::at_c<n+1>(storage_))(static_cast<X&&>(x))...
0086             );
0087         }
0088     };
0089 
0090     template <typename F>
0091     struct pre_lockstep_t {
0092         F f;
0093 
0094         template <typename ...G>
0095         constexpr lockstep_t<std::make_index_sequence<sizeof...(G)>, F,
0096                              typename detail::decay<G>::type...>
0097         operator()(G&& ...g) const& {
0098             return {make_pre_lockstep_t::secret{}, this->f, static_cast<G&&>(g)...};
0099         }
0100 
0101         template <typename ...G>
0102         constexpr lockstep_t<std::make_index_sequence<sizeof...(G)>, F,
0103                              typename detail::decay<G>::type...>
0104         operator()(G&& ...g) && {
0105             return {make_pre_lockstep_t::secret{}, static_cast<F&&>(this->f),
0106                                                    static_cast<G&&>(g)...};
0107         }
0108     };
0109 
0110     BOOST_HANA_INLINE_VARIABLE constexpr make_pre_lockstep_t lockstep{};
0111 #endif
0112 }} // end namespace boost::hana
0113 
0114 #endif // !BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP