Get most D type from type

Basile B. via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Mar 18 08:57:26 PDT 2017


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;
}
```


More information about the Digitalmars-d-learn mailing list