Re: How to unpack template parameters,Or how to forward parameters?

2022-05-06 Thread zjh via Digitalmars-d-learn

On Friday, 6 May 2022 at 05:44:39 UTC, vit wrote:


Try this:


Very Good,Thank you very much!


Re: How to unpack template parameters,Or how to forward parameters?

2022-05-05 Thread vit via Digitalmars-d-learn

On Friday, 6 May 2022 at 00:41:18 UTC, zjh wrote:

Hello everyone,I have following function:
```d
import core.stdc.stdio;
void f(int i,int j){
printf("%i,%i",i,j);
}
```
I want to forward `int[N]` to `(int i,int j)` etc. How can I 
write a forwarding function?

```d
void ff(alias g,int...I)(int[2]k){
g(k[I]);
}//How to unpack template variable parameters?

void f(int[2]k){
ff!(f,0,1)(k);//how to forward?
}

```

main function:
```d
extern(C):void main()
{
int[2] a=[2,4];
f(a);//calling like this
}
```


Try this:

```d
import core.stdc.stdio;

void f(int i,int j){
printf("%i,%i",i,j);
}


import std.range :  iota;
import std.traits :  isStaticArray;
import std.meta :  AliasSeq;


template expand(alias arr)
if(isStaticArray!(typeof(arr))){
auto get(size_t I)(){
return arr[I];
}

alias Result = AliasSeq!();

static foreach(I; iota(0, arr.length))
Result = AliasSeq!(Result, get!I);

alias expand = Result;
}


extern(C):void main(){
int[2] a=[2,4];
f(expand!a);
}
```


How to unpack template parameters,Or how to forward parameters?

2022-05-05 Thread zjh via Digitalmars-d-learn

Hello everyone,I have following function:
```d
import core.stdc.stdio;
void f(int i,int j){
printf("%i,%i",i,j);
}
```
I want to forward `int[N]` to `(int i,int j)` etc. How can I 
write a forwarding function?

```d
void ff(alias g,int...I)(int[2]k){
g(k[I]);
}//How to unpack template variable parameters?

void f(int[2]k){
ff!(f,0,1)(k);//how to forward?
}

```

main function:
```d
extern(C):void main()
{
int[2] a=[2,4];
f(a);//calling like this
}
```



Re: Understanding alias template parameters

2022-04-22 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 22 April 2022 at 08:04:16 UTC, JG wrote:

On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote:

Hi,

Could someone possibly help me to understand why the commented 
line doesn't compile?





Good job, works great! Potential is high:

```d
void main()
{
  alias type = real;
  auto range = iota!type(1, 4, .5);

  alias fun1 = (type a) => a * a;
  alias fun2 = (type a) => a * 2;
  alias fun3 = (type a) => a + 1;
  alias fun4 = (type a) => a - 1;
  alias fun5 = (type a) => a / 2;

  alias func = type function(type a);
  alias MR = MapResult!(typeof(range), func);

  MR[] mr;
  tuple(fun1, fun2, fun3, fun4, fun5)
   .each!(f => mr ~= MR(range, f));

  mr.writefln!"%-(%s\n%)";

} /* OUTPUT:
[1, 2.25, 4, 6.25, 9, 12.25]
[2, 3, 4, 5, 6, 7]
[2, 2.5, 3, 3.5, 4, 4.5]
[0, 0.5, 1, 1.5, 2, 2.5]
[0.5, 0.75, 1, 1.25, 1.5, 1.75]
*/
```



Re: Understanding alias template parameters

2022-04-22 Thread Ali Çehreli via Digitalmars-d-learn

On 4/22/22 01:04, JG wrote:

> In response to the change to "alias", which has several upsides
> including faster code. I would note it also has some downsides including
> every lambda produces a new type so that (at the moment) the following
> assert
> holds:

I got confused a little bit there. To make sure: alias would cause 
different template instantiation. That's why the following types are 
different for 'map'.


> ```d
> auto r = iota(10).map!(x=>x+1);
> auto s = iota(10).map!(x=>x+1);
> assert(!is(typeof(r)==typeof(s)));
> ```

When you use your MyMap, the range types are the same.

Having an alias parameter, myMap() function will still cause multiple 
instances but that's life.


Ali



Re: Understanding alias template parameters

2022-04-22 Thread JG via Digitalmars-d-learn

On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote:

Hi,

Could someone possibly help me to understand why the commented 
line doesn't compile?



```d
import std;

struct MapResult(R,F)
{
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
return MapResult!(R,typeof(f))(r,f);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this 
compile?


}
```

(I do know that Phobos's map works differently with better 
performance).



Thank you to all for the great replies. To fix it one could do:

```d
import std;

struct MapResult(R,F) {
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
static if(__traits(compiles,f!(typeof(R.init.front {
auto fun = f!(typeof(R.init.front));
return MapResult!(R,typeof(fun))(r,fun);
} else {
return MapResult!(R,typeof(f))(r,f);
}
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   iota(10).myMap!(x=>2*x).writeln;

}
```

In response to the change to "alias", which has several upsides
including faster code. I would note it also has some downsides 
including
every lambda produces a new type so that (at the moment) the 
following assert

holds:
```d
auto r = iota(10).map!(x=>x+1);
auto s = iota(10).map!(x=>x+1);
assert(!is(typeof(r)==typeof(s)));
```


Re: Understanding alias template parameters

2022-04-21 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Apr 21, 2022 at 09:02:47PM +, JG via Digitalmars-d-learn wrote:
> Hi,
> 
> Could someone possibly help me to understand why the commented line
> doesn't compile?
> 
> 
> ```d
> import std;
> 
> struct MapResult(R,F)
> {
> R r;
> const F f;
> auto empty() { return r.empty; }
> auto front() { return f(r.front); }
> void popFront() { r.popFront; }
> auto save() { return typeof(this)(r.save,f); }
> }
> 
> auto myMap(alias f, R)(R r) {
> return MapResult!(R,typeof(f))(r,f);
> }
> 
> 
> void main()
> {
>int function(int) f = x=>2*x;
>iota(10).myMap!f.writeln;
>//iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this compile?
> 
> }
> ```

Check the compiler's error message carefully:

/tmp/test.d(6): Error: variable `test.MapResult!(Result, void).MapResult.f` 
variables cannot be of type `void`
   ^^^
The error comes from line 6, which is:

>const F f;

A lambda literal like `x=>2*x` is a template, so you cannot store it in
a variable. You need to either explicitly wrap it in a delegate, or
forward the alias to your struct as a template parameter, e.g.:

struct MapResult(alias f, R)
{
... // remove the line `const F f;`
}
auto myMap(alias f, R)(R r) {
return MapResult!(f, R)(r);
}


T

-- 
Truth, Sir, is a cow which will give [skeptics] no more milk, and so they are 
gone to milk the bull. -- Sam. Johnson


Re: Understanding alias template parameters

2022-04-21 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 21 April 2022 at 21:38:14 UTC, Ali Çehreli wrote:

```d
auto myMap(alias f, R)(R r) {
  pragma(msg, typeof(f));
return MapResult!(R, f)(r);
}
```


It looks delicious when the convenience function works magic with 
Voldemort:


```d
import std.range,  std.stdio;

auto myMap(alias f, R)(R r) {
  struct Map {
auto empty() {
  return r.empty;
}

auto front() {
  return f(r.front);
}

void popFront() {
  r.popFront;
}
  }
  return Map();
}

void main() {

  // with convenience function:

  alias func = (int x) =>  2 * x;
  auto range = 1.iota(11);

  range.myMap!func.writeln;
  range.myMap!(x => 2 * x).writeln;

  // with only struct:

  struct MapResult(alias range, alias f) {
auto empty() { return range.empty; }
auto front() { return f(range.front); }
void popFront() { range.popFront; }
  }

  MapResult!(range, func) mp;
  foreach(result; mp) result.writeln;

} /* OUTPUT:
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
2
4
6
8
10
12
14
16
18
20
*/

```
SDB@79


Re: Understanding alias template parameters

2022-04-21 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote:

Hi,

Could someone possibly help me to understand why the commented 
line doesn't compile?



```d
import std;

struct MapResult(R,F)
{
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
return MapResult!(R,typeof(f))(r,f);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this 
compile?


}
```


When you write a lambda without type annotations, like `x => 
2*x`, the compiler interprets it as a function template. So in 
this case, it's the same as if you'd written


```d
T func(T)(T x) { return 2*x; }
iota(10).myMap!func.writeln;
```

The problem is, you can't store a template in a variable:

```d
auto f = func; // doesn't work - func does not have a value
```

So, when you try to create a `MapResult` with the template `x => 
2*x` as one of its member variables, it doesn't work.


By the way, you may have noticed that the error message you got 
says something about variables of type `void` not being allowed. 
That's because of [a long-standing bug][1] that causes `typeof` 
returns `void` when applied to a template. However, that bug is 
not the cause of the error here--even if it were fixed, your code 
still would not work.


[1]: https://issues.dlang.org/show_bug.cgi?id=7947


Re: Understanding alias template parameters

2022-04-21 Thread Ali Çehreli via Digitalmars-d-learn

On 4/21/22 14:02, JG wrote:

> Could someone possibly help me to understand why the commented line
> doesn't compile?

  iota(10).myMap!(x=>2*x).writeln;

It is because x=>2*x is just a template. I don't know why the compiler 
chooses 'void' for typeof(f) but apparently that's how it represents the 
types of function templates.


One way of changing the code is to use the following but it does not 
really fit because of course you may want types other than 'int':


  (int x) => 2 * x  // Now the type is known

The more logical thing to do is to stay with alias template parameters 
for MapResult as well. I am not sure why you need the member 'f' so I 
commented it out but now it compiles after some trivial changes:


import std;

struct MapResult(R, alias f)  // <== HERE
{
R r;
// const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save); }
}

auto myMap(alias f, R)(R r) {
  pragma(msg, typeof(f));
return MapResult!(R, f)(r);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   iota(10).myMap!(x=>2*x).writeln;
}

Ali



Understanding alias template parameters

2022-04-21 Thread JG via Digitalmars-d-learn

Hi,

Could someone possibly help me to understand why the commented 
line doesn't compile?



```d
import std;

struct MapResult(R,F)
{
R r;
const F f;
auto empty() { return r.empty; }
auto front() { return f(r.front); }
void popFront() { r.popFront; }
auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
return MapResult!(R,typeof(f))(r,f);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
   //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this 
compile?


}
```

(I do know that Phobos's map works differently with better 
performance).


Re: template parameters :: fix

2021-09-03 Thread Charles Hixson via Digitalmars-d-learn

change:

            {    rl.remove(i);

to:

           {    rl  =  rl.remove(i);

--
Javascript is what you use to allow third party programs you don't know 
anything about and doing you know not what to run on your computer.



Re: template parameters

2021-09-02 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Sep 02, 2021 at 02:28:23PM -0700, Charles Hixson via 
Digitalmars-d-learn wrote:
[...]
> -- 
> Javascript is what you use to allow third part programs you don't know
> anything about and doing you know not what to run on your computer.

ROFL!  I'm st^Wborrowing this for my quotes file. ;-)


T

-- 
"How are you doing?" "Doing what?"


Re: template parameters

2021-09-02 Thread Charles Hixson via Digitalmars-d-learn

Thanks.  See below for what I did.

On 8/29/21 5:05 PM, Ali Çehreli via Digitalmars-d-learn wrote:

On 8/29/21 3:31 PM, Charles Hixson wrote:
> Thanks.  I going to have to study:
>
> enum supportsCall = isIntegral!(typeof(T.init.%s()));
>
>
> for awhile to make any sense of that, but it looks like just what I was
> looking for.

Trying to explain with comments:

// This is an eponymous template because it contains
// a symbol that's the same as the name of this template.
// And that symbol is 'supportsCall'. So, this template
// will be whatever that symbol is. (In this case, it
// will be a compile-time know entity: 'enum bool'.)

template supportsCall(T, string func) {
  import std.format : format;
  import std.traits : isIntegral;

  // This is a string expression we will mix-in below.
  enum expr = format!q{
    enum supportsCall = isIntegral!(typeof(T.init.%s()));
  }(func);

  // The above expression will be the following e.g.
  // for 'int' and for "ndx":
  //
  //   enum supportsCall = isIntegral!(typeof(int.init.ndx()));
  //
  // So, it's determining whether the typeof the expression
  // int.init.ndx() is an integral.
  //
  // 'supportsCall' is a bool, which I could have made explicit:
  //
  //   enum bool supportsCall = [...]
  //
  // You can prove it for yourself by "printing" the expression
  // at compile time:

  pragma(msg, expr);

  // Here is where we mix-in the expression into this template's
  // definition.

  mixin (expr);
}

Then the whole template can be used as a compile-time bool value.

Ali

I'm going to need to save that for the future.  I ran into errors in 
other sections.  I suspect that a general form would require static if 
tests in numerous routines.  Anyway, if you're interested this is what I 
ended up with. (I think it's error free, but not all paths have been 
tested.)


import    std.algorithm : remove;
import    std.exception;
import    std.stdio;
import    std.traits : isIntegral;

import    utils;    //    this is for my randomized integer code based 
on time:  rndT


/**    An Associative Array with some Randomization and Linear features.
 * Note:  This is done in a simplified and not too generalized fashion 
so that I don't need to
 *         figure out template parameters at the moment.  It should be 
redone later, when my mastery
 *         is better.  The current version should work for classes and 
structs that have a function
 *         int T.ndx() that returns a unique id.  That id (called the 
key) is used as an AA index

 *         to find the instance, with duplicates not being allowed.    */
class    AARL2 (T)
{    /**    The associative array of cells, with the index as the key.    */
    T[int]    aa;
    /**    A linear array of cell key values.  This is ordered by the 
order in which they were

     * inserted rather than by value.    */
    int[]    rl;

    /**    Create an AARL from an array of cells.  The array must have 
no entries with duplicate
     * key values (i.e. cell.ndx).  Currently this throws an 
exception.  Consider how it could

     * be handled more gracefully.    */
    this (T[] inp)
    {    foreach (T c; inp)
        {    int    key    =    c.ndx;
            enforce (key !in aa, "Attempt to insert a key already 
present.");

            aa[key]    =    c;
            rl    ~=    key;
        }
    }
    this ()    {}

    /**    Access members by serial position of key.  (Not the value of 
the key!)    */

    T    at (int i)
    in    {    assert (i >= 0 && i < rl.length, "Index outside 
bounds");    }

    body
    {    int    key    =    rl[i];
        return    aa[key];
    }

    /**    This is a read-only count of number of entries.    */
    long    length()    {    return    aa.length;    }

    bool opBinaryRight(string op)(int key) const
            if (op == "in")
    {    return    cast (bool)(key in aa);    }

    bool opBinaryRight(string op)(T c) const
            if (op == "in")
    {    return    cast (bool)(c.ndx in aa);    }

    /**    Allow the [] operator to retrieve instances by key value.    */
    T opIndex(int key)
    {    if    (key in aa)    return    aa[key];
        return    null;
    }

    /**    "append" an instance of T.    */
    void opOpAssign (string op)(T c)
//            if    (op == "~=" && isIntegral!(typeof(T.init.ndx())
            if    (op == "~")
    {    append (c);    }

    /**    "append" an instance of T.
     * Note:  I need a better response to an attempt to add 
duplicates.    */

    void    append (T c)
    {    if    (c is null)
        {    stderr.writeln ("Attempt to add a null T to the AARL 
rejected.");

            return;
        }
        int    key    =    c.ndx;
        if (key in aa)
        {    aa[key]    =    c;    }
        else
        {    aa[key]    =    c;
            rl    ~=    key;
 

Re: template parameters

2021-08-29 Thread Ali Çehreli via Digitalmars-d-learn

On 8/29/21 3:31 PM, Charles Hixson wrote:
> Thanks.  I going to have to study:
>
> enum supportsCall = isIntegral!(typeof(T.init.%s()));
>
>
> for awhile to make any sense of that, but it looks like just what I was
> looking for.

Trying to explain with comments:

// This is an eponymous template because it contains
// a symbol that's the same as the name of this template.
// And that symbol is 'supportsCall'. So, this template
// will be whatever that symbol is. (In this case, it
// will be a compile-time know entity: 'enum bool'.)

template supportsCall(T, string func) {
  import std.format : format;
  import std.traits : isIntegral;

  // This is a string expression we will mix-in below.
  enum expr = format!q{
enum supportsCall = isIntegral!(typeof(T.init.%s()));
  }(func);

  // The above expression will be the following e.g.
  // for 'int' and for "ndx":
  //
  //   enum supportsCall = isIntegral!(typeof(int.init.ndx()));
  //
  // So, it's determining whether the typeof the expression
  // int.init.ndx() is an integral.
  //
  // 'supportsCall' is a bool, which I could have made explicit:
  //
  //   enum bool supportsCall = [...]
  //
  // You can prove it for yourself by "printing" the expression
  // at compile time:

  pragma(msg, expr);

  // Here is where we mix-in the expression into this template's
  // definition.

  mixin (expr);
}

Then the whole template can be used as a compile-time bool value.

Ali



Re: template parameters

2021-08-29 Thread Charles Hixson via Digitalmars-d-learn

Thanks.  I going to have to study:

enum supportsCall = isIntegral!(typeof(T.init.%s()));


for awhile to make any sense of that, but it looks like just what I was 
looking for.



On 8/29/21 2:41 PM, Ali Çehreli via Digitalmars-d-learn wrote:

On 8/29/21 11:32 AM, Charles H. wrote:

I've set up a class template (so far untested) thus:

 class    AARL (T, ndx = "ndx")
 if (isIntegral(T.init.ndx) )

 If I'm correct, this should work for ndx an integer variable of 
T, but I'd really like T to be able to be anything which can be 
stored both in an array and in an associative array.  But I can't 
figure out how to specify ndx.  After all, T might be a float, so it 
wouldn't have any appropriate attributes.  And I'd also like ndx to 
be able to be a function either a member of the class/struct T or a 
stand alone function.


So how should I set up this template?



I came up with the following:

template supportsCall(T, string func) {
  import std.format : format;
  import std.traits : isIntegral;

  enum expr = format!q{
    enum supportsCall = isIntegral!(typeof(T.init.%s()));
  }(func);

  mixin (expr);
}

class AARL (T, string func = "ndx")
if (supportsCall!(T, func)) {
}

int ndx(int i) {
  return 42;
}

struct S {
  long ndx() {
    return 100;
  }
}

void main() {
  auto a = new AARL!int();
  auto b = new AARL!S();
}

Ali


--
Javascript is what you use to allow third part programs you don't know anything 
about and doing you know not what to run on your computer.



Re: template parameters

2021-08-29 Thread Ali Çehreli via Digitalmars-d-learn

On 8/29/21 11:32 AM, Charles H. wrote:

I've set up a class template (so far untested) thus:

     class    AARL (T, ndx = "ndx")
     if (isIntegral(T.init.ndx) )

     If I'm correct, this should work for ndx an integer variable of T, 
but I'd really like T to be able to be anything which can be stored both 
in an array and in an associative array.  But I can't figure out how to 
specify ndx.  After all, T might be a float, so it wouldn't have any 
appropriate attributes.  And I'd also like ndx to be able to be a 
function either a member of the class/struct T or a stand alone function.


So how should I set up this template?



I came up with the following:

template supportsCall(T, string func) {
  import std.format : format;
  import std.traits : isIntegral;

  enum expr = format!q{
enum supportsCall = isIntegral!(typeof(T.init.%s()));
  }(func);

  mixin (expr);
}

class AARL (T, string func = "ndx")
if (supportsCall!(T, func)) {
}

int ndx(int i) {
  return 42;
}

struct S {
  long ndx() {
return 100;
  }
}

void main() {
  auto a = new AARL!int();
  auto b = new AARL!S();
}

Ali



template parameters

2021-08-29 Thread Charles Hixson via Digitalmars-d-learn

I've set up a class template (so far untested) thus:

class    AARL (T, ndx = "ndx")
        if (isIntegral(T.init.ndx) )
If I'm correct, this should work for ndx an integer variable of T, but 
I'd really like T to be able to be anything which can be stored both in 
an array and in an associative array.  But I can't figure out how to 
specify ndx.  After all, T might be a float, so it wouldn't have any 
appropriate attributes.  And I'd also like ndx to be able to be a 
function either a member of the class/struct T or a stand alone function.


So how should I set up this template?

--
Javascript is what you use to allow third part programs you don't know anything 
about and doing you know not what to run on your computer.



template parameters

2021-08-29 Thread Charles H. via Digitalmars-d-learn

I've set up a class template (so far untested) thus:

classAARL (T, ndx = "ndx")
if (isIntegral(T.init.ndx) )

If I'm correct, this should work for ndx an integer variable 
of T, but I'd really like T to be able to be anything which can 
be stored both in an array and in an associative array.  But I 
can't figure out how to specify ndx.  After all, T might be a 
float, so it wouldn't have any appropriate attributes.  And I'd 
also like ndx to be able to be a function either a member of the 
class/struct T or a stand alone function.


So how should I set up this template?



Re: Is there a "nice" way to access the names of template parameters outside?

2021-07-27 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 27 July 2021 at 10:15:51 UTC, Lukas  Borin wrote:

On Tuesday, 27 July 2021 at 09:31:07 UTC, Paul Backus wrote:

On Tuesday, 27 July 2021 at 08:15:12 UTC, Lukas  Borin wrote:

Consider the following template

```D
auto foo(T, int W, int H)(T p1, T p2) { }
```

Is there a "nice" way from the outside the get the names of 
the template values?


As far as I'm aware there is no way to introspect on template 
parameters at all.


Let's say i instantiate the template does that change anything? 
Can I get the "placeholder" names in any way then?


I don't think instantiating it changes anything. The underlying 
issue is that `is(symbol == __parameters)` doesn't work on 
templates.


Re: Is there a "nice" way to access the names of template parameters outside?

2021-07-27 Thread Lukas Borin via Digitalmars-d-learn

On Tuesday, 27 July 2021 at 09:31:07 UTC, Paul Backus wrote:

On Tuesday, 27 July 2021 at 08:15:12 UTC, Lukas  Borin wrote:

Consider the following template

```D
auto foo(T, int W, int H)(T p1, T p2) { }
```

Is there a "nice" way from the outside the get the names of 
the template values?


As far as I'm aware there is no way to introspect on template 
parameters at all.


Let's say i instantiate the template does that change anything? 
Can I get the "placeholder" names in any way then?


Re: Is there a "nice" way to access the names of template parameters outside?

2021-07-27 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 27 July 2021 at 08:15:12 UTC, Lukas  Borin wrote:

Consider the following template

```D
auto foo(T, int W, int H)(T p1, T p2) { }
```

Is there a "nice" way from the outside the get the names of the 
template values?


As far as I'm aware there is no way to introspect on template 
parameters at all.


Is there a "nice" way to access the names of template parameters outside?

2021-07-27 Thread Lukas Borin via Digitalmars-d-learn

Consider the following template

```D
auto foo(T, int W, int H)(T p1, T p2) { }
```

Is there a "nice" way from the outside the get the names of the 
template values?


E.g:
```D
pragma(msg, TemplateParameterNames!(foo)); // AliasSeq!("T", "W", 
"H") or ["T", "W", "H"]

```

I know you can find the names values in a very hacky way. 
(atleast in dmd 2.097.1)


```D
template HackyHack(alias T) {
   enum RawName = T.stringof;
   enum HackyHack = parseRawName(RawName); // Or 
templateParse!RawString;

}

```

I currently have the HackyHack solution *"working"* but I really 
don't like it and I would be supprised if it works on other dmd 
version or other compilers.



I know I can do things like:

```D
template foo(T, int W, int H) {
   enum names = ... // some magic with __traits or just assing it 
to ["T", "W", "H"]

   auto foo(T p1, T p2) { }
}
```

Use template mixins or other solutions to get what I want but if 
possible I prefer to just introspect on the template.


Usecase right now is to do some cuda kernel generation from a D 
shortfunction.


Something like this:

```D
@kernel
auto saxpy(T, int Iters, int N, int Stride)(T a, T* x, T* y, T* 
output) => q{

int tid = blockIdx.x * blockDim.x + threadIdx.x;
for(int idx = tid, int i = 0; i < Iters && idx < N; ++i, idx 
+= Stride) {

output[idx] = a * x[idx] + y[idx];
}
};
```

Would get transformed to:
```D
template
__global__ void saxpy(T a, T* x, T* y, T* output) {
//Identical function body / parameters and template arguments 
from the @kernel

//D function.
int tid = blockIdx.x * blockDim.x + threadIdx.x;
for(int idx = tid, int i = 0; i < Iters && idx < N; ++i, idx 
+= Stride) {

output[idx] = a * x[idx] + y[idx];
}
}
```

Really need the names to make this translation, correctly.

Just to be clear i'm not interested in getting the arguments a 
template was instantiated with. I can use TemplateArgsOf!T for 
that.


Re: If statements and unused template parameters in Phobos documentation

2020-12-20 Thread Rekel via Digitalmars-d-learn

On Sunday, 20 December 2020 at 13:58:00 UTC, Max Haughton wrote:

The if is a template constraint.


Ah sorry! I must have missed that part of the dlang tour.
(https://tour.dlang.org/tour/en/gems/template-meta-programming)

Thanks a lot!


Re: If statements and unused template parameters in Phobos documentation

2020-12-20 Thread Max Haughton via Digitalmars-d-learn

On Sunday, 20 December 2020 at 13:51:08 UTC, Rekel wrote:
I found a lot of the Phobos documentation to contain template 
arguments and if statements that made no sense to me, for 
example:


```
 uint readf(alias format, A...) (
 auto ref A args
)
if (isSomeString!(typeof(format)));

uint readf(A...) (
 scope const(char)[] format,
 auto ref A args
);
``` https://dlang.org/library/std/stdio/file.readf.html

From stdio.readf & stdio.File.readf. I'm assuming this is some 
kind of template, but often it seems there are more parameters 
in the first '()' part than are ever given. Am I missing 
something? Additionally, what is that if statement for? It 
precedes nothing.


The if is a template constraint.


If statements and unused template parameters in Phobos documentation

2020-12-20 Thread Rekel via Digitalmars-d-learn
I found a lot of the Phobos documentation to contain template 
arguments and if statements that made no sense to me, for example:


```
 uint readf(alias format, A...) (
 auto ref A args
)
if (isSomeString!(typeof(format)));

uint readf(A...) (
 scope const(char)[] format,
 auto ref A args
);
``` https://dlang.org/library/std/stdio/file.readf.html

From stdio.readf & stdio.File.readf. I'm assuming this is some 
kind of template, but often it seems there are more parameters in 
the first '()' part than are ever given. Am I missing something? 
Additionally, what is that if statement for? It precedes nothing.


Re: Why are default template parameters not permitted on class templates?

2020-11-29 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 29 November 2020 at 21:52:10 UTC, JN wrote:

ValueHolder v2; // error


Make it `ValueHolder!()` and it works.

Default template params are only considered *after* it is clear a 
template needs to be instantiated. `ValueHolder` by itself is 
just the name of the template which is still distinct from the 
instance. The !() tells it you want an instance, then it will 
fill in default params for the missing items.


You might want to do like

class ValueHolderT!(T = int) {}

alias ValueHolder = ValueHolderT!();

if you want users to use the naked name while keeping the other 
thing available.


Why are default template parameters not permitted on class templates?

2020-11-29 Thread JN via Digitalmars-d-learn

class ValueHolder(T = int)
{
T t;
}

void main()
{
ValueHolder!int v1;
ValueHolder v2; // error
}

onlineapp.d(9): Error: template class onlineapp.ValueHolder(T = 
int) is used as a type without instantiation; to instantiate it 
use ValueHolder!(arguments)


Re: synthesising instantiated template parameters and arguments

2020-10-29 Thread Jacob Carlborg via Digitalmars-d-learn
On Wednesday, 28 October 2020 at 05:51:14 UTC, Nicholas Wilson 
wrote:


but for a templated C this is tricker as I can't use a template 
sequence parameter (...) unless C uses it in the same position 
(I'm trying to generate a mangle from it so it needs to be 
exact). Given


class A(T,int,args...) {}
alias C = A!(int, 0, float);

I need `ScopeClass!C` to be

template ScopeClass(C)
{
class Anon(T,int,args...) // name doesn't matter
{
 // implement members with compile time reflection
}

alias ScopeClass = Anon!(int, 0, float);
}

How do I do this?


Are you looking for `TemplateArgsOf` [1] ?

[1] https://dlang.org/phobos/std_traits.html#TemplateArgsOf

--
/Jacob Carlborg


Re: synthesising instantiated template parameters and arguments

2020-10-28 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 28 October 2020 at 05:51:14 UTC, Nicholas Wilson 
wrote:

class A(T,int,args...) {}
alias C = A!(int, 0, float);

I need `ScopeClass!C` to be

template ScopeClass(C)
{
class Anon(T,int,args...) // name doesn't matter
{
 // implement members with compile time reflection
}

alias ScopeClass = Anon!(int, 0, float);
}


So I'm not sure you can do what you want to do - D doesn't have 
any way to reflect on template parameters (though you CAN extract 
arguments I don't think it really helps here since you can't tell 
if the arguments were from `int, float` or from `T...` for 
example).


But like I don't really get why you need this. Can't you just use 
the arguments C already has and not have the extra layer? So 
you'd treat templated C the same was as non-templated C, and then 
if you want the mangle, just use like C.mangleof instead of 
trying to reconstruct it.


What's the bigger picture here?


synthesising instantiated template parameters and arguments

2020-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

Given

template ScopeClass(C)
{
//...
}


where C is a, possibly templated, class I want the eponymous 
member of ScopeClass!(C) to have the same templatedness (both 
parameters and arguments)as C.

For a non-template C this is a simple as:

template ScopeClass(C)
{
class ScopeClass
{
 // implement members with compile time reflection
}
}

but for a templated C this is tricker as I can't use a template 
sequence parameter (...) unless C uses it in the same position 
(I'm trying to generate a mangle from it so it needs to be 
exact). Given


class A(T,int,args...) {}
alias C = A!(int, 0, float);

I need `ScopeClass!C` to be

template ScopeClass(C)
{
class Anon(T,int,args...) // name doesn't matter
{
 // implement members with compile time reflection
}

alias ScopeClass = Anon!(int, 0, float);
}

How do I do this?


Re: Count template parameters of method

2020-10-12 Thread Andrey via Digitalmars-d-learn

And what about:

void test() {}

and

void text(alias qqq)() {}

?


Re: Count template parameters of method

2020-10-11 Thread Basile B. via Digitalmars-d-learn

On Sunday, 11 October 2020 at 06:53:59 UTC, Andrey wrote:

Hello,

How to count a number of parameters in uninitialized template 
method?


For example:

struct Test
{
void abc(int a, bool status, string text)() {}
{


The method "Test.abc" has three template paramenters.

I know that "TemplateArgsOf" exists but it is used only for 
INITIALIZED templates...


You can count the commas in the text representation  but this is 
not a good solution. The default value of a 
TemplateValueParameter can lead to wrong results, for example if 
it's an array literal or a string literal.


---
size_t countTP(alias T)()
{
import std.algorithm : count;
return T.stringof.count(',') + 1;
}

template T1(A){}
template T2(A,B){}
template T3(A,B,C){}

void main()
{
pragma(msg, countTP!T1);
pragma(msg, countTP!T2);
pragma(msg, countTP!T3);
}
---

probably the countTP function can be enhanced to handle corner 
cases I mentioned.


Count template parameters of method

2020-10-11 Thread Andrey via Digitalmars-d-learn

Hello,

How to count a number of parameters in uninitialized template 
method?


For example:

struct Test
{
void abc(int a, bool status, string text)() {}
{


The method "Test.abc" has three template paramenters.

I know that "TemplateArgsOf" exists but it is used only for 
INITIALIZED templates...


Function Templates with Only Template Parameters and UFCS

2020-05-10 Thread Seven Seas via Digitalmars-d-learn

Given the code:

```
auto foo(alias A, string str)()
{
// do stuff
}

struct Bar
{
// members
}

Bar bar;
bar.foo!"hello"; // This is an error. Would have to do foo!(bar, 
"hello")

```

Assuming that I haven't misunderstood or borked something, having 
UFCS for function templates whose parameters are only for the 
template would, seemingly, be nice. Are there workarounds? Is it 
possible to implement, and possibly the more important question, 
is it a good idea? One downside is there would be more ambiguity 
when one is parsing that last line.





Re: Variadic template parameters, refactor a long chain of static if's to 'functions'.

2019-06-28 Thread realhet via Digitalmars-d-learn

On Tuesday, 11 June 2019 at 13:22:26 UTC, Adam D. Ruppe wrote:

On Tuesday, 11 June 2019 at 09:26:56 UTC, realhet wrote:

  static bool processId(bool captureIntId, alias r, alias a)(){
mixin("alias ta = typeof("~a.stringof~");");


As I have been saying a lot, mixin and stringof should almost 
never be used together. You could write this a lot easier:

...


Thank you for the long example, it helped me a lot!

The thing is now capable of:

- getting a specific type of parameter -> 
args.paramByType!(string[int]).writeln;


- including wrapper structs. In that case, optionally can fall 
back to the type inside the struct.


- handle and call events (structs or fallback as well)

- It is super easy now to make a function that can process a 
specific set of events:

struct onClick  { void delegate() val; }
...
struct onHold   { void delegate() val; }

void processBtnEvents(T...)(bool click, bool state, bool chg, 
T args){
  if(click) args.paramCall!(onClick, true/*fallback to pure 
delegate*/);

  if(state) args.paramCall!onHold;
  if(chg){
args.paramCall!onChange;
if(state) args.paramCall!onPress;
 else args.paramCall!onRelease;
  }
}

- Also I've found a way to exchange state values (for example a 
bool for a CheckBox control):

  - I can give it a pointer to a bool
  - Or I can give a getter and 0 or more setter(s): bool 
delegate(), void delegate(bool)

  - Can be functionPointers too, not just delegates.
  - example:
void fIncrementer(T...)(T args){
  paramGetterType!T x;
  args.paramGetter(x);
  x = (x + 1).to!(paramGetterType!T);
  args.paramSetter(x);
}
  - it is letting me use enumerated types too -> I will not have 
to write anything, and there will be an automatic 
RadioButtonGroup on the screen, just bu mentioning that variable. 
It will be awesome!


- Sorry for the lot of string processing and some mixin()s :D At 
the end of the code below, I've learned a lot while being able to 
write nicer code.


Thank you for your example code, I've learned a lot from it.

--
private{
  bool is2(A, B)() { return is(immutable(A)==immutable(B)); }

  bool isBool  (A)(){ return is2!(A, bool  ); }
  bool isInt   (A)(){ return is2!(A, int   ) || is2!(A, uint  ); }
  bool isFloat (A)(){ return is2!(A, float ) || is2!(A, double); }
  bool isString(A)(){ return is2!(A, string); }

  bool isSimple(A)(){ return isBool!A || isInt!A || isFloat!A || 
isString!A; }


  bool isGetter(A, T)(){
enum a = A.stringof, t = T.stringof;
return a.startsWith(t~" delegate()")
|| a.startsWith(t~" function()");
  }
  bool isSetter(A, T)(){
enum a = A.stringof, t = T.stringof;
return a.startsWith("void delegate("~t~" ")
|| a.startsWith("void function("~t~" ");
  }
  bool isEvent(A)(){ return isGetter!(A, void); } //event = void 
getter


  bool isCompatible(TDst, TSrc, bool compiles, bool 
compilesDelegate)(){

return (isBool  !TDst && isBool  !TSrc)
|| (isInt   !TDst && isInt   !TSrc)
|| (isFloat !TDst && isFloat !TSrc)
|| (isString!TDst && isString!TSrc)
|| !isSimple!TDst && (compiles || compilesDelegate); 
//assignment is working. This is the last priority

  }
}

auto paramByType(Tp, bool fallback=false, T...)(T args){
  Tp res;

  enum isWrapperStruct = __traits(hasMember, Tp, "val") && 
Fields!Tp.length==1; //is it encapsulated in a wrapper struct?  
-> struct{ type val; }


  enum checkDuplicatedParams = q{
static assert(!__traits(compiles, duplicated_parameter), 
"Duplicated parameter type: %s%s".format(Tp.stringof, fallback ? 
"("~typeof(Tp.val).stringof~")" : ""));

enum duplicated_parameter = 1;
  };

  static foreach_reverse(idx, t; T){
//check simple types/structs
static if(isCompatible!(typeof(res), t, __traits(compiles, 
res = args[idx]), __traits(compiles, res = 
args[idx].toDelegate))){
  static if(__traits(compiles, res = args[idx]))   
res = args[idx];else res = args[idx].toDelegate;

  mixin(checkDuplicatedParams);
}else
//check fallback struct.val
static if(fallback && isWrapperStruct && 
isCompatible!(typeof(res.val), t, __traits(compiles, res.val = 
args[idx]), __traits(compiles, res.val = args[idx].toDelegate))){
  static if(__traits(compiles, res.val = args[idx]))  
res.val = args[idx];  
  else res.val = args[idx].toDelegate;

  mixin(checkDuplicatedParams);
}
  }

  static if(isWrapperStruct) return res.val;
else return res;
}

void paramCall(Tp, bool fallback=false, T...)(T args){
  auto e = paramByType!(Tp, fallback)(args);
  static assert(isEvent!(typeof(e)), "paramCallEvent() error: %s 
is not an event.".format(Tp.stringof));

  if(e !is null) e();
}

template paramGetterType(T...){
  static foreach(t; T){
static 

Re: Variadic template parameters, refactor a long chain of static if's to 'functions'.

2019-06-11 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 11 June 2019 at 09:26:56 UTC, realhet wrote:

  static bool processId(bool captureIntId, alias r, alias a)(){
mixin("alias ta = typeof("~a.stringof~");");


As I have been saying a lot, mixin and stringof should almost 
never be used together. You could write this a lot easier:


alias ta = typeof(a);

no need for mixin at all.


Error: template instance processId!(true, id, _param_1) 
processId!(true, id, _param_1) is nested in both Args and btn


So Args is a runtime thing, but you are trying to use it in 
compile time. The compiler can handle one layer of this - it 
basically inlines a runtime function when you do that - but with 
more layers it gets lost.


What you'll need to do is to kinda embrace this and have a helper 
struct that returns the stuff by value. To avoid holding all the 
possible types, pass what you want to it as type arguments inside 
the function.


Check this out:


---

struct ID { int val; }
struct enabled { bool val; }
struct disabled { bool val; }

struct PossibleArguments(T...) {

this(Args...)(Args args) {
static foreach(arg; args) {{
enum idx = TindexOf!(typeof(arg));
static if(idx >= 0)
contents[idx] = arg;
else
static assert(0, "Unusable arg " 
~ typeof(arg).stringof);

}}
}

private T contents;
private static int TindexOf(What)() {
static foreach(idx, t; T) {
// you could use your isSame here
static if(is(t == What))
return cast(int) idx;
}
return -1;
}

auto opDispatch(string n)() {
static foreach(idx, item; T)
if(item.stringof == n)
return contents[idx].val;
assert(0);
}
}

void btn(T...)(string params, T args) {
 // here's the usage: list args I want to support as CT,
 // then pass the other args as runtime
auto r = PossibleArguments!(
ID,
enabled
)(args);

import std.stdio;
writeln(r.opDispatch!"ID"); // or r.ID, but while 
debugging it helps to explicitly all r.opDispatch so you get the 
full error instead of "no such property"

writeln(r.enabled);
}


void main() {
// I enabled the first two, but not disabled, so this is 
an error

//btn("ignored", ID(5), enabled(true), disabled(false));

// but this works
btn("ignored", ID(5), enabled(true));

// and it can be reordered/ignored/etc
btn("ignored", enabled(false));
}

---



So now you avoid the list of ifs thanks to that TindexOf helper 
thing while still getting the helpful user error message, and the 
opDispatch can make feel like you are accessing by name inside.


Extending it to other types is an exercise for you :) 
Particularly, the event ones will need a different approach of 
some sort.


I would suggest actually putting them in a wrapper struct so you 
can  still use this cool name trick.


But alternatively, you could special-case them in the two loops, 
like always knowing void delegate() is going to be named onClick. 
I can help you solve this later too if you wanna go that way, I 
just g2g right now lol.


Variadic template parameters, refactor a long chain of static if's to 'functions'.

2019-06-11 Thread realhet via Digitalmars-d-learn

Hi again,

I'm trying to do variadic parameter processing, and I have the 
following function that works fine:


  static bool same(T1, T2)(){
pragma(msg, "same? "~T1.stringof~" "~T2.stringof);
return is(immutable(T1)==immutable(T2));
  }

  Btn btn(T...)(string params, T args){
enum captureIntID = true,
 captureBoolEnabled = true,
 captureFunct = true;

Args r; //Arg is a struct to store all the possible 
parameters in runtime

static foreach(a; args){
  //process id parameter
   static if(same!(typeof(a), id)) r.id = a.val;
  else static if(captureIntID && (same!(typeof(a), int) || 
same!(typeof(a), uint))) r.id = a;


  //process enabled/disabled
  else static if(same!(typeof(a), enabled )) r.enabled = 
a.val;
  else static if(same!(typeof(a), disabled)) r.enabled = 
!a.val;
  else static if(captureBoolEnabled && same!(typeof(a), bool) 
) r.enabled = a;


  //process data events
  else static if(same!(typeof(a), onClick  )) 
r.events.onClick   = a.f;
  else static if(same!(typeof(a), onPress  )) 
r.events.onPress   = a.f;
  else static if(same!(typeof(a), onRelease)) 
r.events.onRelease = a.f;
  else static if(same!(typeof(a), onChange )) 
r.events.onChange  = a.f;
  else static if(same!(typeof(a), onTrue   )) r.events.onTrue 
   = a.f;
  else static if(same!(typeof(a), onFalse  )) 
r.events.onFalse   = a.f;
  else static if(same!(typeof(a), onBool   )) r.events.onBool 
   = a.f;
  else static if(typeof(a).stringof.startsWith("void 
delegate()")) r.events.onClick = a;
  else static if(typeof(a).stringof.startsWith("void 
delegate(bool)")) r.events.onBool = a;


  else static assert(false, "Unsupported type 
"~typeof(a).stringof);

}

return new Btn(params, r.id, r.enabled, r.events);
  }


The long chain of is's are required to be able to show the error 
message at the end when an unhandled parameter type is found.


I will have more of these and want to reuse these ifs in other 
functions as well, so I decided to take out the first 2 if's and 
put it into a template function:


  static bool processId(bool captureIntId, alias r, alias a)(){
mixin("alias ta = typeof("~a.stringof~");");
pragma(msg, "ta "~ta.stringof);
 static if(same!(ta, id)) { r = a.val; return true; }
else static if(captureIntId && (same!(ta, int) || same!(ta, 
uint))) { r = a; return true; }

else return false;
  }

later I call it with:

  static if(processId!(true, r.id, a)){}
  else static if(...

'a' is the variadic foreach variable (_param_1 and so on),
'r.id' is the result field from an Arg structure.
Both 'a' and 'r.id' are existing and compiling, also the pragma 
messages are good, I see it can find the right types, but I have 
the following error for every variadic parameter:


Error: template instance processId!(true, id, _param_1) 
processId!(true, id, _param_1) is nested in both Args and btn


id is a struct. And also a field in the Args struct. I changed it 
to id1 in the Args struct ant the error remains the same.
Everything resides in the scope of a class called 
ContainerBuilder.


Is there a way to do this elegantly?
Maybe if I put everything in a very large chain of if's and 
enable the required parameters with a set of flags, but that's 
not structured well, and also needs the biggest possible set of 
runtime parameter storage to store the processed parametest.


Here's an example using the above function:
btn(`Yes flex=1`, id(54231), enabled(true), { lastClickedBtn = 
"Yes"; hehe = true; })

checkbox("Checkbox_1", 12345432, (bool b){ hehe = b; })

I will have a lot of controls and a lot of parameter types. I 
wanna do something like in the old VisualBasic, where you can 
skip a lot of default parameters, and also access the only few 
you need by name. Something like this: btn("caption", 
hint:"blabla", icon:"icon.ico"), but as I currently know this is 
not implemented in D.


Thank You in advance!




Re: Getting template parameters by its name

2019-01-11 Thread Yui Hosaka via Digitalmars-d-learn

On Friday, 11 January 2019 at 06:13:11 UTC, Paul Backus wrote:

On Friday, 11 January 2019 at 04:59:50 UTC, Yui Hosaka wrote:

I want to do something like this:


template S(T) {
}

void main() {
  pragma(msg, S!(int).T);  // Error: no property `T` for type 
`void`

}



You can get the arguments of a template instance as an AliasSeq 
using `std.traits.TemplateArgsOf`.


https://dlang.org/phobos/std_traits.html#TemplateArgsOf


It seems a good choice to me. Thank you!


Re: Getting template parameters by its name

2019-01-10 Thread Paul Backus via Digitalmars-d-learn

On Friday, 11 January 2019 at 04:59:50 UTC, Yui Hosaka wrote:

I want to do something like this:


template S(T) {
}

void main() {
  pragma(msg, S!(int).T);  // Error: no property `T` for type 
`void`

}



You can get the arguments of a template instance as an AliasSeq 
using `std.traits.TemplateArgsOf`.


https://dlang.org/phobos/std_traits.html#TemplateArgsOf


Getting template parameters by its name

2019-01-10 Thread Yui Hosaka via Digitalmars-d-learn

I want to do something like this:


template S(T) {
}

void main() {
  pragma(msg, S!(int).T);  // Error: no property `T` for type 
`void`

}


Using alias, it is possible to get T by another name:


template S(T) {
  alias t = T;
}

void main() {
  pragma(msg, S!(int).t);
}


But the same identifier cannot be used:


template S(T) {
  alias T = T;  // Error: `alias T = T;` cannot alias itself, use 
a qualified name to create an overload set

}

void main() {
  pragma(msg, S!(int).T);
}


Is there any nice way that `S!(int).T` works?



Re: Implicit Template Parameters Cannot Decipher Aliases?

2018-04-25 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 11:26:40 UTC, Vijay Nayar wrote:

On Wednesday, 25 April 2018 at 10:25:11 UTC, Simen Kjærås wrote:
In the general case, the issue is unsolvable, since the 
relationship between template parameters and alias results may 
be arbitrarily complex. A simple degenerate case is this:


Ok, wow, you weren't kidding. That becomes really complex 
really fast.


In that case, is the general rule of thumb that programmers 
should not use aliases for templated types when specifying 
template function parameters?  No implicit type inference is 
done on the return type or on local variables, so these alias 
seem fine enough there. Or should they just be entirely avoided 
to avoid these kinds of problems?


Right now, yeah, that's probably the most sensible rule to follow.

If someone were to write a DIP, the simple cases (which I'd guess 
constitute >90% of realistic use cases) could be handled. It 
would have to be somewhat limited, and identifying a sensible set 
of limitations would be an important part of the work.


I'm not sure exactly what's the best way to implement this - 
maybe a lowering from


auto foo(T)(Vector3!T arg) {}

to

auto foo(T)(Vector!(T,3) arg) {}

That would only work if there's a single overload and no static 
ifs involved. For a solution that works with static ifs or 
overloads, something must be done about how the matching itself 
works.



On Wednesday, 25 April 2018 at 11:42:12 UTC, ag0aep6g wrote:

https://issues.dlang.org/show_bug.cgi?id=1807


Thanks. :)

--
  Simen


Re: Implicit Template Parameters Cannot Decipher Aliases?

2018-04-25 Thread ag0aep6g via Digitalmars-d-learn

On 04/25/2018 12:25 PM, Simen Kjærås wrote:
It's a known issue, and could be solved in some cases by partial 
template expansion, which is currently not part of the language. I 
believe it's in bugzilla somewhere, but a cursory search yielded no 
results.


https://issues.dlang.org/show_bug.cgi?id=1807


Re: Implicit Template Parameters Cannot Decipher Aliases?

2018-04-25 Thread Vijay Nayar via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 10:25:11 UTC, Simen Kjærås wrote:
In the general case, the issue is unsolvable, since the 
relationship between template parameters and alias results may 
be arbitrarily complex. A simple degenerate case is this:


Ok, wow, you weren't kidding. That becomes really complex really 
fast.


In that case, is the general rule of thumb that programmers 
should not use aliases for templated types when specifying 
template function parameters?  No implicit type inference is done 
on the return type or on local variables, so these alias seem 
fine enough there. Or should they just be entirely avoided to 
avoid these kinds of problems?


Re: Implicit Template Parameters Cannot Decipher Aliases?

2018-04-25 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 07:39:28 UTC, Vijay Nayar wrote:
I have encountered a problem where whenever I attempt to use a 
templated function with alias that partially limits the type of 
the arguments, the program fails to compile.  But if I avoid 
using an alias, the same function can infer all arguments.


Is this working as intended or have I encountered a bug or 
missing feature?


It's a known issue, and could be solved in some cases by partial 
template expansion, which is currently not part of the language. 
I believe it's in bugzilla somewhere, but a cursory search 
yielded no results.


In the general case, the issue is unsolvable, since the 
relationship between template parameters and alias results may be 
arbitrarily complex. A simple degenerate case is this:


alias Foo(T) = string;

T fun(T)(Foo!T a) { return T.init; }

unittest {
// What's val's type?
auto val = fun("");
}

Since in this case Foo!T retains no information about T, it's 
impossible to figure out what T should be. In a more realistic 
case, where the alias template body includes static ifs, or there 
are overloads, the relationship is also hard to trace:


template Foo(T) if (T.sizeof < 4) {
alias T[T.sizeof] Foo;
}
template Foo(T) if (T.sizeof >= 4) {
alias T[T.sizeof/2] Foo;
}

T fun(T)(Foo!T a) { return T.init; }

unittest {
   int[2] a;
   auto val = fun(a);
}

Sure, for a human it's easy to figure out which overload is the 
right one, but defining the rules such that the compiler can 
reliably do it is harder.


--
  Simen


Re: Implicit Template Parameters Cannot Decipher Aliases?

2018-04-25 Thread Vijay Nayar via Digitalmars-d-learn

On Wednesday, 25 April 2018 at 07:39:28 UTC, Vijay Nayar wrote:


  addAllWithAlias(v1); // Error!


One more note, this following line works correctly.


 addAllWithAlias!double(v1);  // OK.


Implicit Template Parameters Cannot Decipher Aliases?

2018-04-25 Thread Vijay Nayar via Digitalmars-d-learn
I have encountered a problem where whenever I attempt to use a 
templated function with alias that partially limits the type of 
the arguments, the program fails to compile.  But if I avoid 
using an alias, the same function can infer all arguments.


Is this working as intended or have I encountered a bug or 
missing feature?


Example below:

```
/**
 * Demonstrate an unexpected compiler error when using implicit 
template parameters

 * combined with aliases to partially instantiate templates.
 */

struct Vector(ElemT, size_t SizeV) {
private:
  ElemT[SizeV] _data;
public:
  @property
  ElemT[SizeV] data() {
return _data;
  }

  ElemT opIndex(size_t i) {
return _data[i];
  }
}

// A helper alias to partially set a portion of compile-time 
arguments.

template Vector3(ElemT) {
  alias Vector3 = Vector!(ElemT, 3);
}

T addAllWithAlias(T)(Vector3!T v1) {
  T sum = 0;
  foreach (T v; v1.data) {
sum += v;
  }
  return sum;
}

T addAll(T)(Vector!(T, 3) v1) {
  T sum = 0;
  foreach (T v; v1.data) {
sum += v;
  }
  return sum;
}

void main() {
  auto v1 = Vector3!double([1.0, 2.0, 3.0]);
  assert(v1[1] == 2.0);

  addAllWithAlias(v1); // Error!
  // template.d(35): Error: template template.addAllWithAlias 
cannot deduce function from

  // argument types !()(Vector!(double, 3LU)), candidates are:
  //   template.d(24):
template.addAllWithAlias(T)(Vector3!T v1)


  addAll(v1);  // OK.
}
```


Re: Append variadic template parameters

2017-02-05 Thread Mark Fisher via Digitalmars-d-learn

On Sunday, 5 February 2017 at 21:51:14 UTC, Meta wrote:

On Sunday, 5 February 2017 at 20:36:57 UTC, Mark Fisher wrote:

I want to write a template:

static auto ref BindArg(alias Func,alias arg,args...)() {
return Func(arg,args);
}

where Func is called with 'arg' followed by the 'args' 
parameters.

eg:

string f(string a,int b,int c);


BindArg(f,"1",2,3);

You forgot the !



The compiler throws an error:
Error: function f (string a, int b, int c) is not callable 
using argument types ()


How do I append the parameters?


doh!

Thank you.



Re: Append variadic template parameters

2017-02-05 Thread Meta via Digitalmars-d-learn

On Sunday, 5 February 2017 at 20:36:57 UTC, Mark Fisher wrote:

I want to write a template:

static auto ref BindArg(alias Func,alias arg,args...)() {
return Func(arg,args);
}

where Func is called with 'arg' followed by the 'args' 
parameters.

eg:

string f(string a,int b,int c);


BindArg(f,"1",2,3);

You forgot the !



The compiler throws an error:
Error: function f (string a, int b, int c) is not callable 
using argument types ()


How do I append the parameters?





Re: Append variadic template parameters

2017-02-05 Thread ag0aep6g via Digitalmars-d-learn

On Sunday, 5 February 2017 at 20:36:57 UTC, Mark Fisher wrote:

static auto ref BindArg(alias Func,alias arg,args...)() {
return Func(arg,args);
}

[...]

BindArg(f,"1",2,3);


You forgot an exclamation mark there:

BindArg!(f,"1",2,3);


Append variadic template parameters

2017-02-05 Thread Mark Fisher via Digitalmars-d-learn

I want to write a template:

static auto ref BindArg(alias Func,alias arg,args...)() {
return Func(arg,args);
}

where Func is called with 'arg' followed by the 'args' parameters.
eg:

string f(string a,int b,int c);
BindArg(f,"1",2,3);

The compiler throws an error:
Error: function f (string a, int b, int c) is not callable using 
argument types ()


How do I append the parameters?




Re: Changing template parameters

2017-01-16 Thread Dlearner via Digitalmars-d-learn

On Monday, 16 January 2017 at 16:08:07 UTC, Rene Zwanenburg wrote:

On Monday, 16 January 2017 at 15:56:16 UTC, Jack Stouffer wrote:

Same way you use any template parameters,

 auto i = uniform!("(]")(0, 1000);


Also, if the template parameter consists of a single token you 
can omit the parens:


auto i = uniform!"(]"(0, 1000);


Ahhh, thanks a lot!


Re: Changing template parameters

2017-01-16 Thread Rene Zwanenburg via Digitalmars-d-learn

On Monday, 16 January 2017 at 15:56:16 UTC, Jack Stouffer wrote:

Same way you use any template parameters,

 auto i = uniform!("(]")(0, 1000);


Also, if the template parameter consists of a single token you 
can omit the parens:


auto i = uniform!"(]"(0, 1000);


Re: Changing template parameters

2017-01-16 Thread Jack Stouffer via Digitalmars-d-learn

On Monday, 16 January 2017 at 15:32:33 UTC, Dlearner wrote:

Hey, quick question!

I'm messing around with std.random and noticed that you can 
change the boundaries parameter to be either open or closed 
intervals on either side.  By default it is "[)".  How do I 
change these template parameters?


Same way you use any template parameters,

 auto i = uniform!("(]")(0, 1000);


Changing template parameters

2017-01-16 Thread Dlearner via Digitalmars-d-learn

Hey, quick question!

I'm messing around with std.random and noticed that you can 
change the boundaries parameter to be either open or closed 
intervals on either side.  By default it is "[)".  How do I 
change these template parameters?


Re: Template parameters that don't affect template type

2016-08-12 Thread Engine Machine via Digitalmars-d-learn

On Thursday, 11 August 2016 at 20:43:13 UTC, Meta wrote:
On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine 
wrote:

[...]


It can be done, but you have to be explicit and should think 
very carefully if this is really a good design.


struct X(int defaultSize = 100)
{
int size;
int* p;

void foo(int size)
{
size = max(size, defaultSize);
p = cast(int*)malloc(size);
}

X opAssign(X2: X!n, int n)(X2 other)
{
//Do whatever you want here
}

X2 changeDefaultSize(int n)()
{
auto newX = X!n(n, p);
p = null; //Release ownership of p

return newX;
}
}

void takesX50(X!50 x)
{
//...
}

void main()
{
X!100 n;
X!100 m;
X!50 o;

n = m;
o = m;

takesX50(n); //Error
takesX50(n.changeDefaultSize!50); //Okay
}

Really though this problem is properly solved by runtime 
polymorphism.


Thanks. I am using templates and in some cases use template 
arguments to set compile time properties, hence runtime won't 
work.  These arguments don't affect the type itself, as far as 
the functionality/behavior as I use them.


Re: Template parameters that don't affect template type

2016-08-11 Thread Meta via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:
I have the need, in some cases, to pass static information to a 
template class but don't want it to affect its type.


import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. 
The type it self does not depend on the default size.


While one could argue that it can be unsafe, in the my context, 
it is not.


Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


I use several parameters to pass info to the type that does not 
change affect the type itself. It prevents the "same type" from 
being used with "itself".


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is 
important!


I guess D just can't handle it though?


It can be done, but you have to be explicit and should think very 
carefully if this is really a good design.


struct X(int defaultSize = 100)
{
int size;
int* p;

void foo(int size)
{
size = max(size, defaultSize);
p = cast(int*)malloc(size);
}

X opAssign(X2: X!n, int n)(X2 other)
{
//Do whatever you want here
}

X2 changeDefaultSize(int n)()
{
auto newX = X!n(n, p);
p = null; //Release ownership of p

return newX;
}
}

void takesX50(X!50 x)
{
//...
}

void main()
{
X!100 n;
X!100 m;
X!50 o;

n = m;
o = m;

takesX50(n); //Error
takesX50(n.changeDefaultSize!50); //Okay
}

Really though this problem is properly solved by runtime 
polymorphism.


Re: Template parameters that don't affect template type

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 4:15 PM, Engine Machine wrote:

On Thursday, 11 August 2016 at 18:42:51 UTC, Steven Schveighoffer wrote:

On 8/11/16 2:11 PM, Engine Machine wrote:

I have the need, in some cases, to pass static information to a template
class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The type it
self does not depend on the default size.


And they should be different types. The code generated for the type is
different, in this case it's important to declare these are not the
same type.

For example, if x = y worked, then what should x.foo(5) do?


While one could argue that it can be unsafe, in the my context, it is
not.

Is there any way to get D to understand I want do not want a template
parameter to be part of the type comparison?


The type is part of the template, and the instantiations are
different. So no.


I use several parameters to pass info to the type that does not change
affect the type itself. It prevents the "same type" from being used with
"itself".


Then define how the compiler can convert from one to another. Or
redesign the type to specify the parameters at the right time.


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is
important!


That's not how template types work.

your code is shorthand for:

template s(T1, T2)
{
   struct s
   {
  T1 t1; // I assume you wanted to put a member here?
   }
}

Two different instantiations of s create two different namespaces
where the structs are not the same.



I don't think this proves anything. You just rewrote the template. T2 is
still not used in either case and hence the type does not depend on it.


OK, I'll use a different example:

struct S(int N)
{
   int x;
}

S!1 s1;
S!2 s2 = s1; // error

This is very similar to what you are asking for.

This can be reimagined like so:

struct S1
{
   int x;
}

struct S2
{
   int x;
}

S1 s1;
S2 s2 = s1; // error

The names end in a different number. They have the same types and 
structure, but the compiler considers them to be different types.


Each instantiation of a template defines a DIFFERENT namespace. The only 
time the namespaces are identical are when the template parameters are 
identical. The reason templates are so useful is because I don't HAVE to 
write both S1 and S2. I can write it once and not have to repeat myself. 
But the template itself is not a namespace. Only the instantiated 
template is one.



Basically your logic is something like: A = 0*5 is different than B =
0*6. But both are the same, just because they look different doesn't
change that.


Not at all. This is way off.


You are misunderstanding what I am asking or saying.

The code may be different, but one reference can store the value of
another. The type itself does not depend on the parameter.


The namespace in which the type is declared depends on the parameter. 
Templates depend on this.


For instance:

template Foo(string name)
{
   static int x;
}

Foo!"blah".x = 5;

auto y = Foo!"blar".x;

The namespace I've declared depends on the name I've passed the 
template. I want to fetch a *different* x when I declare a *different* 
namespace. That's the point!


If the compiler said "hey, you aren't using the name string, so I'm just 
going to assume all these are the same", that's going to screw up the 
entire purpose of this construct.



X!100 x;
X!50 y;

50 for y does not change anything to the outside world about y.

So, for all practical purposes, we have

X x;
X y;


No, you have

X100 x;
X50 y;

Where X100 and X50 have the exact same structure. But they are different 
types because the names are different.



You are confusing the general case with the specific case. Sure, in
general, it doesn't work, we know that. But not all types are dependent
on their type parameter. Just because such parameters are specified does
not necessarily mean they should be different types.


Again, not how templates work. You are looking for a different mechanism.

-Steve


Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn
On Thursday, 11 August 2016 at 18:42:51 UTC, Steven Schveighoffer 
wrote:

On 8/11/16 2:11 PM, Engine Machine wrote:
I have the need, in some cases, to pass static information to 
a template

class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. 
The type it

self does not depend on the default size.


And they should be different types. The code generated for the 
type is different, in this case it's important to declare these 
are not the same type.


For example, if x = y worked, then what should x.foo(5) do?

While one could argue that it can be unsafe, in the my 
context, it is not.


Is there any way to get D to understand I want do not want a 
template

parameter to be part of the type comparison?


The type is part of the template, and the instantiations are 
different. So no.


I use several parameters to pass info to the type that does 
not change
affect the type itself. It prevents the "same type" from being 
used with

"itself".


Then define how the compiler can convert from one to another. 
Or redesign the type to specify the parameters at the right 
time.



another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used 
is important!


That's not how template types work.

your code is shorthand for:

template s(T1, T2)
{
   struct s
   {
  T1 t1; // I assume you wanted to put a member here?
   }
}

Two different instantiations of s create two different 
namespaces where the structs are not the same.




I don't think this proves anything. You just rewrote the 
template. T2 is still not used in either case and hence the type 
does not depend on it.


Basically your logic is something like: A = 0*5 is different than 
B = 0*6. But both are the same, just because they look different 
doesn't change that.


I'd suggest if you don't use a template parameter, don't 
declare it. If you use it in a member function only (as in your 
first example), declare it in the member function as a template 
parameter.



I guess D just can't handle it though?


No, it doesn't handle incorrect assumptions very well ;)

-Steve


You are misunderstanding what I am asking or saying.

The code may be different, but one reference can store the value 
of another. The type itself does not depend on the parameter.


X!100 x;
X!50 y;

50 for y does not change anything to the outside world about y.

So, for all practical purposes, we have

X x;
X y;

in which case we can do

x = y; with no problem.

You are confusing the general case with the specific case. Sure, 
in general, it doesn't work, we know that. But not all types are 
dependent on their type parameter. Just because such parameters 
are specified does not necessarily mean they should be different 
types.



My example is not good because the types are different. If I did 
something like


void foo(int size)
   {
   Size = max(size, defaultSize, 100);
p = cast(int*)malloc(Size);
   }


Then it would be different.

in this case X!50 and X!100 would be the same. X!101 would not.



Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

Also, what if we use a class instead of a struct?

in this case they are both references to the same thing.

I see a problem with reflection though, as one could get the 
template parameter value and it would wrong on conversion. D 
takes the easy way out of just preventing complex and potentially 
ill-defined behavior, I guess that is ultimately a good thing, 
even if it makes it a pain in some cases.




Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn
On Thursday, 11 August 2016 at 19:28:47 UTC, Lodovico Giaretta 
wrote:
On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine 
wrote:

[...]


If, in your case, it is possible to use one type as the other, 
then specify it.
I mean, implement a templated opAssign that allows you to 
assign values of one instantiation to values of another. While 
doing so, remember that this will not change the behaviour of 
the assigned-to variable, but will only transfer the runtime 
state from one variable to the other.


struct S(T1, T2)
{
T1 t;
void opAssign(T)(auto ref S!(T1, T) other)
{
t = other.t;
}
}
unittest
{
S!(int, float) x(1);
S!(int, char) y(3);

x = y;
assert(x.t == 3);// the 
value of x is changed
static assert(is(typeof(x) == S!(int, float)))   // the 
type of x isn't changed

}


Ok, well, my point is that in some cases, the OpAssign is 
trivially since everything is copied. I guess being explicit is 
not a bad thing in this case though.





Re: Template parameters that don't affect template type

2016-08-11 Thread Lodovico Giaretta via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:

[...]


If, in your case, it is possible to use one type as the other, 
then specify it.
I mean, implement a templated opAssign that allows you to assign 
values of one instantiation to values of another. While doing so, 
remember that this will not change the behaviour of the 
assigned-to variable, but will only transfer the runtime state 
from one variable to the other.


struct S(T1, T2)
{
T1 t;
void opAssign(T)(auto ref S!(T1, T) other)
{
t = other.t;
}
}
unittest
{
S!(int, float) x(1);
S!(int, char) y(3);

x = y;
assert(x.t == 3);// the value 
of x is changed
static assert(is(typeof(x) == S!(int, float)))   // the type 
of x isn't changed

}




Re: Template parameters that don't affect template type

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 2:42 PM, Steven Schveighoffer wrote:

On 8/11/16 2:11 PM, Engine Machine wrote:

I have the need, in some cases, to pass static information to a template
class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The type it
self does not depend on the default size.


And they should be different types. The code generated for the type is
different, in this case it's important to declare these are not the same
type.

For example, if x = y worked, then what should x.foo(5) do?


Of course, I meant x = z :)

-Steve


Re: Template parameters that don't affect template type

2016-08-11 Thread Ali Çehreli via Digitalmars-d-learn

On 08/11/2016 11:11 AM, Engine Machine wrote:
> I have the need, in some cases, to pass static information to a template
> class but don't want it to affect its type.
>
> import std.algorithm, core.stdc.stdlib;
> struct X(int defaultSize = 100)
> {
>int Size;
>int* p;
>void foo(int size)
>{
> Size = max(size, defaultSize);
> p = cast(int*)malloc(Size);
>}
> }
>
> If I do
>
> X!100 x;
> X!100 y;
> X!50 z;
>
> then I can do
>
> x = y;
>
> but not
>
> x = z;
>
> but of course D things these are completely different types.

The reason they are different types is the fact that the code generated 
for X!100 and X!50 are different. If x=z were allowed, which foo() would 
you expect to be executed for x.foo()? If it would change at run time 
depending on the actual type, we need a run-time expression, which 
cannot be a template parameter.


> The type it
> self does not depend on the default size.
>
> While one could argue that it can be unsafe, in the my context, it is 
not.


Understood but not possible with the template definition of D.

> Is there any way to get D to understand I want do not want a template
> parameter to be part of the type comparison?

It must involve runtime.

> I use several parameters to pass info to the type that does not change
> affect the type itself. It prevents the "same type" from being used with
> "itself".
>
> another example:
>
> struct s(T1, T2)
> {
> T1;
> }
>
> then
>
> s!(int, double)
>
> and
>
> s!(int, float)
>
> should really be the same type! The fact that T2 is not used is 
important!


It's not used in this module but another module may be using __traits 
(or std.traits) to inspect that second argument.


> I guess D just can't handle it though?

By design, no. (Another language that behaves this way is C++.)

Ali



Re: Template parameters that don't affect template type

2016-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/11/16 2:11 PM, Engine Machine wrote:

I have the need, in some cases, to pass static information to a template
class but don't want it to affect its type.

import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The type it
self does not depend on the default size.


And they should be different types. The code generated for the type is 
different, in this case it's important to declare these are not the same 
type.


For example, if x = y worked, then what should x.foo(5) do?


While one could argue that it can be unsafe, in the my context, it is not.

Is there any way to get D to understand I want do not want a template
parameter to be part of the type comparison?


The type is part of the template, and the instantiations are different. 
So no.



I use several parameters to pass info to the type that does not change
affect the type itself. It prevents the "same type" from being used with
"itself".


Then define how the compiler can convert from one to another. Or 
redesign the type to specify the parameters at the right time.



another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is important!


That's not how template types work.

your code is shorthand for:

template s(T1, T2)
{
   struct s
   {
  T1 t1; // I assume you wanted to put a member here?
   }
}

Two different instantiations of s create two different namespaces where 
the structs are not the same.


I'd suggest if you don't use a template parameter, don't declare it. If 
you use it in a member function only (as in your first example), declare 
it in the member function as a template parameter.



I guess D just can't handle it though?


No, it doesn't handle incorrect assumptions very well ;)

-Steve


Re: Template parameters that don't affect template type

2016-08-11 Thread sldkf via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:
Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


No. Use a standard run-time parameter. Your problem can be solved 
by defining a constructor.


Re: Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn

On Thursday, 11 August 2016 at 18:11:30 UTC, Engine Machine wrote:
I have the need, in some cases, to pass static information to a 
template class but don't want it to affect its type.


import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. 
The type it self does not depend on the default size.


While one could argue that it can be unsafe, in the my context, 
it is not.


Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


I use several parameters to pass info to the type that does not 
change affect the type itself. It prevents the "same type" from 
being used with "itself".


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is 
important!


I guess D just can't handle it though?


Another good example is if something like

template X(bool ClearMemory = false)
{

}

ClearMemory would clearly not affect the type if it just clears 
memory that is malloc'ed, yet D would treat treat X!true from 
X!false.




Template parameters that don't affect template type

2016-08-11 Thread Engine Machine via Digitalmars-d-learn
I have the need, in some cases, to pass static information to a 
template class but don't want it to affect its type.


import std.algorithm, core.stdc.stdlib;
struct X(int defaultSize = 100)
{
   int Size;
   int* p;
   void foo(int size)
   {
Size = max(size, defaultSize);
p = cast(int*)malloc(Size);
   }
}

If I do

X!100 x;
X!100 y;
X!50 z;

then I can do

x = y;

but not

x = z;

but of course D things these are completely different types. The 
type it self does not depend on the default size.


While one could argue that it can be unsafe, in the my context, 
it is not.


Is there any way to get D to understand I want do not want a 
template parameter to be part of the type comparison?


I use several parameters to pass info to the type that does not 
change affect the type itself. It prevents the "same type" from 
being used with "itself".


another example:

struct s(T1, T2)
{
T1;
}

then

s!(int, double)

and

s!(int, float)

should really be the same type! The fact that T2 is not used is 
important!


I guess D just can't handle it though?







Re: Passing anonymous templated functions as template parameters

2016-06-15 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 23:52:56 UTC, Basile B. wrote:

On Wednesday, 15 June 2016 at 22:27:38 UTC, pineapple wrote:
Here's a simple code example to illustrate what I expected to 
work and didn't - is this a mistake in my syntax or a 
limitation of the language?


template SomeTemplate(alias func){
auto templatefunc(T)(int x){
return func!T(x);
}
}

// Valid
auto somefunc(T)(int x){
return cast(T) x;
}
alias fn1 = SomeTemplate!somefunc;

// Not valid
alias fn2 = SomeTemplate!(
(T)(int x){return cast(T) x;}
);


This syntax passes:

alias fn2(T) = SomeTemplate!((int x){return cast(T) x;});


I didn't try to instanciate previously. It works a bit with a 
lambda to the

extent that the alias has the template parameter list.

import std.stdio;

template A(alias func)
{
auto a(T)(int x)
{
return func!T(x);
}
}

alias spec(T) = A!(x => (cast(T) x));

void main(string[] args)
{
writeln((spec!byte).a!int(257)); // 1
}


Re: Passing anonymous templated functions as template parameters

2016-06-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/15/16 7:52 PM, Basile B. wrote:

On Wednesday, 15 June 2016 at 22:27:38 UTC, pineapple wrote:

Here's a simple code example to illustrate what I expected to work and
didn't - is this a mistake in my syntax or a limitation of the language?

template SomeTemplate(alias func){
auto templatefunc(T)(int x){
return func!T(x);
}
}

// Valid
auto somefunc(T)(int x){
return cast(T) x;
}
alias fn1 = SomeTemplate!somefunc;

// Not valid
alias fn2 = SomeTemplate!(
(T)(int x){return cast(T) x;}


This isn't valid syntax.

I don't think you can create anonymous templates. I could be wrong.

-Steve


Re: Passing anonymous templated functions as template parameters

2016-06-15 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 22:27:38 UTC, pineapple wrote:
Here's a simple code example to illustrate what I expected to 
work and didn't - is this a mistake in my syntax or a 
limitation of the language?


template SomeTemplate(alias func){
auto templatefunc(T)(int x){
return func!T(x);
}
}

// Valid
auto somefunc(T)(int x){
return cast(T) x;
}
alias fn1 = SomeTemplate!somefunc;

// Not valid
alias fn2 = SomeTemplate!(
(T)(int x){return cast(T) x;}
);


This syntax passes:

alias fn2(T) = SomeTemplate!((int x){return cast(T) x;});


Passing anonymous templated functions as template parameters

2016-06-15 Thread pineapple via Digitalmars-d-learn
Here's a simple code example to illustrate what I expected to 
work and didn't - is this a mistake in my syntax or a limitation 
of the language?


template SomeTemplate(alias func){
auto templatefunc(T)(int x){
return func!T(x);
}
}

// Valid
auto somefunc(T)(int x){
return cast(T) x;
}
alias fn1 = SomeTemplate!somefunc;

// Not valid
alias fn2 = SomeTemplate!(
(T)(int x){return cast(T) x;}
);


Re: Access template parameters?

2016-02-16 Thread Gavin Maye via Digitalmars-d-learn

On Tuesday, 16 February 2016 at 19:00:19 UTC, Ali Çehreli wrote:


std.traits.TemplateArgsOf:

  http://dlang.org/phobos/std_traits.html#TemplateArgsOf

import std.traits;

class Foo(type1,type2)
{}

class Bar(FooType)
{
// pragma(msg, TemplateArgsOf!FooType);

alias ReturnType = TemplateArgsOf!FooType[0];

ReturnType DoSomething() {
return ReturnType.init;
}
}

void main() {
auto b = new Bar!(Foo!(string, double));
}

However, there are other ways of achieving the same thing at 
least when returning from a function, e.g.:


auto DoSomething() {}

(Check out typeof(return) which may be useful in that case.)

Ali


Thanks Ali!



Re: Access template parameters?

2016-02-16 Thread Ali Çehreli via Digitalmars-d-learn

On 02/16/2016 10:34 AM, Gavin Maye wrote:

Say you have

class Foo(type1,type2)
{

}

And a concrete Foo is passed as a parameter to another template, is
there a way to get type1 and type2 from Foo so you can use them in the
new template... For example..

class Bar(FooType)
{
 FooType.type1 DoSomething() { ... }
}

or Even something like

class Bar(FooType) : Baz!(FooType.type1)
{
 FooType.type1 DoSomething() { ... }
}




std.traits.TemplateArgsOf:

  http://dlang.org/phobos/std_traits.html#TemplateArgsOf

import std.traits;

class Foo(type1,type2)
{}

class Bar(FooType)
{
// pragma(msg, TemplateArgsOf!FooType);

alias ReturnType = TemplateArgsOf!FooType[0];

ReturnType DoSomething() {
return ReturnType.init;
}
}

void main() {
auto b = new Bar!(Foo!(string, double));
}

However, there are other ways of achieving the same thing at least when 
returning from a function, e.g.:


auto DoSomething() {}

(Check out typeof(return) which may be useful in that case.)

Ali



Access template parameters?

2016-02-16 Thread Gavin Maye via Digitalmars-d-learn

Say you have

class Foo(type1,type2)
{
   
}

And a concrete Foo is passed as a parameter to another template, 
is there a way to get type1 and type2 from Foo so you can use 
them in the new template... For example..


class Bar(FooType)
{
FooType.type1 DoSomething() { ... }
}

or Even something like

class Bar(FooType) : Baz!(FooType.type1)
{
FooType.type1 DoSomething() { ... }
}




Re: Variadic template parameters T... bounding

2016-02-02 Thread Daniel Kozak via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 13:57:54 UTC, Marc Schütz wrote:

On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
The last call should work IMO, but it doesn't. I believe 
that's a compiler bug.


Filed:
https://issues.dlang.org/show_bug.cgi?id=15640


I would say it is not a bug
test!A(new B(), new C()); // works
which is what I expected


Re: Variadic template parameters T... bounding

2016-02-02 Thread Daniel Kozak via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 14:47:43 UTC, Marc Schütz wrote:

On Tuesday, 2 February 2016 at 14:12:54 UTC, Daniel Kozak wrote:

On Tuesday, 2 February 2016 at 13:57:54 UTC, Marc Schütz wrote:
On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz 
wrote:
The last call should work IMO, but it doesn't. I believe 
that's a compiler bug.


Filed:
https://issues.dlang.org/show_bug.cgi?id=15640


I would say it is not a bug
test!A(new B(), new C()); // works
which is what I expected


if you mix ints and floats, the common type is deduced 
correctly:


this is a bug for me :). I do not like this. I am ok with (u)byte 
to int conversion and similar, but mixing float and integral 
types does not seems to be OK.


Re: Variadic template parameters T... bounding

2016-02-02 Thread Voitech via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:

On Tuesday, 2 February 2016 at 13:20:33 UTC, Voitech wrote:

[...]


Two possible solutions... If you don't need to know the number 
of arguments at compile time, you can use normal variadic 
arguments:


[...]


Thank you I'll try that.


Re: Variadic template parameters T... bounding

2016-02-02 Thread Marc Schütz via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 14:55:42 UTC, Daniel Kozak wrote:

On Tuesday, 2 February 2016 at 14:47:43 UTC, Marc Schütz wrote:
if you mix ints and floats, the common type is deduced 
correctly:


this is a bug for me :). I do not like this. I am ok with 
(u)byte to int conversion and similar, but mixing float and 
integral types does not seems to be OK.


I see. But it's also consistent with array type deduction 
elsewhere:


auto a = [1, 2.5];
pragma(msg, typeof(a));  // double[]

... and more importantly:

class A { }
class B : A { }
class C : A { }
auto a = [new A(), new B()];
pragma(msg, typeof(a));  // A[]


Re: Variadic template parameters T... bounding

2016-02-02 Thread Marc Schütz via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 14:12:54 UTC, Daniel Kozak wrote:

On Tuesday, 2 February 2016 at 13:57:54 UTC, Marc Schütz wrote:

On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
The last call should work IMO, but it doesn't. I believe 
that's a compiler bug.


Filed:
https://issues.dlang.org/show_bug.cgi?id=15640


I would say it is not a bug
test!A(new B(), new C()); // works
which is what I expected


The bug is that `T` is not automatically inferred to be `A`. 
That's not a restriction of type inference in general: if you mix 
ints and floats, the common type is deduced correctly, just not 
for classes.


Variadic template parameters T... bounding

2016-02-02 Thread Voitech via Digitalmars-d-learn
Hi, Is it possible to bound T... in template with some type ? For 
single Parameter declaration it can be done by T:SomeType but 
variadics does not seems to have that possibility ?

Cheers


Re: Variadic template parameters T... bounding

2016-02-02 Thread Daniel Kozak via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 13:20:33 UTC, Voitech wrote:
Hi, Is it possible to bound T... in template with some type ? 
For single Parameter declaration it can be done by T:SomeType 
but variadics does not seems to have that possibility ?

Cheers


import std.stdio;
import std.meta: allSatisfy;
import std.traits;

void some(T...)(T Args) if (allSatisfy!(isIntegral,T)) {
writeln(Args);
}

void main()
{
some(1);
some(1,2,3);
some(1,2,3.0); // error
}


Re: Variadic template parameters T... bounding

2016-02-02 Thread Marc Schütz via Digitalmars-d-learn

On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
The last call should work IMO, but it doesn't. I believe that's 
a compiler bug.


Filed:
https://issues.dlang.org/show_bug.cgi?id=15640


Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Jay Norwood via Digitalmars-d-learn

On Monday, 11 January 2016 at 00:50:37 UTC, Ilya Yaroshenko wrote:
I will add such function. But it is not safe to do so (Slice 
can have strides not equal to 1). So it is like a hack ([0, 
0, 0])[0 .. ret.elementsCount]).


Have you made comparison between my and yours parallel versions?
https://github.com/9il/examples/blob/parallel/image_processing/median-filter/source/app.d
-- Ilya


Thanks.  No, I haven't studied it previously, but I see how you 
used the 'hack' in your code, and it works out to the statement 
below in my case.


medians[i] = median(vec, ([task,0])[0 .. bigd]);

which compiled.  It ran in the faster time without the .array 
copying.

parallel time medians msec:87

That 'hack' seems to be related to the third from below.
https://dlang.org/spec/arrays.html
b = a;
b = a[];
b = a[0 .. a.length];



Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Jay Norwood via Digitalmars-d-learn

On Sunday, 10 January 2016 at 22:23:18 UTC, Ilya Yaroshenko wrote:

Could you please provide full code and error (git gists)? -- 
Ilya


ok, thanks.
I'm building with DMD32 D Compiler v2.069.2 on Win32.  The 
dub.json is included.


https://gist.github.com/jnorwood/affd05b69795c20989a3



Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Sunday, 10 January 2016 at 23:24:24 UTC, Jay Norwood wrote:
On Sunday, 10 January 2016 at 22:23:18 UTC, Ilya Yaroshenko 
wrote:


Could you please provide full code and error (git gists)? -- 
Ilya


ok, thanks.
I'm building with DMD32 D Compiler v2.069.2 on Win32.  The 
dub.json is included.


https://gist.github.com/jnorwood/affd05b69795c20989a3


Just use normal arrays for buffer (median accepts array on second 
argument for optimisation reasons).


BTW, dip80-ndslice moved to http://code.dlang.org/packages/mir
-- Ilya


Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Jay Norwood via Digitalmars-d-learn

On Sunday, 10 January 2016 at 23:31:47 UTC, Ilya Yaroshenko wrote:
Just use normal arrays for buffer (median accepts array on 
second argument for optimisation reasons).


ok, I think I see. I created a slice(numTasks, bigd) over an 
allocated double[] dbuf, but slb[task] will be returning some 
struct instead of the double[] that i need in this case.


If I add .array to the Slice, it does compile, and executes, but 
slower than using the buffer directly.


medians[i] = median(vec, slb[task].array);
parallel time medians msec:113

original version using the computed slice of the original 
allocated dbuf.

medians[i] = median(vec,dbuf[j .. k]);
parallel time medians msec:85

The .array appears to make a copy. Is there some other call in 
ndslice to return the double[] slice of the original array?




Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Monday, 11 January 2016 at 00:39:04 UTC, Jay Norwood wrote:
On Sunday, 10 January 2016 at 23:31:47 UTC, Ilya Yaroshenko 
wrote:
Just use normal arrays for buffer (median accepts array on 
second argument for optimisation reasons).


ok, I think I see. I created a slice(numTasks, bigd) over an 
allocated double[] dbuf, but slb[task] will be returning some 
struct instead of the double[] that i need in this case.


If I add .array to the Slice, it does compile, and executes, 
but slower than using the buffer directly.


medians[i] = median(vec, slb[task].array);
parallel time medians msec:113

original version using the computed slice of the original 
allocated dbuf.

medians[i] = median(vec,dbuf[j .. k]);
parallel time medians msec:85

The .array appears to make a copy. Is there some other call in 
ndslice to return the double[] slice of the original array?


I will add such function. But it is not safe to do so (Slice can 
have strides not equal to 1). So it is like a hack ([0, 0, 
0])[0 .. ret.elementsCount]).


Have you made comparison between my and yours parallel versions?
https://github.com/9il/examples/blob/parallel/image_processing/median-filter/source/app.d
-- Ilya



ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Jay Norwood via Digitalmars-d-learn
I cut this median template from Jack Stouffer's article and was 
attempting to use it in  a parallel function.  As shown, it 
builds and execute correctly, but it failed to compile if I 
attempting to use

medians[i] = median(vec,slb[task]);

in place of the
medians[i] = median(vec,dbuf[j .. k]);

Is there a cast needed?


import std.array : array;
import std.algorithm;
import std.datetime;
import std.conv : to;
import std.stdio;
import std.experimental.ndslice;

shared double[] medians;
double[] data;
shared double[] dbuf;
int numTasks;
const int smalld = 1000;
const int bigd = 10_000;
const int fulld = bigd*smalld;

/**
Params:
r = input range
buf = buffer with length no less than the number of elements in 
`r`

Returns:
median value over the range `r`
*/
T median(Range, T)(Range r, T[] buf)
{
import std.algorithm.sorting: sort;

size_t n;

foreach (e; r) {
buf[n++] = e;
}

buf[0 .. n].sort();
immutable m = n >> 1;
return n & 1 ? buf[m] : cast(T)((buf[m - 1] + buf[m]) / 2);
}


void f3() {
import std.parallelism;
auto sl = data.sliced(smalld,bigd);
auto slb = dbuf.sliced(numTasks,bigd);
foreach(i,vec; parallel(sl)){
int task = taskPool.workerIndex;
int j = task*bigd;
int k = j+bigd;
medians[i] = median(vec,dbuf[j .. k]);
}
}


void main() {
import std.parallelism;
numTasks = taskPool.size+1;
data = new double[fulld];
dbuf = new double[bigd*numTasks];
medians = new double[smalld];

for(int i=0;i

Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Sunday, 10 January 2016 at 22:00:20 UTC, Jay Norwood wrote:
I cut this median template from Jack Stouffer's article and was 
attempting to use it in  a parallel function.  As shown, it 
builds and execute correctly, but it failed to compile if I 
attempting to use

medians[i] = median(vec,slb[task]);

[...]


Could you please provide full code and error (git gists)? -- Ilya


Re: ndslice, using a slice in place of T[] in template parameters

2016-01-10 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Sunday, 10 January 2016 at 23:24:24 UTC, Jay Norwood wrote:
On Sunday, 10 January 2016 at 22:23:18 UTC, Ilya Yaroshenko 
wrote:


Could you please provide full code and error (git gists)? -- 
Ilya


ok, thanks.
I'm building with DMD32 D Compiler v2.069.2 on Win32.  The 
dub.json is included.


https://gist.github.com/jnorwood/affd05b69795c20989a3


I have create parallel test to (it requires mir v0.10.0-beta )
https://github.com/9il/examples/blob/parallel/image_processing/median-filter/source/app.d
Could you please create a benchmark with default values of nc & 
nc for single thread app, your parallel version, and my.
My version has some additional overhead and I am interesting if 
it is significant.

-- Ilya


Re: Template Parameters in Struct Member Functions

2015-08-22 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 22 August 2015 at 16:49:26 UTC, DarthCthulhu wrote:
I'm having difficulty understanding how templates operate as 
function parameters.


Say I have this:

struct ArrayTest {

void arrayTest(T) (T arrayT) {

writeln(arrayT);
}
}

unittest {

ArrayTest test;

float farray[] = [
0.5f,  0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f,  0.5f, 0.0f
];

test.arrayTest(farray);

}

Everything works peachy as expected. But as soon as I add 
another parameter to the arrayTest function like so (and 
changing the unit test to match):


void arrayTest(T, int passing) (T arrayT) { ... }

I get 'cannot deduce function from argument types' errors.

Specifically stating the type of the function doesn't seem to 
help:


test.arrayTest(float [])(farray, 1);


test.arrayTest!(float, 1)(farray);



Re: Template Parameters in Struct Member Functions

2015-08-22 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 22 August 2015 at 17:08:36 UTC, Mike Parker wrote:

void arrayTest(T, int passing) (T arrayT) { ... }

I get 'cannot deduce function from argument types' errors.

Specifically stating the type of the function doesn't seem to 
help:


test.arrayTest(float [])(farray, 1);


test.arrayTest!(float, 1)(farray);


Sorry, that should be:

test.arrayTest!(float[], 1)(farray);

In your template declaration, you have declared two template 
parameters, T and passing, and one function parameter, arrayT. It 
is equivalent to:


template arrayTest(T, int passing) {
void arrayTest(T arrayT) {...}
}

To call the function, you have to explicitly instantiate the 
template with the instantiation operator (which is !) and give it 
two arguments as template parameters in the first pair of 
parentheses, then you have to give it one function argument in 
the second pair of parentheses. The template parameters are 
compile-time arguments, the function parameter is runtime.


With this form:

void arrayTest(T)(T arrayT) {...}

There is no need for the explicit instantiation. The compiler is 
able to deduce what T should be since it has all the information 
it needs, so you can call it like:


test.arrayTest(foo);



Template Parameters in Struct Member Functions

2015-08-22 Thread DarthCthulhu via Digitalmars-d-learn
I'm having difficulty understanding how templates operate as 
function parameters.


Say I have this:

struct ArrayTest {

void arrayTest(T) (T arrayT) {

writeln(arrayT);
}
}

unittest {

ArrayTest test;

float farray[] = [
0.5f,  0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f,  0.5f, 0.0f
];

test.arrayTest(farray);

}

Everything works peachy as expected. But as soon as I add another 
parameter to the arrayTest function like so (and changing the 
unit test to match):


void arrayTest(T, int passing) (T arrayT) { ... }

I get 'cannot deduce function from argument types' errors.

Specifically stating the type of the function doesn't seem to 
help:


test.arrayTest(float [])(farray, 1);

There must be a way to mix template and non-template parameters, 
right? What am I missing here?


In addition, as I understand it, one can restrict the type of 
parameter a template can use. So if I only wanted arrays as the 
function name indicates, I should be able to do this:


void arrayTest(T : T[]) (T arrayT) { ... }

But that also doesn't seem to work.


Re: Is there a way to get the types of all template parameters?

2015-06-04 Thread Meta via Digitalmars-d-learn

On Thursday, 4 June 2015 at 13:38:20 UTC, Atila Neves wrote:
For regular runtime parameters, there's ParameterTypeTuple. How 
would I write an equivalent template for template parameters? 
i.e.


void fun(Foo foo, Bar bar)() {}

alias types = CtParameterTypeTuple!fun; //TypeTuple!(Foo, 
Bar)


I've tried but my is expression kung fu was weak.

Atila


There is http://dlang.org/phobos/std_traits.html#TemplateArgsOf, 
but it only

works with an instantiated template.


Re: Structs as template parameters: weird error message

2015-04-02 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 2 April 2015 at 23:12:25 UTC, biozic wrote:

The code below doesn't compile. Why this error message?
---
struct Item {
int i;
}

struct Params {
Item* item;

this(int i) {
item = new Item(i);  // line 9
}
}

struct Foo(Params params) {}

enum foo = Foo!(Params(1));
---

test.d(9): Error: Item(1) is not an lvalue


this doesn't work because struct Foo is parameterised by in 
instance of Params. (like if you were implementing a fixed size 
array: struct FixedSizeArray(size_t len) {...}. here 
FixedSizeArray is parameterised by in instance of a size_t).


Item is a pointer in Params and thus if it were to compile the 
compiler would need to know the value returned by `new`at compile 
time.


There are two ways to get that to compile change `Item* item;` to 
`Item item;` or change `item = new Item(1);` to `item = null;`


tl;dr you can't have r-value (pointers) in instance template 
parameter lists.
i.e. struct foo(my_reference_type_or_type_containg_pointers 
instance) { ... }


Structs as template parameters: weird error message

2015-04-02 Thread biozic via Digitalmars-d-learn

The code below doesn't compile. Why this error message?
---
struct Item {
int i;
}

struct Params {
Item* item;

this(int i) {
item = new Item(i);  // line 9
}
}

struct Foo(Params params) {}

enum foo = Foo!(Params(1));
---

test.d(9): Error: Item(1) is not an lvalue


expand variadic template parameters

2015-03-10 Thread André

Hi,

in this minified example I try to expand the variadic parmaters of
foo to bar:

import std.typecons;

void foo(T ...)(T args)
{
 bar(args.expand);
}

void bar(int i, string s){}

void main()
{
foo(1, a);
}

I got the syntax error: no property 'expand' for type '(int,
string)'
I understand args is a TypeTuple and therefore expand is not
working.
Is there a simple way to get it working?

Kind regards
André


Re: expand variadic template parameters

2015-03-10 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 10 March 2015 at 19:11:22 UTC, André wrote:

Is there a simple way to get it working?


The simplest: just write `bar(args);` - the variadic arguments 
will automatically expand.


Re: expand variadic template parameters

2015-03-10 Thread ketmar via Digitalmars-d-learn
On Tue, 10 Mar 2015 19:11:21 +, André wrote:

 Hi,
 
 in this minified example I try to expand the variadic parmaters of foo
 to bar:
 
 import std.typecons;
 
 void foo(T ...)(T args)
 {
   bar(args.expand);
 }
 
 void bar(int i, string s){}
 
 void main()
 {
   foo(1, a);
 }
 
 I got the syntax error: no property 'expand' for type '(int, string)'
 I understand args is a TypeTuple and therefore expand is not working.
 Is there a simple way to get it working?

sure. just remove `.expand`. ;-)

  void foo(T...) (T args) {
bar(args);
  }


signature.asc
Description: PGP signature


  1   2   >