From 3ba7519feebd8982f8e1d1506a80540d38a2b164 Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Fri, 11 Sep 2015 14:43:46 -0500 Subject: [PATCH] Implement TensorAccessors::extract --- include/deal.II/base/tensor_accessors.h | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/include/deal.II/base/tensor_accessors.h b/include/deal.II/base/tensor_accessors.h index 9d4e405a7f..80cd779e2d 100644 --- a/include/deal.II/base/tensor_accessors.h +++ b/include/deal.II/base/tensor_accessors.h @@ -72,6 +72,7 @@ namespace TensorAccessors namespace internal { template class ReorderedIndexView; + template struct ExtractHelper; } @@ -198,6 +199,34 @@ namespace TensorAccessors } + /** + * Return a reference (const or non-const) to a subobject of a tensorial + * object @p t of type @p T, as described by an array type @p ArrayType + * object @p indices. For example: @code + * Tensor<5, dim> tensor; + * TableIndices<5> indices (0, 1, 2, 3, 4); + * TensorAccessors::extract(tensor, indices) = 42; + * @endcode + * This is equivalent to tensor[0][1][2][3][4] = 42.. + * + * @tparam T A tensorial object of rank @p rank. @p T must provide a + * local typedef value_type and an index operator + * operator[]() that returns a (const or non-const) + * reference of value_type. Further, its tensorial rank must + * be equal or greater than @p rank + * + * @tparam ArrayType An array like object, such as std::array, or + * dealii::TableIndices that stores at least @p rank indices that can be + * accessed via operator[](). + */ + template typename + ReturnType::value_type & + extract(T &t, const ArrayType &indices) + { + return internal::ExtractHelper<0, rank>::template extract(t, indices); + } + + namespace internal { // ------------------------------------------------------------------------- @@ -412,6 +441,41 @@ namespace TensorAccessors const int i_; }; + + // ------------------------------------------------------------------------- + // Implemenation of helper classes for extract + // ------------------------------------------------------------------------- + + // Straightforward recursion implemented by specializing ExtractHelper + // for position == rank. We use the type trait ReturnType to + // have an idea what the final type will be. + template + struct ExtractHelper + { + template + inline static + typename ReturnType::value_type & + extract(T &t, const ArrayType &indices) + { + return ExtractHelper:: + template extract::value_type, ArrayType> + (t[indices[position]], indices); + } + }; + + // For dimension == rank there is nothing to extract, just return the + // object. + template + struct ExtractHelper + { + template + inline static + T &extract(T &t, const ArrayType &indices) + { + return t; + } + }; + // ------------------------------------------------------------------------- } /* namespace internal */ -- 2.39.5