Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-16 07:35:13

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <functional>
0012 #include <utility>
0013 
0014 namespace Acts {
0015 
0016 namespace detail {
0017 
0018 /// @brief Base case: apply a single function to a value.
0019 /// @param x The input value
0020 /// @param f The function to apply
0021 /// @return The result of invoking @p f with @p x
0022 template <typename T, typename F>
0023 decltype(auto) applyRight(T&& x, const F& f) {
0024   return std::invoke(f, std::forward<T>(x));
0025 }
0026 
0027 /// @brief Recursive case: apply the last function first, then fold right.
0028 /// @param x The input value
0029 /// @param f The outermost function to apply last
0030 /// @param rest The remaining functions, applied right-to-left
0031 /// @return The result of the right-to-left function chain
0032 template <typename T, typename F, typename... Rest>
0033 decltype(auto) applyRight(T&& x, const F& f, const Rest&... rest) {
0034   return std::invoke(f, applyRight(std::forward<T>(x), rest...));
0035 }
0036 
0037 }  // namespace detail
0038 
0039 /// @brief Compose multiple callables into a single callable, applied
0040 ///        right-to-left (mathematical convention).
0041 ///
0042 /// Given `compose(f, g, h)`, the returned callable computes `f(g(h(x)))`.
0043 /// All callables are stored exactly once in a tuple, avoiding the nested-copy
0044 /// overhead of a recursive lambda approach.
0045 ///
0046 /// @tparam Fs The callable types
0047 /// @param fs The callables to compose
0048 /// @return A callable that applies @p fs right-to-left
0049 template <typename... Fs>
0050 auto compose(Fs&&... fs) {
0051   return [tup = std::make_tuple(std::forward<Fs>(fs)...)]<typename T>(
0052              T&& x) -> decltype(auto) {
0053     return std::apply(
0054         [&](const auto&... fns) -> decltype(auto) {
0055           return detail::applyRight(std::forward<T>(x), fns...);
0056         },
0057         tup);
0058   };
0059 }
0060 
0061 }  // namespace Acts