Thread overview
Grouping specialisations / constraints
Jul 17, 2004
Matthew
Jul 17, 2004
Andy Friesen
Jul 17, 2004
J Anderson
Jul 17, 2004
Russ Lewis
Jul 17, 2004
Matthew
Jul 18, 2004
Russ Lewis
Jul 18, 2004
Matthew
Jul 18, 2004
Russ Lewis
July 17, 2004
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;
    }


July 17, 2004
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
July 17, 2004
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/
July 17, 2004
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?

July 17, 2004
"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. :)


July 18, 2004
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);
}

July 18, 2004
"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. :)


July 18, 2004
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.