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