Thread overview |
---|
October 24, 2015 No shortcircuit for static if or template constraints? | ||||
---|---|---|---|---|
| ||||
Hi All, Given this code: --- import std.traits; import std.range; import std.stdio; enum isSupportedRange(T) = (isInputRange!T && isIntegral!(ForeachType!T)); void func(T)(T vals) { static if(isSupportedRange!T) { // Do something with a range } else { // Do something with a scalar } } void main() { int a1 = 0; int[] a2 = [1,2,3]; func(a1); func(a2); } --- I a compile error like so: ...std/traits.d(6136): Error: invalid foreach aggregate 0 hack.d(6): Error: template instance std.traits.ForeachType!int error instantiating hack.d(10): instantiated from here: isSupportedRange!int hack.d(22): instantiated from here: func!int However, if I remove the Foreach part the "isInputRange!T" clearly fails. I also tried overloading the function like so: --- enum isSupportedRange(T) = (isInputRange!T && isIntegral!(ForeachType!T)); void func(T)(T vals) if(isSupportedRange!T) { // Do something with a range } void func(T)(T vals) if(isNumeric!T) { // Do something with a scalar } --- Again, if I remove the Foreach part and ignore element type of the range it works OK. Am I doing something wrong? Thanks, stew |
October 24, 2015 Re: No shortcircuit for static if or template constraints? | ||||
---|---|---|---|---|
| ||||
Posted in reply to stewart | On Saturday, 24 October 2015 at 23:26:09 UTC, stewart wrote:
> Hi All,
>
> Given this code:
>
> ---
> import std.traits;
> import std.range;
> import std.stdio;
>
> enum isSupportedRange(T) = (isInputRange!T && isIntegral!(ForeachType!T));
>
> void func(T)(T vals)
> {
> static if(isSupportedRange!T) {
> // Do something with a range
> } else {
> // Do something with a scalar
> }
> }
>
> void main() {
> int a1 = 0;
> int[] a2 = [1,2,3];
>
> func(a1);
> func(a2);
> }
> ---
>
> I a compile error like so:
>
> ...std/traits.d(6136): Error: invalid foreach aggregate 0
> hack.d(6): Error: template instance std.traits.ForeachType!int error instantiating
> hack.d(10): instantiated from here: isSupportedRange!int
> hack.d(22): instantiated from here: func!int
>
> However, if I remove the Foreach part the "isInputRange!T" clearly fails.
>
> I also tried overloading the function like so:
>
> ---
> enum isSupportedRange(T) = (isInputRange!T && isIntegral!(ForeachType!T));
>
> void func(T)(T vals) if(isSupportedRange!T) {
> // Do something with a range
> }
> void func(T)(T vals) if(isNumeric!T) {
> // Do something with a scalar
> }
> ---
>
> Again, if I remove the Foreach part and ignore element type of the range it works OK.
>
> Am I doing something wrong?
>
> Thanks,
> stew
Oh and the workaround I'm using is this:
---
void func(T)(T vals) {
static if(isInputRange!T) {
static if(isIntegral!(ForeachType!T)) {
// Do something with range
}
} else {
// do something with scalar
}
}
---
which is a bit ugly.
|
October 24, 2015 Re: No shortcircuit for static if or template constraints? | ||||
---|---|---|---|---|
| ||||
Posted in reply to stewart | On Saturday, 24 October 2015 at 23:34:19 UTC, stewart wrote:
> On Saturday, 24 October 2015 at 23:26:09 UTC, stewart wrote:
>> [...]
>
>
> Oh and the workaround I'm using is this:
>
> ---
> void func(T)(T vals) {
> static if(isInputRange!T) {
> static if(isIntegral!(ForeachType!T)) {
> // Do something with range
> }
> } else {
> // do something with scalar
> }
> }
> ---
>
> which is a bit ugly.
Maybe this could work:
---
enum isSupportedRange(T) = isInputRange!T && is(ForeachType!T) && (isIntegral!(ElementType!T));
---
ElementType() should return exactly what you excpeted with ForeachType().
|
October 25, 2015 Re: No shortcircuit for static if or template constraints? | ||||
---|---|---|---|---|
| ||||
Posted in reply to qsdfghjk | On Saturday, 24 October 2015 at 23:59:02 UTC, qsdfghjk wrote:
> On Saturday, 24 October 2015 at 23:34:19 UTC, stewart wrote:
>> On Saturday, 24 October 2015 at 23:26:09 UTC, stewart wrote:
>>> [...]
>>
>>
>> Oh and the workaround I'm using is this:
>>
>> ---
>> void func(T)(T vals) {
>> static if(isInputRange!T) {
>> static if(isIntegral!(ForeachType!T)) {
>> // Do something with range
>> }
>> } else {
>> // do something with scalar
>> }
>> }
>> ---
>>
>> which is a bit ugly.
>
> Maybe this could work:
>
> ---
> enum isSupportedRange(T) = isInputRange!T && is(ForeachType!T) && (isIntegral!(ElementType!T));
> ---
>
> ElementType() should return exactly what you excpeted with ForeachType().
Oh no! there's been a copy & paste error. I actually meant:
---
enum isSupportedRange(T) = isInputRange!T && (isIntegral!(ElementType!T));
|
October 25, 2015 Re: No shortcircuit for static if or template constraints? | ||||
---|---|---|---|---|
| ||||
Posted in reply to qsdfghjk | On Saturday, 24 October 2015 at 23:59:02 UTC, qsdfghjk wrote:
> On Saturday, 24 October 2015 at 23:34:19 UTC, stewart wrote:
>> On Saturday, 24 October 2015 at 23:26:09 UTC, stewart wrote:
>>> [...]
>>
>>
>> Oh and the workaround I'm using is this:
>>
>> ---
>> void func(T)(T vals) {
>> static if(isInputRange!T) {
>> static if(isIntegral!(ForeachType!T)) {
>> // Do something with range
>> }
>> } else {
>> // do something with scalar
>> }
>> }
>> ---
>>
>> which is a bit ugly.
>
> Maybe this could work:
>
> ---
> enum isSupportedRange(T) = isInputRange!T && is(ForeachType!T) && (isIntegral!(ElementType!T));
> ---
>
> ElementType() should return exactly what you excpeted with ForeachType().
Yep, that works, thanks!
I also found I can do it with __traits, but I think your way is cleaner.
enum bool isSupportedRange(T) = __traits(compiles, isInputRange!T && isIntegral!(ForeachType!T));
cheers,
stew
|
Copyright © 1999-2021 by the D Language Foundation