www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - alias type reduction

reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
This has probably been asked a million times.

given A(T1, T2)
alias A!(T1, int) A!(T1);

specifically,

http://dpaste.dzfl.pl/64025e0a

in that code, if I want to add a parameter to A, then at line 65 
I want the alias to represent that.

I am trying to hide away the "true"(as it is always true and used 
for other things the user doesn't care about).

class _A(T, _NestLevel) { }
alias _A!(T, true) A!(T) // <- does not work but essentially what 
I want


(or even better)

class A(T, _NestLevel) { }
alias A!(T, true) A!(T)

this way, I can instantiate A's without having to specify true 
everywhere. (which would liter the code with "true" tokens for no 
good reason)
Dec 13 2012
parent reply "anonymous" <anonymous example.com> writes:
On Thursday, 13 December 2012 at 09:29:46 UTC, js.mdnq wrote:
 class _A(T, _NestLevel) { }
 alias _A!(T, true) A!(T) // <- does not work but essentially 
 what I want
template A(T) { alias _A!(T, true) A; }
 (or even better)

 class A(T, _NestLevel) { }
 alias A!(T, true) A!(T)
class A(T, bool _NestLevel = true) {}
Dec 13 2012
next sibling parent "anonymous" <anonymous example.com> writes:
On Thursday, 13 December 2012 at 10:03:34 UTC, anonymous wrote:
 On Thursday, 13 December 2012 at 09:29:46 UTC, js.mdnq wrote:
 class _A(T, _NestLevel) { }
 alias _A!(T, true) A!(T) // <- does not work but essentially 
 what I want
template A(T) { alias _A!(T, true) A; }
 (or even better)

 class A(T, _NestLevel) { }
 alias A!(T, true) A!(T)
class A(T, bool _NestLevel = true) {}
For completeness' sake, this works too: class A(T, bool b) {} template A(T) { alias A!(T, true) A; }
Dec 13 2012
prev sibling parent reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Thursday, 13 December 2012 at 10:03:34 UTC, anonymous wrote:
 On Thursday, 13 December 2012 at 09:29:46 UTC, js.mdnq wrote:
 class _A(T, _NestLevel) { }
 alias _A!(T, true) A!(T) // <- does not work but essentially 
 what I want
template A(T) { alias _A!(T, true) A; }
 (or even better)

 class A(T, _NestLevel) { }
 alias A!(T, true) A!(T)
class A(T, bool _NestLevel = true) {}
yeah, I tried that and got errors, I guess it works now. I still can't use the same class name as the alias though because I get a recursion error. It's not a huge deal but would be nicer to not have to mangle the class names to get it to work. The template stuff didn't work or I wasn't using it correctly.
Dec 13 2012
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
 yeah, I tried that and got errors, I guess it works now. I still can't use
 the same class name as the alias though because I get a recursion error.
 It's not a huge deal but would be nicer to not have to mangle the class
 names to get it to work. The template stuff didn't work or I wasn't using
 it correctly.
What do you mean, 'mangle'? Using _ before the name? It seems to me you can use the same name: class A(T, bool condition) {} template A(T) { alias A!(T, true) A; } void main() { A!(int) a; }
Dec 13 2012
parent reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Thursday, 13 December 2012 at 22:16:00 UTC, Philippe Sigaud 
wrote:
 yeah, I tried that and got errors, I guess it works now. I 
 still can't use
 the same class name as the alias though because I get a 
 recursion error.
 It's not a huge deal but would be nicer to not have to mangle 
 the class
 names to get it to work. The template stuff didn't work or I 
 wasn't using
 it correctly.
What do you mean, 'mangle'? Using _ before the name?
Yes.
 It seems to me you can use the same name:

 class A(T, bool condition)
 {}

 template A(T)
 {
   alias A!(T, true) A;
 }

 void main()
 {
     A!(int) a;
 }
Ok, I'll try again. when I was doing it I would get circular referencing but maybe I did something wrong...
Dec 13 2012
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
 Ok, I'll try again. when I was doing it I would get circular referencing
 but maybe I did something wrong...
Another possibility is to use `.A`: the (.) prefix means the symbol is looked in the external scope, not inside the template. So the 2-params A is found. template A(T) { alias .A!(T, true) A; }
Dec 13 2012
parent reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Friday, 14 December 2012 at 05:54:33 UTC, Philippe Sigaud 
wrote:
 Ok, I'll try again. when I was doing it I would get circular 
 referencing
 but maybe I did something wrong...
Another possibility is to use `.A`: the (.) prefix means the symbol is looked in the external scope, not inside the template. So the 2-params A is found. template A(T) { alias .A!(T, true) A; }
I guess I'm being dense, I can't seem to get any of the "solutions" to work. If you don't mind, could you see if your solutions work on the following code: http://dpaste.dzfl.pl/64025e0a What I'm trying to do is "hide" the _NestLevel argument of the template(it should always be true). I can use alias directly as long as the class name is "mangled" but when I try to use templates I can't seem to get it to work. This is possibly because I want to design the code to work with a variable number of arguments(hence my asking for the number of arguments of a templated class in the other post). e.g., I want class A(..., bool _NestLevel = true) { } then A(...) a; to create an object. (note the _NestLevel is "hidden") If A has only one template argument, _NestLevel, then I want this to reduce to A a; Thanks.
Dec 14 2012
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
 If you don't mind, could you see if your solutions work on the following
 code:

 http://dpaste.dzfl.pl/64025e0a
What you're doing here is a bit different (AFAICT). _A is a template, not a 'real' class. So, it has no classinfo. The only real type here is the template instantiation you call A. Honestly, I have trouble reading your code, even though mine look much like yours. I really do not get what you're trying to do. Maybe I'm too tired. This is possibly because I want to design the code to work with a variable
 number of arguments(hence my asking for the number of arguments of a
 templated class in the other post).

 e.g., I want

 class A(..., bool _NestLevel = true) { }

 then

 A(...) a; to create an object. (note the _NestLevel is "hidden")

 If A has only one template argument, _NestLevel, then I want this to
 reduce to

 A a;

 Thanks.
You should try to use templated factory functions: auto makeA(..., bool _NestLevel = true) { return new A!(..., _NestLevel)(); }
Dec 15 2012
parent reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Saturday, 15 December 2012 at 22:21:21 UTC, Philippe Sigaud 
wrote:
 If you don't mind, could you see if your solutions work on the 
 following
 code:

 http://dpaste.dzfl.pl/64025e0a
What you're doing here is a bit different (AFAICT). _A is a template, not a 'real' class. So, it has no classinfo. The only real type here is the template instantiation you call A. Honestly, I have trouble reading your code, even though mine look much like yours. I really do not get what you're trying to do. Maybe I'm too tired.
I'm not sure what part of the code you don't understand but as a whole, the code simply makes using nested structs "cheaper" by calculating the "outer"parents location. To do this, unfortunately requires templating both classes. This, then, adds nonsense for the user to use those classes. I do not want them to see _NestLevel or _Offset. `mixin(StructNestType!("B", "b1"));` is basically the same as `B b1;`. It just ends up creating `B!(ofs) b1` so that b1 contains it's own offset into it the class so the parent can be found. If you wanted to hard code the offset you could simply do `B!(23) b1;` but that makes it hard to manage. So, all the template code and stuff is there to allow for automatic offset calculations. (The compiler could do all this behind the scenes and make it completely transparent(or near so)) In any case, the code works and I've written a more detailed post somewhere in http://forum.dlang.org/thread/ceyjrolnxatcdsnmufac forum.dlang.org if you care to know more. The real issue I'm having now is not having to mangle the names and hide the `_NestLevel` and `_Offset` dependencies. alias works for the case of one template argument to _A. Simply `alias _A!(true) A`. But when I have more than one such as `class _A(T1, bool)` I can't do `alias _A!(T1, true) A(T1)` analogous to the first case. Which, I guess, is why you guys decided to try to use templates, but I can't get it to work properly. Also, as I've mented, I'm trying to not use A instead of _A but I almost always get recursion issues. (if I try some of the suggestions other errors occur)
 This is possibly because I want to design the code to work with 
 a variable
 number of arguments(hence my asking for the number of 
 arguments of a
 templated class in the other post).

 e.g., I want

 class A(..., bool _NestLevel = true) { }

 then

 A(...) a; to create an object. (note the _NestLevel is 
 "hidden")

 If A has only one template argument, _NestLevel, then I want 
 this to
 reduce to

 A a;

 Thanks.
You should try to use templated factory functions: auto makeA(..., bool _NestLevel = true) { return new A!(..., _NestLevel)(); }
Ok, I'm not familiar with these, I've seen a lot of "weird" notation dealing with a variable number of template args(I think it's `T...`?) and such. I'll play around with it and hopefully get somewhere ;)
Dec 15 2012
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
 The real issue I'm having now is not having to mangle the names and hide
 the `_NestLevel` and `_Offset` dependencies.

 alias works for the case of one template argument to _A. Simply `alias
 _A!(true) A`. But when I have more than one such as `class _A(T1, bool)` I
 can't do `alias _A!(T1, true) A(T1)` analogous to the first case.
Because A(T1) would itself be a template, hence our proposal: template A(T1) { ... } You could also use overloads, as for functions: class A ( 3 args version) { ... } class A (2 args version) { ... } class A (1 arg ) { ... }
 You should try to use templated factory functions:

 auto makeA(..., bool _NestLevel = true)
 {
     return new A!(..., _NestLevel)();
 }
Ok, I'm not familiar with these, I've seen a lot of "weird" notation dealing with a variable number of template args(I think it's `T...`?)
and such. I'll play around with it and hopefully get somewhere ;)

Yes, Symbol... (three dots) is the template tuple parameter syntax. They
are heavily used and are one of the most useful parts of D templates. Docs
are here:

http://dlang.org/template.html#TemplateTupleParameter
http://dlang.org/tuple.html
http://dlang.org/variadic-function-templates.html
http://dlang.org/templates-revisited.html

They are a bit old (they were already there in 2008 when I began with D),
but still useful.

Also, I wrote a tutorial on templates with other people being kind enough
to put example code in it. You'll find it here:


https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf?raw=true
Dec 16 2012
parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Sunday, 16 December 2012 at 15:21:17 UTC, Philippe Sigaud
wrote:
 The real issue I'm having now is not having to mangle the 
 names and hide
 the `_NestLevel` and `_Offset` dependencies.

 alias works for the case of one template argument to _A. 
 Simply `alias
 _A!(true) A`. But when I have more than one such as `class 
 _A(T1, bool)` I
 can't do `alias _A!(T1, true) A(T1)` analogous to the first 
 case.
Because A(T1) would itself be a template, hence our proposal: template A(T1) { ... } You could also use overloads, as for functions: class A ( 3 args version) { ... } class A (2 args version) { ... } class A (1 arg ) { ... }
 You should try to use templated factory functions:

 auto makeA(..., bool _NestLevel = true)
 {
     return new A!(..., _NestLevel)();
 }
Ok, I'm not familiar with these, I've seen a lot of "weird" notation dealing with a variable number of template args(I think it's `T...`?)
and such. I'll play around with it and hopefully get somewhere ;)

 Yes, Symbol... (three dots) is the template tuple parameter 
 syntax. They
 are heavily used and are one of the most useful parts of D 
 templates. Docs
 are here:

 http://dlang.org/template.html#TemplateTupleParameter
 http://dlang.org/tuple.html
 http://dlang.org/variadic-function-templates.html
 http://dlang.org/templates-revisited.html

 They are a bit old (they were already there in 2008 when I 
 began with D),
 but still useful.

 Also, I wrote a tutorial on templates with other people being 
 kind enough
 to put example code in it. You'll find it here:


 https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf?raw=true
Thanks, I'll look into these. It's nice D has such features but it's a pain to find all the documentation to help get a grip on how to use it ;)
Dec 16 2012