Thread overview | ||||||
---|---|---|---|---|---|---|
|
December 31, 2017 static if and early exit from function doesn't seem to work? | ||||
---|---|---|---|---|
| ||||
Alo! I'm making a recursive concat function that is similar to chain. The following code works: import std.range: isInputRange; auto concat(R, V...)(R range, V values) if (isInputRange!R) { import std.range: chain, ElementType; static if (V.length) { static if (isInputRange!(V[0])) { return range.chain(values[0]).concat(values[1..$]); } else static if (is(V[0] == ElementType!R)) { return range.chain([values[0]]).concat(values[1..$]); } // add an else assert here. } else { return range; } } But the following does not: auto concat(R, V...)(R range, V values) if (isInputRange!R) { import std.range: chain, ElementType; static if (!V.length) { return range; } static if (isInputRange!(V[0])) { return range.chain(values[0]).concat(values[1..$]); } static if (is(V[0] == ElementType!R)) { return range.chain([values[0]]).concat(values[1..$]); } } You get a: Error: tuple index 0 exceeds 0 Error: template instance range.concat.concat!(Result) error instantiating So it seems it tries to compile the statements below the check on V.length even though it's guaranteed to be true and there's a return statement inside the if. Is it a current limitation of static if? or a bug? or is something like this just not possible because of something I'm not seeing? Cheers |
December 31, 2017 Re: static if and early exit from function doesn't seem to work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Sunday, 31 December 2017 at 13:32:03 UTC, aliak wrote:
> Alo! I'm making a recursive concat function that is similar to chain. The following code works:
>
> [...]
I suspect it's because you've no 'else static if'.
|
December 31, 2017 Re: static if and early exit from function doesn't seem to work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | On Sunday, 31 December 2017 at 13:32:03 UTC, aliak wrote: > So it seems it tries to compile the statements below the check on V.length even though it's guaranteed to be true and there's a return statement inside the if. Yeah, static if includes or excludes code independently at compile time. So what you wrote there would be like, assuming the first to static ifs pass: auto concat(R, V...)(R range, V values) if (isInputRange!R) { import std.range: chain, ElementType; return range; return range.chain(values[0]).concat(values[1..$]); } The code is still there, even if it isn't reached due to an early return, and thus still must compile. Using else static if means it won't be generated. |
January 01, 2018 Re: static if and early exit from function doesn't seem to work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Sunday, 31 December 2017 at 13:47:32 UTC, Adam D. Ruppe wrote:
> On Sunday, 31 December 2017 at 13:32:03 UTC, aliak wrote:
>> So it seems it tries to compile the statements below the check on V.length even though it's guaranteed to be true and there's a return statement inside the if.
>
> Yeah, static if includes or excludes code independently at compile time.
>
> So what you wrote there would be like, assuming the first to static ifs pass:
>
> auto concat(R, V...)(R range, V values) if (isInputRange!R) {
> import std.range: chain, ElementType;
> return range;
> return range.chain(values[0]).concat(values[1..$]);
> }
>
>
> The code is still there, even if it isn't reached due to an early return, and thus still must compile.
>
> Using else static if means it won't be generated.
Ah ok, thanks! So it is intended behavior. I wonder if treating a return like a static else would be a good idea though. I at least can't see how it would break anything at this time.
|
Copyright © 1999-2021 by the D Language Foundation