I have a templated class:
template<Vector T>
struct diagonal_matrix;
Now, I want to create a concept DiagonalMatrix
for all of templated class versions. So:
DiagonalMatrix<diagonal_matrix<std::vector<double>>> == true
DiagonalMatrix<diagonal_matrix<std::array<float, 4>>> == true
DiagonalMatrix<diagonal_matrix<std::span<int, 10>>> == true
DiagonalMatrix<diagonal_matrix<my::random_access_container_view<unsigned int>>> == true
DiagonalMatrix<other_matrix> == false
Keep in mind that diagonal_matrix
has a subset of other_matrix
functionality.
Is there a way to create a concept DiagonalMatrix
which only accepts struct diagonal_matrix<?>
without tagging the struct with a static constexpr bool I_am_a_diagonal_matrix = true;
?. I don't care for implementations other than struct diagonal_matrix<?>
.
CodePudding user response:
Just wrap a plain old type trait:
#include <type_traits>
namespace detail {
template<typename>
constexpr bool is_diagonal_matrix_v{};
}
template<typename T>
concept DiagonalMatrix =
detail::is_diagonal_matrix_v<std::remove_cvref_t<T>>;
Then only types for which detail::is_diagonal_matrix_v<>
is appropriately specialized will satisfy (i.e. it is extensible and not strictly limited to diagonal_matrix<>
).
CodePudding user response:
If diagonal_matrix
has a member aliases for all it's template parameters, you can substitute them into diagonal_matrix<>
, then check you get what you started with.
template <typename M>
concept DiagonalMatrix = std::same_as<M, diagonal_matrix<typename M::vector_type>>;