Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <memory>
7 : #include <type_traits>
8 :
9 : #include "DataStructures/DataBox/MetavariablesTag.hpp"
10 : #include "DataStructures/DataBox/TagTraits.hpp"
11 : #include "Utilities/NoSuchType.hpp"
12 : #include "Utilities/TMPL.hpp"
13 : #include "Utilities/TypeTraits/IsA.hpp"
14 :
15 1 : namespace Tags {
16 : /*!
17 : * \ingroup DataBoxTagsGroup
18 : * \brief Tag used to retrieve the DataBox from the `db::get` function
19 : *
20 : * The main use of this tag is to allow fetching the DataBox from itself. The
21 : * primary use case is to allow an invokable to take a DataBox as an argument
22 : * when called through `db::apply`.
23 : *
24 : * \snippet Test_DataBox.cpp databox_self_tag_example
25 : */
26 1 : struct DataBox {
27 : // Trick to get friend function declaration to compile but a const
28 : // NoSuchtype****& is rather useless
29 0 : using type = NoSuchType****;
30 : };
31 : } // namespace Tags
32 :
33 : namespace db {
34 :
35 : namespace detail {
36 : template <typename TagsList,
37 : typename MatchingTagsList = tmpl::filter<
38 : TagsList, tt::is_a<Parallel::Tags::MetavariablesImpl, tmpl::_1>>>
39 : struct metavars_tag_impl {
40 : static_assert(tmpl::size<MatchingTagsList>::value == 1);
41 : using type = tmpl::front<MatchingTagsList>;
42 : };
43 :
44 : template <typename TagsList>
45 : struct metavars_tag_impl<TagsList, tmpl::list<>> {
46 : using type = NoSuchType;
47 : };
48 :
49 : template <typename TagList, typename Tag>
50 : using list_of_matching_tags = tmpl::conditional_t<
51 : std::is_same_v<Tag, ::Tags::DataBox>, tmpl::list<::Tags::DataBox>,
52 : tmpl::conditional_t<
53 : std::is_same_v<Tag, Parallel::Tags::Metavariables>,
54 : tmpl::list<Parallel::Tags::Metavariables>,
55 : tmpl::filter<TagList, std::is_base_of<tmpl::pin<Tag>, tmpl::_1>>>>;
56 :
57 : template <typename Tag, typename TagList,
58 : typename MatchingTagsList = list_of_matching_tags<TagList, Tag>>
59 : struct first_matching_tag_impl {
60 : using type = tmpl::front<MatchingTagsList>;
61 : };
62 :
63 : template <typename Tag, typename TagList>
64 : struct first_matching_tag_impl<Tag, TagList, tmpl::list<>> {
65 : static_assert(std::is_same<Tag, NoSuchType>::value,
66 : "Could not find the DataBox tag in the list of DataBox tags. "
67 : "The first template parameter of 'first_matching_tag_impl' is "
68 : "the tag that cannot be found and the second is the list of "
69 : "tags being searched.");
70 : using type = NoSuchType;
71 : };
72 :
73 : template <typename TagList, typename Tag>
74 : using first_matching_tag = typename first_matching_tag_impl<Tag, TagList>::type;
75 :
76 : template <typename TagList, typename Tag>
77 : constexpr auto number_of_matching_tags =
78 : tmpl::size<list_of_matching_tags<TagList, Tag>>::value;
79 :
80 : template <typename TagList, typename Tag>
81 : struct has_unique_matching_tag
82 : : std::integral_constant<bool, number_of_matching_tags<TagList, Tag> == 1> {
83 : };
84 :
85 : template <typename TagList, typename Tag>
86 : using has_unique_matching_tag_t =
87 : typename has_unique_matching_tag<TagList, Tag>::type;
88 :
89 : template <typename TagList, typename Tag>
90 : constexpr bool has_unique_matching_tag_v =
91 : has_unique_matching_tag<TagList, Tag>::value;
92 :
93 : template <typename TagList, typename Tag>
94 : struct has_no_matching_tag
95 : : std::integral_constant<bool, number_of_matching_tags<TagList, Tag> == 0> {
96 : };
97 :
98 : template <typename TagList, typename Tag>
99 : using has_no_matching_tag_t = typename has_no_matching_tag<TagList, Tag>::type;
100 :
101 : template <typename TagList, typename Tag>
102 : constexpr bool has_no_matching_tag_v = has_no_matching_tag<TagList, Tag>::value;
103 :
104 : template <typename T>
105 : struct ConvertToConst {
106 : using type = const T&;
107 : };
108 :
109 : template <typename T>
110 : struct ConvertToConst<std::unique_ptr<T>> {
111 : using type = const T&;
112 : };
113 :
114 : template <typename Tag, typename TagsList>
115 : struct const_item_type_impl {
116 : using type = typename db::detail::ConvertToConst<
117 : std::decay_t<typename Tag::type>>::type;
118 : };
119 :
120 : template <typename TagsList>
121 : struct const_item_type_impl<Parallel::Tags::Metavariables, TagsList> {
122 : using type = const typename detail::metavars_tag_impl<TagsList>::type::type&;
123 : };
124 : } // namespace detail
125 :
126 : template <typename Tag, typename TagsList>
127 0 : using const_item_type =
128 : typename detail::const_item_type_impl<Tag, TagsList>::type;
129 : } // namespace db
|