opm-simulators
propertysystem.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*****************************************************************************
4  * See the file COPYING for full copying permissions. *
5  * *
6  * This program is free software: you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation, either version 3 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18  *****************************************************************************/
26 #ifndef OPM_PROPERTY_SYSTEM_HH
27 #define OPM_PROPERTY_SYSTEM_HH
28 
29 #include <dune/common/classname.hh>
30 
31 #include <tuple>
32 #include <type_traits>
33 
34 namespace Opm {
35 namespace Properties {
36 
39 
40 template <class TypeTag, class MyTypeTag>
41 struct Splices
42 {
43  using type = std::tuple<>;
44 };
45 
47 namespace Detail {
48 
50 template<class P>
51 constexpr auto isDefinedProperty(int)
52 -> decltype(std::integral_constant<bool, !std::is_same<typename P::type, UndefinedProperty>::value>{})
53 { return {}; }
54 
56 template<class P>
57 constexpr std::true_type isDefinedProperty(...) { return {}; }
58 
60 template<class T>
61 constexpr auto hasParentTypeTag(int)
62 -> decltype(std::declval<typename T::InheritsFrom>(), std::true_type{})
63 { return {}; }
64 
66 template<class T>
67 constexpr std::false_type hasParentTypeTag(...) { return {}; }
68 
70 template<class ...Tuples>
71 using ConCatTuples = decltype(std::tuple_cat(std::declval<Tuples>()...));
72 
74 template<class TypeTag, template<class,class> class Property, class TTagList>
75 struct GetDefined;
76 
78 template<class TypeTag, template<class,class> class Property, class TTagList, class Enable>
80 
81 template<class TypeTag, template<class,class> class Property, class LastTypeTag>
82 struct GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, std::enable_if_t<hasParentTypeTag<LastTypeTag>(int{}), void>>
84 
85 template<class TypeTag, template<class,class> class Property, class LastTypeTag>
86 struct GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, std::enable_if_t<!hasParentTypeTag<LastTypeTag>(int{}), void>>
87 { using type = UndefinedProperty; };
88 
89 template<class TypeTag, template<class,class> class Property, class FirstTypeTag, class ...Args>
90 struct GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<hasParentTypeTag<FirstTypeTag>(int{}), void>>
91 { using type = typename GetDefined<TypeTag, Property, ConCatTuples<typename FirstTypeTag::InheritsFrom, std::tuple<Args...>>>::type; };
92 
93 template<class TypeTag, template<class,class> class Property, class FirstTypeTag, class ...Args>
94 struct GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<!hasParentTypeTag<FirstTypeTag>(int{}), void>>
95 { using type = typename GetDefined<TypeTag, Property, std::tuple<Args...>>::type; };
96 
97 template<class TypeTag, template<class,class> class Property, class LastTypeTag>
98 struct GetDefined<TypeTag, Property, std::tuple<LastTypeTag>>
99 {
100 // For clang, the following alias triggers compiler warnings if instantiated
101 // from something like `GetPropType<..., DeprecatedProperty>`, even if that is
102 // contained in a diagnostic pragma construct that should prevent these warnings.
103 // As a workaround, also add the pragmas around this line.
104 // See the discussion in MR 1647 for more details.
105 #ifdef __clang__
106 #pragma clang diagnostic push
107 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
108 #endif
109  using LastType = Property<TypeTag, LastTypeTag>;
110 #ifdef __clang__
111 #pragma clang diagnostic pop
112 #endif
113  using type = std::conditional_t<isDefinedProperty<LastType>(int{}), LastType,
114  typename GetNextTypeTag<TypeTag, Property, std::tuple<LastTypeTag>, void>::type>;
115 };
116 
117 template<class TypeTag, template<class,class> class Property, class FirstTypeTag, class ...Args>
118 struct GetDefined<TypeTag, Property, std::tuple<FirstTypeTag, Args...>>
119 {
120 // See the comment above.
121 #ifdef __clang__
122 #pragma clang diagnostic push
123 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
124 #endif
125  using FirstType = Property<TypeTag, FirstTypeTag>;
126 #ifdef __clang__
127 #pragma clang diagnostic pop
128 #endif
129  using type = std::conditional_t<isDefinedProperty<FirstType>(int{}), FirstType,
130  typename GetNextTypeTag<TypeTag, Property, std::tuple<FirstTypeTag, Args...>, void>::type>;
131 };
132 
133 
135 template<class TypeTag, class TTagList>
137 
139 template<class TypeTag, class TTagList, class Enable>
141 
142 template<class TypeTag, class LastTypeTag>
143 struct GetNextSpliceTypeTag<TypeTag, std::tuple<LastTypeTag>, std::enable_if_t<hasParentTypeTag<LastTypeTag>(int{}), void>>
145 
146 template<class TypeTag, class LastTypeTag>
147 struct GetNextSpliceTypeTag<TypeTag, std::tuple<LastTypeTag>, std::enable_if_t<!hasParentTypeTag<LastTypeTag>(int{}), void>>
148 { using type = std::tuple<>; };
149 
150 template<class TypeTag, class FirstTypeTag, class ...Args>
151 struct GetNextSpliceTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<hasParentTypeTag<FirstTypeTag>(int{}), void>>
152 { using type = typename GetDefinedSplice<TypeTag, ConCatTuples<typename FirstTypeTag::InheritsFrom, std::tuple<Args...>>>::type; };
153 
154 template<class TypeTag, class FirstTypeTag, class ...Args>
155 struct GetNextSpliceTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<!hasParentTypeTag<FirstTypeTag>(int{}), void>>
156 { using type = typename GetDefinedSplice<TypeTag, std::tuple<Args...>>::type; };
157 
159 template<class S>
160 constexpr auto isDefinedSplice(int)
161 -> decltype(std::integral_constant<bool, !std::is_same<typename S::type, std::tuple<>>::value>{})
162 { return {}; }
163 
165 template<class S>
166 constexpr std::true_type isDefinedSplice(...) { return {}; }
167 
168 template<class TypeTag, class LastTypeTag>
169 struct GetDefinedSplice<TypeTag, std::tuple<LastTypeTag>>
170 {
172  using nexttuple = typename GetNextSpliceTypeTag<TypeTag,
173  ConCatTuples<
174  std::tuple<LastTypeTag>,
175  typename LastSplice::type
176  >,
177  void>::type;
178 
179  using type = std::conditional_t<isDefinedSplice<LastSplice>(int{}),
181  nexttuple>;
182 };
183 
184 template<class TypeTag, class FirstTypeTag, class ...Args>
185 struct GetDefinedSplice<TypeTag, std::tuple<FirstTypeTag, Args...>>
186 {
188  using nexttuple = typename GetNextSpliceTypeTag<TypeTag,
189  ConCatTuples<
190  std::tuple<FirstTypeTag, Args...>,
191  typename FirstSplice::type
192  >,
193  void>::type;
194 
195  using type = std::conditional_t<isDefinedSplice<FirstSplice>(int{}),
197  nexttuple>;
198 };
199 
201 template<class TypeTag, template<class,class> class Property>
203 {
204  using tuple = typename Detail::GetDefinedSplice<TypeTag, std::tuple<TypeTag>>::type;
205  using type = typename Detail::GetDefined<TypeTag,
206  Property,
208  >::type;
209  static_assert(!std::is_same<type, UndefinedProperty>::value, "Property is undefined!");
210 };
211 
212 template<class TypeTag, class SpliceTypeTag, template<class,class> class Property>
214 {
216  static_assert(!std::is_same<type, std::tuple<>>::value, "Splice is undefined!");
217 };
218 
219 } // end namespace Detail
220 } // end namespace Property
221 
223 template<class TypeTag, template<class,class> class Property>
224 using GetProp = typename Properties::Detail::GetPropImpl<TypeTag, Property>::type;
225 
226 // See the comment above.
227 #ifdef __clang__
228 #pragma clang diagnostic push
229 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
230 #endif
231 template<class TypeTag, template<class,class> class Property>
234 
235 template<class TypeTag, class SpliceTypeTag, template<class,class> class Property>
237 
239 template<class TypeTag, template<class,class> class Property>
241 
242 #ifdef __clang__
243 #pragma clang diagnostic pop
244 #endif
245 
246 } // end namespace Opm
247 
248 #endif
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:224
constexpr auto hasParentTypeTag(int) -> decltype(std::declval< typename T::InheritsFrom >(), std::true_type
check if a TypeTag inherits from other TypeTags
Definition: propertysystem.hh:61
Definition: propertysystem.hh:41
decltype(std::tuple_cat(std::declval< Tuples >()...)) ConCatTuples
helper alias to concatenate multiple tuples
Definition: propertysystem.hh:71
a tag to mark properties as undefined
Definition: propertysystem.hh:38
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
constexpr auto getPropValue()
get the value data member of a property
Definition: propertysystem.hh:240
helper struct to get the first property that is defined in the TypeTag hierarchy
Definition: propertysystem.hh:75
helper struct to get the first property that is defined in the TypeTag hierarchy
Definition: propertysystem.hh:136
helper struct to iterate over the TypeTag hierarchy
Definition: propertysystem.hh:79
helper struct to iterate over the TypeTag hierarchy
Definition: propertysystem.hh:140
helper struct to extract get the Property specilization given a TypeTag, asserts that the property is...
Definition: propertysystem.hh:202
constexpr auto isDefinedProperty(int) -> decltype(std::integral_constant< bool, !std::is_same< typename P::type, UndefinedProperty >::value >
check if a property P is defined
Definition: propertysystem.hh:51
constexpr auto isDefinedSplice(int) -> decltype(std::integral_constant< bool, !std::is_same< typename S::type, std::tuple<>>::value >
check if a splice S is defined
Definition: propertysystem.hh:160
Definition: propertysystem.hh:213