An idiom for disabling implicit conversions

Uranuz via Digitalmars-d digitalmars-d at puremagic.com
Tue Aug 26 08:38:37 PDT 2014


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...


More information about the Digitalmars-d mailing list