Skip to content

Commit

Permalink
Provide a C++17 implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
bangerth committed Jan 16, 2024
1 parent b6339d6 commit fd3c9ec
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions include/deal.II/base/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,7 @@ Tensor<rank_, dim, Number>::Tensor(const ArrayLike &initializer,
}


# ifdef DEAL_II_HAVE_CXX20

template <int rank_, int dim, typename Number>
constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE
Expand Down Expand Up @@ -1375,6 +1376,55 @@ Tensor<rank_, dim, Number>::Tensor()
}(std::make_index_sequence<dim>()))
{}

# else

// The C++17 case works in essence the same, except that we can't use a
// lambda function with explicit template parameters, i.e., we can't do
// []<std::size_t... I>(const std::index_sequence<I...> &)
// as above because that's a C++20 feature. Lambda functions in C++17 can
// have template packs as arguments, but we need the ability to *name*
// that template pack (the 'I' above) and that's not possible in C++17.
//
// We work around this by moving the lambda function to a global function
// and using the traditional template syntax on it.
namespace internal
{
namespace TensorInitialization
{
template <int rank, int dim, typename Number, std::size_t... I>
constexpr std::array<typename Tensor<rank, dim, Number>::value_type, dim>
make_zero_array(const std::index_sequence<I...> &)
{
static_assert(sizeof...(I) == dim, "This is bad.");

if constexpr (rank == 1)
{
auto get_zero_and_ignore_argument = [](int) {
return internal::NumberType<Number>::value(0.0);
};
return {{(get_zero_and_ignore_argument(I))...}};
}
else
{
auto get_zero_and_ignore_argument = [](int) {
return Tensor<rank - 1, dim, Number>();
};
return {{(get_zero_and_ignore_argument(I))...}};
}
};
} // namespace TensorInitialization
} // namespace internal


template <int rank_, int dim, typename Number>
constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE
Tensor<rank_, dim, Number>::Tensor()
: values(internal::TensorInitialization::make_zero_array<rank_, dim, Number>(
std::make_index_sequence<dim>()))
{}


# endif


template <int rank_, int dim, typename Number>
Expand Down

0 comments on commit fd3c9ec

Please sign in to comment.