Re: Multiple template alias parameters

2015-05-09 Thread Artur Skawina via Digitalmars-d-learn
On 05/08/15 23:56, Brian Schott via Digitalmars-d-learn wrote:
> On Friday, 8 May 2015 at 12:44:31 UTC, Artur Skawina wrote:
>> On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
>>> The problem occurs when I want to register multiple modules to scan for 
>>> functions. The grammar does not allow this syntax:
>>>
>>> ```
>>> template (alias Modules ...) {
>>> ...
>>> ```
>>
>> The grammar allows omitting the 'alias' keyword.
>>
>> artur
> 
> alias parameters are different from normal template parameters. They're not 
> necessary for this problem, but they are for others.

I was trying to hint at the fact that D's template tuple parameters
already have the required magic.
Hence, the trailing '...' makes that 'alias' unnecessary.

> As an example:
> 
> 
> void traceVar(alias var, size_t line = __LINE__, string file = __FILE__)()
> {
> import std.stdio: stderr;
> stderr.writeln(file, "(", line, ") ", var.stringof, ": ", var);
> }
> 
> This allows you to print a variable's name and value by only passing the 
> variable once as a template argument. Allowing "template Tem(alias Args ...)" 
> syntax would let me trace multiple variables at once.
> 
> If you omit "alias", "var.stringof" evaluates to "var" instead of its name in 
> the calling context.

   template traceVar(VARS...) {
  void traceVar(size_t line = __LINE__, string file = __FILE__)() {
 import std.stdio: stderr;
 foreach (I, ref var; VARS)
stderr.writeln(file, "(", line, ") ", VARS[I].stringof, ": ", var);
  }
   }

artur



Re: Multiple template alias parameters

2015-05-08 Thread anonymous via Digitalmars-d-learn

On Friday, 8 May 2015 at 22:29:28 UTC, Biotronic wrote:
Sadly, the ... syntax precludes the use of __LINE__ and 
__FILE__. :(


You can put them in the runtime parameters:


void traceVars(alias T, U...)(size_t line = __LINE__, string file 
= __FILE__) {

import std.stdio : writeln;
writeln(file, "(", line, ") ", T.stringof, ": ", T);
static if (U.length > 0) {
traceVars!(U)(line, file);
}
}


Or you can nest two templates:


template traceVars(alias T, U...) {
void traceVars(size_t line = __LINE__, string file = 
__FILE__)() {

import std.stdio : writeln;
writeln(file, "(", line, ") ", T.stringof, ": ", T);
static if (U.length > 0) {
alias t = .traceVars!U;
t!(line, file);
}
}
}



Re: Multiple template alias parameters

2015-05-08 Thread Biotronic via Digitalmars-d-learn

On Friday, 8 May 2015 at 21:56:56 UTC, Brian Schott wrote:
Allowing "template Tem(alias Args ...)" syntax would let me 
trace multiple variables at once.


Actually, this already works:

void traceVars(alias T, U...)() {
import std.stdio : writeln;
writeln(T.stringof, ": ", T);
static if (U.length > 0) {
traceVars!(U);
}
}

void main(string[] args) {
auto argslength = args.length;
auto args0 = args[0];

traceVars!(args, argslength, args0);
}

Sadly, the ... syntax precludes the use of __LINE__ and __FILE__. 
:(


Re: Multiple template alias parameters

2015-05-08 Thread Brian Schott via Digitalmars-d-learn

On Friday, 8 May 2015 at 12:44:31 UTC, Artur Skawina wrote:

On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
The problem occurs when I want to register multiple modules to 
scan for functions. The grammar does not allow this syntax:


```
template (alias Modules ...) {
...
```


The grammar allows omitting the 'alias' keyword.

artur


alias parameters are different from normal template parameters. 
They're not necessary for this problem, but they are for others.


As an example:


void traceVar(alias var, size_t line = __LINE__, string file = 
__FILE__)()

{
import std.stdio: stderr;
stderr.writeln(file, "(", line, ") ", var.stringof, ": ", var);
}

This allows you to print a variable's name and value by only 
passing the variable once as a template argument. Allowing 
"template Tem(alias Args ...)" syntax would let me trace multiple 
variables at once.


If you omit "alias", "var.stringof" evaluates to "var" instead of 
its name in the calling context.


Re: Multiple template alias parameters

2015-05-08 Thread Brian Schott via Digitalmars-d-learn

On Friday, 8 May 2015 at 02:03:17 UTC, Rikki Cattermole wrote:

Can you not use something like this?


Yes. I was getting confused by another problem that I had just 
worked on before this one.


Re: Multiple template alias parameters

2015-05-08 Thread Artur Skawina via Digitalmars-d-learn
On 05/08/15 03:53, Brian Schott via Digitalmars-d-learn wrote:
> The problem occurs when I want to register multiple modules to scan for 
> functions. The grammar does not allow this syntax:
> 
> ```
> template (alias Modules ...) {
> ...
> ```

The grammar allows omitting the 'alias' keyword.

artur


Re: Multiple template alias parameters

2015-05-07 Thread Rikki Cattermole via Digitalmars-d-learn

On 8/05/2015 1:53 p.m., Brian Schott wrote:

I have some code that automatically wires up control flow based on
annotations. Use of this code looks something like this:

```
import some_package.some_module;
void main(string[] args) {
doMagicStuff!(some_package.some_module)(args);
}
```

All of this works and everything is happy (Except the implementation,
which is ugly because Phobos is missing a lot of functionality, but
that's not the topic I'm discussing here).

The problem occurs when I want to register multiple modules to scan for
functions. The grammar does not allow this syntax:

```
template (alias Modules ...) {
...
```

Any ideas (besides "STRING MIXINS EVERYWHERE")?



Can you not use something like this?

import std.stdio;
import std.traits;

void main() {
func!(std.stdio, std.traits)(); 
}


void func(T...)() {
pragma(msg, T.stringof);
pragma(msg, fullyQualifiedName!(T[0]));

}


Multiple template alias parameters

2015-05-07 Thread Brian Schott via Digitalmars-d-learn
I have some code that automatically wires up control flow based 
on annotations. Use of this code looks something like this:


```
import some_package.some_module;
void main(string[] args) {
   doMagicStuff!(some_package.some_module)(args);
}
```

All of this works and everything is happy (Except the 
implementation, which is ugly because Phobos is missing a lot of 
functionality, but that's not the topic I'm discussing here).


The problem occurs when I want to register multiple modules to 
scan for functions. The grammar does not allow this syntax:


```
template (alias Modules ...) {
...
```

Any ideas (besides "STRING MIXINS EVERYWHERE")?



Re: Template alias parameters to local variables

2014-09-17 Thread via Digitalmars-d-learn

On Saturday, 13 September 2014 at 11:34:01 UTC, Marc Schütz wrote:

Consider the following code:

  alias Sink = scope void delegate(const(char)[]);

  private template generateAliases(int __i, __vars...) {
  import std.conv : to;

  static if(__i < __vars.length)
  enum generateAliases = "alias " ~
__vars[__i].stringof ~ " =
   __vars[" ~ __i.to!string ~ "];\n" ~
   generateAliases!(__i+1, __vars);
  else
  enum generateAliases = "";
  }

  template render(string __tpl, __vars...) {
  void render(Sink sink) {
  static void render2(string __tpl2, 
__vars2...)(Sink

sink2 = sink) {
  .render!(__tpl2, __vars2)(sink2);
  }
  void render3(string __tpl2, __vars2...)(Sink 
sink2 =

sink) {
  .render!(__tpl2, __vars2)(sink2);
  }

  alias __sink = sink;

  mixin(generateAliases!(0, __vars));
  //mixin(generateRenderer(__tpl));

  alias x = __vars[0];
  alias y = __vars[1];

  render2!("...", x, y);// ERROR
  render3!("...", x, y);// ERROR
  }
  }

  void main() {
  import std.stdio;
  int a, b;
  render!("...", a, b)(s => write(s));
  }

Inside the `render` function, which takes a string and several
variables as template parameters, as well as a delegate as
runtime parameter, I want another function to be available, 
which

should again accept a string and several aliases (including some
that `render` previously received as aliases). At the same time,
the function should implicitly pick up the sink that has been
passed to `render`. I'm trying to slightly different
implementations, `render2` and `render3`. They both produce
compile errors:

render2:
test.d(16): Error: static function test.main.render!("...", a,
b).render2 cannot access frame of function D main
test.d(29): Error: static function test.main.render!("...", a,
b).render2 cannot access frame of function D main

render3:
test.d(30): Error: template instance render3!("...", a, b) 
cannot

use local 'a' as parameter to non-global template render3(string
__tpl2, __vars2...)(Sink sink2 = sink)

I would prefer `render2`, because it is static and thus doesn't
need to allocate a context for the sink. Indeed, it used to
work before this issue was fixed:
https://issues.dlang.org/show_bug.cgi?id=11946
https://github.com/D-Programming-Language/dmd/pull/3884

Now, has this fix gone too far? On first glance, the `render2`
error message seems to make sense, but why doesn't the same 
error

occur for `render`?

However, why doesn't at least `render3` work? It's strange local
templates cannot accept local variables as aliases...

Alternatively, does anyone know of another way to achieve what I
want?


Anyone an idea?


Re: Template alias parameters to local variables

2014-09-14 Thread via Digitalmars-d-learn

On Sunday, 14 September 2014 at 09:29:16 UTC, Kagamin wrote:

Doesn't this cause infinite recursion?


No, because the inner templates are instantiated with different 
first template parameters. Even if all template parameters were 
the same, it would only be a runtime recursion.


Re: Template alias parameters to local variables

2014-09-14 Thread Kagamin via Digitalmars-d-learn

Doesn't this cause infinite recursion?


Template alias parameters to local variables

2014-09-13 Thread via Digitalmars-d-learn

Consider the following code:

  alias Sink = scope void delegate(const(char)[]);

  private template generateAliases(int __i, __vars...) {
  import std.conv : to;

  static if(__i < __vars.length)
  enum generateAliases = "alias " ~
__vars[__i].stringof ~ " =
   __vars[" ~ __i.to!string ~ "];\n" ~
   generateAliases!(__i+1, __vars);
  else
  enum generateAliases = "";
  }

  template render(string __tpl, __vars...) {
  void render(Sink sink) {
  static void render2(string __tpl2, __vars2...)(Sink
sink2 = sink) {
  .render!(__tpl2, __vars2)(sink2);
  }
  void render3(string __tpl2, __vars2...)(Sink sink2 =
sink) {
  .render!(__tpl2, __vars2)(sink2);
  }

  alias __sink = sink;

  mixin(generateAliases!(0, __vars));
  //mixin(generateRenderer(__tpl));

  alias x = __vars[0];
  alias y = __vars[1];

  render2!("...", x, y);// ERROR
  render3!("...", x, y);// ERROR
  }
  }

  void main() {
  import std.stdio;
  int a, b;
  render!("...", a, b)(s => write(s));
  }

Inside the `render` function, which takes a string and several
variables as template parameters, as well as a delegate as
runtime parameter, I want another function to be available, which
should again accept a string and several aliases (including some
that `render` previously received as aliases). At the same time,
the function should implicitly pick up the sink that has been
passed to `render`. I'm trying to slightly different
implementations, `render2` and `render3`. They both produce
compile errors:

render2:
test.d(16): Error: static function test.main.render!("...", a,
b).render2 cannot access frame of function D main
test.d(29): Error: static function test.main.render!("...", a,
b).render2 cannot access frame of function D main

render3:
test.d(30): Error: template instance render3!("...", a, b) cannot
use local 'a' as parameter to non-global template render3(string
__tpl2, __vars2...)(Sink sink2 = sink)

I would prefer `render2`, because it is static and thus doesn't
need to allocate a context for the sink. Indeed, it used to
work before this issue was fixed:
https://issues.dlang.org/show_bug.cgi?id=11946
https://github.com/D-Programming-Language/dmd/pull/3884

Now, has this fix gone too far? On first glance, the `render2`
error message seems to make sense, but why doesn't the same error
occur for `render`?

However, why doesn't at least `render3` work? It's strange local
templates cannot accept local variables as aliases...

Alternatively, does anyone know of another way to achieve what I
want?


Re: template alias parameters

2011-04-06 Thread Jesse Phillips
enuhtac Wrote:

> Hi,
> 
> I'm playing around with template alias parameters. At the moment I'm
> considering the following simple code:
> 
> struct A
> {};
> 
> struct B( T )
> {
> T t;
> };
> 
> struct C( alias T )
> {
> T t;
> };
> 
> void main()
> {
> B!A a;
> C!A b;
> }
> 
> What exactly is the difference between a and b? Both seem to do the same

No difference.

> thing but obviously there is a difference as I cannot instanciate C with
> buildin types as template parameter ("C!int c" results in "Error:
> template instance C!(int) does not match template declaration C(alias T)").

I'm going to take a guess at the issue here. alias parameters are supposed to 
bind to a symbol. Types aren't symbols, they aren't things that will have an 
address during runtime. I'm not exactly sure why the struct is excepted.
 
> The other question is: is there a possibility to distinguinish between
> different "things" passed to a template alias paramter? - Like "isType",
> "isVariable", "isLiteral", "isTemplate" ...
> 
> enuhtac

There isn't a distinction for literal vs variable. I'm pretty sure. As 
mentioned you don't pass types to alias. And you probably wouldn't write a 
template that accepts a template or a variable.

As it is a symbol you do get to use typeof() and the likes on it.


template alias parameters

2011-04-06 Thread enuhtac
Hi,

I'm playing around with template alias parameters. At the moment I'm
considering the following simple code:

struct A
{};

struct B( T )
{
T t;
};

struct C( alias T )
{
T t;
};

void main()
{
B!A a;
C!A b;
}

What exactly is the difference between a and b? Both seem to do the same
thing but obviously there is a difference as I cannot instanciate C with
buildin types as template parameter ("C!int c" results in "Error:
template instance C!(int) does not match template declaration C(alias T)").

The other question is: is there a possibility to distinguinish between
different "things" passed to a template alias paramter? - Like "isType",
"isVariable", "isLiteral", "isTemplate" ...

enuhtac


Re: Comparing template alias parameters

2010-12-13 Thread Simen kjaeraas

Simen kjaeraas  wrote:


Given an index structure like this:

struct Index( alias arr ) if ( is( typeof( arr ) t : U[], U ) ) {
 private size_t idx;
 @property pure nothrow size_t get( ) const {
 return idx;
 }
 alias get this;

 invariant( ) {
 assert( idx < arr.length );
 }

 this( size_t value ) {
 idx = value;
 }

 Index opAssign( size_t value ) {
 idx = value;
 return this;
 }
}

would it be possible to do something akin to this:

void foo( T )( T[] arr, Index!arr a ) {
}

void bar( ) {
 int[] a = [1,2,3];
 Index!a idx;
 foo( a, idx ); // ensures idx is a valid index for a
}


Somewhat trivial an application, as this could easily be tested
with an in clause, but imagine that ( arr is Index!(arr).arr )
has to be true.



Nobody? Meh.

--
Simen


Comparing template alias parameters

2010-12-10 Thread Simen kjaeraas

Given an index structure like this:

struct Index( alias arr ) if ( is( typeof( arr ) t : U[], U ) ) {
private size_t idx;
@property pure nothrow size_t get( ) const {
return idx;
}
alias get this;

invariant( ) {
assert( idx < arr.length );
}

this( size_t value ) {
idx = value;
}

Index opAssign( size_t value ) {
idx = value;
return this;
}
}

would it be possible to do something akin to this:

void foo( T )( T[] arr, Index!arr a ) {
}

void bar( ) {
int[] a = [1,2,3];
Index!a idx;
foo( a, idx ); // ensures idx is a valid index for a
}


Somewhat trivial an application, as this could easily be tested
with an in clause, but imagine that ( arr is Index!(arr).arr )
has to be true.


--
Simen