class specialization for integral types

Charles Hixson charleshixsn at earthlink.net
Sat Sep 24 17:41:52 PDT 2011


I spoke too soon.
class	AA(Key, Data)	if	(isNumeric (Key) )
  didn't work with a larger case,

s$ dmd aa.d
/usr/include/d/dmd/phobos/std/traits.d(2576): Error: template 
std.traits.isNumeric(T) is not a function template
aa.d(200): Error: template std.traits.isNumeric(T) cannot deduce 
template function from argument types !()(int)
aa.d(494): Error: template instance AA!(int,string) does not match 
template declaration AA(Key,Data) if (isNumeric(Key))
aa.d(494): Error: AA!(int,string) is used as a type


though
class	AA (Key, Data)	if (is (Key : long))
did work.  Or at least it compiled without error.

On 09/24/2011 05:05 PM, Charles Hixson wrote:
On 09/24/2011 05:05 PM, Charles Hixson wrote:
> On 09/24/2011 04:31 PM, Jonathan M Davis wrote:
>> On Saturday, September 24, 2011 16:14:48 Charles Hixson wrote:
>>> On 09/24/2011 02:33 PM, Jonathan M Davis wrote:
>>>> On Saturday, September 24, 2011 14:16:12 Charles Hixson wrote:
>>>>> How would a specialize a parameterized class to only allow integral
>>>>> parameters (i.e., anything that would respond "true" to
>>>>> static if (is (T : long) )
>>>>>
>>>>> (I'd have said "static if (is (T : cent) )" or "static if (is (T :
>>>>> ucent) )", but those are still marked "reserved for future use".)
>>>>>
>>>>> I do want to allow byte, ubyte, etc. to be legal values.
>>>>
>>>> Parameterized? As in templated? Just use a template constraint.
>>>>
>>>> class C(T)
>>>>
>>>> if(is(T : long))
>>>>
>>>> {
>>>> }
>>>>
>>>> T will then be allowed to be anything which is implicitly
>>>> convertible to
>>>> long. I'd suggest using std.traits.isIntegral instead though.
>>>>
>>>> class C(T)
>>>>
>>>> if(isIntegral!T)
>>>>
>>>> {
>>>> }
>>>>
>>>> It specifically tests for whether the type is a byte, ubyte, short,
>>>> ushort, int, uint, long, or ulong, so it won't included stray structs
>>>> or classes which would be implicitly convertible to long, and if/when
>>>> eont and ucent come along, they'd be added to isIntegral and be
>>>> automatically supported.
>>>>
>>>> - Jonathan M Davis
>>>
>>> Thanks. isIntegral has given me some error messages that I couldn't
>>> understand, though, so I'll take your first suggestion.
>>>
>>> This is actually a rephrase of the question I first sent, when somehow
>>> didn't appear on the list:
>>>
>>> When checking a template variable, what are the base cases for is?
>>> long will satisfy all integer types. I.e.
>>> is (typeof(tst0) : long) == true
>>> real will satisfy all floating point types.
>>> I think that string will satisfy all arrays of characters (need to check
>>> that).
>>>
>>> But there are lots of other kinds of array. And while Object will
>>> satisfy all classes, I don't know anything analogous for structs. Then
>>> there's enums (would they be caught by their base type as above, or with
>>> they be like string and require an immutable corresponding to the
>>> base type?
>>>
>>> I'd like to create a chunk of code that will handle all possible types
>>> (for a particular operation) but how to do this isn't obvious. I can
>>> handle most common types, but there seem to be LOTS of less frequent
>>> types.
>>
>> You really should look at std.traits. It has that sort of stuff in it.
>> It's
>> what you should be using for really general stuff. Unqual,
>> isDynamicArray,
>> isFloatingPoint, etc. are all the sorts of things that you should be
>> using for
>> general tests on types.
>>
>> is(T == U) is going to be true if T and U are exactly the same type.
>>
>> is(T : U) is going to be true if T is implicitly convertible to U.
>>
>> If all that you care about is class or struct, then you can use
>>
>> is(T == class)
>> is(T == struct)
>>
>> You should also look at
>> http://www.d-programming-language.org/traits.html.
>>
>> - Jonathan M Davis
>
> You're right. std.traits is where I should be looking.

> On 09/24/2011 04:31 PM, Jonathan M Davis wrote:
>> On Saturday, September 24, 2011 16:14:48 Charles Hixson wrote:
>>> On 09/24/2011 02:33 PM, Jonathan M Davis wrote:
>>>> On Saturday, September 24, 2011 14:16:12 Charles Hixson wrote:
>>>>> How would a specialize a parameterized class to only allow integral
>>>>> parameters (i.e., anything that would respond "true" to
>>>>> static if (is (T : long) )
>>>>>
>>>>> (I'd have said "static if (is (T : cent) )" or "static if (is (T :
>>>>> ucent) )", but those are still marked "reserved for future use".)
>>>>>
>>>>> I do want to allow byte, ubyte, etc. to be legal values.
>>>>
>>>> Parameterized? As in templated? Just use a template constraint.
>>>>
>>>> class C(T)
>>>>
>>>> if(is(T : long))
>>>>
>>>> {
>>>> }
>>>>
>>>> T will then be allowed to be anything which is implicitly
>>>> convertible to
>>>> long. I'd suggest using std.traits.isIntegral instead though.
>>>>
>>>> class C(T)
>>>>
>>>> if(isIntegral!T)
>>>>
>>>> {
>>>> }
>>>>
>>>> It specifically tests for whether the type is a byte, ubyte, short,
>>>> ushort, int, uint, long, or ulong, so it won't included stray structs
>>>> or classes which would be implicitly convertible to long, and if/when
>>>> eont and ucent come along, they'd be added to isIntegral and be
>>>> automatically supported.
>>>>
>>>> - Jonathan M Davis
>>>
>>> Thanks. isIntegral has given me some error messages that I couldn't
>>> understand, though, so I'll take your first suggestion.
>>>
>>> This is actually a rephrase of the question I first sent, when somehow
>>> didn't appear on the list:
>>>
>>> When checking a template variable, what are the base cases for is?
>>> long will satisfy all integer types. I.e.
>>> is (typeof(tst0) : long) == true
>>> real will satisfy all floating point types.
>>> I think that string will satisfy all arrays of characters (need to check
>>> that).
>>>
>>> But there are lots of other kinds of array. And while Object will
>>> satisfy all classes, I don't know anything analogous for structs. Then
>>> there's enums (would they be caught by their base type as above, or with
>>> they be like string and require an immutable corresponding to the
>>> base type?
>>>
>>> I'd like to create a chunk of code that will handle all possible types
>>> (for a particular operation) but how to do this isn't obvious. I can
>>> handle most common types, but there seem to be LOTS of less frequent
>>> types.
>>
>> You really should look at std.traits. It has that sort of stuff in it.
>> It's
>> what you should be using for really general stuff. Unqual,
>> isDynamicArray,
>> isFloatingPoint, etc. are all the sorts of things that you should be
>> using for
>> general tests on types.
>>
>> is(T == U) is going to be true if T and U are exactly the same type.
>>
>> is(T : U) is going to be true if T is implicitly convertible to U.
>>
>> If all that you care about is class or struct, then you can use
>>
>> is(T == class)
>> is(T == struct)
>>
>> You should also look at
>> http://www.d-programming-language.org/traits.html.
>>
>> - Jonathan M Davis
>
> You're right. std.traits is where I should be looking.



More information about the Digitalmars-d-learn mailing list