I am newbie to variadic templates, still I managed to program some code in c++11 using it, but I still feel sour about result because it lacks expressivity.
The issue is to implement a function that accept several bool
conditions (from 1
to whatever) and returns an integer code indicating in what place is the first "false
" argument, or 0
if all of them are true
.
e.g. "error_code(true, true, true);" must return 0
e.g. "error_code(true, true, false);" must return 3
e.g. "error_code(true, false, false);" must return 2
e.g. "error_code(false, false, false);" must return 1
My current code stands for (live link to coliru: http://coliru.stacked-crooked.com/a/1b557f2819ae9775):
#include <tuple>
#include <iostream>
int error_impl(bool cond)
{
return cond;
}
template<typename... Args>
int error_impl(bool cond, Args... args)
{
return cond ? 1 + error_impl(args...) : 0;
}
template<typename... Args>
int error_code(Args... args)
{
constexpr std::size_t size = std::tuple_size<std::tuple<Args...>>::value + 1;
return (error_impl(args...) + 1) % size;
}
int main()
{
auto e1 = error_code(true, true, true);
auto e2 = error_code(true, true, false);
auto e3 = error_code(true, false, false);
auto e4 = error_code(false, false, false);
std::cout << std::boolalpha;
std::cout << "(true, true, true)==0 -> " << (e1 == 0) << "\n";
std::cout << "(true, true, false)==3 -> " << (e2 == 3) << "\n";
std::cout << "(true, false, false)==2 -> " << (e3 == 2)<< "\n";
std::cout << "(false, false, false)==1 -> " << (e4 == 1)<< "\n";
auto e5 = error_code(true, true, true, true);
auto e6 = error_code(true, true, true, false);
auto e7 = error_code(true, true, false, false);
auto e8 = error_code(true, false, false, false);
auto e9 = error_code(false, false, false, false);
std::cout << "(true, true, true, true)==0 -> " << (e5 == 0) << "\n";
std::cout << "(true, true, true, false)==4 -> " << (e6 == 4) << "\n";
std::cout << "(true, true, false, false)==3 -> " << (e7 == 3) << "\n";
std::cout << "(true, false, false, false)==2 -> " << (e8 == 2)<< "\n";
std::cout << "(false, false, false, false)==1 -> " << (e9 == 1)<< "\n";
}
I wonder where this "error_code()
" function can be improved using new unroll features from c++14 / c++17, so it gains in expressivity and uses less than 3 functions.
Any help will be grateful welcomed!