Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Play with C++20 concepts #14836

Merged
merged 6 commits into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions cmake/checks/check_01_cxx_features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ macro(_test_cxx20_support)
# of the C++20 standard (which will have "202002L" when finalized). gcc-10
# exports this version number when configured with C++20 support.
# clang-10 exports the final "202002L" version instead, as does gcc-11.
#
# Beyond this, check for some features we actually need.
CHECK_CXX_SOURCE_COMPILES(
"
#include <cmath>
Expand All @@ -79,6 +81,20 @@ macro(_test_cxx20_support)
# error \"insufficient support for C++20\"
#endif


// Test concepts and requires clauses
template <int dim, int spacedim>
concept is_valid_dim_spacedim = (dim >= 1 && spacedim <= 3 &&
dim <= spacedim);

template <int dim, int spacedim>
requires is_valid_dim_spacedim<dim,spacedim>
class Triangulation
{};

Triangulation<1,3> t;
Comment on lines +85 to +95
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Test concepts and requires clauses
template <int dim, int spacedim>
concept is_valid_dim_spacedim = (dim >= 1 && spacedim <= 3 &&
dim <= spacedim);
template <int dim, int spacedim>
requires is_valid_dim_spacedim<dim,spacedim>
class Triangulation
{};
Triangulation<1,3> t;
#if !(defined __cpp_concepts) || (__cpp_concepts < 201907L)
# error \"insufficient support for C++20\"
#endif

for conformity (might also be slightly faster).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I actually would like to keep it as is. If we don't trust that -std=c++20 works, then we also shouldn't trust that __cpp_concepts is set correctly. Let's test for the actual feature we want to use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of these CMake features check really is that we decide if C++20 is supported based on the capabilities of the compilers with the given flags and not because the user requested C++20 support in any other way (at the moment). Thus, I wouldn't say that we don't trust that -std=c++20 works (since compilers allow passing this flag without supporting all of C++20 anyway). On the other hand, I think that the __cpp_concepts feature check is reliable, though. Anyway, I rather wanted to suggest using that than requesting changes.



int main()
{
}
Expand Down
15 changes: 14 additions & 1 deletion include/deal.II/base/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@
#cmakedefine DEAL_II_HAVE_CXX17
#cmakedefine DEAL_II_HAVE_CXX20

/**
* If we have C++20 available, we can have concepts and requires
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably check that we define DEAL_II_HAVE_CXX20 only if the compiler supports concepts.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean to exclude compilers that have a -std=c++20 command line flag, but do not actually support all of C++20?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, adding something using concepts in cmake/checks/check_01_cxx_features.cmake.

* clauses. We want to avoid using too many `#ifdef` statements, so
* define a convenience macro that allows us to write a 'requires'
* clause that is simply removed when not using C++20.
*/
#ifdef DEAL_II_HAVE_CXX20
# define DEAL_II_CXX20_REQUIRES(condition) requires(condition)
#else
# define DEAL_II_CXX20_REQUIRES(condition)
#endif

#cmakedefine DEAL_II_HAVE_FP_EXCEPTIONS
#cmakedefine DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS
#cmakedefine DEAL_II_HAVE_CXX17_BESSEL_FUNCTIONS
Expand All @@ -174,9 +186,10 @@
#cmakedefine DEAL_II_FALLTHROUGH @DEAL_II_FALLTHROUGH@
#cmakedefine DEAL_II_CONSTEXPR @DEAL_II_CONSTEXPR@

// defined for backwards compatibility with older deal.II versions
// The following two are defined for backwards compatibility with older deal.II versions:
#define DEAL_II_WITH_CXX11
#define DEAL_II_WITH_CXX14

#ifdef DEAL_II_HAVE_CXX17
# define DEAL_II_WITH_CXX17
#endif
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/base/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ DEAL_II_NAMESPACE_OPEN
* @ingroup geomprimitives
*/
template <int dim, typename Number = double>
DEAL_II_CXX20_REQUIRES(dim >= 0)
class Point : public Tensor<1, dim, Number>
{
public:
Expand Down
23 changes: 23 additions & 0 deletions include/deal.II/base/template_constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,29 @@ struct EnableIfScalar<std::complex<T>>
};


/**
* A namespace that is used to declare concepts used in C++20-style
* `requires` clauses.
*/
namespace concepts
{
#ifdef DEAL_II_HAVE_CXX20
/**
* A concept that tests that a combination of `dim` and `spacedim`
* template arguments is valid. Specifically, we must have that
* - `dim>=1`
* - `spacedim<=3`
* - `dim<=spacedim`.
* These are the kinds of requirements that are imposed, for
* example, on class Triangulation.
*/
template <int dim, int spacedim>
concept is_valid_dim_spacedim = (dim >= 1 && spacedim <= 3 &&
dim <= spacedim);
#endif
} // namespace concepts


DEAL_II_NAMESPACE_CLOSE

#endif
3 changes: 3 additions & 0 deletions include/deal.II/base/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ DEAL_II_NAMESPACE_OPEN
#ifndef DOXYGEN
template <typename ElementType, typename MemorySpace>
class ArrayView;

template <int dim, typename Number>
DEAL_II_CXX20_REQUIRES(dim >= 0)
class Point;

template <int rank_, int dim, typename Number = double>
class Tensor;
template <typename Number>
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/base/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ DEAL_II_NAMESPACE_OPEN
// forward declare Point
#ifndef DOXYGEN
template <int dim, typename Number>
DEAL_II_CXX20_REQUIRES(dim >= 0)
class Point;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/distributed/p4est_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace parallel
namespace distributed
{
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
}
} // namespace parallel
Expand Down
2 changes: 2 additions & 0 deletions include/deal.II/dofs/block_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <deal.II/base/memory_consumption.h>
#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>

#include <deal.II/lac/block_indices.h>

Expand All @@ -30,6 +31,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declarations
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
4 changes: 3 additions & 1 deletion include/deal.II/dofs/dof_accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,7 @@ class DoFAccessor : public dealii::internal::DoFAccessorImplementation::
// Make the DoFHandler class a friend so that it can call the set_xxx()
// functions.
template <int, int>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
friend class DoFHandler;

friend struct dealii::internal::DoFHandlerImplementation::Policy::
Expand Down Expand Up @@ -1208,7 +1209,8 @@ class DoFAccessor<0, 1, spacedim, level_dof_access>

// Make the DoFHandler class a friend so that it can call the set_xxx()
// functions.
template <int, int>
template <int dim1, int spacedim1>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim1, spacedim1>))
friend class DoFHandler;

friend struct dealii::internal::DoFHandlerImplementation::Policy::
Expand Down
2 changes: 2 additions & 0 deletions include/deal.II/dofs/dof_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ DEAL_II_NAMESPACE_OPEN
template <int dim, int spacedim>
class FiniteElement;
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;

namespace internal
Expand Down Expand Up @@ -310,6 +311,7 @@ namespace parallel
* @ingroup dofs
*/
template <int dim, int spacedim = dim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler : public Subscriptor
{
using ActiveSelector =
Expand Down
3 changes: 2 additions & 1 deletion include/deal.II/dofs/dof_handler_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ DEAL_II_NAMESPACE_OPEN

// Forward declaration
#ifndef DOXYGEN
template <int, int>
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/dofs/dof_iterator_selector.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ template <int dim, int spacedim, bool lda>
class DoFCellAccessor;

template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;

template <typename Accessor>
Expand Down
4 changes: 3 additions & 1 deletion include/deal.II/dofs/dof_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
#include <deal.II/base/config.h>

#include <deal.II/base/exceptions.h>
#include <deal.II/base/template_constraints.h>

#include <vector>

DEAL_II_NAMESPACE_OPEN

// Forward declarations
#ifndef DOXYGEN
template <int, int>
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/fe/fe_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Quadrature;
template <int dim, int spacedim>
class FiniteElement;
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
template <int dim>
class FiniteElementData;
Expand Down
3 changes: 2 additions & 1 deletion include/deal.II/fe/mapping_q_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ DEAL_II_NAMESPACE_OPEN

// Forward declarations
#ifndef DOXYGEN
template <int, int>
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
3 changes: 2 additions & 1 deletion include/deal.II/grid/cell_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ DEAL_II_NAMESPACE_OPEN

// Forward declarations
#ifndef DOXYGEN
template <int, int>
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
#endif

Expand Down
3 changes: 2 additions & 1 deletion include/deal.II/grid/grid_in.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ DEAL_II_NAMESPACE_OPEN

// Forward declarations
#ifndef DOXYGEN
template <int dim, int space_dim>
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
template <int dim>
struct CellData;
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/grid/grid_out.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ DEAL_II_NAMESPACE_OPEN
#ifndef DOXYGEN
class ParameterHandler;
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
template <int dim, int spacedim>
class Mapping;
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/grid/grid_refinement.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ DEAL_II_NAMESPACE_OPEN
// forward declarations
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
template <typename Number>
class Vector;
Expand Down
2 changes: 1 addition & 1 deletion include/deal.II/grid/grid_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace parallel
{
namespace distributed
{
template <int, int>
template <int dim, int spacedim>
class Triangulation;
}
} // namespace parallel
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/grid/tria.h
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,7 @@ namespace internal
* @ingroup grid aniso
*/
template <int dim, int spacedim = dim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation : public Subscriptor
{
private:
Expand Down
4 changes: 4 additions & 0 deletions include/deal.II/grid/tria_accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declarations
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
template <typename Accessor>
class TriaRawIterator;
Expand All @@ -54,6 +55,7 @@ namespace parallel
}

template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
template <int dim, int spacedim, bool lda>
class DoFCellAccessor;
Expand Down Expand Up @@ -1870,6 +1872,7 @@ class TriaAccessor : public TriaAccessorBase<structdim, dim, spacedim>

private:
template <int, int>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
friend class Triangulation;

friend struct dealii::internal::TriangulationImplementation::Implementation;
Expand Down Expand Up @@ -4170,6 +4173,7 @@ class CellAccessor : public TriaAccessor<dim, dim, spacedim>
set_direction_flag(const bool new_direction_flag) const;

template <int, int>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
friend class Triangulation;

template <int, int>
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/grid/tria_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declarations
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
template <int, int, int>
class TriaAccessorBase;
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/grid/tria_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declarations
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class Triangulation;
template <class Accessor>
class TriaRawIterator;
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/hp/refinement.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ template <typename Number>
class Vector;

template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/multigrid/mg_constrained_dofs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declaration
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/multigrid/mg_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declarations
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
class MGConstrainedDoFs;
#endif
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/multigrid/mg_transfer_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declaration
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/multigrid/mg_transfer_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declaration
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
1 change: 1 addition & 0 deletions include/deal.II/numerics/data_out_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ DEAL_II_NAMESPACE_OPEN
// Forward declaration
#ifndef DOXYGEN
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
#endif

Expand Down
3 changes: 2 additions & 1 deletion include/deal.II/numerics/error_estimator.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ DEAL_II_NAMESPACE_OPEN

// Forward declarations
#ifndef DOXYGEN
template <int, int>
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;
template <int, int>
class Mapping;
Expand Down
1 change: 1 addition & 0 deletions include/deal.II/numerics/matrix_creator.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class SparseMatrix;
template <int dim, int spacedim>
class Mapping;
template <int dim, int spacedim>
DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
class DoFHandler;

namespace hp
Expand Down