Jump to page: 1 2
Thread overview
Is there a way to make a function parameter accept only values that can be checked at compile time?
Dec 28, 2021
rempas
Dec 28, 2021
Tobias Pankrath
Dec 28, 2021
Ali Çehreli
Dec 29, 2021
Stanislav Blinov
Dec 29, 2021
rempas
Dec 29, 2021
rempas
Dec 29, 2021
rempas
Dec 28, 2021
max haughton
Dec 29, 2021
rempas
Dec 29, 2021
max haughton
Dec 29, 2021
rempas
Dec 29, 2021
max haughton
Dec 29, 2021
rempas
Dec 29, 2021
max haughton
Dec 29, 2021
rempas
December 28, 2021

I would like to know if that's possible. Actually I would like to do something like the following:

extern (C) void main() {
  void print_num(int num, comp_time_type int mul) {
    static if (is(mul == ten)) {
      printf("%d\n", num * 10);
    } else static if (is(mul == three)) {
      printf("%d\n", num * 3);
    } else {
      printf("%d\n", num);
    }
  }

  int multi = 211;
  print_num(10, 3);     // Ok, accept this
  print_num(10, multi); // Error, do not accept this
}

So I want to have "mul" only accept values that can be calculate at compile time so I can use it with things like "static if". Is this possible?

December 28, 2021

On Tuesday, 28 December 2021 at 21:19:29 UTC, rempas wrote:

>

I would like to know if that's possible. Actually I would like to do something like the following:

extern (C) void main() {
  void print_num(int num, comp_time_type int mul) {
    static if (is(mul == ten)) {
      printf("%d\n", num * 10);
    } else static if (is(mul == three)) {
      printf("%d\n", num * 3);
    } else {
      printf("%d\n", num);
    }
  }

  int multi = 211;
  print_num(10, 3);     // Ok, accept this
  print_num(10, multi); // Error, do not accept this
}

So I want to have "mul" only accept values that can be calculate at compile time so I can use it with things like "static if". Is this possible?

I think you have to make 'mul' a template parameter.

December 28, 2021

On 12/28/21 4:19 PM, rempas wrote:

Here:

>
extern (C) void main() {
   void print_num(int mul)(int num) {
     static if (is(mul == ten)) {
       printf("%d\n", num * 10);
     } else static if (is(mul == three)) {
       printf("%d\n", num * 3);
     } else {
       printf("%d\n", num);
     }
   }

   int multi = 211;
   print_num!3(10);     // Ok, accept this
   print_num!multi(10); // Error, do not accept this
}

-Steve

December 28, 2021

On Tuesday, 28 December 2021 at 21:19:29 UTC, rempas wrote:

>

I would like to know if that's possible. Actually I would like to do something like the following:

extern (C) void main() {
  void print_num(int num, comp_time_type int mul) {
    static if (is(mul == ten)) {
      printf("%d\n", num * 10);
    } else static if (is(mul == three)) {
      printf("%d\n", num * 3);
    } else {
      printf("%d\n", num);
    }
  }

  int multi = 211;
  print_num(10, 3);     // Ok, accept this
  print_num(10, multi); // Error, do not accept this
}

So I want to have "mul" only accept values that can be calculate at compile time so I can use it with things like "static if". Is this possible?

Why do you need this? What's wrong with a normal branch in this case.

December 28, 2021
On 12/28/21 2:06 PM, Steven Schveighoffer wrote:

>>    void print_num(int mul)(int num) {

Wasn't there a way of telling whether an 'auto ref' parameter is copied or not?

void print_num()(int num, auto ref int mul) {
  // ?
}

And that would indicate  that the argument was an rvalue?

I realize that rvalues are not exactly what the OP is interested in.

Ali

December 29, 2021
On Tuesday, 28 December 2021 at 22:30:30 UTC, Ali Çehreli wrote:
> On 12/28/21 2:06 PM, Steven Schveighoffer wrote:
>
>>>    void print_num(int mul)(int num) {
>
> Wasn't there a way of telling whether an 'auto ref' parameter is copied or not?
>
> void print_num()(int num, auto ref int mul) {
>   // ?
> }
>
> And that would indicate  that the argument was an rvalue?

__traits(isRef, mul).

> I realize that rvalues are not exactly what the OP is interested in.

Yup, different thing.

One can also do this kind of stuff:


```d
import core.stdc.stdio;

struct Literal(alias val)
{
    enum value = val;
}

enum lit(alias val) = Literal!val.init;

void print_num(Arg)(int num, Arg mul)
{
    static if (is(Arg == Literal!val, alias val))
    {
        static if (is(typeof(val) == string))
            printf("mul by compile-time string \"%s\"!\n", val.ptr);
        else static if (is(typeof(val) == int) && (val == 3))
            printf("mul by compile-time 3!\n");
        else
            printf("mul by compile-time thing\n");
    }
    else
    {
        printf("mul by runtime thing\n");
    }
}

void main()
{
    print_num(10, lit!"hello"); // mul by compile-time string "hello"!
    print_num(10, lit!3);       // mul by compile-time 3!
    print_num(10, lit!'a');     // mul by compile-time thing
    print_num(10, 10);          // mul by runtime thing
}
```
December 29, 2021

On Tuesday, 28 December 2021 at 22:06:50 UTC, Steven Schveighoffer wrote:

>

On 12/28/21 4:19 PM, rempas wrote:

Here:

>
extern (C) void main() {
   void print_num(int mul)(int num) {
     static if (is(mul == ten)) {
       printf("%d\n", num * 10);
     } else static if (is(mul == three)) {
       printf("%d\n", num * 3);
     } else {
       printf("%d\n", num);
     }
   }

   int multi = 211;
   print_num!3(10);     // Ok, accept this
   print_num!multi(10); // Error, do not accept this
}

-Steve

Thanks! That's cool but I don't want this to be this way. Or at least I want it to be able to take a default value so we don't have to get passed all the time. So something like this:

extern (C) void main() {
  void print_num(int num, comp_time_type int mul = 100) {
    static if (is(mul == ten)) {
      printf("%d\n", num * 10);
    } else static if (is(mul == three)) {
      printf("%d\n", num * 3);
    } else {
      printf("%d\n", num);
    }
  }

  int multi = 211;
  print_num(10, 3);     // Set the value
  print_num(30);        // Get the default value, have the "else" branch executed
}

Is this possible?

December 29, 2021

On Tuesday, 28 December 2021 at 22:26:33 UTC, max haughton wrote:

>

Why do you need this? What's wrong with a normal branch in this case.

Runtime performance. I want the value to get checked at compile time and use "static if" with it

December 29, 2021
On Wednesday, 29 December 2021 at 01:34:22 UTC, Stanislav Blinov wrote:
> One can also do this kind of stuff:
>
>
> ```d
> import core.stdc.stdio;
>
> struct Literal(alias val)
> {
>     enum value = val;
> }
>
> enum lit(alias val) = Literal!val.init;
>
> void print_num(Arg)(int num, Arg mul)
> {
>     static if (is(Arg == Literal!val, alias val))
>     {
>         static if (is(typeof(val) == string))
>             printf("mul by compile-time string \"%s\"!\n", val.ptr);
>         else static if (is(typeof(val) == int) && (val == 3))
>             printf("mul by compile-time 3!\n");
>         else
>             printf("mul by compile-time thing\n");
>     }
>     else
>     {
>         printf("mul by runtime thing\n");
>     }
> }
>
> void main()
> {
>     print_num(10, lit!"hello"); // mul by compile-time string "hello"!
>     print_num(10, lit!3);       // mul by compile-time 3!
>     print_num(10, lit!'a');     // mul by compile-time thing
>     print_num(10, 10);          // mul by runtime thing
> }
> ```

Thanks! That's awesome tho It will be annoying to have to type "lit!3" and not just pass it a literal or an "enum" or anything else that is guaranteed to be able to read at compile time.
December 29, 2021

On Wednesday, 29 December 2021 at 08:56:47 UTC, rempas wrote:

>

On Tuesday, 28 December 2021 at 22:26:33 UTC, max haughton wrote:

>

Why do you need this? What's wrong with a normal branch in this case.

Runtime performance. I want the value to get checked at compile time and use "static if" with it

If the value is known at compile time the compiler can pretty easily do that for you unless you're really unlucky.

« First   ‹ Prev
1 2