diff --git a/CHANGELOG.md b/CHANGELOG.md index ab7277f33d5ef7ecfd74dd26074c5df4d2d2f111..496998179e0b5d9158c0c2f058abaddba41273ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ from the parameter input file. The constructor takes the expression and an array be evaluated with the function values provided in the same order as the names where specified. An arbitrary number of arguments is supported. ExprTK support very complex expressions, see https://www.partow.net/programming/exprtk/. - __Time loop__: Fixed a bug when the time is chosen to be negative and/or the end time is set to zero. (Before we assume time is always positive and endtime never zero.) - __Hyperelastic__: Added a hyperelastic model (large deformations) and a test (in geomechanics) - +- __Property system__: Added a function `inheritsFrom` that allows to query whether a type tag is present in the inheritance hierarchy of another type tag ### Immediate interface changes not allowing/requiring a deprecation period: diff --git a/dumux/common/properties/propertysystem.hh b/dumux/common/properties/propertysystem.hh index 916e6dc78e9dd8f149300f8e4c801a398d85e7bb..d28cbb58d2502a702534b138ef2d8d4fcf23b1a4 100644 --- a/dumux/common/properties/propertysystem.hh +++ b/dumux/common/properties/propertysystem.hh @@ -218,6 +218,25 @@ struct GetPropOrImpl using type = std::conditional_t<std::is_same_v<PT, UndefinedProperty>, WrapperT, PT>; }; +template<class ParentTag, class TypeTag, bool hasParents = hasParentTypeTag<TypeTag>(int{})> +struct InheritsFrom; + +template<class ParentTag, class TypeTag> +struct InheritsFrom<ParentTag, TypeTag, false> { + static constexpr bool value = std::is_same_v<ParentTag, TypeTag>; +}; + +template<class ParentTag, class TypeTag> +struct InheritsFrom<ParentTag, TypeTag, true> { + static constexpr bool value = std::is_same_v<ParentTag, TypeTag> + || InheritsFrom<ParentTag, typename TypeTag::InheritsFrom, false>::value; +}; + +template<class ParentTag, class... TypeTags> +struct InheritsFrom<ParentTag, std::tuple<TypeTags...>, false> { + static constexpr bool value = (InheritsFrom<ParentTag, TypeTags>::value || ...); +}; + } // end namespace Dumux::Properties::Detail #endif // DOXYGEN @@ -235,6 +254,16 @@ inline constexpr bool hasDefinedType() return !std::is_same_v<type, UndefinedProperty>; } +/*! + * \ingroup Properties + * \brief Return true if the given type tag inherits from the given parent type tag + */ +template<class ParentTypeTag, class TypeTag> +inline constexpr bool inheritsFrom() +{ + return Detail::InheritsFrom<ParentTypeTag, TypeTag>::value; +} + } // end namespace Dumux::Properties namespace Dumux { diff --git a/test/common/propertysystem/test_propertysystem.cc b/test/common/propertysystem/test_propertysystem.cc index 38328c381e9d050ca1d2b91de084623dbefa03a6..47acac0631f17146016f70ac951022ab22cb6660 100644 --- a/test/common/propertysystem/test_propertysystem.cc +++ b/test/common/propertysystem/test_propertysystem.cc @@ -115,6 +115,11 @@ int main(int argc, char* argv[]) DUNE_THROW(Dune::InvalidStateException, "Property UseTpfaFlux in TTag::CCTpfaDisc should be true!"); } + static_assert(inheritsFrom<TTag::Base, TTag::CCTpfaDisc>()); + static_assert(!inheritsFrom<TTag::CCTpfaDisc, TTag::Base>()); + static_assert(inheritsFrom<TTag::Base, TTag::OnePTest>()); + static_assert(!inheritsFrom<TTag::OnePTest, TTag::Base>()); + std::cout << "All tests passed!" << std::endl; return 0; }