Is there a hack to support range case in a c(99?) or objective C switch statement ?
I know this is not supported to write something like this:
switch(x)
case 1:
case 2..10:
case 11:
But I was thinking there should be a way to generate code with a #define macro. Of course
I can define a macro with the list of cases but I was hoping for a more elegant way like
CASERANGE(x,x+10) which would generate:
case x
case x+1
case x+2
is it even possible ?
GCC has an extension to the C language that allows something similar to your first example, but other than that, if there was a portable/ANSI way of doing it, it would have been done by now. I don't believe there is one.
Doing this with macros is near to or impossible. Compiler extensions exist, but they are compiler specific and not cross-platform/standard. There is no standard way to do this, use if/else chains instead.
In modern C (C99, with variable length macros), doing this with macros is possible. But you probably wouldn't want to code this completely yourself. P99 provides a toolbox for this. In particular there is a meta-macro P99_FOR
that allows you to do unrolling of finite length argument lists.
#define P00_CASE_FL(NAME, X, I) case I: NAME(X); break
#define CASES_FL(NAME, ...) P99_FOR(NAME, P99_NARG(__VA_ARGS__), P00_SEQ, P00_CASE_FL, __VA_ARGS__)
would expand CASES_FL(myFunc, oi, ui, ei)
to something like
case 0: myFunc(oi); break; case 1: myFunc(ui); break; case 2: myFunc(ei); break
Edit: to reply to the concrete question
#define P00_CASESEP(NAME, I, X, Y) X:; Y
#define P00_CASERANGE(NAME, X, I) case ((NAME)+I)
#define P99_CASERANGE(START, LEN) P99_FOR(START, LEN, P00_CASESEP, P00_CASERANGE, P99_REP(LEN,))
where P00_CASESEP
just ensures that there are the :;
between the cases, and P99_REP
generates a list with LEN
empty arguments.
You'd use that e.g as
switch(i) {
P99_CASERANGE('0',10): return i;
}
Observe the :
after the macro to keep it as close as possible to the usual case syntax, and also that the LEN
parameter has to expand to a plain decimal number, not an expression or so.