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