Commit 24e19192 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'feature/switch_cases' into 'master'

add hybrid utility SwitchCases for dynamic and static dispatching

See merge request amdis/amdis-core!51
parents b1153129 2222b5c8
......@@ -26,6 +26,7 @@ install(FILES
Resize.hpp
StaticSize.hpp
String.hpp
SwitchCases.hpp
Tags.hpp
Transposed.hpp
TupleUtility.hpp
......
#pragma once
#include <cassert>
#include <dune/common/hybridutilities.hh>
#include <dune/common/rangeutilities.hh>
namespace AMDiS
{
// static switching. Iterates over all possible values
template <class T, T to, T from, class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<T,to,from>& cases, const Value& value,
Then&& thenBranch, Else&& elseBranch)
{
using integer_sequence = typename Dune::StaticIntegralRange<T,to,from>::integer_sequence;
return Dune::Hybrid::switchCases(integer_sequence{}, value, FWD(thenBranch), FWD(elseBranch));
}
// dynamic switching. Calls the `thenBranch` or `elseBranch` directly
template <class T, class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::IntegralRange<T>& cases, const Value& value,
Then&& thenBranch, Else&& elseBranch)
{
if (value >= cases[0] && value <= cases[cases.size()-1])
return thenBranch(value);
else
return elseBranch(value);
}
// static switching. Iterates over all possible values
template<class T, T to, T from, class Value, class Then>
constexpr void switchCases(const Dune::StaticIntegralRange<T,to,from>& cases, const Value& value, Then&& thenBranch)
{
using integer_sequence = typename Dune::StaticIntegralRange<T,to,from>::integer_sequence;
Dune::Hybrid::switchCases(integer_sequence{}, value, FWD(thenBranch));
}
// dynamic switching. Calls the `thenBranch` directly
template<class T, class Value, class Then>
constexpr void switchCases(const Dune::IntegralRange<T>& cases, const Value& value, Then&& thenBranch)
{
assert(value >= cases[0] && value <= cases[cases.size()-1]);
thenBranch(value);
}
} // end namespace AMDiS
......@@ -67,6 +67,9 @@ dune_add_test(SOURCES RangeTypeTest.cpp
dune_add_test(SOURCES ResizeTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES SwitchCasesTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES StringTest.cpp
LINK_LIBRARIES amdis)
......
#include <amdis/AMDiS.hpp>
#include <amdis/common/SwitchCases.hpp>
using namespace AMDiS;
template <std::size_t i>
struct Foo
{
void foo() {}
};
struct Bar
{
void bar(std::size_t i) {}
};
template <std::size_t max_i>
void call_foo(std::size_t i)
{
switchCases(Dune::range(index_t<max_i>{}), i, [](auto _i) { Foo<_i.value>{}.foo(); });
}
void call_bar(std::size_t i, std::size_t max_i)
{
switchCases(Dune::range(max_i), i, [](auto _i) { Bar{}.bar(_i); });
}
int main(int argc, char** argv)
{
call_foo<1>(0);
call_foo<2>(1);
call_foo<3>(2);
call_foo<10>(7);
call_bar(0, 1);
call_bar(1, 2);
call_bar(2, 3);
call_bar(7, 10);
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment