Thread overview
How made my to!MyStruct
Jun 25, 2011
Zardoz
Jun 25, 2011
Jonathan M Davis
Jun 25, 2011
Jesse Phillips
Jun 25, 2011
Jonathan M Davis
Jun 25, 2011
Zardoz
June 25, 2011
Hi. I made a parametrized struct, a Vector, and I'm trying to make to! work to make conversion between Vectors with different parametrized type.

Code :

public struct Vector(T, size_t dim_)
if (__traits(isFloating, T) ) {
  static enum size_t dim = dim_; /// Vector Dimension

  static assert (dim >= 2 && dim <= 4, "Not valid dimension size.");
  static assert (__traits(isFloating, T), "Type not is a Float Point type."); // Ok, redundant
  static assert (is(T : real), "Type not is like a Float Point type.");

  union {
    private T[dim] coor; /// Vector coords like Array

    struct {
      static if( dim >= 1) T x;
      static if( dim >= 2) T y;
      static if( dim >= 3) T z;
      static if( dim >= 4) T w;
    }
  }
  // Constructors and other methods/stuff....
}

Actually I saw std.conv code and I see that to! call to a parametrized funtion called toImpl(T,S) (S s).
I made my own toImpl for convert a Vector to another Vector and I checked that it works calling directly :
/**
* to converto a vector to other vector
*/
T toImpl(T, S)(S s)
if (!implicitlyConverts!(S, T) && isVector!T && isVector!S )
{
  static assert (T.dim >= S.dim, "Original Vector bigger that destiny Vector");
  T newVector; auto i = 0;
  static if (is (typeof(newVector.x) == typeof(s.x)))  {
    for (; i < S.dim; i++)
      newVector.coor[i] =  s.coor[i];
  } else {
    for (; i < S.dim; i++)
      newVector.coor[i] =  to!(typeof(newVector.x))(s.coor[i]);
  }

  for (; i< T.dim; i++) // Expands a small vector to a bigger dimension with 0 value in extra dimension
    newVector.coor[i] = 0;

  return newVector;
}

But when I try to use to! (for example to!Vector(double, 4) (other_Vector)), I get a error from srd.conv :

/usr/include/d/dmd/phobos/std/conv.d(99): Error: template std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) &&
isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) does not match any function template
declaration
/usr/include/d/dmd/phobos/std/conv.d(99): Error: template std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) &&
isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) cannot deduce template function from
argument types !(Vector!(double,4))(Vector!(float,2))
/usr/include/d/dmd/phobos/std/conv.d(99): Error: template instance errors instantiating template
src/vector.d(139): Error: template instance std.conv.to!(Vector!(double,4)).to!(Vector!(float,2)) error instantiating

What I'm doing wrong ???

June 25, 2011
On 2011-06-25 11:09, Zardoz wrote:
> Hi. I made a parametrized struct, a Vector, and I'm trying to make to! work to make conversion between Vectors with different parametrized type.
> 
> Code :
> 
> public struct Vector(T, size_t dim_)
> if (__traits(isFloating, T) ) {
>   static enum size_t dim = dim_; /// Vector Dimension
> 
>   static assert (dim >= 2 && dim <= 4, "Not valid dimension size.");
>   static assert (__traits(isFloating, T), "Type not is a Float Point
> type."); // Ok, redundant static assert (is(T : real), "Type not is like a
> Float Point type.");
> 
>   union {
>     private T[dim] coor; /// Vector coords like Array
> 
>     struct {
>       static if( dim >= 1) T x;
>       static if( dim >= 2) T y;
>       static if( dim >= 3) T z;
>       static if( dim >= 4) T w;
>     }
>   }
>   // Constructors and other methods/stuff....
> }
> 
> Actually I saw std.conv code and I see that to! call to a parametrized
> funtion called toImpl(T,S) (S s). I made my own toImpl for convert a
> Vector to another Vector and I checked that it works calling directly :
> /**
> * to converto a vector to other vector
> */
> T toImpl(T, S)(S s)
> if (!implicitlyConverts!(S, T) && isVector!T && isVector!S )
> {
>   static assert (T.dim >= S.dim, "Original Vector bigger that destiny
> Vector"); T newVector; auto i = 0;
>   static if (is (typeof(newVector.x) == typeof(s.x)))  {
>     for (; i < S.dim; i++)
>       newVector.coor[i] =  s.coor[i];
>   } else {
>     for (; i < S.dim; i++)
>       newVector.coor[i] =  to!(typeof(newVector.x))(s.coor[i]);
>   }
> 
>   for (; i< T.dim; i++) // Expands a small vector to a bigger dimension
> with 0 value in extra dimension newVector.coor[i] = 0;
> 
>   return newVector;
> }
> 
> But when I try to use to! (for example to!Vector(double, 4)
> (other_Vector)), I get a error from srd.conv :
> 
> /usr/include/d/dmd/phobos/std/conv.d(99): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
> isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) does not match
> any function template declaration
> /usr/include/d/dmd/phobos/std/conv.d(99): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
> isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) cannot deduce
> template function from argument types
> !(Vector!(double,4))(Vector!(float,2))
> /usr/include/d/dmd/phobos/std/conv.d(99): Error: template instance errors
> instantiating template src/vector.d(139): Error: template instance
> std.conv.to!(Vector!(double,4)).to!(Vector!(float,2)) error instantiating
> 
> What I'm doing wrong ???

std.conv.to does not currently work to convert between user-defined types. There has been some discussion about making it work for such cases, and there's currently a pull request on github that deals with it, so it may be possible to convert between user-defined types with std.conv.to in the next release, but you can't currently do it.

- Jonathan M Davis
June 25, 2011
Zardoz Wrote:

> Hi. I made a parametrized struct, a Vector, and I'm trying to make to! work to make conversion between Vectors with different parametrized type.

You should be able to override opCast and have it work with std.to, or I believe that is intended to work.

June 25, 2011
On 2011-06-25 14:45, Jesse Phillips wrote:
> Zardoz Wrote:
> > Hi. I made a parametrized struct, a Vector, and I'm trying to make to! work to make conversion between Vectors with different parametrized type.
> 
> You should be able to override opCast and have it work with std.to, or I believe that is intended to work.

Nope. It won't work. It'll probably work with the next release, but it won't work right now. You can use std.conv.to instead of a cost for converting between derived objects; you can use it to convert an object to a string using its toString function; and if you have a to function on your struct or class which converts to a primitive type, you can use that with std.conv.to. But you can't currently convert between two unrelated objects using std.conv.to, even if they have the appropriate opCasts or constructors. That should change soon, but for now, we're out of luck.

- Jonathan M Davis
June 25, 2011
On Sat, 25 Jun 2011 15:32:40 -0700, Jonathan M Davis wrote:

> On 2011-06-25 14:45, Jesse Phillips wrote:
>> Zardoz Wrote:
>> > Hi. I made a parametrized struct, a Vector, and I'm trying to make to! work to make conversion between Vectors with different parametrized type.
>> 
>> You should be able to override opCast and have it work with std.to, or I believe that is intended to work.
> 
> Nope. It won't work. It'll probably work with the next release, but it won't work right now. You can use std.conv.to instead of a cost for converting between derived objects; you can use it to convert an object to a string using its toString function; and if you have a to function on your struct or class which converts to a primitive type, you can use that with std.conv.to. But you can't currently convert between two unrelated objects using std.conv.to, even if they have the appropriate opCasts or constructors. That should change soon, but for now, we're out of luck.
> 
> - Jonathan M Davis

Yep, I try with opCast and to! not works yet. At least, I can do now, things like :

auto v2d = Vector!(doble, 2) (1, 1);
auto v = cast(Vector!(float, 4)) v2d;
assert (v[0] == 1);
assert (v[1] == 1);
assert (v[2] == 0);
assert (v[3] == 0);

PD: Yep, I'm learning making a small lib to work with Vectors, Quaternions and squared Matrix...
-- 
Yep, I'm afraid that I have a blog : zardoz.es