Line data Source code
1 0 : // 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 1 : 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 1 : 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 1 : 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 1 : using remove_all_prefixes = 101 : typename detail::remove_all_prefixes_impl<Tag>::type; 102 : } // namespace db