digitalmars.D.learn - How made my to!MyStruct

• Zardoz (51/51) Jun 25 2011 Hi. I made a parametrized struct, a Vector, and I'm trying to make to! w...
• Jonathan M Davis (7/76) Jun 25 2011 std.conv.to does not currently work to convert between user-defined type...
• Jesse Phillips (2/4) Jun 25 2011 You should be able to override opCast and have it work with std.to, or I...
• Jonathan M Davis (10/17) Jun 25 2011 Nope. It won't work. It'll probably work with the next release, but it w...
• Zardoz (13/33) Jun 25 2011 Yep, I try with opCast and to! not works yet. At least, I can do now,
```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 ???
```
Jun 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
```
Jun 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.
```
Jun 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
```
Jun 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 == 1);
assert (v == 1);
assert (v == 0);
assert (v == 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
```
Jun 25 2011