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: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 DavisHi. 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 Sat, 25 Jun 2011 15:32:40 -0700, Jonathan M Davis wrote:On 2011-06-25 14:45, Jesse Phillips wrote: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.esZardoz Wrote: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 DavisHi. 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