www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Use template functions within mixin

reply Timoses <timosesu gmail.com> writes:
Hey there,

I'm wondering how I can use a template function within my mixin:

```
                 ubyte[] value = x[33, 3a,3f, d4];
                 foreach (type; TypeTuple!("int", "unsigned int", 
"byte"))
                 {
                     mixin(`if (value.length == type.sizeof)
                             {
                                 ubyte[type.sizeof] raw = 
value[0..$];
                                 auto fValue = 
raw.littleEndianToNative!(type);
                                 displayinfo(fValue);
                             }
                             break;
                         `);
                 }
```


Error: template std.bitmanip.littleEndianToNative cannot deduce 
function from argument types !("int")(ubyte[8]), candidates are:
[..]\src\phobos\std\bitmanip.d(2560,3):        
std.bitmanip.littleEndianToNative(T, uint n)(ubyte[n] val) if 
(canSwapEndianness!T && n == T.sizeof)

```
`raw.littleEndianToNative!` ~ type ~ `;`
```

neither works..

Any way to accomplish this?
Jun 06 2017
next sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Tuesday, 6 June 2017 at 15:00:50 UTC, Timoses wrote:
 Hey there,

 I'm wondering how I can use a template function within my mixin:

 ```
                 ubyte[] value = x[33, 3a,3f, d4];
                 foreach (type; TypeTuple!("int", "unsigned 
 int", "byte"))
                 {
                     mixin(`if (value.length == type.sizeof)
                             {
                                 ubyte[type.sizeof] raw = 
 value[0..$];
                                 auto fValue = 
 raw.littleEndianToNative!(type);
                                 displayinfo(fValue);
                             }
                             break;
                         `);
                 }
 ```


 Error: template std.bitmanip.littleEndianToNative cannot deduce 
 function from argument types !("int")(ubyte[8]), candidates are:
 [..]\src\phobos\std\bitmanip.d(2560,3):        
 std.bitmanip.littleEndianToNative(T, uint n)(ubyte[n] val) if 
 (canSwapEndianness!T && n == T.sizeof)

 ```
 `raw.littleEndianToNative!` ~ type ~ `;`
 ```
Did you also put the ` ~ type ~ ` on the 2 other cases where you use the variable type? mixin(`if (value.length == ` ~ type ~ `.sizeof) { ubyte[` ~ type ~ `.sizeof] raw = value[0..$]; auto fValue = raw.littleEndianToNative!(` ~ type ~ `); displayinfo(fValue); } break; `);
Jun 06 2017
prev sibling next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, June 06, 2017 15:00:50 Timoses via Digitalmars-d-learn wrote:
 Hey there,

 I'm wondering how I can use a template function within my mixin:

 ```
                  ubyte[] value = x[33, 3a,3f, d4];
                  foreach (type; TypeTuple!("int", "unsigned int",
 "byte"))
                  {
                      mixin(`if (value.length == type.sizeof)
                              {
                                  ubyte[type.sizeof] raw =
 value[0..$];
                                  auto fValue =
 raw.littleEndianToNative!(type);
                                  displayinfo(fValue);
                              }
                              break;
                          `);
                  }
 ```


 Error: template std.bitmanip.littleEndianToNative cannot deduce
 function from argument types !("int")(ubyte[8]), candidates are:
 [..]\src\phobos\std\bitmanip.d(2560,3):
 std.bitmanip.littleEndianToNative(T, uint n)(ubyte[n] val) if
 (canSwapEndianness!T && n == T.sizeof)

 ```
 `raw.littleEndianToNative!` ~ type ~ `;`
 ```

 neither works..

 Any way to accomplish this?
Well, for starters, I see no reason to even use mixins here. Just do foreach(type; TypeTuple!(int, uint, byte)) { } and write the code normally. Also, unsigned int isn't a type in D. It's uint. And with what you have, mixing in "type.sizeof" is just going to result in getting size of the type string. You'd need to do something like "ubyte[" ~ type ~ "].sizeof] raw =" if you wanted to have the value of type mixed in. Also, FYI, TypeTuple was renamed to AliasSeq, so that's what's normally used now (though TypeTuple wasn't deprecated because of the amount of existing code that uses it, so it will still work). In any case, there's really no reason to be using string mixins here. TypeTuple/AliasSeq and foreach will work with the actual types. - Jonathan M Davis
Jun 06 2017
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
Just import modules at local scopes. Here is something that works:

void displayinfo(T)(T v) {
     import std.stdio : writefln;
     writefln("%08x", v);
}

void foo() {
     import std.meta : AliasSeq;

     enum value = cast(ubyte[])x"33 3a 3f d4";
     foreach (type; AliasSeq!(int, uint, byte)) {
         static if (value.length == type.sizeof) {
             import std.bitmanip : littleEndianToNative;

             pragma(msg, "working with " ~ type.stringof);

             ubyte[type.sizeof] raw = value;
             auto fValue = raw.littleEndianToNative!type;
             displayinfo(fValue);
             break;
         }
     }
}

void main() {
     foo();
}

Ali
Jun 06 2017
parent Timoses <timosesu gmail.com> writes:
On Tuesday, 6 June 2017 at 18:08:52 UTC, Ali Çehreli wrote:
 Just import modules at local scopes. Here is something that 
 works:

 void displayinfo(T)(T v) {
     import std.stdio : writefln;
     writefln("%08x", v);
 }

 void foo() {
     import std.meta : AliasSeq;

     enum value = cast(ubyte[])x"33 3a 3f d4";
     foreach (type; AliasSeq!(int, uint, byte)) {
         static if (value.length == type.sizeof) {
             import std.bitmanip : littleEndianToNative;

             pragma(msg, "working with " ~ type.stringof);

             ubyte[type.sizeof] raw = value;
             auto fValue = raw.littleEndianToNative!type;
             displayinfo(fValue);
             break;
         }
     }
 }

 void main() {
     foo();
 }

 Ali
Sorry, it was probably a bad example. The value ubyte[] array read at run-time. The way of Patrick Schluter works! ``` void displayinfo(T)(T ff) { writeln(ff); } switch (varType) { import std.meta; foreach (type; AliasSeq!("int", "uint", "byte")) { pragma(msg, type); mixin(`case `~type~`.stringof: if (value.length == `~type~`.sizeof) { ubyte[`~type~`.sizeof] raw = value[0..$]; auto fValue = raw.littleEndianToNative!(`~type~`); displayinfo(fValue); } break;`); } ``` I'm trying to detect whether the type is `uint`, but the following does not seem to work: ``` static if (is (type == uint)) { pragma(msg, "isi uint"); assert(0); } ``` The reason is that I'd like to have the cases: - `case "uint":` - `case "unsigned int":` for the uint loop turn.
Jun 07 2017