*/
Number value;
- /**
- * Internal helper function for unroll.
- */
- template <typename Iterator>
- Iterator
- unroll_recursion(const Iterator current, const Iterator end) const;
-
// Allow an arbitrary Tensor to access the underlying values.
template <int, int, typename>
friend class Tensor;
// ... avoid a compiler warning in case of dim == 0 and ensure that the
// array always has positive size.
- /**
- * Internal helper function for unroll.
- */
- template <typename Iterator>
- Iterator
- unroll_recursion(const Iterator current, const Iterator end) const;
-
/**
* This constructor is for internal use. It provides a way
* to create constexpr constructors for Tensor<rank, dim, Number>
-template <int dim, typename Number>
-template <typename Iterator>
-Iterator
-Tensor<0, dim, Number>::unroll_recursion(const Iterator current,
- const Iterator end) const
-{
- (void)end;
- Assert(dim != 0,
- ExcMessage("Cannot unroll an object of type Tensor<0,0,Number>"));
- Assert(std::distance(current, end) >= 1,
- ExcMessage("The provided iterator range must contain at least one "
- "element."));
- *current = value;
- return std::next(current);
-}
-
-
-
template <int dim, typename Number>
constexpr inline void
Tensor<0, dim, Number>::clear()
inline void
Tensor<0, dim, Number>::unroll(const Iterator begin, const Iterator end) const
{
+ (void)end;
AssertDimension(std::distance(begin, end), n_independent_components);
- unroll_recursion(begin, end);
+ Assert(dim != 0,
+ ExcMessage("Cannot unroll an object of type Tensor<0,0,Number>"));
+ Assert(std::distance(begin, end) >= 1,
+ ExcMessage("The provided iterator range must contain at least one "
+ "element."));
+ *begin = value;
}
Tensor<rank_, dim, Number>::unroll(const Iterator begin,
const Iterator end) const
{
- AssertDimension(std::distance(begin, end), n_independent_components);
- unroll_recursion(begin, end);
+ if constexpr (rank_ > 1)
+ {
+ // For higher-rank tensors, we recurse to the sub-tensors:
+ Iterator next = begin;
+ for (unsigned int i = 0; i < dim; ++i)
+ {
+ values[i].unroll(next, end);
+ std::advance(
+ next, Tensor<rank_ - 1, dim, Number>::n_independent_components);
+ }
+ }
+ else
+ {
+ // For rank-1 tensors, we can simply copy the current elements from
+ // our linear array into the output range, and then return the
+ // iterator moved forward by 'dim' elements:
+ Assert(std::distance(begin, end) >= dim,
+ ExcMessage(
+ "The provided iterator range must contain at least 'dim' "
+ "elements."));
+ std::copy(&values[0], &values[dim], begin);
+ }
}
-template <int rank_, int dim, typename Number>
-template <typename Iterator>
-Iterator
-Tensor<rank_, dim, Number>::unroll_recursion(const Iterator current,
- const Iterator end) const
-{
- Iterator next = current;
- for (unsigned int i = 0; i < dim; ++i)
- next = values[i].unroll_recursion(next, end);
- return next;
-}
-
-
template <int rank_, int dim, typename Number>
constexpr inline unsigned int
Tensor<rank_, dim, Number>::component_to_unrolled_index(