Skip to content
Snippets Groups Projects
Commit 11a18eb6 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

add test for switchCases

parent 662a6b31
No related branches found
No related tags found
1 merge request!51add hybrid utility SwitchCases for dynamic and static dispatching
......@@ -7,6 +7,7 @@
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)
......@@ -15,6 +16,7 @@ namespace AMDiS
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)
......@@ -25,6 +27,55 @@ namespace AMDiS
return elseBranch(value);
}
// specialization for the case value in {0}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,1,0>& cases, const Value& value,
Then&& thenBranch, Else&& elseBranch)
{
return std::size_t(value) == std::size_t(0) ? thenBranch(index_t<0>{}) : elseBranch();
}
// specialization for the case value in {0,1}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,2,0>& cases, const Value& value,
Then&& thenBranch, Else&& elseBranch)
{
switch (std::size_t(value)) {
case 0u: return thenBranch(index_t<0>{});
case 1u: return thenBranch(index_t<1>{});
default: return elseBranch();
}
}
// specialization for the case value in {0,1,2}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,3,0>& cases, const Value& value,
Then&& thenBranch, Else&& elseBranch)
{
switch (std::size_t(value)) {
case 0u: return thenBranch(index_t<0>{});
case 1u: return thenBranch(index_t<1>{});
case 2u: return thenBranch(index_t<2>{});
default: return elseBranch();
}
}
// specialization for the case value in {0,1,2,3}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,4,0>& cases, const Value& value,
Then&& thenBranch, Else&& elseBranch)
{
switch (std::size_t(value)) {
case 0u: return thenBranch(index_t<0>{});
case 1u: return thenBranch(index_t<1>{});
case 2u: return thenBranch(index_t<2>{});
case 3u: return thenBranch(index_t<3>{});
default: return elseBranch();
}
}
// 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)
{
......@@ -32,6 +83,7 @@ namespace AMDiS
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)
{
......@@ -39,4 +91,48 @@ namespace AMDiS
thenBranch(value);
}
// specialization for the case value in {0}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,1,0>& cases, const Value& value, Then&& thenBranch)
{
assert(std::size_t(value) < 1u);
return thenBranch(index_t<0>{});
}
// specialization for the case value in {0,1}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,2,0>& cases, const Value& value, Then&& thenBranch)
{
assert(std::size_t(value) < 2u);
switch (std::size_t(value)) {
case 0u: return thenBranch(index_t<0>{});
default: return thenBranch(index_t<1>{});
}
}
// specialization for the case value in {0,1,2}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,3,0>& cases, const Value& value, Then&& thenBranch)
{
assert(std::size_t(value) < 3u);
switch (std::size_t(value)) {
case 0u: return thenBranch(index_t<0>{});
case 1u: return thenBranch(index_t<1>{});
default: return thenBranch(index_t<2>{});
}
}
// specialization for the case value in {0,1,2,3}
template <class Value, class Then, class Else>
constexpr decltype(auto) switchCases(const Dune::StaticIntegralRange<std::size_t,4,0>& cases, const Value& value, Then&& thenBranch)
{
assert(std::size_t(value) < 3u);
switch (std::size_t(value)) {
case 0u: return thenBranch(index_t<0>{});
case 1u: return thenBranch(index_t<1>{});
case 2u: return thenBranch(index_t<2>{});
default: return thenBranch(index_t<3>{});
}
}
} // end namespace AMDiS
......@@ -64,6 +64,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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment