www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Grouping specialisations / constraints

reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
Is there an alternate mechanism to the following? (I'm getting real sick of the
boilerplate, and we've no preprocessor ... ;/ )


    module std.type.traits;

    private template _isMinValue(T) { bool _isMinValue(T value)
    {
        return value == T.min;
    }}


    bool isMinValue(bit value)      {   return _isMinValue!(bit)(value);    }
    bool isMinValue(byte value)     {   return _isMinValue!(byte)(value);   }
    bool isMinValue(ubyte value)    {   return _isMinValue!(ubyte)(value);  }
    bool isMinValue(short value)    {   return _isMinValue!(short)(value);  }
    bool isMinValue(ushort value)   {   return _isMinValue!(ushort)(value); }
    bool isMinValue(int value)      {   return _isMinValue!(int)(value);    }
    bool isMinValue(uint value)     {   return _isMinValue!(uint)(value);   }
    bool isMinValue(long value)     {   return _isMinValue!(long)(value);   }
    bool isMinValue(ulong value)    {   return _isMinValue!(ulong)(value);  }

    bool isMinValue(Object value)
    {
        return false;
    }
Jul 16 2004
next sibling parent Andy Friesen <andy ikagames.com> writes:
Matthew wrote:
 Is there an alternate mechanism to the following? (I'm getting real sick of the
 boilerplate, and we've no preprocessor ... ;/ )
 
 
     module std.type.traits;
 
     private template _isMinValue(T) { bool _isMinValue(T value)
     {
         return value == T.min;
     }}
 
 
     bool isMinValue(bit value)      {   return _isMinValue!(bit)(value);    }
     bool isMinValue(byte value)     {   return _isMinValue!(byte)(value);   }
     bool isMinValue(ubyte value)    {   return _isMinValue!(ubyte)(value);  }
     bool isMinValue(short value)    {   return _isMinValue!(short)(value);  }
     bool isMinValue(ushort value)   {   return _isMinValue!(ushort)(value); }
     bool isMinValue(int value)      {   return _isMinValue!(int)(value);    }
     bool isMinValue(uint value)     {   return _isMinValue!(uint)(value);   }
     bool isMinValue(long value)     {   return _isMinValue!(long)(value);   }
     bool isMinValue(ulong value)    {   return _isMinValue!(ulong)(value);  }
 
     bool isMinValue(Object value)
     {
         return false;
     }
You can *almost* do this by iterating over a typelist, mixing in a template as you go. What kills you is the fact that mixed methods can't have the same name, even if they have the same signature. :( <http://andy.tadan.us/d/metatest.d> There may be a way to work around this little wart using mixin names and aliases, though... -- andy
Jul 17 2004
prev sibling next sibling parent J Anderson <REMOVEanderson badmama.com.au> writes:
Matthew wrote:

Is there an alternate mechanism to the following? (I'm getting real sick of the
boilerplate, and we've no preprocessor ... ;/ )


    module std.type.traits;

    private template _isMinValue(T) { bool _isMinValue(T value)
    {
        return value == T.min;
    }}


    bool isMinValue(bit value)      {   return _isMinValue!(bit)(value);    }
    bool isMinValue(byte value)     {   return _isMinValue!(byte)(value);   }
    bool isMinValue(ubyte value)    {   return _isMinValue!(ubyte)(value);  }
    bool isMinValue(short value)    {   return _isMinValue!(short)(value);  }
    bool isMinValue(ushort value)   {   return _isMinValue!(ushort)(value); }
    bool isMinValue(int value)      {   return _isMinValue!(int)(value);    }
    bool isMinValue(uint value)     {   return _isMinValue!(uint)(value);   }
    bool isMinValue(long value)     {   return _isMinValue!(long)(value);   }
    bool isMinValue(ulong value)    {   return _isMinValue!(ulong)(value);  }

    bool isMinValue(Object value)
    {
        return false;
    }

  
You can use alias alias _isMinValue!(bit) isMinValue; alias _isMinValue!(byte) isMinValue; alias _isMinValue!(ubyte) isMinValue; alias _isMinValue!(short) isMinValue; alias _isMinValue!(ushort) isMinValue; //ect... However I agree, there should be some sort of parameter that you can use to pass groups of types (I requested this before). something like: alias [bit, byte, ubyte, short, ushort] primitives; //This would be defined in the standard lib somewhere with all the primitive types alias _isMinValue!(primitives) isMinValue; //Creates alias for bit, byte, ubyte, short, ushort Another thing that would help (also requested ages ago), would be if you could pass in the name of a function like: //In the overload module template param1(name1, name2) { alias _name1!(bit) name2; alias _name1!(byte) name2; alias _name1!(ubyte) name2; alias _name1!(short) name2; alias _name1!(ushort) name2; //ect } //In the traits module alias param1!(_isMinValue, isMinValue) minMixin; //In the user file mixin minMixin; -- -Anderson: http://badmama.com.au/~anderson/
Jul 17 2004
prev sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Matthew wrote:
 Is there an alternate mechanism to the following? (I'm getting real sick of the
 boilerplate, and we've no preprocessor ... ;/ )
 
 
     module std.type.traits;
 
     private template _isMinValue(T) { bool _isMinValue(T value)
     {
         return value == T.min;
     }}
 
 
     bool isMinValue(bit value)      {   return _isMinValue!(bit)(value);    }
     bool isMinValue(byte value)     {   return _isMinValue!(byte)(value);   }
     bool isMinValue(ubyte value)    {   return _isMinValue!(ubyte)(value);  }
     bool isMinValue(short value)    {   return _isMinValue!(short)(value);  }
     bool isMinValue(ushort value)   {   return _isMinValue!(ushort)(value); }
     bool isMinValue(int value)      {   return _isMinValue!(int)(value);    }
     bool isMinValue(uint value)     {   return _isMinValue!(uint)(value);   }
     bool isMinValue(long value)     {   return _isMinValue!(long)(value);   }
     bool isMinValue(ulong value)    {   return _isMinValue!(ulong)(value);  }
 
     bool isMinValue(Object value)
     {
         return false;
     }
Could you use a mixin here?
Jul 17 2004
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:cdbkk3$1e5b$1 digitaldaemon.com...
 Matthew wrote:
 Is there an alternate mechanism to the following? (I'm getting real sick of
the
 boilerplate, and we've no preprocessor ... ;/ )


     module std.type.traits;

     private template _isMinValue(T) { bool _isMinValue(T value)
     {
         return value == T.min;
     }}


     bool isMinValue(bit value)      {   return _isMinValue!(bit)(value);    }
     bool isMinValue(byte value)     {   return _isMinValue!(byte)(value);   }
     bool isMinValue(ubyte value)    {   return _isMinValue!(ubyte)(value);  }
     bool isMinValue(short value)    {   return _isMinValue!(short)(value);  }
     bool isMinValue(ushort value)   {   return _isMinValue!(ushort)(value); }
     bool isMinValue(int value)      {   return _isMinValue!(int)(value);    }
     bool isMinValue(uint value)     {   return _isMinValue!(uint)(value);   }
     bool isMinValue(long value)     {   return _isMinValue!(long)(value);   }
     bool isMinValue(ulong value)    {   return _isMinValue!(ulong)(value);  }

     bool isMinValue(Object value)
     {
         return false;
     }
Could you use a mixin here?
I'd happily look at an implementation, if you can provide one. :)
Jul 17 2004
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Matthew wrote:
Could you use a mixin here?
I'd happily look at an implementation, if you can provide one. :)
template the_mixin(alias templateName, retType) { retType theThing(bit value) { printf("bit specialization\n"); return templateName!(bit)(value); } retType theThing(char value) { printf("char specialization\n"); return templateName!(char)(value); } } template _isMinValue(T) { bool _isMinValue(T value) { return value == T.min; }} mixin the_mixin!(_isMinValue, bool) whatever; alias whatever.theThing isMinValue; int main() { bit b = bit.min; char c = char.min; return isMinValue(b) && isMinValue(c); }
Jul 17 2004
parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:cdcekv$1p34$1 digitaldaemon.com...
 Matthew wrote:
Could you use a mixin here?
I'd happily look at an implementation, if you can provide one. :)
template the_mixin(alias templateName, retType) { retType theThing(bit value) { printf("bit specialization\n"); return templateName!(bit)(value); } retType theThing(char value) { printf("char specialization\n"); return templateName!(char)(value); } } template _isMinValue(T) { bool _isMinValue(T value) { return value == T.min; }} mixin the_mixin!(_isMinValue, bool) whatever; alias whatever.theThing isMinValue; int main() { bit b = bit.min; char c = char.min; return isMinValue(b) && isMinValue(c); }
Hmm. I think there's a problem here. You see, the point is that the built-in types represent the special cases. In principle, the isMinValue() will always return false for a class type. According to your implementation, - which I like, and which teaches me a practical use for alias, btw <g> - I'd have to write the false-returning specialisations for all class types; a specialisation for Object would only rule out Object, would it not? I'll go and try it, and let you know if I'm wrong. Thanks for the info, anyway. :) ... after trying, I am wrong. In fact, this'll save some effort, and I now see some real utility in this. It hasn't really addressed my main problem, since one still has to provide BuiltinTransformMixin.txFn() methods for each built-in type. But it's a help. Thanks. See the code below, which is now : private template BuiltinTransformMixin(alias templateName, retType) { retType txFn(bit value) { return templateName!(bit)(value); } retType txFn(byte value) { return templateName!(byte)(value); } retType txFn(ubyte value) { return templateName!(ubyte)(value); } retType txFn(short value) { return templateName!(short)(value); } retType txFn(ushort value) { return templateName!(ushort)(value); } retType txFn(int value) { return templateName!(int)(value); } retType txFn(uint value) { return templateName!(uint)(value); } retType txFn(long value) { return templateName!(long)(value); } retType txFn(ulong value) { return templateName!(ulong)(value); } retType txFn(char value) { return templateName!(char)(value); } } private template _isMinValue(T) { bool _isMinValue(T value) { return value == T.min; }} private template _isMaxValue(T) { bool _isMaxValue(T value) { return value == T.max; }} alias BuiltinTransformMixin!(_isMinValue, bool).txFn isMinValue; alias BuiltinTransformMixin!(_isMaxValue, bool).txFn isMaxValue; bool isMinValue(Object o) { return false; } bool isMaxValue(Object o) { return false; } I still don't understand alias, but I guess I'll be learning pretty soon. :)
Jul 18 2004
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Matthew wrote:
 It hasn't really addressed my main problem, since one still has to provide
 BuiltinTransformMixin.txFn() methods for each built-in type. But it's a help.
 Thanks.
My thought is that the BuiltinTransformMixin template should go into a library somewhere so that we only have to write it once. Thereafter, we get pretty easy template arugment deduction. The library should also have versions that return void (or can you do that already with that template?) and probably versions that include multiple arguments.
Jul 18 2004