Commit 720a8837 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Issue/cleanup concepts

parent 224f40e9
...@@ -16,7 +16,7 @@ namespace AMDiS ...@@ -16,7 +16,7 @@ namespace AMDiS
struct InterpolateData struct InterpolateData
{ {
template <class Data> template <class Data>
auto requires_(Data const& data) -> decltype( auto require(Data const& data) -> decltype(
const_cast<Data&>(data).preAdapt(true), const_cast<Data&>(data).preAdapt(true),
const_cast<Data&>(data).postAdapt(true) const_cast<Data&>(data).postAdapt(true)
); );
...@@ -25,7 +25,7 @@ namespace AMDiS ...@@ -25,7 +25,7 @@ namespace AMDiS
struct UpdateData struct UpdateData
{ {
template <class Basis> template <class Basis>
auto requires_(Basis const& basis) -> decltype( auto require(Basis const& basis) -> decltype(
const_cast<Basis&>(basis).update(basis.gridView()) const_cast<Basis&>(basis).update(basis.gridView())
); );
}; };
...@@ -35,9 +35,16 @@ namespace AMDiS ...@@ -35,9 +35,16 @@ namespace AMDiS
template <class Data> template <class Data>
constexpr bool InterpolateData = models<Definition::InterpolateData(Data)>; constexpr bool InterpolateData = models<Definition::InterpolateData(Data)>;
template <class Data>
using InterpolateData_t = models_t<Definition::InterpolateData(Data)>;
template <class Basis> template <class Basis>
constexpr bool UpdateData = models<Definition::UpdateData(Basis)>; constexpr bool UpdateData = models<Definition::UpdateData(Basis)>;
template <class Basis>
using UpdateData_t = models_t<Definition::UpdateData(Basis)>;
} // end namespace Concepts } // end namespace Concepts
/// @} /// @}
......
...@@ -15,30 +15,30 @@ namespace AMDiS ...@@ -15,30 +15,30 @@ namespace AMDiS
struct HasVectorAccess struct HasVectorAccess
{ {
template <class V, class I> template <class V, class I>
auto requires_(V&& v, I&& i, Dune::PriorityTag<2>) -> decltype( v[i] ); auto require(V&& v, I&& i, Dune::PriorityTag<2>) -> decltype( v[i] );
template <class V, class I> template <class V, class I>
auto requires_(V&& v, I&& i, Dune::PriorityTag<1>) -> decltype( v(i) ); auto require(V&& v, I&& i, Dune::PriorityTag<1>) -> decltype( v(i) );
}; };
struct HasMatrixAccess struct HasMatrixAccess
{ {
template <class M, class I, class J> template <class M, class I, class J>
auto requires_(M&& m, I&& i, J&& j, Dune::PriorityTag<2>) -> decltype( m[i][j] ); auto require(M&& m, I&& i, J&& j, Dune::PriorityTag<2>) -> decltype( m[i][j] );
template <class M, class I, class J> template <class M, class I, class J>
auto requires_(M&& m, I&& i, J&& j, Dune::PriorityTag<1>) -> decltype( m(i,j) ); auto require(M&& m, I&& i, J&& j, Dune::PriorityTag<1>) -> decltype( m(i,j) );
}; };
} // end namespace Definition } // end namespace Definition
/// Vector component can be accessed either with [.] or (.) /// Vector component can be accessed either with [.] or (.)
template <class V, class I> template <class V, class I>
using VectorAccessible_t = bool_t<models<Definition::HasVectorAccess(V, I, Dune::PriorityTag<42>)>>; using VectorAccessible_t = models_t<Definition::HasVectorAccess(V, I, Dune::PriorityTag<42>)>;
/// Matrix component can be accessed either with [.][.] or (.,.) /// Matrix component can be accessed either with [.][.] or (.,.)
template <class M, class I, class J> template <class M, class I, class J>
using MatrixAccessible_t = bool_t<models<Definition::HasMatrixAccess(M, I, J, Dune::PriorityTag<42>)>>; using MatrixAccessible_t = models_t<Definition::HasMatrixAccess(M, I, J, Dune::PriorityTag<42>)>;
} // end namespace Concepts } // end namespace Concepts
......
...@@ -53,19 +53,9 @@ namespace AMDiS ...@@ -53,19 +53,9 @@ namespace AMDiS
struct IsReferenceWrapper<std::reference_wrapper<T>> struct IsReferenceWrapper<std::reference_wrapper<T>>
: std::true_type {}; : std::true_type {};
template <class, class = void>
struct IsDefined
: std::false_type {};
template <class T>
struct IsDefined<T, std::enable_if_t<std::is_object<T>::value &&
!std::is_pointer<T>::value &&
(sizeof(T) > 0)> >
: std::true_type {};
} // end namespace Traits } // end namespace Traits
namespace Concepts namespace Concepts
{ {
#ifndef DOXYGEN #ifndef DOXYGEN
...@@ -75,33 +65,42 @@ namespace AMDiS ...@@ -75,33 +65,42 @@ namespace AMDiS
struct Callable struct Callable
{ {
template <class F, class... Args> template <class F, class... Args>
auto requires_(F&& f, Args&&... args) -> decltype(f(FWD(args)...)); auto require(F&& f, Args&&... args) -> decltype(
f(FWD(args)...)
);
}; };
// idx[0] // idx[0]
struct MultiIndex struct MultiIndex
{ {
template <class MI> template <class MI>
auto requires_(MI&& idx) -> decltype( auto require(MI&& idx) -> decltype(
Concepts::valid_expr( idx[0],
idx[0], idx.size(),
idx.size(), idx.max_size()
idx.max_size() );
/* ,idx.resize() */
));
}; };
} // end namespace Definition } // end namespace Definition
#endif // DOXYGEN #endif // DOXYGEN
/// Types are the same /// Types are the same
template <class... Ts> template <class... Ts>
constexpr bool Same = Traits::IsSame<Ts...>::value; constexpr bool Same = Traits::IsSame<Ts...>::value;
template <class... Ts>
using Same_t = Traits::IsSame<Ts...>;
/// Types are the same, up to decay of qualifiers /// Types are the same, up to decay of qualifiers
template <class A, class B> template <class A, class B>
constexpr bool Similar = Traits::IsSimilar<A, B>::value; constexpr bool Similar = Traits::IsSimilar<A, B>::value;
template <class A, class B>
using Similar_t = Traits::IsSimilar<A, B>;
/// \brief A Collable is a function `F` that can be called with arguments of type `Args...`. /// \brief A Collable is a function `F` that can be called with arguments of type `Args...`.
/** /**
* To be used as follows: `Concepts::Collable<F, Args...>`. Returns true, if * To be used as follows: `Concepts::Collable<F, Args...>`. Returns true, if
...@@ -111,6 +110,9 @@ namespace AMDiS ...@@ -111,6 +110,9 @@ namespace AMDiS
template <class F, class... Args> template <class F, class... Args>
constexpr bool Callable = models<Definition::Callable(F, Args...)>; constexpr bool Callable = models<Definition::Callable(F, Args...)>;
template <class F, class... Args>
using Callable_t = models_t<Definition::Callable(F, Args...)>;
/// \brief A Functor is a function `F` with signature `Signature`. /// \brief A Functor is a function `F` with signature `Signature`.
/** /**
...@@ -121,18 +123,26 @@ namespace AMDiS ...@@ -121,18 +123,26 @@ namespace AMDiS
template <class F, class Signature> // F, Signature=Return(Arg) template <class F, class Signature> // F, Signature=Return(Arg)
constexpr bool Functor = Dune::Functions::Concept::isFunction<F, Signature>(); constexpr bool Functor = Dune::Functions::Concept::isFunction<F, Signature>();
template <class F, class Signature> // F, Signature=Return(Arg)
using Functor_t = bool_t<Functor<F,Signature>>;
/// A predicate is a function that returns a boolean. /// A predicate is a function that returns a boolean.
template <class F, class... Args> template <class F, class... Args>
constexpr bool Predicate = Functor<F, bool(Args...)>; constexpr bool Predicate = Functor<F, bool(Args...)>;
template <class F, class... Args>
using Predicate_t = Functor_t<F, bool(Args...)>;
/// A multi-index type
template <class MI> template <class MI>
constexpr bool MultiIndex = models<Definition::MultiIndex(MI)>; constexpr bool MultiIndex = models<Definition::MultiIndex(MI)>;
template <class T> template <class MI>
constexpr bool Defined = Traits::IsDefined<T>::value; using MultiIndex_t = models_t<Definition::MultiIndex(MI)>;
/** @} **/ /** @} **/
} // end namespace Concepts } // end namespace Concepts
} // end namespace AMDiS } // end namespace AMDiS
...@@ -32,21 +32,10 @@ namespace AMDiS ...@@ -32,21 +32,10 @@ namespace AMDiS
{}; {};
template <class Concept, class... Ts> template <class Concept, class... Ts>
struct models<Concept(Ts...), void_t< decltype(std::declval<Concept>().requires_(std::declval<Ts>()...)) >> struct models<Concept(Ts...), void_t< decltype(std::declval<Concept>().require(std::declval<Ts>()...)) >>
: std::true_type : std::true_type
{}; {};
struct valid_expr
{
template <class... Ts>
void operator()(Ts&&...) const;
#if defined(__GNUC__) && !defined(__clang__)
template <class... Ts>
void operator()(Ts const&...) const;
#endif
};
} // end namespace Impl_ } // end namespace Impl_
...@@ -54,9 +43,9 @@ namespace AMDiS ...@@ -54,9 +43,9 @@ namespace AMDiS
template <class Concept> template <class Concept>
constexpr bool models = Impl_::models<Concept>::value; constexpr bool models = Impl_::models<Concept>::value;
constexpr Impl_::valid_expr valid_expr = {}; template <class Concept>
using models_t = Impl_::models<Concept>;
#endif // DOXYGEN #endif // DOXYGEN
} // end namespace Concepts } // end namespace Concepts
} // end namespace AMDiS } // end namespace AMDiS
...@@ -14,32 +14,32 @@ namespace AMDiS ...@@ -14,32 +14,32 @@ namespace AMDiS
struct VectorResizable struct VectorResizable
{ {
template <class V> template <class V>
auto requires_(V const& vec, Dune::PriorityTag<2>) -> decltype( const_cast<V&>(vec).resize(0u), 0); auto require(V const& vec, Dune::PriorityTag<2>) -> decltype( const_cast<V&>(vec).resize(0u), 0);
template <class V> template <class V>
auto requires_(V const& vec, Dune::PriorityTag<1>) -> decltype( const_cast<V&>(vec).change_dim(0u), 0); auto require(V const& vec, Dune::PriorityTag<1>) -> decltype( const_cast<V&>(vec).change_dim(0u), 0);
}; };
struct MatrixResizable struct MatrixResizable
{ {
template <class M> template <class M>
auto requires_(M const& mat, Dune::PriorityTag<3>) -> decltype( const_cast<M&>(mat).resize(0u,0u), 0); auto require(M const& mat, Dune::PriorityTag<3>) -> decltype( const_cast<M&>(mat).resize(0u,0u), 0);
template <class M> template <class M>
auto requires_(M const& mat, Dune::PriorityTag<2>) -> decltype( const_cast<M&>(mat).change_dim(0u,0u), 0); auto require(M const& mat, Dune::PriorityTag<2>) -> decltype( const_cast<M&>(mat).change_dim(0u,0u), 0);
template <class M> template <class M>
auto requires_(M const& mat, Dune::PriorityTag<1>) -> decltype( const_cast<M&>(mat).setSize(0u,0u), 0); auto require(M const& mat, Dune::PriorityTag<1>) -> decltype( const_cast<M&>(mat).setSize(0u,0u), 0);
}; };
} }
/// Checks whether a vector can be resized by various resize methods /// Checks whether a vector can be resized by various resize methods
template <class Vector> template <class Vector>
using VectorResizable_t = bool_t<models<Definition::VectorResizable(Vector, Dune::PriorityTag<42>)> >; using VectorResizable_t = models_t<Definition::VectorResizable(Vector, Dune::PriorityTag<42>)>;
/// Checks whether a matrix can be resized by various resize methods /// Checks whether a matrix can be resized by various resize methods
template <class Matrix> template <class Matrix>
using MatrixResizable_t = bool_t<models<Definition::MatrixResizable(Matrix, Dune::PriorityTag<42>)> >; using MatrixResizable_t = models_t<Definition::MatrixResizable(Matrix, Dune::PriorityTag<42>)>;
} // end namespace Concepts } // end namespace Concepts
......
...@@ -193,6 +193,9 @@ namespace AMDiS ...@@ -193,6 +193,9 @@ namespace AMDiS
Definition::CallableDow<F, WORLDDIM>; Definition::CallableDow<F, WORLDDIM>;
#endif #endif
template <class F>
using CallableDomain_t = bool_t<CallableDomain<F>>;
} // end namespace Concepts } // end namespace Concepts
......
...@@ -28,19 +28,19 @@ namespace AMDiS ...@@ -28,19 +28,19 @@ namespace AMDiS
struct HasDerivative struct HasDerivative
{ {
template <class F, class T> template <class F, class T>
auto requires_(F&& f, T&& t) -> decltype( derivative(f,t) ); auto require(F&& f, T&& t) -> decltype( derivative(f,t) );
}; };
struct HasLocalFunctionDerivative struct HasLocalFunctionDerivative
{ {
template <class F, class T> template <class F, class T>
auto requires_(F&& f, T&& t) -> decltype( derivative(localFunction(f),t) ); auto require(F&& f, T&& t) -> decltype( derivative(localFunction(f),t) );
}; };
struct HasPartial struct HasPartial
{ {
template <class F, class I> template <class F, class I>
auto requires_(F&& f, I&& i) -> decltype( partial(f, i) ); auto require(F&& f, I&& i) -> decltype( partial(f, i) );
}; };
} // end namespace Definition } // end namespace Definition
...@@ -50,14 +50,25 @@ namespace AMDiS ...@@ -50,14 +50,25 @@ namespace AMDiS
template <class GF, class Type> template <class GF, class Type>
constexpr bool HasDerivative = models<Definition::HasDerivative(GF,Type)>; constexpr bool HasDerivative = models<Definition::HasDerivative(GF,Type)>;
template <class GF, class Type>
using HasDerivative_t = models_t<Definition::HasDerivative(GF,Type)>;
/// \brief GridFunction GF has free function `derivative(localFunction(F))` /// \brief GridFunction GF has free function `derivative(localFunction(F))`
template <class GF, class Type> template <class GF, class Type>
constexpr bool HasLocalFunctionDerivative = models<Definition::HasLocalFunctionDerivative(GF,Type)>; constexpr bool HasLocalFunctionDerivative = models<Definition::HasLocalFunctionDerivative(GF,Type)>;
template <class GF, class Type>
using HasLocalFunctionDerivative_t = models_t<Definition::HasLocalFunctionDerivative(GF,Type)>;
/// \brief Functor F has free function `partial(F,_0)` /// \brief Functor F has free function `partial(F,_0)`
template <class F> template <class F>
constexpr bool HasPartial = models<Definition::HasPartial(F,index_t<0>)>; constexpr bool HasPartial = models<Definition::HasPartial(F,index_t<0>)>;
template <class F>
using HasPartial_t = models_t<Definition::HasPartial(F,index_t<0>)>;
/** @} **/ /** @} **/
} // end namespace Concepts } // end namespace Concepts
......
...@@ -20,16 +20,12 @@ namespace AMDiS ...@@ -20,16 +20,12 @@ namespace AMDiS
struct DomainType struct DomainType
{ {
using type = typename T0::Domain; using type = typename T0::Domain;
// static_assert( all_of_v< std::is_same<type, typename DomainType<Ts>::type>::value... >,
// "All GridFunctions must have the same Domain." );
}; };
template <class T0, class... Ts> template <class T0, class... Ts>
struct EntitySetType struct EntitySetType
{ {
using type = typename T0::EntitySet; using type = typename T0::EntitySet;
// static_assert( all_of_v< std::is_same<type, typename EntitySetType<Ts>::type>::value... >,
// "All GridFunctions must have the same EntitySet." );
}; };
} // end namespace Impl } // end namespace Impl
......
...@@ -38,16 +38,19 @@ namespace AMDiS ...@@ -38,16 +38,19 @@ namespace AMDiS
struct HasLocalFunction struct HasLocalFunction
{ {
template <class F> template <class F>
auto requires_(F&& f) -> decltype( localFunction(f) ); auto require(F&& f) -> decltype(
localFunction(f)
);
}; };
struct HasGridFunctionTypes struct HasGridFunctionTypes
{ {
template <class GF> template <class GF>
auto requires_(GF const& /*gf*/) -> void_t< auto require(GF const& /*gf*/) -> void_t<
typename GF::Range, typename GF::Range,
typename GF::Domain, typename GF::Domain,
typename GF::EntitySet >; typename GF::EntitySet
>;
}; };
} // end namespace Definition } // end namespace Definition
...@@ -57,12 +60,20 @@ namespace AMDiS ...@@ -57,12 +60,20 @@ namespace AMDiS
template <class GF> template <class GF>
constexpr bool HasLocalFunction = models<Definition::HasLocalFunction(GF)>; constexpr bool HasLocalFunction = models<Definition::HasLocalFunction(GF)>;
template <class GF>
using HasLocalFunction_t = models_t<Definition::HasLocalFunction(GF)>;
/// \brief GridFunction GF is a Type that has LocalFunction and provides some /// \brief GridFunction GF is a Type that has LocalFunction and provides some
/// typedefs for `Domain`, `Range`, and `EntitySet`. /// typedefs for `Domain`, `Range`, and `EntitySet`.
template <class GF> template <class GF>
constexpr bool GridFunction = constexpr bool GridFunction =
HasLocalFunction<GF> && models<Definition::HasGridFunctionTypes(GF)>; HasLocalFunction<GF> && models<Definition::HasGridFunctionTypes(GF)>;
template <class GF>
using GridFunction_t = bool_t<GridFunction<GF>>;
/// \brief Concept is fulfilled, if at least one of the massed Expressions /// \brief Concept is fulfilled, if at least one of the massed Expressions
/// can be converted to a GridFunction, or is already a GridFunction. /// can be converted to a GridFunction, or is already a GridFunction.
template <class... GFs> template <class... GFs>
...@@ -70,6 +81,9 @@ namespace AMDiS ...@@ -70,6 +81,9 @@ namespace AMDiS
any_of_v<GridFunction<remove_cvref_t<GFs>>...> || any_of_v<GridFunction<remove_cvref_t<GFs>>...> ||
any_of_v<Traits::IsPreGridFunction<remove_cvref_t<GFs>>::value...>; any_of_v<Traits::IsPreGridFunction<remove_cvref_t<GFs>>::value...>;
template <class... GFs>
using AnyGridFunction_t = bool_t<AnyGridFunction<GFs...>>;
/** @} **/ /** @} **/
} // end namespace Concepts } // end namespace Concepts
...@@ -137,7 +151,7 @@ namespace AMDiS ...@@ -137,7 +151,7 @@ namespace AMDiS
template <class PreGridFct, class GridView> template <class PreGridFct, class GridView>
decltype(auto) makeGridFunction(PreGridFct const& preGridFct, GridView const& gridView) decltype(auto) makeGridFunction(PreGridFct const& preGridFct, GridView const& gridView)
{ {
using isGridFct = bool_t<Concepts::GridFunction<PreGridFct>>; using isGridFct = Concepts::GridFunction_t<PreGridFct>;
return Impl::makeGridFunctionImpl(preGridFct, gridView, isGridFct{}); return Impl::makeGridFunctionImpl(preGridFct, gridView, isGridFct{});
} }
......
...@@ -24,13 +24,17 @@ namespace AMDiS ...@@ -24,13 +24,17 @@ namespace AMDiS
struct HasLocalFunctionOrder struct HasLocalFunctionOrder
{ {
template <class F> template <class F>
auto requires_(F&& f) -> decltype( order(localFunction(f)) ); auto require(F&& f) -> decltype(
order(localFunction(f))
);
}; };
struct HasOrder struct HasOrder
{ {
template <class F> template <class F>
auto requires_(F&& f) -> decltype( order(f) ); auto require(F&& f) -> decltype(
order(f)
);
}; };
} // end namespace Definition