PrefixHelpers.hpp
1 // 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 #include "Utilities/TypeTraits/IsA.hpp"
9 
10 /// \cond
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 list of Tags by wrapping each tag in `TagList` using the
26 /// `Wrapper`.
27 template <template <typename...> class Wrapper, typename TagList,
28  typename... Args>
29 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 from the tags of
48 /// VariablesTag, wrapping each tag with Prefix, which may have additional
49 /// template arguments Args.
50 template <template <typename...> class Prefix, typename Tag, typename... Args>
51 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 a variables tag if `Tag` is a `Tags::Variables`.
74 template <typename Tag>
75 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 DataBoxGroup
98 /// Completely remove all prefix tags from a Tag, or all prefixes from
99 /// the tags in the tag list of a `Tags::Variables`.
100 template <typename Tag>
101 using remove_all_prefixes =
102  typename detail::remove_all_prefixes_impl<Tag>::type;
103 } // namespace db
db::add_tag_prefix
typename detail::add_tag_prefix_impl< Prefix, Tag, Args... >::type add_tag_prefix
Definition: PrefixHelpers.hpp:52
Tags::Variables
Definition: VariablesTag.hpp:21
db::remove_all_prefixes
typename detail::remove_all_prefixes_impl< Tag >::type remove_all_prefixes
Definition: PrefixHelpers.hpp:102
Requires.hpp
db::wrap_tags_in
tmpl::transform< TagList, tmpl::bind< Wrapper, tmpl::_1, tmpl::pin< Args >... > > wrap_tags_in
Create a new list of Tags by wrapping each tag in TagList using the Wrapper.
Definition: PrefixHelpers.hpp:30
Requires
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t
Definition: Requires.hpp:67
TMPL.hpp
db
Namespace for DataBox related things.
Definition: DataBox.hpp:43
db::remove_tag_prefix
typename detail::remove_tag_prefix_impl< Tag >::type remove_tag_prefix
Definition: PrefixHelpers.hpp:75