OK. Nobody ansvered anything yet. So I was thinking about this problem for a while so I figured out possible soulution.

What I can do in this situation in to forbid these opertions and make compiler issue an error during compilation or implement functionality for all types that implicitly convertible to int.

But what I don't like about this idea is if I forget about some type or something will change in the future it can become failing in runtime but will issue an error compile-time. Also I need to implement a lot of methods.

In my real project ListControl is interface template so CheckListBox is also class template.

import std.stdio, std.typecons, std.traits, std.typetuple;


interface ListControl(ValueType)
{
        @property {
                void selValue(ValueType value);
        
                void selValue(Nullable!ValueType value);
                
                static if( is( ValueType == int ) )
                {
                        mixin(genSetSelValueDecls(IntCastedTypes));
                }
                else static if( is( ValueType == uint) )
                {
                        //Declaration for uint type
                }
        }
}

enum IntCastedTypes = ["bool", "byte", "ubyte", "short", "ushort", "char", "wchar"];

string genSetSelValueDecls(string[] types)
{
        string result;
        
        foreach( type; types )
                result ~= `
                        void selValue(Nullable!` ~ type ~ ` value);
                `;
        
        return result;
}

string genSetSelValueMethods(string[] types)
{
        string result;
        
        foreach( type; types )
                result ~= `
                        void selValue(Nullable!` ~ type ~ ` value)
                        {       writeln("value: ", typeof(value).stringof);
                        }
                `;
        
        return result;
}


class CheckBoxList(ValueType): ListControl!(ValueType)
{
        override @property {
                void selValue(ValueType value)
                {
                        writeln("value: ", typeof(value).stringof);   
                }
        
                void selValue(Nullable!ValueType value)
                {
                        writeln("value: ", typeof(value).stringof);   
                }
                
                static if( is( ValueType == int ) )
                {
                        mixin(genSetSelValueMethods(IntCastedTypes));
                }
                else static if( is( ValueType == uint) )
                {
                        //implementation for uint type
                }
        }

}

void main()
{
        Nullable!ubyte myValue; //it is null/uninitialized
        
        //Creating object
        auto checkBoxList = new CheckBoxList!int;
        
        checkBoxList.selValue = myValue;
}

So this is working and does what is expected to do. Although is should be unittested pretty well to eliminate all sorts of bugs.

Types that implicitly convertible to int were taken from:
http://dlang.org/type.html (IntegerPromotions)

But what I noticed is that uint type is implicitly convertible to int to. So this is not covered by example because it is not documented case. May be it is just nasty bug in compiler (I don't know but I think it is).

I thing this is a bug because uint.max cannot be correctly represented in int and shouldn't be implicitly convertibe. I raised problems with conversions between integer types a time ago but it had no result or resolution. And it's strange for me that so trivial aspects of language become source of nasty bugs.
For example:

import std.stdio;

void main()
{
        uint a = uint.max;
        writeln(a); // 4294967295
        
        int b = a;
        writeln(b); // -1
}

I don't like the situation that when implementing new feature in my library I must fight the compiler in order to get what obviously expected from it. I like the language but lots of small bugs makes me get upset.

Please fix integers! I want to use all of them: ubyte, long, short. Not only int that is considerer as priorite for some reason that I don't understand. I don't thing that compatibility with C/C++ reasons should create such a mess about integer type casts. I haven't such problems whaen I was programming in C/C++. Also notice that C is language with weak type system but D is declared to have type system. So rules should be slightly different.

Of course all of the above is just my own opinion and language designers may do whatever they like. But...

Reply via email to