SpECTRE Documentation Coverage Report
Current view: top level - Utilities - Tuple.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 100.0 % 4 4
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            1 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : /// \file
       5              : /// Defines functions for manipulating tuples
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <tuple>
      10              : #include <utility>
      11              : 
      12              : namespace tuple_impl_detail {
      13              : template <bool ReverseIteration, typename... Elements, typename N_aryOp,
      14              :           typename... Args, size_t... Is>
      15              : constexpr inline void tuple_fold_impl(const std::tuple<Elements...>& tupull,
      16              :                                       N_aryOp&& op,
      17              :                                       std::index_sequence<Is...> /*meta*/,
      18              :                                       Args&... args) {
      19              :   constexpr size_t tuple_size = sizeof...(Elements);
      20              :   static_cast<void>(std::initializer_list<char>{
      21              :       (static_cast<void>(
      22              :            op(std::get<(ReverseIteration ? tuple_size - 1 - Is : Is)>(tupull),
      23              :               args...)),
      24              :        '0')...});
      25              : }
      26              : 
      27              : template <bool ReverseIteration, typename... Elements, typename N_aryOp,
      28              :           typename... Args, size_t... Is>
      29              : constexpr inline void tuple_counted_fold_impl(
      30              :     const std::tuple<Elements...>& tupull, N_aryOp&& op,
      31              :     std::index_sequence<Is...> /*meta*/, Args&... args) {
      32              :   constexpr size_t tuple_size = sizeof...(Elements);
      33              :   static_cast<void>(std::initializer_list<char>{
      34              :       (static_cast<void>(
      35              :            op(std::get<(ReverseIteration ? tuple_size - 1 - Is : Is)>(tupull),
      36              :               (ReverseIteration ? tuple_size - 1 - Is : Is), args...)),
      37              :        '0')...});
      38              : }
      39              : 
      40              : template <bool ReverseIteration, typename... Elements, typename N_aryOp,
      41              :           typename... Args, size_t... Is>
      42              : constexpr inline void tuple_transform_impl(
      43              :     const std::tuple<Elements...>& tupull, N_aryOp&& op,
      44              :     std::index_sequence<Is...> /*meta*/, Args&... args) {
      45              :   constexpr size_t tuple_size = sizeof...(Elements);
      46              :   static_cast<void>(std::initializer_list<char>{(
      47              :       static_cast<void>(op(
      48              :           std::get<(ReverseIteration ? tuple_size - 1 - Is : Is)>(tupull),
      49              :           std::integral_constant<size_t, (ReverseIteration ? tuple_size - 1 - Is
      50              :                                                            : Is)>{},
      51              :           args...)),
      52              :       '0')...});
      53              : }
      54              : }  // namespace tuple_impl_detail
      55              : 
      56              : /// @{
      57              : /*!
      58              :  * \ingroup UtilitiesGroup
      59              :  * \brief Perform a fold over a std::tuple
      60              :  *
      61              :  * \details
      62              :  * Iterates over the elements in a std::tuple `tuple` from left to right
      63              :  * (left fold) calling `op(element, args...)` on each element in `tuple`. A
      64              :  * right fold can be done by explicitly setting the first template parameter
      65              :  * to true. Folds are easily implemented using `tuple_fold` by updating
      66              :  * one of the `args...` at each iteration. If you need the index of the current
      67              :  * element you can use the `tuple_counted_fold` variant. `tuple_counted_fold`
      68              :  * passes the current index as the second argument to the Callable `op`. That
      69              :  * is, `op(element, index, args...)`.
      70              :  *
      71              :  * \example
      72              :  * The sum of a std::tuple of Arithmetics can be computed in several ways.
      73              :  * First, you can use a lambda:
      74              :  * \snippet Utilities/Test_Tuple.cpp tuple_fold_lambda
      75              :  * You'll notice that `state` is taken by reference and mutated.
      76              :  *
      77              :  * You can do the same thing with a struct defined as
      78              :  * \snippet Utilities/Test_Tuple.cpp tuple_fold_struct_defn
      79              :  * and then using an instance of the struct
      80              :  * \snippet Utilities/Test_Tuple.cpp tuple_fold_struct
      81              :  *
      82              :  * \note You are not able to pass a function pointer to `tuple_fold` or
      83              :  * `tuple_counted_fold` because you cannot pass a pointer to a function
      84              :  * template, only a function.
      85              :  *
      86              :  * \see expand_pack tuple_transform tuple_fold tuple_counted_fold std::tuple
      87              :  */
      88              : template <bool ReverseIteration = false, typename... Elements, typename N_aryOp,
      89              :           typename... Args>
      90            1 : constexpr inline void tuple_fold(const std::tuple<Elements...>& tuple,
      91              :                                  N_aryOp&& op, Args&&... args) {
      92              :   tuple_impl_detail::tuple_fold_impl<ReverseIteration>(
      93              :       tuple, std::forward<N_aryOp>(op),
      94              :       std::make_index_sequence<sizeof...(Elements)>{}, args...);
      95              : }
      96              : 
      97              : template <bool ReverseIteration = false, typename... Elements, typename N_aryOp,
      98              :           typename... Args>
      99            1 : constexpr inline void tuple_counted_fold(const std::tuple<Elements...>& tuple,
     100              :                                          N_aryOp&& op, Args&&... args) {
     101              :   tuple_impl_detail::tuple_counted_fold_impl<ReverseIteration>(
     102              :       tuple, std::forward<N_aryOp>(op),
     103              :       std::make_index_sequence<sizeof...(Elements)>{}, args...);
     104              : }
     105              : /// @}
     106              : 
     107              : /*!
     108              :  * \ingroup UtilitiesGroup
     109              :  * \brief Perform a transform over a std::tuple
     110              :  *
     111              :  * \details
     112              :  * Iterates over the elements in a std::tuple `tuple` from left to right
     113              :  * calling `op.operator()(element, index, args...)` on each element
     114              :  * in `tuple`. A right-to-left transform can be done by explicitly setting
     115              :  * the first template parameter to true. The second argument of the invokable
     116              :  * will be a deduced `std::integral_constant<size_t, value>`, from which the
     117              :  * current index can be extracted by using `decltype(index)::%value`.
     118              :  * For a function object the `decltype(index)` can be replaced by the deduced
     119              :  * type of `index`. For example,
     120              :  * \snippet Utilities/Test_Tuple.cpp tuple_transform_negate
     121              :  *
     122              :  * Using `tuple_transform` with a generic lambda goes as follows,
     123              :  * \snippet Utilities/Test_Tuple.cpp tuple_transform
     124              :  *
     125              :  * \see expand_pack tuple_fold tuple_counted_fold std::tuple
     126              :  */
     127              : template <bool ReverseIteration = false, typename... Elements, typename N_aryOp,
     128              :           typename... Args>
     129            1 : constexpr inline void tuple_transform(const std::tuple<Elements...>& tuple,
     130              :                                       N_aryOp&& op, Args&&... args) {
     131              :   tuple_impl_detail::tuple_transform_impl<ReverseIteration>(
     132              :       tuple, std::forward<N_aryOp>(op),
     133              :       std::make_index_sequence<sizeof...(Elements)>{}, args...);
     134              : }
        

Generated by: LCOV version 2.0-1