Thread overview
Templates ~ best way to limit types?
Dec 12, 2005
Kris
Dec 12, 2005
Don Clugston
Dec 12, 2005
kris
Dec 12, 2005
Sean Kelly
Dec 12, 2005
Kris
Dec 12, 2005
Sean Kelly
Dec 12, 2005
Sean Kelly
Dec 12, 2005
Oskar Linde
Dec 12, 2005
Kris
December 12, 2005
class MyTemplate(T)
{
        static if (is (T == char)) {}
        else
        static if (is (T == wchar)) {}
        else
        static if (is (T == wchar)) {}
        else
           {
           pragma (msg, "Template type must be char, wchar, or dchar");
           static assert(0);
           }

    // ...
}

what is the best (most succinct?) way to limit the T type? What I'm looking for is a nice compile time message saying "type must be x, y, or z" ...

The current approach is noted above, but I imagine/hope it could be a lot better?

Also, is there a better way to halt the compiler? So many error messages are emitted that it's quite hard to see the pragma message :-)

Thanks;


December 12, 2005
Kris wrote:
> class MyTemplate(T)
> {
>         static if (is (T == char)) {}
>         else
>         static if (is (T == wchar)) {}
>         else
>         static if (is (T == wchar)) {}
>         else
>            {
>            pragma (msg, "Template type must be char, wchar, or dchar");
>            static assert(0);
>            }
> 
>     // ...
> }
> 
> what is the best (most succinct?) way to limit the T type? What I'm looking for is a nice compile time message saying "type must be x, y, or z" ...

Hmm, sounds like the 'constraints' proposal being discussed for C++0x.
Right now, the best I can think of is something like:

template isInList(T, A, B, C) {
static if (is (T==A)) const bool isInList=true;
else static if (is(T==B)) const bool isInList=true;
else static if (is(T==C)) const bool isInList=true;
else const bool isInList=false;
}

class MyTemplate(T)
{
   static assert(isInList(T, char, wchar, dchar));
}

obviously with overloads of isInList() for different numbers of arguments. The preprocessor strikes again, until we get varag templates...

> Also, is there a better way to halt the compiler? So many error messages are emitted that it's quite hard to see the pragma message :-)

I think that static assert() should halt compilation, just as assert() halts at runtime. Do you see any problems with that?
(I've had terrible problems with a static assert in a recursive function, you get the same error two million times).
December 12, 2005
Don Clugston wrote:
> Kris wrote:
> 
>> class MyTemplate(T)
>> {
>>         static if (is (T == char)) {}
>>         else
>>         static if (is (T == wchar)) {}
>>         else
>>         static if (is (T == wchar)) {}
>>         else
>>            {
>>            pragma (msg, "Template type must be char, wchar, or dchar");
>>            static assert(0);
>>            }
>>
>>     // ...
>> }
>>
>> what is the best (most succinct?) way to limit the T type? What I'm looking for is a nice compile time message saying "type must be x, y, or z" ...
> 
> 
> Hmm, sounds like the 'constraints' proposal being discussed for C++0x.
> Right now, the best I can think of is something like:
> 
> template isInList(T, A, B, C) {
> static if (is (T==A)) const bool isInList=true;
> else static if (is(T==B)) const bool isInList=true;
> else static if (is(T==C)) const bool isInList=true;
> else const bool isInList=false;
> }
> 
> class MyTemplate(T)
> {
>    static assert(isInList(T, char, wchar, dchar));
> }
> 
> obviously with overloads of isInList() for different numbers of arguments. The preprocessor strikes again, until we get varag templates...
> 
>> Also, is there a better way to halt the compiler? So many error messages are emitted that it's quite hard to see the pragma message :-)
> 
> 
> I think that static assert() should halt compilation, just as assert() halts at runtime. Do you see any problems with that?
> (I've had terrible problems with a static assert in a recursive function, you get the same error two million times).

Thanks Don!

That looks more useful. Static assert() does halt, but not quickly enough I'm afraid ~ it just adds another little warning to the sea washing over the console :)
December 12, 2005
Don Clugston wrote:
> Kris wrote:
>> class MyTemplate(T)
>> {
>>         static if (is (T == char)) {}
>>         else
>>         static if (is (T == wchar)) {}
>>         else
>>         static if (is (T == wchar)) {}
>>         else
>>            {
>>            pragma (msg, "Template type must be char, wchar, or dchar");
>>            static assert(0);
>>            }
>>
>>     // ...
>> }
>>
>> what is the best (most succinct?) way to limit the T type? What I'm looking for is a nice compile time message saying "type must be x, y, or z" ...
> 
> Hmm, sounds like the 'constraints' proposal being discussed for C++0x.
> Right now, the best I can think of is something like:
> 
> template isInList(T, A, B, C) {
> static if (is (T==A)) const bool isInList=true;
> else static if (is(T==B)) const bool isInList=true;
> else static if (is(T==C)) const bool isInList=true;
> else const bool isInList=false;
> }
> 
> class MyTemplate(T)
> {
>    static assert(isInList(T, char, wchar, dchar));
> }
> 
> obviously with overloads of isInList() for different numbers of arguments. The preprocessor strikes again, until we get varag templates...

You can also do something like this:

template isValidType( T ) {
    const bit isValidType = is(T:char) || is(T:wchar);
}

template doSomething( T, bit vt : true = isValidType!(T) )
{
	// make sure the user isn't trying to trick us
	static assert( isValidType!(T) );
	...
}


Sean
December 12, 2005
Thx Sean;

What is the difference between "is (T:char)" and "is (T == char)" ? I had the impression there was one, but can't find it now ...



"Sean Kelly" <sean@f4.ca> wrote in message news:dnklve$2cqj$1@digitaldaemon.com...
> Don Clugston wrote:
>> Kris wrote:
>>> class MyTemplate(T)
>>> {
>>>         static if (is (T == char)) {}
>>>         else
>>>         static if (is (T == wchar)) {}
>>>         else
>>>         static if (is (T == wchar)) {}
>>>         else
>>>            {
>>>            pragma (msg, "Template type must be char, wchar, or dchar");
>>>            static assert(0);
>>>            }
>>>
>>>     // ...
>>> }
>>>
>>> what is the best (most succinct?) way to limit the T type? What I'm looking for is a nice compile time message saying "type must be x, y, or z" ...
>>
>> Hmm, sounds like the 'constraints' proposal being discussed for C++0x. Right now, the best I can think of is something like:
>>
>> template isInList(T, A, B, C) {
>> static if (is (T==A)) const bool isInList=true;
>> else static if (is(T==B)) const bool isInList=true;
>> else static if (is(T==C)) const bool isInList=true;
>> else const bool isInList=false;
>> }
>>
>> class MyTemplate(T)
>> {
>>    static assert(isInList(T, char, wchar, dchar));
>> }
>>
>> obviously with overloads of isInList() for different numbers of arguments. The preprocessor strikes again, until we get varag templates...
>
> You can also do something like this:
>
> template isValidType( T ) {
>     const bit isValidType = is(T:char) || is(T:wchar);
> }
>
> template doSomething( T, bit vt : true = isValidType!(T) )
> {
> // make sure the user isn't trying to trick us
> static assert( isValidType!(T) );
> ...
> }
>
>
> Sean


December 12, 2005
Kris wrote:
> Thx Sean;
> 
> What is the difference between "is (T:char)" and "is (T == char)" ? I had the impression there was one, but can't find it now ...

You probably want "T==char."  IIRC, "T:char" requires that T be convertible to char while "T==char" requires that T be the type 'char'.  I really need to fix this for std.atomic as well :-)


Sean
December 12, 2005
Sean Kelly wrote:
> Kris wrote:
>> Thx Sean;
>>
>> What is the difference between "is (T:char)" and "is (T == char)" ? I had the impression there was one, but can't find it now ...
> 
> You probably want "T==char."  IIRC, "T:char" requires that T be convertible to char while "T==char" requires that T be the type 'char'.  I really need to fix this for std.atomic as well :-)

Oh, the reason I suggested my method is that it should just not instantiate the template at all if the type doesn't match, which should provide more useful error messages.  I do like Don's pseudo typelist approach for over my isValidType template, so the two could be combined as well.


Sean
December 12, 2005
Kris wrote:
> Thx Sean;
> 
> What is the difference between "is (T:char)" and "is (T == char)" ? I had the impression there was one, but can't find it now ...

As far as I have understood,
is (T:char) is true if T is implicitly convertible to char,
is (T == char) is true only for T == char

i.e. is (int:char) is true, while is (int == char) is false.

/Oskar
December 12, 2005
Thx!

"Oskar Linde" <oskar.lindeREM@OVEgmail.com> wrote in message news:dnknih$2f3j$1@digitaldaemon.com...
> Kris wrote:
>> Thx Sean;
>>
>> What is the difference between "is (T:char)" and "is (T == char)" ? I had the impression there was one, but can't find it now ...
>
> As far as I have understood,
> is (T:char) is true if T is implicitly convertible to char,
> is (T == char) is true only for T == char
>
> i.e. is (int:char) is true, while is (int == char) is false.
>
> /Oskar