SpECTRE Documentation Coverage Report
Current view: top level - DataStructures - TaggedContainers.hpp Hit Total Coverage
Commit: a6a8ee404306bec9d92da8ab89f636b037aefc25 Lines: 4 5 80.0 %
Date: 2024-07-26 22:35:59
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 1.14