Skip to content

Reimplement the switchCases() hybrid implementation using array lookup

Summary

Reimplement the function Hybrid::switchCases(Range r,Index i,Function f) that calls the function f with an integral-constant that has the same value as the (possibly) runtime index i if the range is a static-range and with a runtime index if it is a dynamic-range.

Details

Instead of tail-recursion as in the old implementation it is implemented as kind-of an automatically generated lookup-table and thus does not need a recursion-break condition.

It is also hybrid in two senses:

  1. if the range is static, call the function with an integral constant, otherwise with a runtime index
  2. if the index is a runtime index, perform a lookup to call the function with the corresponding integral constant, otherwise if it is already an integral constant, pass it directly to the function.

Examples

Zero-based vectors that can be indexed by integral constants only:

auto t = Dune::makeTupleVector(std::string("1"), 2, 3.0f);
Hybrid::switchCases<decltype(t)::size()>(1, [&t](auto ii) { t[ii] = 20; });

Using different ranges with different access:

auto t = Dune::makeTupleVector(std::string("1"), 2, 3.0f);
auto v = std::vector<double>{1.0, 2.0, 3.0};
// StaticIntegralRange
Hybrid::switchCases(range(Hybrid::size(t)), 1, [&t](auto ii) { t[ii] = 20; });
// IntegralRange
Hybrid::switchCases(range(Hybrid::size(v)), 1, [&v](auto ii) { t[ii] = 20.0; });

Accessing a tuple by lookup or by direct index access:

auto t = Dune::makeTupleVector(std::string("1"), 2, 3.0f);
auto index_seq = std::make_index_sequence<decltype(t)::size()>{};
// search for index 1 in index sequence
Hybrid::switchCases(index_seq, 1, [&t](auto ii) { t[ii] = 20; });
// call function directly
Hybrid::switchCases(index_seq, index_constant<1>{}, [&t](auto ii) { t[ii] = 20; });

Notes

Since all the code in the dune core/staging modules that use Hybrid::switchCases essentially are restricted to simple index lookup, all can be replaced by the new implementation. The advantage is that we do not need to provide a fallback implementation in case the index is out of range. This is necessary for the old switchCases implementation in case a value should be returned.

Edited by Simon Praetorius

Merge request reports