SpECTRE Documentation Coverage Report
Current view: top level - Utilities - Tuple.hpp Hit Total Coverage
Commit: 17268ad40c735180c87c60a23676ef5c9a12b1bf Lines: 4 4 100.0 %
Date: 2024-07-24 22:11:27
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 1.14