mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-22 09:16:27 -06:00
Merge pull request #882 from akva2/remove_propsystem_macros
remove last remnants of property system macros
This commit is contained in:
commit
6fd995caab
@ -56,11 +56,9 @@ template<class P>
|
||||
constexpr std::true_type isDefinedProperty(...) { return {}; }
|
||||
|
||||
//! check if a TypeTag inherits from other TypeTags
|
||||
//! the enable_if portion of decltype is only needed for the macro hack to work, if no macros are in use anymore it can be removed,
|
||||
//! i.e. then trailing return type is then -> decltype(std::declval<typename T::InheritsFrom>(), std::true_type{})
|
||||
template<class T>
|
||||
constexpr auto hasParentTypeTag(int)
|
||||
-> decltype(std::declval<typename T::InheritsFrom>(), std::enable_if_t<!std::is_same<typename T::InheritsFrom, void>::value, int>{}, std::true_type{})
|
||||
-> decltype(std::declval<typename T::InheritsFrom>(), std::true_type{})
|
||||
{ return {}; }
|
||||
|
||||
//! fall back if a TypeTag doesn't inherit
|
||||
@ -256,9 +254,4 @@ void printValues(std::ostream& os)
|
||||
|
||||
} // end namespace Opm
|
||||
|
||||
// remove this after release 2021.04 to remove macros completely
|
||||
#if OPM_ENABLE_OLD_PROPERTY_MACROS
|
||||
#include <opm/models/utils/propertysystemmacros.hh>
|
||||
#endif // OPM_ENABLE_OLD_PROPERTY_MACROS
|
||||
|
||||
#endif
|
||||
|
@ -1,390 +0,0 @@
|
||||
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
// vi: set et ts=4 sw=4 sts=4:
|
||||
/*****************************************************************************
|
||||
* See the file COPYING for full copying permissions. *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*****************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
* \ingroup Properties
|
||||
* \brief Provides the magic behind the DuMuX property system.
|
||||
*
|
||||
* Properties allow to associate arbitrary data types to
|
||||
* identifiers. A property is always defined on a pair (TypeTag,
|
||||
* PropertyTag) where TypeTag is the identifier for the object the
|
||||
* property is defined for and PropertyTag is an unique identifier of
|
||||
* the property.
|
||||
*
|
||||
* Type tags are hierarchic and inherit properties defined on their
|
||||
* ancesters. At each level, properties defined on lower levels can be
|
||||
* overwritten or even made undefined. It is also possible to define
|
||||
* defaults for properties if it makes sense.
|
||||
*
|
||||
* Properties may make use other properties for the respective type
|
||||
* tag and these properties can also be defined on an arbitrary level
|
||||
* of the hierarchy.
|
||||
*/
|
||||
#ifndef OPM_PROPERTY_SYSTEM_MACROS_HH
|
||||
#define OPM_PROPERTY_SYSTEM_MACROS_HH
|
||||
#warning "Property macros are deprecated and will be removed after release 2021.04. \
|
||||
If you are not using property macros you can disable this warning by \
|
||||
setting OPM_ENABLE_OLD_PROPERTY_MACROS to 0 (false) when configuring OPM. \
|
||||
OPM_ENABLE_OLD_PROPERTY_MACROS defaults to 1 (true) until release 2020.10. \
|
||||
After release 2020.10 it will default to 0 (false) so you will have to manually \
|
||||
enable property macros in order to use them."
|
||||
|
||||
#include <opm/models/utils/propertysystem.hh>
|
||||
|
||||
namespace Opm {
|
||||
namespace Properties {
|
||||
|
||||
namespace TTag {}
|
||||
|
||||
/*!
|
||||
* \brief Makes a type out of a type tag name
|
||||
*/
|
||||
#define TTAG(TypeTagName) ::Opm::Properties::TTag::TypeTagName
|
||||
|
||||
/*!
|
||||
* \brief Makes a type out of a property tag name
|
||||
*/
|
||||
//#define PTAG(PropTagName) PropTagName
|
||||
|
||||
/*!
|
||||
* \brief Makes a type out of a property tag name
|
||||
*/
|
||||
#define PTAG_(PropTagName) ::Opm::Properties::PropTagName
|
||||
|
||||
|
||||
// in the old property system the order in inherit_from was the other way around
|
||||
// this flips the order of a tuple to restore old behaviour when using the macro.
|
||||
// when you are using non-macro version make sure to flip the order.
|
||||
template<class Tuple, class IndexSequence>
|
||||
struct ReverseTupleImpl;
|
||||
|
||||
template<class Tuple, size_t... I>
|
||||
struct ReverseTupleImpl<Tuple, std::index_sequence<I...>>
|
||||
{
|
||||
using type = std::tuple<std::tuple_element_t<sizeof...(I) - 1 - I, Tuple>...>;
|
||||
};
|
||||
|
||||
// revert tuple argument order
|
||||
template<class Tuple>
|
||||
using ReverseTuple = typename ReverseTupleImpl<Tuple, std::make_index_sequence<std::tuple_size<Tuple>::value>>::type;
|
||||
|
||||
// a temporary hack to make the macro still work, we set using InheritsFrom = void,
|
||||
// which gets picked up by the new property as non inheritance, this can be removed
|
||||
// once all macros are gone
|
||||
namespace Detail {
|
||||
template<class TypeTagTuple>
|
||||
struct GetTypeTagInheritance;
|
||||
|
||||
template<class OneTypeTag>
|
||||
struct GetTypeTagInheritance<std::tuple<OneTypeTag>>
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template<class FirstTypeTag, class ...OtherTypeTags>
|
||||
struct GetTypeTagInheritance<std::tuple<FirstTypeTag, OtherTypeTags...>>
|
||||
{
|
||||
// reverse order to restore old behaviour
|
||||
using type = ReverseTuple<std::tuple<OtherTypeTags...>>;
|
||||
};
|
||||
} // end namespace Detail
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Define a new type tag.
|
||||
*
|
||||
* A type tag can inherit the properties defined on up to five parent
|
||||
* type tags. Examples:
|
||||
*
|
||||
* \code
|
||||
* // The type tag doesn't inherit any properties from other type tags
|
||||
* NEW_TYPE_TAG(FooTypeTag);
|
||||
*
|
||||
* // BarTypeTag inherits all properties from FooTypeTag
|
||||
* NEW_TYPE_TAG(BarTypeTag, INHERITS_FROM(FooTypeTag));
|
||||
*
|
||||
* // FooBarTypeTag inherits the properties of FooTypeTag as well as
|
||||
* // those of BarTypeTag. Properties defined on BarTypeTag have
|
||||
* // preceedence over those defined for FooTypeTag:
|
||||
* NEW_TYPE_TAG(FooBarTypeTag, INHERITS_FROM(FooTypeTag, BarTypeTag));
|
||||
* \endcode
|
||||
*/
|
||||
#define OPM_GET_HEAD_(Arg1, ...) Arg1
|
||||
|
||||
#define NEW_TYPE_TAG(...) \
|
||||
namespace TTag { \
|
||||
struct OPM_GET_HEAD_(__VA_ARGS__) \
|
||||
{ using InheritsFrom = Detail::GetTypeTagInheritance<std::tuple<__VA_ARGS__>>::type; }; \
|
||||
} extern int semicolonHack_
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Syntactic sugar for NEW_TYPE_TAG.
|
||||
*
|
||||
* See the documentation for NEW_TYPE_TAG.
|
||||
*/
|
||||
#define INHERITS_FROM(...) __VA_ARGS__
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Define a property tag.
|
||||
*
|
||||
* A property tag is the unique identifier for a property. It may only
|
||||
* be declared once in your program. There is also no hierarchy of
|
||||
* property tags as for type tags.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* \code
|
||||
* NEW_PROP_TAG(blubbPropTag);
|
||||
* NEW_PROP_TAG(blabbPropTag);
|
||||
* \endcode
|
||||
*/
|
||||
#define NEW_PROP_TAG(PTagName) \
|
||||
template<class TypeTag, class MyTypeTag> \
|
||||
struct PTagName { using type = UndefinedProperty; }; \
|
||||
extern int semicolonHack_
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Set a property for a specific type tag.
|
||||
*
|
||||
* After this macro, you must to specify a complete body of a class
|
||||
* template, including the trailing semicolon. If you need to retrieve
|
||||
* another property within the class body, you can use TypeTag as the
|
||||
* argument for the type tag for the GET_PROP macro.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* \code
|
||||
* SET_PROP(FooTypeTag, blubbPropTag)
|
||||
* {
|
||||
* static int value = 10;
|
||||
* static int calculate(int arg)
|
||||
* { calculateInternal_(arg); }
|
||||
*
|
||||
* private:
|
||||
* // retrieve the blabbProp property for the real TypeTag the
|
||||
* // property is defined on. Note that blabbProb does not need to
|
||||
* // be defined on FooTypeTag, but can also be defined for some
|
||||
* // derived type tag.
|
||||
* using blabb = typename GET_PROP(TypeTag, blabbProp);
|
||||
*
|
||||
* static int calculateInternal_(int arg)
|
||||
* { return arg * blabb::value; };
|
||||
* \endcode
|
||||
* };
|
||||
*/
|
||||
#define SET_PROP(EffTypeTagName, PropTagName) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)>
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Set a property to a simple constant integer value.
|
||||
*
|
||||
* The constant can be accessed by the 'value' attribute.
|
||||
*/
|
||||
#define SET_INT_PROP(EffTypeTagName, PropTagName, /*Value*/...) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)> \
|
||||
{ \
|
||||
using type = int; \
|
||||
static constexpr int value = __VA_ARGS__; \
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Set a property to a simple constant boolean value.
|
||||
*
|
||||
* The constant can be accessed by the 'value' attribute.
|
||||
*/
|
||||
#define SET_BOOL_PROP(EffTypeTagName, PropTagName, /*Value*/...) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)> \
|
||||
{ \
|
||||
using type = bool; \
|
||||
static constexpr bool value = __VA_ARGS__; \
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Set a property which defines a type.
|
||||
*
|
||||
* The type can be accessed by the 'type' attribute.
|
||||
*/
|
||||
#define SET_TYPE_PROP(EffTypeTagName, PropTagName, /*Value*/...) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)> \
|
||||
{ \
|
||||
using type = __VA_ARGS__; \
|
||||
}
|
||||
|
||||
template <class TypeTag, class MyTypeTag>
|
||||
struct Scalar;
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Set a property to a simple constant scalar value.
|
||||
*
|
||||
* The constant can be accessed by the 'value' attribute. In order to
|
||||
* use this macro, the property tag "Scalar" needs to be defined for
|
||||
* the real type tag.
|
||||
*/
|
||||
#define SET_SCALAR_PROP(EffTypeTagName, PropTagName, ...) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)> \
|
||||
{ \
|
||||
using Scalar = Opm::GetPropType<TypeTag, Scalar>; \
|
||||
public: \
|
||||
using type = Scalar; \
|
||||
static const Scalar value; \
|
||||
}; \
|
||||
template <class TypeTag> \
|
||||
const typename PropTagName<TypeTag, TTAG(EffTypeTagName)>::type \
|
||||
PropTagName<TypeTag, TTAG(EffTypeTagName)>::value(__VA_ARGS__)
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Set a property to a simple constant string value.
|
||||
*
|
||||
* The constant can be accessed by the 'value' attribute and is of
|
||||
* type std::string.
|
||||
*/
|
||||
#define SET_STRING_PROP(EffTypeTagName, PropTagName, ...) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)> \
|
||||
{ \
|
||||
public: \
|
||||
using type = std::string; \
|
||||
static const std::string value; \
|
||||
}; \
|
||||
template <class TypeTag> \
|
||||
const typename PropTagName<TypeTag, TTAG(EffTypeTagName)>::type \
|
||||
PropTagName<TypeTag, TTAG(EffTypeTagName)>::value(__VA_ARGS__)
|
||||
|
||||
|
||||
// getters
|
||||
#define GET_PROP(TypeTag, PropTagName) ::Opm::Properties::Detail::GetPropImpl<TypeTag, PTAG_(PropTagName)>::type
|
||||
#define GET_PROP_VALUE(TypeTag, PropTagName) ::Opm::Properties::Detail::GetPropImpl<TypeTag, PTAG_(PropTagName)>::type::value
|
||||
#define GET_PROP_TYPE(TypeTag, PropTagName) ::Opm::Properties::Detail::GetPropImpl<TypeTag, PTAG_(PropTagName)>::type::type
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Define splices for a given type tag.
|
||||
*
|
||||
* Splices can be seen as children which can be overridden lower in
|
||||
* the hierarchy. It can thus be seen as a "deferred inheritance"
|
||||
* mechanism. Example:
|
||||
*
|
||||
* \code
|
||||
* // First, define type tags for two different linear solvers:
|
||||
* // BiCGStab and SuperLU. The first needs the "MaxIterations"
|
||||
* // property, the second defines the "UsePivoting" property.
|
||||
* NEW_TYPE_TAG(BiCGStabSolver);
|
||||
* NEW_PROP_TAG(MaxIterations);
|
||||
* SET_INT_PROP(BiCGStabSolver, MaxIterations, 100);
|
||||
*
|
||||
* NEW_TYPE_TAG(SuperLUSolver);
|
||||
* NEW_PROP_TAG(UsePivoting);
|
||||
* SET_BOOL_PROP(SuperLUSolver, UsePivoting, true);
|
||||
*
|
||||
* // The model type tag defines the splice 'LinearSolver' and sets it
|
||||
* // to the 'BiCGStabSolver' type tag.
|
||||
* NEW_TYPE_TAG(ModelTypeTag);
|
||||
* NEW_PROP_TAG(LinearSolver);
|
||||
* SET_SPLICES(ModelTypeTag, LinearSolver);
|
||||
* SET_TAG_PROP(ModelTypeTag, LinearSolver, BiCGStabSolver);
|
||||
*
|
||||
* // The problem type tag is derived from the model type tag, but uses
|
||||
* // the SuperLU solver. Since this is done using a splice, all properties
|
||||
* // defined for the "SuperLUSolver" are inherited and the ones for the
|
||||
* // BiCGStabSolver type tag are undefined
|
||||
* NEW_TYPE_TAG(ProblemTypeTag, INHERITS_FROM(ModelTypeTag));
|
||||
* SET_TAG_PROP(ProblemTypeTag, LinearSolver, SuperLUSolver);
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#define SET_ONE_SPLICE(TypeTagName, SpliceName) \
|
||||
template<class TypeTag> \
|
||||
struct Splices<TypeTag, TTag::TypeTagName> \
|
||||
{ \
|
||||
using type = std::tuple<GetSplicePropType<TypeTag, TTag::TypeTagName, Properties::SpliceName>>; \
|
||||
}; \
|
||||
extern int semicolonHack_
|
||||
|
||||
#define SET_TWO_SPLICES(TypeTagName, SpliceName1, SpliceName2) \
|
||||
template<class TypeTag> \
|
||||
struct Splices<TypeTag, TTag::TypeTagName> \
|
||||
{ \
|
||||
using type = std::tuple<GetSplicePropType<TypeTag, TTag::TypeTagName, Properties::SpliceName1>, \
|
||||
GetSplicePropType<TypeTag, TTag::TypeTagName, Properties::SpliceName2>>; \
|
||||
}; \
|
||||
extern int semicolonHack_
|
||||
|
||||
#define SET_THREE_SPLICES(TypeTagName, SpliceName1, SpliceName2, SpliceName3) \
|
||||
template<class TypeTag> \
|
||||
struct Splices<TypeTag, TTag::TypeTagName> \
|
||||
{ \
|
||||
using type = std::tuple<GetSplicePropType<TypeTag, TTag::TypeTagName, Properties::SpliceName1>, \
|
||||
GetSplicePropType<TypeTag, TTag::TypeTagName, Properties::SpliceName2>, \
|
||||
GetSplicePropType<TypeTag, TTag::TypeTagName, Properties::SpliceName3>>; \
|
||||
}; \
|
||||
extern int semicolonHack_
|
||||
|
||||
// From https://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments
|
||||
#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME
|
||||
#define SET_SPLICES(...) GET_MACRO(__VA_ARGS__, SET_THREE_SPLICES, SET_TWO_SPLICES, SET_ONE_SPLICE)(__VA_ARGS__)
|
||||
|
||||
#define SET_PROP_(EffTypeTagName, PropKind, PropTagName, ...) \
|
||||
template <class TypeTag> \
|
||||
struct PropTagName<TypeTag, TTAG(EffTypeTagName)>
|
||||
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Define a property containing a type tag.
|
||||
*
|
||||
* This is convenient for splices.
|
||||
*/
|
||||
#define SET_TAG_PROP(EffTypeTagName, PropTagName, ValueTypeTagName) \
|
||||
SET_PROP_(EffTypeTagName, \
|
||||
/*kind=*/"tag ", \
|
||||
PropTagName, \
|
||||
/*value=*/TTAG(ValueTypeTagName)) \
|
||||
{ \
|
||||
using type = TTAG(ValueTypeTagName); \
|
||||
}
|
||||
|
||||
} // namespace Properties
|
||||
} // namespace Opm
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Indicates that property definitions follow
|
||||
*/
|
||||
#define BEGIN_PROPERTIES namespace Opm { namespace Properties {
|
||||
|
||||
/*!
|
||||
* \ingroup Properties
|
||||
* \brief Indicates that all properties have been specified (for now)
|
||||
*/
|
||||
#define END_PROPERTIES }}
|
||||
|
||||
#endif // OPM_PROPERTY_SYSTEM_MACROS_HH
|
Loading…
Reference in New Issue
Block a user