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