www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Lament: unsigned keyword and templates

reply =?ISO-8859-1?Q?Sigbj=F8rn_Lund_Olsen?= <sigbjorn lundolsen.net> writes:
I wish I were able to do this:

interface IInputStream(T, I : IntegralClass)
{
	unsigned I read // out int elementsRead
	(
		inout T[] buffer,
		in I atLeast,
		in I atMost,
		in unsigned I bufferOffset
	);
}

where I would automatically unbox into any scalar, integral type (ie 
byte, short, int, long, cent). But primarily this is a lament to the 
lack of an unsigned keyword - then at least you wouldn't have to have 
two specialization parameters I and UI relying on the user (and I never 
do) to figure out that having UI not be the unsigned variant of I is a 
terribly noxious idea.

Cheers,
Sigbjørn Lund Olsen
Jun 20 2004
parent reply "Walter" <newshound digitalmars.com> writes:
You can work around this by establishing a 'traits' template, specialized
for each signed type, that has an alias in it for the corresponding unsigned
type.

"Sigbjørn Lund Olsen" <sigbjorn lundolsen.net> wrote in message
news:cb4eaf$p5a$1 digitaldaemon.com...
 I wish I were able to do this:

 interface IInputStream(T, I : IntegralClass)
 {
 unsigned I read // out int elementsRead
 (
 inout T[] buffer,
 in I atLeast,
 in I atMost,
 in unsigned I bufferOffset
 );
 }

 where I would automatically unbox into any scalar, integral type (ie
 byte, short, int, long, cent). But primarily this is a lament to the
 lack of an unsigned keyword - then at least you wouldn't have to have
 two specialization parameters I and UI relying on the user (and I never
 do) to figure out that having UI not be the unsigned variant of I is a
 terribly noxious idea.

 Cheers,
 Sigbjørn Lund Olsen
Jun 20 2004
parent reply =?ISO-8859-1?Q?Sigbj=F8rn_Lund_Olsen?= <sigbjorn lundolsen.net> writes:
Walter wrote:

 You can work around this by establishing a 'traits' template, specialized
 for each signed type, that has an alias in it for the corresponding unsigned
 type.
Right... Well, it works for what I had in mind, but tbh I think this is perhaps something you ought to consider whether to change or not. See example below - this level of verbosity isn't good. Frankly, I was yearning for a preprocessor throughout the entire exercise. Having an 'unsigned' keyword to modify the primitives does more correctly show and represent the close relationship between a signed type and its unsigned companion type. It seems, to me, that this is one thing C/C++ got right and therefore shouldn't be thrown into the bin for D. template TFoo(T) { UI aMethod ( in T[] oneArgument, in I anotherArgument, in UI theLastArgument ); } interface IFoo(T, I : byte) { alias byte I; alias ubyte UI; mixin TFoo!(T); } interface IFoo(T, I : short) { alias short I; alias ushort UI; mixin TFoo!(T); } interface IFoo(T, I : int) { alias int I; alias uint UI; mixin TFoo!(T); } interface IFoo(T, I : long) { alias long I; alias ulong UI; mixin TFoo!(T); } int getSign(int number) { if (number < 0) // negative { return -1; } else if (number == 0) { return 0; } else if (number > 0) { return 1; } } class CFoo(T, I) : IFoo!(T, I) { UI aMethod ( in T[] oneArgument, in I anotherArgument, in UI theLastArgument ) body { return oneArgument.length + getSign(anotherArgument) * anotherArgument + theLastArgument; } } alias CFoo!(ubyte, byte) byteFoo; alias CFoo!(ubyte, short) shortFoo; alias CFoo!(ubyte, int) intFoo; int main(char[][] args) { ubyte[3] anArray; anArray[0] = 15; anArray[1] = 3; anArray[2] = 200; byteFoo byteObject = new byteFoo; shortFoo shortObject = new shortFoo; intFoo intObject = new intFoo; printf("byteFoo: %i\n", byteObject.aMethod(anArray, -5, 10)); printf("shortFoo: %i\n", shortObject.aMethod(anArray, 0, 1_000)); printf("intFoo: %i\n", intObject.aMethod(anArray, 17, 100_000)); return 0; } Cheers, Sigbjørn Lund Olsen
Jun 20 2004
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Might it be that you misunderstood Walter? The concept of 'traits' would
give something like:

--------------------------------
// First the wordy, but trivial part:
template INT_TRAITS(T) {
}

template INT_TRAITS(T: int) {
        alias uint unsigned;
        alias int signed;
}

template INT_TRAITS(T: uint) {
        alias uint unsigned;
        alias int signed;
}

template INT_TRAITS(T: byte) {
        alias ubyte unsigned;
        alias byte signed;
}

template INT_TRAITS(T: ubyte) {
        alias ubyte unsigned;
        alias byte signed;
}

// Not the real code:
interface IInputStream(T, I : IntegralClass)
{
        INT_TRAITS!(I).unsigned read // out int elementsRead
        (
                inout T[] buffer,
                in INT_TRAITS!(I).signed atLeast,
                in INT_TRAITS!(I).signed atMost,
                in INT_TRAITS!(I).unsigned bufferOffset
        );
}

----------------------------------





Sigbjørn Lund Olsen wrote:

 Walter wrote:
 
 You can work around this by establishing a 'traits' template, specialized
 for each signed type, that has an alias in it for the corresponding
 unsigned type.
Right... Well, it works for what I had in mind, but tbh I think this is perhaps something you ought to consider whether to change or not. See example below - this level of verbosity isn't good. Frankly, I was yearning for a preprocessor throughout the entire exercise. Having an 'unsigned' keyword to modify the primitives does more correctly show and represent the close relationship between a signed type and its unsigned companion type. It seems, to me, that this is one thing C/C++ got right and therefore shouldn't be thrown into the bin for D. template TFoo(T) { UI aMethod ( in T[] oneArgument, in I anotherArgument, in UI theLastArgument ); } interface IFoo(T, I : byte) { alias byte I; alias ubyte UI; mixin TFoo!(T); } interface IFoo(T, I : short) { alias short I; alias ushort UI; mixin TFoo!(T); } interface IFoo(T, I : int) { alias int I; alias uint UI; mixin TFoo!(T); } interface IFoo(T, I : long) { alias long I; alias ulong UI; mixin TFoo!(T); } int getSign(int number) { if (number < 0) // negative { return -1; } else if (number == 0) { return 0; } else if (number > 0) { return 1; } } class CFoo(T, I) : IFoo!(T, I) { UI aMethod ( in T[] oneArgument, in I anotherArgument, in UI theLastArgument ) body { return oneArgument.length + getSign(anotherArgument) * anotherArgument + theLastArgument; } } alias CFoo!(ubyte, byte) byteFoo; alias CFoo!(ubyte, short) shortFoo; alias CFoo!(ubyte, int) intFoo; int main(char[][] args) { ubyte[3] anArray; anArray[0] = 15; anArray[1] = 3; anArray[2] = 200; byteFoo byteObject = new byteFoo; shortFoo shortObject = new shortFoo; intFoo intObject = new intFoo; printf("byteFoo: %i\n", byteObject.aMethod(anArray, -5, 10)); printf("shortFoo: %i\n", shortObject.aMethod(anArray, 0, 1_000)); printf("intFoo: %i\n", intObject.aMethod(anArray, 17, 100_000)); return 0; } Cheers, Sigbjørn Lund Olsen
Jun 20 2004
parent "Walter" <newshound digitalmars.com> writes:
That's essentially it. I think the traits solution is a bit better than the
unsigned keyword solution, because there are many different kinds of things
one can want with traits, and building them all into the compiler adds too
much baggage.


"Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message
news:cb544a$1odg$1 digitaldaemon.com...
 Might it be that you misunderstood Walter? The concept of 'traits' would
 give something like:

 --------------------------------
 // First the wordy, but trivial part:
 template INT_TRAITS(T) {
 }

 template INT_TRAITS(T: int) {
         alias uint unsigned;
         alias int signed;
 }

 template INT_TRAITS(T: uint) {
         alias uint unsigned;
         alias int signed;
 }

 template INT_TRAITS(T: byte) {
         alias ubyte unsigned;
         alias byte signed;
 }

 template INT_TRAITS(T: ubyte) {
         alias ubyte unsigned;
         alias byte signed;
 }

 // Not the real code:
 interface IInputStream(T, I : IntegralClass)
 {
 INT_TRAITS!(I).unsigned read // out int elementsRead
 (
 inout T[] buffer,
 in INT_TRAITS!(I).signed atLeast,
 in INT_TRAITS!(I).signed atMost,
 in INT_TRAITS!(I).unsigned bufferOffset
 );
 }

 ----------------------------------





 Sigbjørn Lund Olsen wrote:

 Walter wrote:

 You can work around this by establishing a 'traits' template,
specialized
 for each signed type, that has an alias in it for the corresponding
 unsigned type.
Right... Well, it works for what I had in mind, but tbh I think this is perhaps something you ought to consider whether to change or not. See example below - this level of verbosity isn't good. Frankly, I was yearning for a preprocessor throughout the entire exercise. Having an 'unsigned' keyword to modify the primitives does more correctly show and represent the close relationship between a signed type and its unsigned companion type. It seems, to me, that this is one thing C/C++ got right and therefore shouldn't be thrown into the bin for D. template TFoo(T) { UI aMethod ( in T[] oneArgument, in I anotherArgument, in UI theLastArgument ); } interface IFoo(T, I : byte) { alias byte I; alias ubyte UI; mixin TFoo!(T); } interface IFoo(T, I : short) { alias short I; alias ushort UI; mixin TFoo!(T); } interface IFoo(T, I : int) { alias int I; alias uint UI; mixin TFoo!(T); } interface IFoo(T, I : long) { alias long I; alias ulong UI; mixin TFoo!(T); } int getSign(int number) { if (number < 0) // negative { return -1; } else if (number == 0) { return 0; } else if (number > 0) { return 1; } } class CFoo(T, I) : IFoo!(T, I) { UI aMethod ( in T[] oneArgument, in I anotherArgument, in UI theLastArgument ) body { return oneArgument.length + getSign(anotherArgument) * anotherArgument + theLastArgument; } } alias CFoo!(ubyte, byte) byteFoo; alias CFoo!(ubyte, short) shortFoo; alias CFoo!(ubyte, int) intFoo; int main(char[][] args) { ubyte[3] anArray; anArray[0] = 15; anArray[1] = 3; anArray[2] = 200; byteFoo byteObject = new byteFoo; shortFoo shortObject = new shortFoo; intFoo intObject = new intFoo; printf("byteFoo: %i\n", byteObject.aMethod(anArray, -5, 10)); printf("shortFoo: %i\n", shortObject.aMethod(anArray, 0, 1_000)); printf("intFoo: %i\n", intObject.aMethod(anArray, 17, 100_000)); return 0; } Cheers, Sigbjørn Lund Olsen
Jun 20 2004