www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get template parameter value

reply rumbu <rumbu rumbu.ro> writes:
Having a template:

struct SomeStruct(int size)
{

}

Is there any language trait returning the value of size template 
parameter for the template instantiation SomeStruct!10?

In fact, I'm interested in an eponymous template to test if some 
type is a template inttantation for SomeStruct(int size).

template isSomeStruct(T)
{
   enum isSomeStruct = ?
}

template getStructSize(T) if (isSomeStruct!T)
{
   enum getStructSize = ?
}


I know that I can do something like this:

struct SomeStruct(int size)
{
    enum internalSize = size;
}

template isSomeStruct(T)
{
   enum isSomeStruct = is (typeof(T.internalSize): int);
}

template getStructSize(T) if (isSomeStruct!T)
{
   enum getStructSize = T.internalSize;
}

but I wonder that if it's not another simple and safe way. This 
approach is not safe because there is a risk to have 
SomeOtherStruct(int size) defined with similar semantics.

Thanks.
Sep 29 2015
next sibling parent reply Andrea Fontana <nospam example.com> writes:
On Tuesday, 29 September 2015 at 07:50:42 UTC, rumbu wrote:
 Having a template:

 struct SomeStruct(int size)
 {

 }

 Is there any language trait returning the value of size 
 template parameter for the template instantiation SomeStruct!10?
Something like this is ok? struct SomeStruct(int size) { enum structSize = size; } template isSomeStruct(alias S) { void check(alias T)(SomeStruct!T val) { } enum isSomeStruct = __traits(compiles, check(S)); } template getStructSize(alias S) if (isSomeStruct!S) { enum getStructSize = S.structSize; } void main() { import std.stdio; SomeStruct!10 test; writeln(isSomeStruct!test); writeln(getStructSize!test); }
Sep 29 2015
parent Andrea Fontana <nospam example.com> writes:
On Tuesday, 29 September 2015 at 08:44:03 UTC, Andrea Fontana 
wrote:
 On Tuesday, 29 September 2015 at 07:50:42 UTC, rumbu wrote:
 Having a template:

 struct SomeStruct(int size)
 {

 }

 Is there any language trait returning the value of size 
 template parameter for the template instantiation 
 SomeStruct!10?
Something like this is ok? struct SomeStruct(int size) { enum structSize = size; } template isSomeStruct(alias S) { void check(alias T)(SomeStruct!T val) { } enum isSomeStruct = __traits(compiles, check(S)); } template getStructSize(alias S) if (isSomeStruct!S) { enum getStructSize = S.structSize; } void main() { import std.stdio; SomeStruct!10 test; writeln(isSomeStruct!test); writeln(getStructSize!test); }
You can also write void check(alias T) as void check(int T), of course.
Sep 29 2015
prev sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Tuesday, 29 September 2015 at 07:50:42 UTC, rumbu wrote:
 Having a template:

 struct SomeStruct(int size)
 {

 }

 Is there any language trait returning the value of size 
 template parameter for the template instantiation SomeStruct!10?
This should do it (untested): template SomeStructSize(T) { static if(is(T == SomeStruct!n, n)) enum SomeStructSize = n; else static assert(false, T.stringof ~ " is not an instance of SomeStruct"); } Welcome to the weird and wonderful work of http://dlang.org/expression.html#IsExpression
Sep 29 2015
parent reply Kagamin <spam here.lot> writes:
On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin wrote:
 Welcome to the weird and wonderful work of  
 http://dlang.org/expression.html#IsExpression
No, use template pattern matching instead: struct A(int s){} template B(T:A!s, int s){ enum B=s; } static assert(B!(A!4)==4);
Sep 29 2015
next sibling parent John Colvin <john.loughran.colvin gmail.com> writes:
On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
 On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin 
 wrote:
 Welcome to the weird and wonderful work of  
 http://dlang.org/expression.html#IsExpression
No, use template pattern matching instead: struct A(int s){} template B(T:A!s, int s){ enum B=s; } static assert(B!(A!4)==4);
For some reason I never think of template pattern matching. Not my favourite feature, although it's probably just the ':' that bothers me, I always think of implicit convertibility like in is(T : Q). Anyway, you're right, it makes for shorter, neater code in simple cases (the static if version is equivalent if you just add a template constraint to it).
Sep 29 2015
prev sibling parent reply rumbu <rumbu rumbu.ro> writes:
On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
 On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin 
 wrote:
 Welcome to the weird and wonderful work of  
 http://dlang.org/expression.html#IsExpression
No, use template pattern matching instead: struct A(int s){} template B(T:A!s, int s){ enum B=s; } static assert(B!(A!4)==4);
Thank you, this is perfect.
Sep 29 2015
parent Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On 09/29/15 12:13, rumbu via Digitalmars-d-learn wrote:
 On Tuesday, 29 September 2015 at 09:53:39 UTC, Kagamin wrote:
 On Tuesday, 29 September 2015 at 09:11:15 UTC, John Colvin wrote:
 Welcome to the weird and wonderful work of 
http://dlang.org/expression.html#IsExpression
No, use template pattern matching instead: struct A(int s){} template B(T:A!s, int s){ enum B=s; } static assert(B!(A!4)==4);
Thank you, this is perfect.
There's always room for improvement... ;) enum B(T:A!s, int s) = s; artur
Sep 29 2015