From 01483613afec76fc8aa59df90b80e72f14228d77 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 6 Mar 2023 11:30:01 -0700 Subject: [PATCH] Introduce a concept that tests whether something a (writable) vector. --- include/deal.II/base/template_constraints.h | 172 ++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/include/deal.II/base/template_constraints.h b/include/deal.II/base/template_constraints.h index 2f03800ee0..6e2995ef16 100644 --- a/include/deal.II/base/template_constraints.h +++ b/include/deal.II/base/template_constraints.h @@ -22,8 +22,10 @@ #include #include +#include #include + DEAL_II_NAMESPACE_OPEN // Detection idiom adapted from Version 2 of the C++ Extensions for Library @@ -680,6 +682,72 @@ struct EnableIfScalar> }; +// Forward declarations of vector types +template +class Vector; + +template +class BlockVector; + +namespace LinearAlgebra +{ + template + class Vector; + + template + class BlockVector; + + namespace distributed + { + template + class Vector; + + template + class BlockVector; + } // namespace distributed +} // namespace LinearAlgebra + +#ifdef DEAL_II_WITH_PETSC +namespace PETScWrappers +{ + class Vector; + class BlockVector; + + namespace MPI + { + class Vector; + class BlockVector; + } // namespace MPI +} // namespace PETScWrappers +#endif + +#ifdef DEAL_II_WITH_TRILINOS +namespace TrilinosWrappers +{ + namespace MPI + { + class Vector; + class BlockVector; + } // namespace MPI +} // namespace TrilinosWrappers + +namespace LinearAlgebra +{ + namespace EpetraWrappers + { + class Vector; + } + +# ifdef DEAL_II_TRILINOS_WITH_TPETRA + namespace TpetraWrappers + { + class Vector; + } +# endif +} // namespace LinearAlgebra +#endif + + /** * A namespace that is used to declare concepts used in C++20-style * `requires` clauses. @@ -699,6 +767,110 @@ namespace concepts template concept is_valid_dim_spacedim = (dim >= 1 && spacedim <= 3 && dim <= spacedim); + + namespace internal + { + /** + * A template variable that returns whether the template argument is + * a valid deal.II vector type. Its general definition is `false`, with + * specializations dealing with actual vector types for which the + * predicate is `true`. + */ + template + constexpr bool is_dealii_vector_type = false; + + template + constexpr bool is_dealii_vector_type> = true; + + template + constexpr bool is_dealii_vector_type> = true; + + template + constexpr bool + is_dealii_vector_type> = true; + + template + constexpr bool + is_dealii_vector_type> = true; + + template + constexpr bool is_dealii_vector_type< + dealii::LinearAlgebra::distributed::Vector> = true; + + template + constexpr bool is_dealii_vector_type< + dealii::LinearAlgebra::distributed::BlockVector> = true; + +# ifdef DEAL_II_WITH_PETSC + template <> + constexpr bool is_dealii_vector_type = true; + + template <> + constexpr bool is_dealii_vector_type = + true; + + template <> + constexpr bool is_dealii_vector_type = + true; + + template <> + constexpr bool + is_dealii_vector_type = true; +# endif + +# ifdef DEAL_II_WITH_TRILINOS + template <> + constexpr bool + is_dealii_vector_type = true; + + template <> + constexpr bool + is_dealii_vector_type = true; + + template <> + constexpr bool + is_dealii_vector_type = + true; + +# ifdef DEAL_II_TRILINOS_WITH_TPETRA + template <> + constexpr bool + is_dealii_vector_type = + true; +# endif +# endif + } // namespace internal + + + /** + * A concept that tests whether a given template argument is a deal.II + * vector type. This concept is used in many places, such as for the + * functions in namespace VectorTools, where functions take a vector + * as argument, but the type of the vector is a template argument. The + * concept ensures that these functions cannot be called with an `int` + * argument, for example, for which the declaration without the concept + * would be perfectly valid but for which one would later get a linker + * error because the function is only instantiated for deal.II vector + * types. + */ + template + concept is_dealii_vector_type = + internal::is_dealii_vector_type>; + + /** + * A concept that tests whether a given template argument is a deal.II + * vector type into which one can write. It is defined by asking + * whether the is_dealii_vector_type concept is satisfied, and + * that the template argument is not a `const`-qualified type. For + * example, `is_writable_dealii_vector_type` is true, + * whereas `is_writable_dealii_vector_type` is + * not. + */ + template + concept is_writable_dealii_vector_type = is_dealii_vector_type && + (std::is_const_v == + false); + #endif } // namespace concepts -- 2.39.5