Skip to content
Snippets Groups Projects
Commit b4f37070 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

[concept] Return check result as std::integral_constant<bool, *>

By using "std::integral_constant<bool, *>" instead of "constexpr bool"
as return type for Dune::models(), the result can directly be used
in Dune::Hybrid::ifElse():

  T t;
  ifElse(models<HasFoo, T>(), [&](auto id) {
    id(t).foo();
  }, [&](auto id) {
    id(t).bar();
  });

Before one would have to create the integral constant manually
to turn ifElse() into static mode. The change is backward compatible
because integral_constant<bool, *> casts to bool.

Notice that this change requires a small reorganization of code.
To use models() internally we need a forward declaration which
is not possible if the type is deduced (as it is now). Hence
a new function Imp:models() with "constexpr bool" return type
is added for internal use. Its result is encoded as integral_constant
by the actual interface method.
parent 777f016c
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@
#include <dune/common/typeutilities.hh>
#include <dune/common/typelist.hh>
#include <dune/common/tupleutility.hh>
#include <dune/common/std/type_traits.hh>
......@@ -17,12 +18,6 @@ namespace Dune {
// Forward declaration
template<class C, class... T>
constexpr bool models();
/**
* \brief Namespace for concepts
*
......@@ -61,6 +56,12 @@ namespace Imp {
// # for the models() function below.
// #############################################################################
// Forward declaration
template<class C, class... T>
constexpr bool models();
// Here is the implementation of the concept checking.
// The first two overloads do the magic for checking
// if the requirements of a concept are satisfied.
......@@ -97,7 +98,7 @@ namespace Imp {
// and all concepts in the list C1,..,CN.
template<class...T, class C0, class... CC>
constexpr bool modelsConceptList(TypeList<C0, CC...>)
{ return models<C0, T...>() and modelsConceptList<T...>(TypeList<CC...>()); }
{ return Imp::models<C0, T...>() and modelsConceptList<T...>(TypeList<CC...>()); }
......@@ -118,8 +119,67 @@ namespace Imp {
constexpr bool modelsConcept(PriorityTag<1>)
{ return matchesRequirement<C, T...>(PriorityTag<42>()) and modelsConceptList<T...>(typename C::BaseConceptList()); }
// This is the full concept check. It's defined here in the
// implementation namespace with 'constexpr bool' return type
// because we need a forward declaration in order to use it
// internally above.
//
// The actual interface function can then call this one and
// return the result as std::integral_constant<bool,*> which
// does not allow for a forward declaration because the return
// type is deduced.
template<class C, class... T>
constexpr bool models()
{
return modelsConcept<C, T...>(PriorityTag<42>());
}
} // namespace Dune::Concept::Imp
} // namespace Dune::Concept
/**
* \brief Check if concept is modeled by given types
*
* This will check if the given concept is modeled by the given
* list of types. This is true if the list of types models all
* the base concepts that are refined by the given concept
* and if it satisfies all additional requirements of the latter.
*
* Notice that a concept may be defined for a list of interacting types.
* The function will check if the given list of types matches the requirements
* on the whole list. It does not check if each individual type in the list
* satisfies the concept.
*
* This concept check mechanism is inspired by the concept checking
* facility in Eric Nieblers range-v3. For more information please
* refer to the libraries project page https://github.com/ericniebler/range-v3
* or this blog entry: http://ericniebler.com/2013/11/23/concept-checking-in-c11.
* In fact the interface provided here is almost exactly the same as in range-v3.
* However the implementation differs, because range-v3 uses its own meta-programming
* library whereas our implementation is more straight forward.
*
* The result is returned as std::integral_constant<bool, ...> which
* allows to nicely use this method with Hybrid::ifElse.
*
* \tparam C The concept to check
* \tparam T The list of type to check against the concept
*
*/
template<class C, class... T>
constexpr auto models()
{
return Std::bool_constant<Concept::Imp::models<C, T...>()>();
}
namespace Concept {
namespace Imp {
// #############################################################################
// # All functions following here are implementation details for the
// # for the tupleEntriesModel() function below.
......@@ -250,39 +310,6 @@ constexpr bool requireSameType()
/**
* \brief Check if concept is modeled by given types
*
* This will check if the given concept is modeled by the given
* list of types. This is true if the list of types models all
* the base concepts that are refined by the given concept
* and if it satisfies all additional requirements of the latter.
*
* Notice that a concept may be defined for a list of interacting types.
* The function will check if the given list of types matches the requirements
* on the whole list. It does not check if each individual type in the list
* satisfies the concept.
*
* This concept check mechanism is inspired by the concept checking
* facility in Eric Nieblers range-v3. For more information please
* refer to the libraries project page https://github.com/ericniebler/range-v3
* or this blog entry: http://ericniebler.com/2013/11/23/concept-checking-in-c11.
* In fact the interface provided here is almost exactly the same as in range-v3.
* However the implementation differs, because range-v3 uses its own meta-programming
* library whereas our implementation is more straight forward.
*
* \tparam C The concept to check
* \tparam T The list of type to check against the concept
*
*/
template<class C, class... T>
constexpr bool models()
{
return Concept::Imp::modelsConcept<C, T...>(PriorityTag<42>());
}
} // namespace Dune
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment