www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - detecting classes, structs, arrays in templates

reply "Luke J. West" <luke west.me.uk> writes:
Hi,

I want to specialize a template function - call it print() - for three
cases: classes, structs and arrays. Ideally I'd like something that
looks 'functional' like a proper specialization, but perhaps I need to
use "static if". I'm still at the beginning of my journey with D so I'd
be grateful for any pointers (sorry - that's a terrible pun). Perhaps
there's a corner of the D2 docs I've glossed over.

Thanks,

Luke


// in words you can understand...

void print(T)() {writefln("general");}

// But what does my specialization look like for all (or any)
// of the implementations of print() for the calls below.

int main() {
 C   c;    // some class
 S   s;    // some struct
 int a[4]; // an array
 int p;    // a primitive type
 
 print(c); // writefln("class");
 print(s); // writefln("struct");
 print(a); // writefln("array");
 print(p); // writefln("primitive");

 return 0;
}
Jan 23 2011
next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Luke J. West <luke west.me.uk> wrote:

 Hi,

 I want to specialize a template function - call it print() - for three
 cases: classes, structs and arrays. Ideally I'd like something that
 looks 'functional' like a proper specialization, but perhaps I need to
 use "static if". I'm still at the beginning of my journey with D so I'd
 be grateful for any pointers (sorry - that's a terrible pun). Perhaps
 there's a corner of the D2 docs I've glossed over.

 Thanks,

 Luke


 // in words you can understand...

 void print(T)() {writefln("general");}

 // But what does my specialization look like for all (or any)
 // of the implementations of print() for the calls below.

 int main() {
  C   c;    // some class
  S   s;    // some struct
  int a[4]; // an array
  int p;    // a primitive type
 print(c); // writefln("class");
  print(s); // writefln("struct");
  print(a); // writefln("array");
  print(p); // writefln("primitive");

  return 0;
 }

You want to have a look-see at isExpressions[1]: void print(T)(T t) if (is(T == class)){ writeln("class"); } void print(T)(T t) if (is(T == struct)){ writeln("struct"); } void print(T)(T t) if (is(T U == U[])){ writeln("array"); } void print(T)(T t) if (isNumeric!T || isSomeChar!T){ writeln("primitive"); } Haven't actually tested these, as I don't have D here. Note also that two specializations are missing - pointer and associative array: void print(T)(T t) if (is(T U == U[V], V)){ writeln("associative array"); } void print(T)(T t) if (is(T U == U*)){ writeln("pointer"); } http://digitalmars.com/d/2.0/expression.html#IsExpression -- Simen
Jan 23 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Luke J. West:

 Hi,
 
 I want to specialize a template function - call it print() - for three
 cases: classes, structs and arrays. Ideally I'd like something that
 looks 'functional' like a proper specialization, but perhaps I need to
 use "static if". I'm still at the beginning of my journey with D so I'd
 be grateful for any pointers (sorry - that's a terrible pun). Perhaps
 there's a corner of the D2 docs I've glossed over.

I suggest you to ask such questions in the D.learn newsgroup. Here are two possible implementations: import std.stdio: writeln; import std.traits: isArray; void print(T)(T x) if (!isArray!T && !is(T == class) && !is(T == struct)) { writeln("general"); } void print(T)(T[] x) { writeln("Dynamic array or fixed-sized array"); } void print(T)(T x) if (is(T == class)) { writeln("Class instance"); } void print(T)(T x) if (is(T == struct)) { writeln("Struct instance"); } void print2(T)(T x) { static if (isArray!T) writeln("Dynamic array or fixed-sized array"); else static if (is(T == class)) writeln("Class instance"); else static if (is(T == struct)) writeln("Struct instance"); else writeln("general"); } class C {} struct S {} void main() { C c; // some class S s; // some struct int[4] a; // a fixed-sized array int p; // a primitive type print(a); print(p); print(c); print(s); writeln(); print2(a); print2(p); print2(c); print2(s); } Bye, bearophile
Jan 23 2011
prev sibling parent "Luke J. West" <luke west.me.uk> writes:
Thanks for that bearophile - I'll get myself subscribed right away.

Bye for now,

Luke

On Sun, 23 Jan 2011 09:17:05 -0500, "bearophile"
<bearophileHUGS lycos.com> said:
 Luke J. West:
 
 Hi,
 
 I want to specialize a template function - call it print() - for three
 cases: classes, structs and arrays. Ideally I'd like something that
 looks 'functional' like a proper specialization, but perhaps I need to
 use "static if". I'm still at the beginning of my journey with D so I'd
 be grateful for any pointers (sorry - that's a terrible pun). Perhaps
 there's a corner of the D2 docs I've glossed over.

I suggest you to ask such questions in the D.learn newsgroup. Here are two possible implementations: import std.stdio: writeln; import std.traits: isArray; void print(T)(T x) if (!isArray!T && !is(T == class) && !is(T == struct)) { writeln("general"); } void print(T)(T[] x) { writeln("Dynamic array or fixed-sized array"); } void print(T)(T x) if (is(T == class)) { writeln("Class instance"); } void print(T)(T x) if (is(T == struct)) { writeln("Struct instance"); } void print2(T)(T x) { static if (isArray!T) writeln("Dynamic array or fixed-sized array"); else static if (is(T == class)) writeln("Class instance"); else static if (is(T == struct)) writeln("Struct instance"); else writeln("general"); } class C {} struct S {} void main() { C c; // some class S s; // some struct int[4] a; // a fixed-sized array int p; // a primitive type print(a); print(p); print(c); print(s); writeln(); print2(a); print2(p); print2(c); print2(s); } Bye, bearophile

Jan 23 2011