(I'm using catch
for unit testing, which unfortunately doesn't yet have what it's calling generators to do this sort of thing.)
In c++17
, is there a way to reduce this:
assert("" == String{"" }.removeLeading(' '));
assert("a" == String{" a").removeLeading(' '));
assert("a" == String("a" }.removeLeading(' '));
assert("a" == String{"a "}.removeLeading(' '));
With a macro, template, or function like this:
#define MACRO(className, method, arg, ...) \
for(auto [x, y] : { __VA_ARGS }) { \
assert(x == className{y}.method(arg)); \
}
So it's shorter like this:
MACRO(String, removeLeading, ' ',
{ "", "" }, {"a", " a"}, {"a", "a"}, {"a", "a "})
// or
MACRO(String, removeLeading, ' ',
"", "", "a", " a", "a", "a", "a", "a ")
Assuming that all ...
arguments "auto
" to the same type.
Basically with no limit on the number of ...
args. (Maybe could go up to 100?)
Using the first MACRO()
gives: unable to deduce 'std::initializer_list<auto>&&' from...
(it also doesn't understand the semantics so strictly breaks apart on ,
tokens, but as long as it's put together correctly, doesn't matter.)
Using the second MACRO()
gives: cannot decompose non-array non-class type 'const char*'
Trying templates:
template<typename T>
void TEMP(T a, T b) {
assert(a == String{ b }.removeLeading(' '));
}
template<typename T, typename... Args>
void TEMP(T a, T b, Args... args) {
TEMP(a, b);
TEMP(args...);
}
TEMP("", "", "a", " ", "a", "a", "a", "a ");
This at least works, but I don't want className
, method
, and arg
to be hardcoded as "String"
, "removeLeading"
, and " "
.
I wonder if there's a way to pull this off with all the new type trait / "meta" templates (not sure what else to call them) that I haven't done much with. (I look at some of the libraries available in the last year or two, and they almost look like a different language to me...)
{{"", ""}, {"a", " a"}, ...}`?
– Barry Oct 25 '17 at 21:34