www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get most D type from type

reply Hussien <SH glory.com> writes:
I am using Parameters and ReturnType which give me the "name" of 
the type used. e.g.,

int foo(SomeEnum)

will give SomeEnum and int for the type respectively.

What I need to do, is also get the D types that these use.

int is int, but SomeEnum is an enum.

Is there a traits function or some way to reduce the derived type 
to it's most primitive D type?

A specific class should give "class", some enum should give 
"enum", an interface "interface", a function should give 
"function", etc.
Mar 17
next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 17 March 2017 at 23:54:36 UTC, Hussien wrote:
 I am using Parameters and ReturnType which give me the "name" 
 of the type used. e.g.,

 int foo(SomeEnum)

 will give SomeEnum and int for the type respectively.

 What I need to do, is also get the D types that these use.

 int is int, but SomeEnum is an enum.

 Is there a traits function or some way to reduce the derived 
 type to it's most primitive D type?

 A specific class should give "class", some enum should give 
 "enum", an interface "interface", a function should give 
 "function", etc.
Parameters!foo[0] == SomeEnum SomeEnum == enum if some enum is SomeEnum : int { someValue } then static assert (is(Parameters!foo[0] == T, T : int)); will pass.
Mar 17
parent reply Hussien <SH glory.com> writes:
On Saturday, 18 March 2017 at 00:36:21 UTC, Nicholas Wilson wrote:
 On Friday, 17 March 2017 at 23:54:36 UTC, Hussien wrote:
 I am using Parameters and ReturnType which give me the "name" 
 of the type used. e.g.,

 int foo(SomeEnum)

 will give SomeEnum and int for the type respectively.

 What I need to do, is also get the D types that these use.

 int is int, but SomeEnum is an enum.

 Is there a traits function or some way to reduce the derived 
 type to it's most primitive D type?

 A specific class should give "class", some enum should give 
 "enum", an interface "interface", a function should give 
 "function", etc.
Parameters!foo[0] == SomeEnum SomeEnum == enum if some enum is SomeEnum : int { someValue } then static assert (is(Parameters!foo[0] == T, T : int)); will pass.
I need the general solution. One that simply returns the type. None of what you said helps...
Mar 17
parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 18 March 2017 at 02:23:01 UTC, Hussien wrote:

 I need the general solution. One that simply returns the type. 
 None of what you      said helps...
string dtype(T)() { static if(is(T == enum)) return "enum"; else static if(is(T == class)) return "class"; else static if(is(T == struct)) return "struct"; // etc... } void main() { struct Foo {}; assert(dtype!Foo == "struct"); }
Mar 17
parent reply Hussien <SH glory.com> writes:
On Saturday, 18 March 2017 at 05:15:07 UTC, Mike Parker wrote:
 On Saturday, 18 March 2017 at 02:23:01 UTC, Hussien wrote:

 I need the general solution. One that simply returns the type. 
 None of what you      said helps...
string dtype(T)() { static if(is(T == enum)) return "enum"; else static if(is(T == class)) return "class"; else static if(is(T == struct)) return "struct"; // etc... } void main() { struct Foo {}; assert(dtype!Foo == "struct"); }
So you are telling me there is no way to do this easily? I have to fill in the // etc part with all the possible types that can exist in D? I guess there could be a default that simply returns the typeof, but just seems like a hack overall.
Mar 18
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 18 March 2017 at 13:06:56 UTC, Hussien wrote:
 So you are telling me there is no way to do this easily?
What are you actually trying to do?
Mar 18
parent reply Hussien <SH glory.com> writes:
On Saturday, 18 March 2017 at 13:16:49 UTC, Adam D. Ruppe wrote:
 On Saturday, 18 March 2017 at 13:06:56 UTC, Hussien wrote:
 So you are telling me there is no way to do this easily?
What are you actually trying to do?
Glad you asked! It is very simple: I am trying to get the underlying D type from a type that I have. interface X; => dtype!(X) == "interface" enum X; => dtype!(X) == "enum" class X; => dtype!(X) == "class" struct X; => dtype!(X) == "struct" union X; => dtype!(X) == "union" wchar* X; => dtype!(X) == "wchar*" int X; => dtype!(X) == "int" void function() X; => dtype!(X) == "function*" void X(); => dtype!(X) == "function" etc.. etc.. The very right terms should only be terms that are listed in the D grammar as types besides the *'s. If a type is a pointer to a _type_, dtype should return _type_*, etc.
Mar 18
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 18 March 2017 at 13:30:22 UTC, Hussien wrote:
 Glad you asked! It is very simple: I am trying to get the 
 underlying D type from a type that I have.
But why? What are you going to do with it?
Mar 18
parent Hussien <SH glory.com> writes:
On Saturday, 18 March 2017 at 13:47:50 UTC, Adam D. Ruppe wrote:
 On Saturday, 18 March 2017 at 13:30:22 UTC, Hussien wrote:
 Glad you asked! It is very simple: I am trying to get the 
 underlying D type from a type that I have.
But why? What are you going to do with it?
I'm going to use it in my D program to do some amazing things!
Mar 18
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Saturday, 18 March 2017 at 13:30:22 UTC, Hussien wrote:
 On Saturday, 18 March 2017 at 13:16:49 UTC, Adam D. Ruppe wrote:
 On Saturday, 18 March 2017 at 13:06:56 UTC, Hussien wrote:
 So you are telling me there is no way to do this easily?
What are you actually trying to do?
Glad you asked! It is very simple: I am trying to get the underlying D type from a type that I have. interface X; => dtype!(X) == "interface" enum X; => dtype!(X) == "enum" class X; => dtype!(X) == "class" struct X; => dtype!(X) == "struct" union X; => dtype!(X) == "union" wchar* X; => dtype!(X) == "wchar*" int X; => dtype!(X) == "int" void function() X; => dtype!(X) == "function*" void X(); => dtype!(X) == "function" etc.. etc.. The very right terms should only be terms that are listed in the D grammar as types besides the *'s. If a type is a pointer to a _type_, dtype should return _type_*, etc.
The problem with enums is that it contains several stuff. It's actually a storage class. enums can be - named enum - anonymous enum - manifest constant - lambda - templates The others stuff are easy to retrieve, like you've been said earlier.
Mar 18
parent reply Hussien <SH glory.com> writes:
On Saturday, 18 March 2017 at 15:16:35 UTC, Basile B. wrote:
 On Saturday, 18 March 2017 at 13:30:22 UTC, Hussien wrote:
 On Saturday, 18 March 2017 at 13:16:49 UTC, Adam D. Ruppe 
 wrote:
 On Saturday, 18 March 2017 at 13:06:56 UTC, Hussien wrote:
 So you are telling me there is no way to do this easily?
What are you actually trying to do?
Glad you asked! It is very simple: I am trying to get the underlying D type from a type that I have. interface X; => dtype!(X) == "interface" enum X; => dtype!(X) == "enum" class X; => dtype!(X) == "class" struct X; => dtype!(X) == "struct" union X; => dtype!(X) == "union" wchar* X; => dtype!(X) == "wchar*" int X; => dtype!(X) == "int" void function() X; => dtype!(X) == "function*" void X(); => dtype!(X) == "function" etc.. etc.. The very right terms should only be terms that are listed in the D grammar as types besides the *'s. If a type is a pointer to a _type_, dtype should return _type_*, etc.
The problem with enums is that it contains several stuff. It's actually a storage class. enums can be - named enum - anonymous enum - manifest constant - lambda - templates The others stuff are easy to retrieve, like you've been said earlier.
I'm just going to use what Mike Parker suggested. I'll fill in the types I need as necessary. Luckily I do not need to many and I will tweak for my needs. I was hoping for a general solution. I simply need some way to pass around the base type in a string since I cannot pass a generic arbitrary type. obviously a lambda would return "lambda", a template should return template, etc. Manifest constant could return "manifest constant". I don't care about the exact value as long as I can pass it around and use it and there is always a one to one correspondence.
Mar 18
parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 18 March 2017 at 15:30:27 UTC, Hussien wrote:
 On Saturday, 18 March 2017 at 15:16:35 UTC, Basile B. wrote:
 On Saturday, 18 March 2017 at 13:30:22 UTC, Hussien wrote:
 On Saturday, 18 March 2017 at 13:16:49 UTC, Adam D. Ruppe 
 wrote:
 On Saturday, 18 March 2017 at 13:06:56 UTC, Hussien wrote:
 So you are telling me there is no way to do this easily?
What are you actually trying to do?
Glad you asked! It is very simple: I am trying to get the underlying D type from a type that I have. interface X; => dtype!(X) == "interface" enum X; => dtype!(X) == "enum" class X; => dtype!(X) == "class" struct X; => dtype!(X) == "struct" union X; => dtype!(X) == "union" wchar* X; => dtype!(X) == "wchar*" int X; => dtype!(X) == "int" void function() X; => dtype!(X) == "function*" void X(); => dtype!(X) == "function" etc.. etc.. The very right terms should only be terms that are listed in the D grammar as types besides the *'s. If a type is a pointer to a _type_, dtype should return _type_*, etc.
The problem with enums is that it contains several stuff. It's actually a storage class. enums can be - named enum - anonymous enum - manifest constant - lambda - templates The others stuff are easy to retrieve, like you've been said earlier.
I'm just going to use what Mike Parker suggested. I'll fill in the types I need as necessary. Luckily I do not need to many and I will tweak for my needs. I was hoping for a general solution. I simply need some way to pass around the base type in a string since I cannot pass a generic arbitrary type. obviously a lambda would return "lambda", a template should return template, etc. Manifest constant could return "manifest constant". I don't care about the exact value as long as I can pass it around and use it and there is always a one to one correspondence.
For manifest constants this should work: ``` /** * Indicates wether something is a value known at compile time. * * Params: * V = The value to test. * T = Optional, the expected value type. */ template isCompileTimeValue(alias V, T...) if (T.length == 0 || (T.length == 1 && is(T[0]))) { enum isKnown = is(typeof((){enum v = V;})); static if (!T.length) enum isCompileTimeValue = isKnown; else enum isCompileTimeValue = isKnown && is(typeof(V) == T[0]); } /// unittest { string a; enum b = "0"; enum c = 0; static assert(!isCompileTimeValue!a); static assert(isCompileTimeValue!b); static assert(isCompileTimeValue!c); static assert(isCompileTimeValue!(b,string)); static assert(isCompileTimeValue!(c,int)); static assert(!isCompileTimeValue!(c,char)); static assert(!isCompileTimeValue!(char)); } /// ditto template isCompileTimeValue(V, T...) if (T.length == 0 || (T.length == 1 && is(T[0]))) { enum isCompileTimeValue = false; } ```
Mar 18
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 17 March 2017 at 23:54:36 UTC, Hussien wrote:
 What I need to do, is also get the D types that these use.
Those aren't types, they are more like categories of type, so there's nothing in the language that can represent them to return (except maybe a string). Instead, you can test the family with the is expression, like so: static if(is(SomeEnum == enum)) else static if(is(SomeClass == class)) and so on. you could write a function that checks those (there are only i think 10 possibilities, enum, class, interface, struct, union, function, template, module, or basic type, or not a type at all) and return a string or whatever you choose to represent them.
Mar 17
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 03/17/2017 07:28 PM, Adam D. Ruppe wrote:
 On Friday, 17 March 2017 at 23:54:36 UTC, Hussien wrote:
 What I need to do, is also get the D types that these use.
Those aren't types, they are more like categories of type, so there's nothing in the language that can represent them to return (except maybe a string). Instead, you can test the family with the is expression, like so: static if(is(SomeEnum == enum)) else static if(is(SomeClass == class)) and so on. you could write a function that checks those (there are only i think 10 possibilities, enum, class, interface, struct, union, function, template, module, or basic type, or not a type at all) and return a string or whatever you choose to represent them.
I wrote the following before reading your reply: None of those are concepts that you can capture i.e. you can't say: kind = class; However, the 'is' expression can differentiate between them, in which case you can get e.g. a string out: http://ddili.org/ders/d.en/is_expr.html#ix_is_expr.struct,%20is%20expression template Kind(T) { static if (is (T == struct)) { enum Kind = "struct"; } else static if (is (T == union)) { enum Kind = "union"; } // etc. else { static assert("WAT!"); } } unittest { struct S {} union U {} static assert(Kind!S == "struct"); static assert(Kind!U == "union"); } void main() { } Ali
Mar 17