14#ifndef DUMUX_PROPERTY_SYSTEM_HH
15#define DUMUX_PROPERTY_SYSTEM_HH
19#include <dune/common/std/type_traits.hh>
42namespace Dumux::Properties::Detail {
46constexpr auto isDefinedProperty(
int)
47->
decltype(std::integral_constant<bool, !std::is_same_v<typename P::type, UndefinedProperty>>{})
52constexpr std::true_type isDefinedProperty(...) {
return {}; }
56constexpr auto hasParentTypeTag(
int)
57->
decltype(std::declval<typename T::InheritsFrom>(), std::true_type{})
62constexpr std::false_type hasParentTypeTag(...)
67template<
class P,
class T>
68using TypeAliasPropertyDetector =
typename PropertyAlias<P>::template Alias<T>;
72template<
class P,
class T>
73struct TypeAliasProperty
74{
using type = Dune::Std::detected_or_t<UndefinedProperty, TypeAliasPropertyDetector, P, T>; };
77template<
class P,
class T,
class TypeTag>
78using TemplateAliasPropertyDetector =
typename PropertyAlias<P>::template TemplateAlias<T, TypeTag>;
82template<
class P,
class T,
class TypeTag>
83struct TemplateAliasProperty
84{
using type = Dune::Std::detected_or_t<UndefinedProperty, TemplateAliasPropertyDetector, P, T, TypeTag>; };
89using ValueMemberDetector =
decltype(T::value);
92template<
class T,
bool hasValueMember = Dune::Std::is_detected_v<ValueMemberDetector, T>>
93struct ValueMember {
static constexpr bool value =
false; };
97struct ValueMember<T, true> {
static constexpr auto value = T::value; };
100template<
class PropertySpecialization>
101struct GetPropValue {
static constexpr auto value = ValueMember<PropertySpecialization>::value; };
104template<
class P,
class T>
105struct GetPropValue<TypeAliasProperty<P, T>>
106{
static constexpr auto value = ValueMember<typename TypeAliasProperty<P, T>::type>::value; };
109template<
class P,
class T,
class TypeTag>
110struct GetPropValue<TemplateAliasProperty<P, T, TypeTag>>
111{
static constexpr auto value = ValueMember<typename TemplateAliasProperty<P, T, TypeTag>::type>::value; };
115template<
class ...Tuples>
116using ConCatTuples =
decltype(std::tuple_cat(std::declval<Tuples>()...));
119template<
class TypeTag,
template<
class,
class>
class Property,
class TTagList>
123template<
class TypeTag,
template<
class,
class>
class Property,
class TTagList,
class Enable>
124struct GetNextTypeTag;
126template<
class TypeTag,
template<
class,
class>
class Property,
class LastTypeTag>
127struct GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, std::enable_if_t<hasParentTypeTag<LastTypeTag>(int{}), void>>
128{
using type =
typename GetDefined<TypeTag, Property, typename LastTypeTag::InheritsFrom>::type; };
130template<
class TypeTag,
template<
class,
class>
class Property,
class LastTypeTag>
131struct GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, std::enable_if_t<!hasParentTypeTag<LastTypeTag>(int{}), void>>
132{
using type = UndefinedProperty; };
134template<
class TypeTag,
template<
class,
class>
class Property,
class FirstTypeTag,
class ...Args>
135struct GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<hasParentTypeTag<FirstTypeTag>(int{}), void>>
136{
using type =
typename GetDefined<TypeTag, Property, ConCatTuples<
typename FirstTypeTag::InheritsFrom, std::tuple<Args...>>>::type; };
138template<
class TypeTag,
template<
class,
class>
class Property,
class FirstTypeTag,
class ...Args>
139struct GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<!hasParentTypeTag<FirstTypeTag>(int{}), void>>
140{
using type =
typename GetDefined<TypeTag, Property, std::tuple<Args...>>::type; };
142template<
class TypeTag,
template<
class,
class>
class Property,
class LastTypeTag>
143struct GetDefined<TypeTag, Property, std::tuple<LastTypeTag>>
151#pragma clang diagnostic push
152#pragma clang diagnostic ignored "-Wdeprecated-declarations"
154 using LastType = Property<TypeTag, LastTypeTag>;
156#pragma clang diagnostic pop
158 using DirectType = TypeAliasProperty<LastType, LastTypeTag>;
159 using DirectTemplateType = TemplateAliasProperty<LastType, LastTypeTag, TypeTag>;
161 using type = std::conditional_t<
162 isDefinedProperty<LastType>(
int{}), LastType,
164 isDefinedProperty<DirectTemplateType>(
int{}), DirectTemplateType,
166 isDefinedProperty<DirectType>(
int{}), DirectType,
167 typename GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>,
void>::type
173template<
class TypeTag,
template<
class,
class>
class Property,
class FirstTypeTag,
class ...Args>
174struct GetDefined<TypeTag, Property, std::tuple<FirstTypeTag, Args...>>
178#pragma clang diagnostic push
179#pragma clang diagnostic ignored "-Wdeprecated-declarations"
181 using FirstType = Property<TypeTag, FirstTypeTag>;
183#pragma clang diagnostic pop
185 using DirectType = TypeAliasProperty<FirstType, FirstTypeTag>;
186 using DirectTemplateType = TemplateAliasProperty<FirstType, FirstTypeTag, TypeTag>;
193 using type = std::conditional_t<
194 isDefinedProperty<FirstType>(
int{}), FirstType,
196 isDefinedProperty<DirectTemplateType>(
int{}), DirectTemplateType,
198 isDefinedProperty<DirectType>(
int{}), DirectType,
199 typename GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>,
void>::type
206template<
class TypeTag,
template<
class,
class>
class Property>
209 using type =
typename Detail::GetDefined<TypeTag, Property, std::tuple<TypeTag>>::type;
210 static_assert(!std::is_same_v<type, UndefinedProperty>,
"Property is undefined!");
213template<
class TypeTag,
template<
class,
class>
class Property,
class T>
216 using PT =
typename Detail::GetDefined<TypeTag, Property, std::tuple<TypeTag>>::type;
217 struct WrapperT {
using type = T; };
218 using type = std::conditional_t<std::is_same_v<PT, UndefinedProperty>, WrapperT, PT>;
221template<class ParentTag, class TypeTag, bool hasParents = hasParentTypeTag<TypeTag>(
int{})>
224template<
class ParentTag,
class TypeTag>
225struct InheritsFrom<ParentTag, TypeTag, false> {
226 static constexpr bool value = std::is_same_v<ParentTag, TypeTag>;
229template<
class ParentTag,
class TypeTag>
230struct InheritsFrom<ParentTag, TypeTag, true> {
231 static constexpr bool value = std::is_same_v<ParentTag, TypeTag>
232 || InheritsFrom<ParentTag, typename TypeTag::InheritsFrom, false>::value;
235template<
class ParentTag,
class... TypeTags>
236struct InheritsFrom<ParentTag, std::tuple<TypeTags...>, false> {
237 static constexpr bool value = (InheritsFrom<ParentTag, TypeTags>::value || ...);
250template<
class TypeTag,
template<
class,
class>
class Property>
253 using type =
typename Detail::GetDefined<TypeTag, Property, std::tuple<TypeTag>>::type;
254 return !std::is_same_v<type, UndefinedProperty>;
261template<
class ParentTypeTag,
class TypeTag>
264 return Detail::InheritsFrom<ParentTypeTag, TypeTag>::value;
275template<
class TypeTag,
template<
class,
class>
class Property>
276using GetProp =
typename Properties::Detail::GetPropImpl<TypeTag, Property>::type;
282template<
class TypeTag,
template<
class,
class>
class Property,
class T>
283using GetPropOr =
typename Properties::Detail::GetPropOrImpl<TypeTag, Property, T>::type;
287#pragma clang diagnostic push
288#pragma clang diagnostic ignored "-Wdeprecated-declarations"
295template<
class TypeTag,
template<
class,
class>
class Property>
302template<
class TypeTag,
template<
class,
class>
class Property,
class T>
309template<
class TypeTag,
template<
class,
class>
class Property>
310inline constexpr auto getPropValue() {
return Properties::Detail::GetPropValue<GetProp<TypeTag, Property>>::value; }
312#pragma clang diagnostic pop
349#define DUMUX_DEFINE_PROPERTY(Prop) \
350 template<class TypeTag, class MyTypeTag> \
352 using type = UndefinedProperty; \
354 template<class ...Args> \
355 struct PropertyAlias<Prop<Args...>> { \
356 template <class MyTypeTag> using Alias = typename MyTypeTag::Prop; \
357 template <class MyTypeTag, class TypeTag> using TemplateAlias = typename MyTypeTag::template Prop<TypeTag>; \
constexpr auto getPropValue()
get the value data member of a property
Definition: propertysystem.hh:310
constexpr bool hasDefinedType()
whether the property is defined/specialized for TypeTag
Definition: propertysystem.hh:251
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property
Definition: propertysystem.hh:276
typename Properties::Detail::GetPropOrImpl< TypeTag, Property, T >::type GetPropOr
get the type of a property or the type T if the property is undefined
Definition: propertysystem.hh:283
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
typename GetPropOr< TypeTag, Property, T >::type GetPropTypeOr
get the type alias defined in the property or the type T if the property is undefined
Definition: propertysystem.hh:303
constexpr bool inheritsFrom()
Return true if the given type tag inherits from the given parent type tag.
Definition: propertysystem.hh:262
The energy balance equation for a porous solid.
Definition: common/properties.hh:26
a tag to specify a direct alias for property extraction
Definition: propertysystem.hh:33
a tag to mark properties as undefined
Definition: propertysystem.hh:27