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

add test for switchCases

parent 662a6b31
Branches
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.
Please register or to comment