Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <utility>
7 :
8 : #include "DataStructures/DataBox/DataBox.hpp"
9 : #include "Utilities/Gsl.hpp"
10 : #include "Utilities/TMPL.hpp"
11 :
12 : namespace Initialization {
13 : namespace detail {
14 : template <typename... MutateTags, typename BoxTags, typename... Args>
15 : SPECTRE_ALWAYS_INLINE constexpr void mutate_assign_impl(
16 : // NOLINTNEXTLINE(readability-avoid-const-params-in-decls)
17 : const gsl::not_null<db::DataBox<BoxTags>*> box,
18 : tmpl::list<MutateTags...> /*meta*/, Args&&... args) {
19 : static_assert(sizeof...(MutateTags) == sizeof...(args),
20 : "The number of arguments passed to `mutate_assign` must be "
21 : "equal to the number of tags passed.");
22 : db::mutate<MutateTags...>(
23 : [&args...](const auto... box_args) {
24 : // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
25 : EXPAND_PACK_LEFT_TO_RIGHT((*box_args = std::forward<Args>(args)));
26 : },
27 : box);
28 : }
29 : } // namespace detail
30 :
31 : /*!
32 : * \ingroup DataBoxGroup
33 : * \brief Perform a mutation to the \ref DataBoxGroup `box`, assigning the
34 : * `args` to the tags in `MutateTagList` in order.
35 : */
36 : template <typename MutateTagList, typename BoxTags, typename... Args>
37 1 : SPECTRE_ALWAYS_INLINE constexpr void mutate_assign(
38 : // NOLINTNEXTLINE(readability-avoid-const-params-in-decls)
39 : const gsl::not_null<db::DataBox<BoxTags>*> box, Args&&... args) {
40 : // The impl works for zero tags, but we can skip it to improve
41 : // compilation performance.
42 : if constexpr (tmpl::size<MutateTagList>::value != 0) {
43 : detail::mutate_assign_impl(box, MutateTagList{},
44 : std::forward<Args>(args)...);
45 : } else {
46 : (void)box;
47 : expand_pack(args...);
48 : }
49 : }
50 : } // namespace Initialization
|