www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Some problems with std.typecons.Nullable. It automaticaly calls get

reply "Uranuz" <neuranuz gmail.com> writes:
In my code I wanted to use std.typecons.Nullable to get 
advantages in web application when working with database values. 
I'm writing some struct that can get Nullable!int as input value. 
But instead of getting struct object itself (in case of 
overloading) *get* method called and programme fails. This 
happens when Nullable is null. I'll give an example:

//------
import std.stdio;

import std.typecons;

template isStdNullable(N)
{
	static if( is( N == NullableRef!(TL1), TL1... ) )
		enum bool isStdNullable = true;
	else static if( is( N == Nullable!(TL2), TL2... ) )
		enum bool isStdNullable = true;
	else
		enum bool isStdNullable = false;
}


template getStdNullableType(N)
{
	static if( is( N == NullableRef!(TL2), TL2... ) )
		alias TL2[0] getStdNullableType;
	else static if( is( N == Nullable!(TL2), TL2... ) )
		alias TL2[0] getStdNullableType;
	else
		static assert (0, `Type ` ~ fullyQualifiedName!(N) ~ ` can't be 
used as Nullable type!!!` );
}



struct Test
{	
	//Uncommenting these lines makes programme fail with assertion
	//string opIndex(int key) const
	//{	return "Not null";	}
	
	//inout(bool) opBinaryRight(string op)(int key) inout
	//{	return true;  }
	
	string opIndex(N)(N key) const
		if( isStdNullable!(N) && is( getStdNullableType!(N) == int )  )
	{	return ( key.isNull() ? "null" : "Not null" );
	
	}	
	
	inout(bool) opBinaryRight(string op, N)(N key) inout
		if(op == "in" && isStdNullable!(N) && is( 
getStdNullableType!(N) == int ))
	{	return ( key.isNull() ? true : false );  }
	
}


void main()
{
	Test test;
	
	Nullable!(int, 10) val5;
	val5 = 5;
	
	Nullable!(int, 15) valNull;
	
	writeln(test[val5]);
	writeln(test[valNull]);
	
	writeln(val5 in test);
	writeln(valNull in test);
	
}
//--------------------

In this code I want get ability to pass int values and 
Nullable!int values using overloaded operators. Template 
"functions" isStdNullable, getStdNullableType help to get 
information about type of *N*. I think that there is something 
that I don't understand about order of instantiation for 
overloaded functions.
How could I solve this problem? Or I need to write my own 
Nullable variant without "alias get this;"?

The example above is also available at: 
http://dpaste.dzfl.pl/6790f60e
Dec 09 2013
next sibling parent reply =?UTF-8?B?U2ltZW4gS2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On 09.12.2013 14:33, Uranuz wrote:
 In my code I wanted to use std.typecons.Nullable to get advantages in
 web application when working with database values. I'm writing some
 struct that can get Nullable!int as input value. But instead of getting
 struct object itself (in case of overloading) *get* method called and
 programme fails. This happens when Nullable is null. I'll give an example:

 //------
 import std.stdio;

 import std.typecons;

 template isStdNullable(N)
 {
      static if( is( N == NullableRef!(TL1), TL1... ) )
          enum bool isStdNullable = true;
      else static if( is( N == Nullable!(TL2), TL2... ) )
          enum bool isStdNullable = true;
      else
          enum bool isStdNullable = false;
 }


 template getStdNullableType(N)
 {
      static if( is( N == NullableRef!(TL2), TL2... ) )
          alias TL2[0] getStdNullableType;
      else static if( is( N == Nullable!(TL2), TL2... ) )
          alias TL2[0] getStdNullableType;
      else
          static assert (0, `Type ` ~ fullyQualifiedName!(N) ~ ` can't be
 used as Nullable type!!!` );
 }



 struct Test
 {
      //Uncommenting these lines makes programme fail with assertion
      //string opIndex(int key) const
      //{    return "Not null";    }

      //inout(bool) opBinaryRight(string op)(int key) inout
      //{    return true;  }

      string opIndex(N)(N key) const
          if( isStdNullable!(N) && is( getStdNullableType!(N) == int )  )
      {    return ( key.isNull() ? "null" : "Not null" );

      }

      inout(bool) opBinaryRight(string op, N)(N key) inout
          if(op == "in" && isStdNullable!(N) && is(
 getStdNullableType!(N) == int ))
      {    return ( key.isNull() ? true : false );  }

 }


 void main()
 {
      Test test;

      Nullable!(int, 10) val5;
      val5 = 5;

      Nullable!(int, 15) valNull;

      writeln(test[val5]);
      writeln(test[valNull]);

      writeln(val5 in test);
      writeln(valNull in test);

 }
 //--------------------

 In this code I want get ability to pass int values and Nullable!int
 values using overloaded operators. Template "functions" isStdNullable,
 getStdNullableType help to get information about type of *N*. I think
 that there is something that I don't understand about order of
 instantiation for overloaded functions.
 How could I solve this problem? Or I need to write my own Nullable
 variant without "alias get this;"?
The simple solution is to make your int-specialized functions do their specialization in template constraints: string opIndex(N)(N key) const if (is(N == int)) { return "Not null"; } bool opBinaryRight(string op, N)(N key) const if (is(N == int)) { return true; } I'm not entirely sure why this behavior occurs. One would think not applying alias this would make for a better match than applying it. btw, in the future you might want to keep discussions like this in digitalmars.D.learn. -- Simen
Dec 09 2013
parent "Uranuz" <neuranuz gmail.com> writes:
Thanks. It works, though it looks awkward.
Dec 09 2013
prev sibling parent "Tommi" <tommitissari hotmail.com> writes:
Perhaps it's a result of a compiler-bug I reported over here:
https://d.puremagic.com/issues/show_bug.cgi?id=11499
Dec 09 2013