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

            Line data    Source code
       1            0 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : #pragma once
       5              : 
       6              : #include <type_traits>
       7              : 
       8              : #include "DataStructures/DataBox/DataBox.hpp"
       9              : #include "DataStructures/TempBuffer.hpp"
      10              : #include "Utilities/Gsl.hpp"
      11              : #include "Utilities/Requires.hpp"
      12              : #include "Utilities/TMPL.hpp"
      13              : #include "Utilities/TypeTraits/IsA.hpp"
      14              : 
      15              : /// @{
      16              : /*!
      17              :  * \ingroup DataStructuresGroup
      18              :  * \brief Retrieves a desired tag from data structures containing tags.
      19              :  *
      20              :  * \details Given multiple containers retrieve a desired tag from the first
      21              :  * container in which it is found. The containers are searched in the order
      22              :  * in which they are supplied (i.e. `first_vars` is checked before `vars`).
      23              :  * An error will be emitted if the tag cannot be found in any container.
      24              :  */
      25              : template <typename Tag, typename... TagsOrTagsList, typename... Ts,
      26              :           template <class...> class U,
      27              :           Requires<(not tt::is_a_v<gsl::not_null, U<TagsOrTagsList...>>)and not(
      28              :               ... and tt::is_a_v<gsl::not_null, std::decay_t<Ts>>)> = nullptr>
      29            1 : const typename Tag::type& get(const U<TagsOrTagsList...>& first_vars,
      30              :                               const Ts&... vars) {
      31              :   if constexpr (tt::is_a_v<db::DataBox, U<TagsOrTagsList...>>) {
      32              :     if constexpr (not db::tag_is_retrievable_v<Tag, U<TagsOrTagsList...>> and
      33              :                   sizeof...(Ts) != 0) {
      34              :       return get<Tag>(vars...);
      35              :     } else {
      36              :       return get<Tag>(first_vars);
      37              :     }
      38              :   } else {
      39              :     if constexpr (not tmpl::list_contains_v<
      40              :                       tmpl::flatten<tmpl::list<TagsOrTagsList...>>, Tag> and
      41              :                   sizeof...(Ts) != 0) {
      42              :       return get<Tag>(vars...);
      43              :     } else {
      44              :       return get<Tag>(first_vars);
      45              :     }
      46              :   }
      47              : }
      48              : 
      49              : template <typename Tag, typename... TagsOrTagsList, typename... Ts,
      50              :           template <class...> class U>
      51            1 : gsl::not_null<typename Tag::type*> get(
      52              :     const gsl::not_null<U<TagsOrTagsList...>*> first_vars,
      53              :     const gsl::not_null<Ts>... vars) {
      54              :   if constexpr (tt::is_a_v<db::DataBox, U<TagsOrTagsList...>>) {
      55              :     if constexpr (not db::tag_is_retrievable_v<Tag, U<TagsOrTagsList...>> and
      56              :                   sizeof...(Ts) != 0) {
      57              :       if constexpr (sizeof...(Ts) == 1) {
      58              :         return make_not_null(&get<Tag>(*vars...));
      59              :       } else {
      60              :         return get<Tag>(vars...);
      61              :       }
      62              :     } else {
      63              :       return make_not_null(&get<Tag>(*first_vars));
      64              :     }
      65              :   } else {
      66              :     if constexpr (not tmpl::list_contains_v<
      67              :                       tmpl::flatten<tmpl::list<TagsOrTagsList...>>, Tag> and
      68              :                   sizeof...(Ts) != 0) {
      69              :       (void)first_vars;
      70              :       if constexpr (sizeof...(Ts) == 1) {
      71              :         return make_not_null(&get<Tag>(*vars...));
      72              :       } else {
      73              :         return get<Tag>(vars...);
      74              :       }
      75              :     } else {
      76              :       return make_not_null(&get<Tag>(*first_vars));
      77              :     }
      78              :   }
      79              : }
      80              : /// @}
      81              : 
      82              : namespace detail {
      83              : template <typename Callable, typename T, typename... Args,
      84              :           typename... ReturnTags, typename... ArgumentTags>
      85              : auto apply_impl([[maybe_unused]] const gsl::not_null<T*> return_args,
      86              :                 tmpl::list<ReturnTags...> /*meta*/,
      87              :                 tmpl::list<ArgumentTags...> /*meta*/, Callable&& fn,
      88              :                 const Args&... args) {
      89              :   return fn.apply(get<ReturnTags>(return_args)...,
      90              :                   get<ArgumentTags>(args...)...);
      91              : }
      92              : 
      93              : template <typename Callable, typename T, typename... Args,
      94              :           typename... ReturnTags, typename... ArgumentTags>
      95              : auto invoke_impl([[maybe_unused]] const gsl::not_null<T*> return_args,
      96              :                  tmpl::list<ReturnTags...> /*meta*/,
      97              :                  tmpl::list<ArgumentTags...> /*meta*/, Callable&& fn,
      98              :                  const Args&... args) {
      99              :   return fn(get<ReturnTags>(return_args)..., get<ArgumentTags>(args...)...);
     100              : }
     101              : }  // namespace detail
     102              : 
     103              : /*!
     104              :  * \brief Call
     105              :  * `fn.apply(get<Callable::return_tags>(return_args)...,
     106              :  * get<Callable::argument_tags>(args...))`
     107              :  */
     108              : template <typename Callable, typename T, typename... Args>
     109            1 : auto apply(const gsl::not_null<T*> return_args, Callable&& fn,
     110              :            const Args&... args) {
     111              :   return detail::apply_impl(return_args, typename Callable::return_tags{},
     112              :                             typename Callable::argument_tags{},
     113              :                             std::forward<Callable>(fn), args...);
     114              : }
     115              : 
     116              : /*!
     117              :  * \brief Call
     118              :  * `fn(get<Callable::return_tags>(return_args)...,
     119              :  * get<Callable::argument_tags>(args...))`
     120              :  */
     121              : template <typename Callable, typename T, typename... Args>
     122            1 : auto invoke(const gsl::not_null<T*> return_args, Callable&& fn,
     123              :             const Args&... args) {
     124              :   return detail::invoke_impl(return_args, typename Callable::return_tags{},
     125              :                              typename Callable::argument_tags{},
     126              :                              std::forward<Callable>(fn), args...);
     127              : }
        

Generated by: LCOV version 2.0-1