Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 :
8 : #include "Utilities/TMPL.hpp"
9 :
10 : /// \cond
11 : template <size_t Dim, typename TagsList>
12 : class BoundaryVariables;
13 : template <typename TagsList>
14 : class Variables;
15 : namespace db {
16 : struct PrefixTag;
17 : struct SimpleTag;
18 : } // namespace db
19 :
20 : namespace Tags {
21 : template <size_t Dim, typename TagsList>
22 : struct BoundaryVariables;
23 : template <typename TagsList>
24 : struct Variables;
25 : } // namespace Tags
26 : /// \endcond
27 :
28 : namespace db {
29 :
30 : /// \ingroup DataBoxTagsGroup
31 : /// \brief Create a new `tmpl::list` of tags by wrapping each tag in `TagList`
32 : /// in `Wrapper<_, Args...>`.
33 : template <template <typename...> class Wrapper, typename TagList,
34 : typename... Args>
35 1 : using wrap_tags_in =
36 : tmpl::transform<TagList, tmpl::bind<Wrapper, tmpl::_1, tmpl::pin<Args>...>>;
37 :
38 : namespace detail {
39 : template <template <typename...> class Prefix, typename Tag, typename... Args>
40 : struct add_tag_prefix_impl {
41 : using type = Prefix<Tag, Args...>;
42 : };
43 :
44 : template <template <typename...> class Prefix, size_t Dim, typename TagList,
45 : typename... Args>
46 : struct add_tag_prefix_impl<Prefix, Tags::BoundaryVariables<Dim, TagList>,
47 : Args...> {
48 : using type =
49 : Tags::BoundaryVariables<Dim, wrap_tags_in<Prefix, TagList, Args...>>;
50 : };
51 :
52 : template <template <typename...> class Prefix, typename TagList,
53 : typename... Args>
54 : struct add_tag_prefix_impl<Prefix, Tags::Variables<TagList>, Args...> {
55 : using type = Tags::Variables<wrap_tags_in<Prefix, TagList, Args...>>;
56 : };
57 : } // namespace detail
58 :
59 : /// \ingroup DataBoxTagsGroup
60 : /// Wrap `Tag` in `Prefix<_, Args...>`, unless `Tag` is a Tags::Variables or
61 : /// Tags::BoundaryVariables, in which case this wraps each tag in
62 : /// `Tag::tags_list` with `Prefix<_, Args...>`.
63 : template <template <typename...> class Prefix, typename Tag, typename... Args>
64 1 : using add_tag_prefix =
65 : typename detail::add_tag_prefix_impl<Prefix, Tag, Args...>::type;
66 :
67 : namespace detail {
68 : template <typename>
69 : struct remove_tag_prefix_impl;
70 :
71 : template <typename WrappedTag, template <typename...> class Prefix,
72 : typename... Args>
73 : struct remove_tag_prefix_impl<Prefix<WrappedTag, Args...>> {
74 : using type = WrappedTag;
75 : };
76 :
77 : template <size_t Dim, typename TagList>
78 : struct remove_tag_prefix_impl<Tags::BoundaryVariables<Dim, TagList>> {
79 : using type = Tags::BoundaryVariables<
80 : Dim, tmpl::transform<TagList, remove_tag_prefix_impl<tmpl::_1>>>;
81 : };
82 :
83 : template <typename TagList>
84 : struct remove_tag_prefix_impl<Tags::Variables<TagList>> {
85 : using type = Tags::Variables<
86 : tmpl::transform<TagList, remove_tag_prefix_impl<tmpl::_1>>>;
87 : };
88 : } // namespace detail
89 :
90 : /// \ingroup DataBoxTagsGroup
91 : /// Remove the outer prefix from a prefixed tag `Tag`, or remove the outer
92 : /// prefix of each tag in `Tag::tags_list` if `Tag` is a Tags::Variables or
93 : /// Tags::BoundaryVariables.
94 : template <typename Tag>
95 1 : using remove_tag_prefix = typename detail::remove_tag_prefix_impl<Tag>::type;
96 :
97 : namespace detail {
98 :
99 : template <typename Tag>
100 : struct remove_all_prefixes_impl {
101 : using type = Tag;
102 : };
103 :
104 : template <typename Tag>
105 : requires(std::is_base_of_v<db::PrefixTag, Tag>)
106 : struct remove_all_prefixes_impl<Tag> {
107 : using type = typename remove_all_prefixes_impl<typename Tag::tag>::type;
108 : };
109 :
110 : template <size_t Dim, typename TagList>
111 : struct remove_all_prefixes_impl<Tags::BoundaryVariables<Dim, TagList>> {
112 : using type = Tags::BoundaryVariables<
113 : Dim, tmpl::transform<TagList, remove_all_prefixes_impl<tmpl::_1>>>;
114 : };
115 :
116 : template <typename TagList>
117 : struct remove_all_prefixes_impl<Tags::Variables<TagList>> {
118 : using type = Tags::Variables<
119 : tmpl::transform<TagList, remove_all_prefixes_impl<tmpl::_1>>>;
120 : };
121 : } // namespace detail
122 :
123 : /// \ingroup DataBoxTagsGroup
124 : /// Completely remove all prefix tags from a Tag, or all prefixes from
125 : /// the tags in `Tag::tags_list` if `Tag` is a Tags::Variables or
126 : /// Tags::BoundaryVariables.
127 : template <typename Tag>
128 1 : using remove_all_prefixes =
129 : typename detail::remove_all_prefixes_impl<Tag>::type;
130 :
131 : namespace detail {
132 : template <template <typename...> typename Wrapper, typename T, typename... Args>
133 : struct prefix_variables {
134 : using type = T;
135 : };
136 :
137 : template <template <typename...> typename Wrapper, size_t Dim, typename Tags,
138 : typename... Args>
139 : struct prefix_variables<Wrapper, BoundaryVariables<Dim, Tags>, Args...> {
140 : using type =
141 : BoundaryVariables<Dim, ::db::wrap_tags_in<Wrapper, Tags, Args...>>;
142 : };
143 :
144 : template <template <typename...> typename Wrapper, typename Tags,
145 : typename... Args>
146 : struct prefix_variables<Wrapper, Variables<Tags>, Args...> {
147 : using type = Variables<::db::wrap_tags_in<Wrapper, Tags, Args...>>;
148 : };
149 : } // namespace detail
150 :
151 : /// \ingroup DataBoxTagsGroup
152 : /// \brief Add a prefix to all tags in a Variables or BoundaryVariables,
153 : /// leaving the argument unchanged if it is not one of those types.
154 : ///
155 : /// \see unprefix_variables, wrap_tags_in
156 : template <template <typename...> class Wrapper, typename T, typename... Args>
157 1 : using prefix_variables =
158 : typename detail::prefix_variables<Wrapper, T, Args...>::type;
159 :
160 : namespace detail {
161 : template <typename T>
162 : struct unprefix_variables {
163 : using type = T;
164 : };
165 :
166 : template <size_t Dim, typename... Tags>
167 : struct unprefix_variables<BoundaryVariables<Dim, tmpl::list<Tags...>>> {
168 : using type = BoundaryVariables<Dim, tmpl::list<tmpl::front<Tags>...>>;
169 : };
170 :
171 : template <typename... Tags>
172 : struct unprefix_variables<Variables<tmpl::list<Tags...>>> {
173 : using type = Variables<tmpl::list<tmpl::front<Tags>...>>;
174 : };
175 : } // namespace detail
176 :
177 : /// \ingroup DataBoxTagsGroup
178 : /// \brief Remove the outer prefix from all tags in a Variables or
179 : /// BoundaryVariables, leaving the argument unchanged if it is not one of
180 : /// those types.
181 : ///
182 : /// \see prefix_variables
183 : template <typename T>
184 1 : using unprefix_variables = typename detail::unprefix_variables<T>::type;
185 : } // namespace db
|