On 26 November 2012 19:11, Adam D. Ruppe <destructiona...@gmail.com> wrote:
> On Monday, 26 November 2012 at 17:03:41 UTC, Manu wrote: > >> Error: variable isProperty cannot be read at compile time >> > > that doesn't make any sense :S > > > TL;DR, std.traits is extremely brittle, and rather incomplete. As a >> programmer with deadlines trying to get work done, it >> is just not yet acceptable >_< >> > > I totally get this though... just look at this pile of crap from my web.d, > which is used in some really ugly conditions. > > I don't even know what it all even does or why it works. It was a few > weekends of random guessing: > > > // these are all filthy hacks > > template isEnum(alias T) if(is(T)) { > static if (is(T == enum)) > enum bool isEnum = true; > else > enum bool isEnum = false; > } > > // WTF, shouldn't is(T == xxx) already do this? > template isEnum(T) if(!is(T)) { > enum bool isEnum = false; > } > > template isStruct(alias T) if(is(T)) { > static if (is(T == struct)) > enum bool isStruct = true; > else > enum bool isStruct = false; > } > > // WTF > template isStruct(T) if(!is(T)) { > enum bool isStruct = false; > } > > template Passthrough(T) { > T Passthrough; > } > > template PassthroughType(T) { > alias T PassthroughType; > } > > > > Soooo yeah. I'm sure there's a way to get what you want, but I'm equally > sure you'll have some pain in the mean time that can take a while to figure > through. > Perhaps, but I've already spent days on this, and many hours of overtime!! I need to draw the line. Here's what I have, and it's not even close to working: template isType( alias T ) { enum isType = is( T ); } template isType( T ) { enum isType = is( T ); } template isFunction( alias T ) { enum isFunction = is( typeof( T ) == function ); } template isFunction( T ) { enum isFunction = is( T == function ); } template isEnum( alias T ) { template knownAtCompileTime( alias T ) { // enum knownAtCompileTime = is( typeof( { enum e = T; } ) ); // immutable breaks this approach enum knownAtCompileTime = !__traits(compiles, ( ref typeof( T ) _x_ ) {}( T ) ); // hack to see if we can pass it by ref } enum isEnum = is( typeof( T ) == enum ) || knownAtCompileTime!T; } template isEnum( T ) { enum isEnum = is( T == enum ); } template isProperty( alias T ) if(isCallable!T) { bool isProperty = (functionAttributes!T & FunctionAttribute.property) ? true : false; } template isProperty( alias T ) if(!isCallable!T) { bool isProperty = false; } template isProperty( T ) { bool isProperty = false; } template isVariable( alias T ) { enum isVariable = !is( T ) && is( typeof( T ) ) // if it is not a type, and does have a type, it starts to look like a variable && !isFunction!T // reject function definitions, they can't be assigned to && !is( typeof( T ) == void ) // reject modules, which appear as a variable of type 'void' && !isEnum!T // reject enum's && !isProperty!T; // seriously, why is this not caught by the function test above?! } template isVariable( T ) { enum isVariable = false; // types aren't variables } import std.stdio; struct a { void m(); static void n(); } alias int b; interface c { void l(); }; int d; immutable e = 10; void function() f; void delegate() g; void h() {} enum i = 10; enum j { k = 10 } @property int p() { return 10; } pragma(msg, "isType"); pragma(msg, isType!int); pragma(msg, isType!a); pragma(msg, isType!b); pragma(msg, isType!c); pragma(msg, isType!d); pragma(msg, isType!e); pragma(msg, isType!f); pragma(msg, isType!g); pragma(msg, isType!h); pragma(msg, isType!i); pragma(msg, isType!j); pragma(msg, isType!(j.k)); pragma(msg, isType!(c.l)); pragma(msg, isType!(a.m)); pragma(msg, isType!(a.n)); pragma(msg, isType!p); pragma(msg, isType!std); pragma(msg, "isFunction"); pragma(msg, isFunction!int); pragma(msg, isFunction!a); pragma(msg, isFunction!b); pragma(msg, isFunction!c); pragma(msg, isFunction!d); pragma(msg, isFunction!e); pragma(msg, isFunction!f); pragma(msg, isFunction!g); pragma(msg, isFunction!h); pragma(msg, isFunction!i); pragma(msg, isFunction!j); pragma(msg, isFunction!(j.k)); pragma(msg, isFunction!(c.l)); pragma(msg, isFunction!(a.m)); pragma(msg, isFunction!(a.n)); pragma(msg, isFunction!p); pragma(msg, isFunction!std); pragma(msg, "isEnum"); pragma(msg, isEnum!int); pragma(msg, isEnum!a); pragma(msg, isEnum!b); pragma(msg, isEnum!c); pragma(msg, isEnum!d); pragma(msg, isEnum!e); pragma(msg, isEnum!f); pragma(msg, isEnum!g); pragma(msg, isEnum!h); pragma(msg, isEnum!i); pragma(msg, isEnum!j); pragma(msg, isEnum!(j.k)); pragma(msg, isEnum!(c.l)); pragma(msg, isEnum!(a.m)); pragma(msg, isEnum!(a.n)); pragma(msg, isEnum!p); pragma(msg, isEnum!std); pragma(msg, "isProperty"); pragma(msg, isProperty!int); pragma(msg, isProperty!a); pragma(msg, isProperty!b); pragma(msg, isProperty!c); pragma(msg, isProperty!d); pragma(msg, isProperty!e); pragma(msg, isProperty!f); pragma(msg, isProperty!g); pragma(msg, isProperty!h); pragma(msg, isProperty!i); pragma(msg, isProperty!j); pragma(msg, isProperty!(j.k)); pragma(msg, isProperty!(c.l)); pragma(msg, isProperty!(a.m)); pragma(msg, isProperty!(a.n)); pragma(msg, isProperty!p); pragma(msg, isProperty!std); pragma(msg, "isVariable"); pragma(msg, isVariable!int); pragma(msg, isVariable!a); pragma(msg, isVariable!b); pragma(msg, isVariable!c); pragma(msg, isVariable!d); pragma(msg, isVariable!e); pragma(msg, isVariable!f); pragma(msg, isVariable!g); pragma(msg, isVariable!h); pragma(msg, isVariable!i); pragma(msg, isVariable!j); pragma(msg, isVariable!(j.k)); pragma(msg, isVariable!(c.l)); pragma(msg, isVariable!(a.m)); pragma(msg, isVariable!(a.n)); pragma(msg, isVariable!p); pragma(msg, isVariable!std);