#pragma once #include #include #include #include #include namespace AMDiS { /** * \brief A simple node to range map using the nested tree indices * * This map directly uses the tree path entries of the given * node to access the nested container. * * If the container does not provide any operator[] access, * it is simply forwarded for all nodes. */ struct HierarchicNodeToRangeMap { // Specialization for ranges with operator[] access template >)> decltype(auto) operator()(const Node& node, const TreePath& treePath, Range&& y) const { return Dune::Functions::resolveStaticMultiIndex(y, transformTreePath(treePath)); } // Specialization for non-container ranges template >)> decltype(auto) operator()(const Node& node, const TreePath& treePath, Range&& y) const { return std::forward(y); } private: #if DUNE_VERSION_GT(DUNE_FUNCTIONS,2,6) template static TreePath const& transformTreePath(TreePath const& treePath) { return treePath; } #else // NOTE: due to a bug in dune-functions <= 2.6, a hybrid-treepath can not be passed to a HierarchicNodeToRangeMap, // i.e. the HybridTreePath missed a size() function template static auto transformTreePath(TreePath const& treePath) { return Ranges::apply([](auto... i) { return Dune::makeTupleVector(i...); }, treePath._data); } #endif }; } // end namespace AMDiS