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 `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 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 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 using remove_tag_prefix = typename detail::remove_tag_prefix_impl<Tag>::type;
75 
76 namespace detail {
77 
78 template <typename Tag, typename = std::nullptr_t>
79 struct remove_all_prefixes_impl {
80  using type = Tag;
81 };
82 
83 template <typename Tag>
84 struct remove_all_prefixes_impl<
85  Tag, Requires<std::is_base_of_v<db::PrefixTag, 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 using remove_all_prefixes =
101  typename detail::remove_all_prefixes_impl<Tag>::type;
102 } // namespace db
db::add_tag_prefix
typename detail::add_tag_prefix_impl< Prefix, Tag, Args... >::type add_tag_prefix
Definition: PrefixHelpers.hpp:51
Tags::Variables
Definition: VariablesTag.hpp:21
db::remove_all_prefixes
typename detail::remove_all_prefixes_impl< Tag >::type remove_all_prefixes
Definition: PrefixHelpers.hpp:101
Requires.hpp
db::wrap_tags_in
tmpl::transform< TagList, tmpl::bind< Wrapper, tmpl::_1, tmpl::pin< Args >... > > wrap_tags_in
Create a new tmpl::list of tags by wrapping each tag in TagList in Wrapper<_, Args....
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:44
db::remove_tag_prefix
typename detail::remove_tag_prefix_impl< Tag >::type remove_tag_prefix
Definition: PrefixHelpers.hpp:74