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