Thread overview
Type constraint
Oct 03
Joel
Oct 03
ryuukk_
Oct 03
Joel
Oct 04
Joel
Oct 08
IchorDev
October 03

I’ve got a struct that has a method that adds numbers together. I want to do something like this, static if (isInteger!T) … but it isn’t working. static if (is(T==int)) works for one integer type.

struct List(T) {
     auto addUp()
         If (isInteger!T) {
             (Add numbers)
         }
    }
}
October 03

On Tuesday, 3 October 2023 at 11:43:46 UTC, Joel wrote:

>

I’ve got a struct that has a method that adds numbers together. I want to do something like this, static if (isInteger!T) … but it isn’t working. static if (is(T==int)) works for one integer type.

struct List(T) {
     auto addUp()
         If (isInteger!T) {
             (Add numbers)
         }
    }
}
static if (__traits(isIntegral, T))
{
}
else static assert(0, "type no supported");

https://dlang.org/spec/traits.html#isIntegral

October 03

On Tuesday, 3 October 2023 at 14:06:37 UTC, ryuukk_ wrote:

>

On Tuesday, 3 October 2023 at 11:43:46 UTC, Joel wrote:

>

I’ve got a struct that has a method that adds numbers together. I want to do something like this, static if (isInteger!T) … but it isn’t working. static if (is(T==int)) works for one integer type.

struct List(T) {
     auto addUp()
         If (isInteger!T) {
             (Add numbers)
         }
    }
}
static if (__traits(isIntegral, T))
{
}
else static assert(0, "type no supported");

https://dlang.org/spec/traits.html#isIntegral

Oh, I found,

static if (isIntegral!T)

seems to work.

October 03
On Tuesday, October 3, 2023 8:35:31 AM MDT Joel via Digitalmars-d-learn wrote:
> Oh, I found,
> ```d
> static if (isIntegral!T)
> ```
> seems to work.

Yeah. static if will compile in the code in that branch based on whether the condition is true, whereas if without the static will branch at runtime, with both branches being compiled in. So, if you want to be changing what code is being compiled in, you need static if, not if.

if(isIntegral!T)

will compile just fine, but it'll just end up being either

if(true)

or

if(false)

and the code within that branch will be compiled in regardless (and potentially result in compiler errors if it doesn't work with the type that that the template is being instantiated with). So, you usually want to use static if with compile-time tests and not if.

- Jonathan M Davis



October 04
On Tuesday, 3 October 2023 at 17:42:51 UTC, Jonathan M Davis wrote:
> On Tuesday, October 3, 2023 8:35:31 AM MDT Joel via Digitalmars-d-learn wrote:
>> [...]
>
> Yeah. static if will compile in the code in that branch based on whether the condition is true, whereas if without the static will branch at runtime, with both branches being compiled in. So, if you want to be changing what code is being compiled in, you need static if, not if.
>
> if(isIntegral!T)
>
> will compile just fine, but it'll just end up being either
>
> if(true)
>
> or
>
> if(false)
>
> and the code within that branch will be compiled in regardless (and potentially result in compiler errors if it doesn't work with the type that that the template is being instantiated with). So, you usually want to use static if with compile-time tests and not if.
>
> - Jonathan M Davis

I think the if without static is still static, since it's part of the function name part, or so (outside of the curly bracket scope).
October 03
On Tuesday, October 3, 2023 7:46:42 PM MDT Joel via Digitalmars-d-learn wrote:
> I think the if without static is still static, since it's part of the function name part, or so (outside of the curly bracket scope).

if on a template (or on a templated function) is a template constraint, in which case, that's a compile-time if like static if, because it's used to indicate whether that particular template can be instantiated with a particular set of arguments. But elsewhere, an if without static is a runtime construct, and you need static on it to make it a compile-time one.

https://dlang.org/spec/template.html#template_constraints https://dlang.org/spec/version.html#staticif https://dlang.org/spec/statement.html#if-statement

http://ddili.org/ders/d.en/templates.html http://ddili.org/ders/d.en/cond_comp.html http://ddili.org/ders/d.en/if.html

- Jonathan M Davis



October 08

On Wednesday, 4 October 2023 at 01:46:42 UTC, Joel wrote:

>

I think the if without static is still static, since it's part of the function name part, or so (outside of the curly bracket scope).

You can't have regular if-statements inside templates. Regular if-statements are checked at runtime but templates only exist at compile-time.

The way to write a template constraint—which is what you want, and uses the if keyword—is thus:

struct List(T)
if(__traits(isIntegral, T)){
  auto addUp()
    //(Add numbers)
  }
}

Notice that the curly brace for the template comes after the template constraint, and that there are only 2 curly braces rather than the 3 from your example.

If the statement in the template constraint (__traits(isIntegral, T)) evaluates false at compile-time, then you will get a compiler error saying that the instantiation doesn't match the template constraints.

October 09

On Sunday, 8 October 2023 at 10:09:02 UTC, IchorDev wrote:

>

On Wednesday, 4 October 2023 at 01:46:42 UTC, Joel wrote:

>

I think the if without static is still static, since it's part of the function name part, or so (outside of the curly bracket scope).

You can't have regular if-statements inside templates. Regular if-statements are checked at runtime but templates only exist at compile-time.

The way to write a template constraint—which is what you want, and uses the if keyword—is thus:

struct List(T)
if(__traits(isIntegral, T)){
  auto addUp()
    //(Add numbers)
  }
}

Notice that the curly brace for the template comes after the template constraint, and that there are only 2 curly braces rather than the 3 from your example.

This snippet does not compile. The curly brackets must be an even number, that is, they must terminate each other.

SDB@79

October 09

On Tuesday, 3 October 2023 at 14:35:31 UTC, Joel wrote:

>

Oh, I found,

static if (isIntegral!T)

seems to work.

If you are using a struct, another way to affect the whole is as follows:

struct S(T)
{

  invariant() {
      static assert(isIntegral!T);
  }

  auto addUp() { /**/ }
}

For detailed information and examples, please continue here:

https://tour.dlang.org/tour/en/gems/contract-programming

SDB@79