Re: Traits
On Friday, October 11, 2013 22:31:25 Jonathan M Davis wrote: > On Saturday, October 12, 2013 00:54:48 luminousone wrote: > > The inability to handle null is pretty big, specially considering > > that at not point is the class instance itself cared about!, > > No. It's expected. When you are casting to a particular object to test > whether the object is of that type, you are testing the type that the > object is, and if the object is null, then it is _not_ of the type that > you're casting to. > > Again this should be done via reflection, this method above is > > hackish at best. > > Testing via compile-time reflection is testing for something fundamentally > different than what casting is testing for. With casting, you're testing > whether the object is the type that you're casting to or a type derived from > the type that you're casting to. With compile-time reflection, you're > testing whether a particular type is derived from another type. One is > testing an instance. The other is testing a type. The two are completely > different. I'd also point out that if you have class A { } class B : A { } B is _not_ an instance of A. It's a subclass of A. An instance is an object in memory, not the type of the object. auto a = new A; //instance of A auto b = new B; //instance of B A c = new B; //instance of B A d; //There is no instance here. The reference is null. B e; //There's no instance here either for the same reason. So, you're using the term "instance of" incorrectly. - Jonathan M Davis
Re: Traits
On Saturday, October 12, 2013 00:54:48 luminousone wrote: > The inability to handle null is pretty big, specially considering > that at not point is the class instance itself cared about!, No. It's expected. When you are casting to a particular object to test whether the object is of that type, you are testing the type that the object is, and if the object is null, then it is _not_ of the type that you're casting to. > Again this should be done via reflection, this method above is > hackish at best. Testing via compile-time reflection is testing for something fundamentally different than what casting is testing for. With casting, you're testing whether the object is the type that you're casting to or a type derived from the type that you're casting to. With compile-time reflection, you're testing whether a particular type is derived from another type. One is testing an instance. The other is testing a type. The two are completely different. - Jonathan M Davis
Can't inherit a class and multiple interfaces.
Like the the title says, i cannot inherit a class and have interfaces. class A { } interface B { } class C : A, B -> Error { } I know that D doesn't support multiple classes, but that means i cannot mix a class and an interface?
Re: Can't inherit a class and multiple interfaces.
On Saturday, 12 October 2013 at 01:35:48 UTC, Agustin wrote: Like the the title says, i cannot inherit a class and have interfaces. class A { } interface B { } class C : A, B -> Error { } I know that D doesn't support multiple classes, but that means i cannot mix a class and an interface? Oh i had a typo error, no need to answer me this :D
Re: My design need friends
On Friday, 11 October 2013 at 22:39:18 UTC, Namespace wrote: On Sunday, 6 October 2013 at 13:11:02 UTC, Andrej Mitrovic wrote: On 10/6/13, Namespace wrote: And I should write a blog post about your and my solution. :) Let me try to hack on __PRETTY_FUNCTION__ first and I'll post a working example here soon. Is there something new? I have. Foo_1: import std.stdio; import Bar_1; struct friend(T) { public: alias Friend = T; } @friend!(Bar) class Foo { public: void call(Bar b) { _call_a_friend(b, this, &b.bar, 42); //b.bar(42); } } Bar_1: import std.stdio; import std.string : format; class Bar { package: void bar(int id) { writeln("Bar.bar with ", id); } } void _call_a_friend(F, T, string filename = __FILE__, size_t line = __LINE__, Args...)(const F friend, const T caller, void delegate(Args) dg, Args args) { bool isFriend = false; foreach (attr; __traits(getAttributes, T)) { isFriend = is(attr.Friend) && is(attr.Friend == F); if (isFriend) break; } //writeln(isFriend); if (isFriend) dg(args); else throw new Exception(format("%s is not a friend of %s.", __traits(identifier, T), __traits(identifier, F)), filename, line); } main: import Foo_1; import Bar_1; void main() { Foo f = new Foo(); Bar b = new Bar(); f.call(b); } I have to admit that the '_call_a_friend' method is a bit parameter heavy. :D Suggestions?
Re: Traits
On Friday, 11 October 2013 at 21:49:50 UTC, Jonathan M Davis wrote: On Friday, October 11, 2013 23:06:53 luminousone wrote: On Friday, 11 October 2013 at 19:54:39 UTC, Jonathan M Davis wrote: > On Friday, October 11, 2013 21:19:29 luminousone wrote: >> Using casts that way won't always be correct, it would be >> better >> to use reflection in some way if possible. > > The only reason that the casts wouldn't be correct would be > if > the class > overrode opCast for the type that you're casting to or had an > alias this > declaration for it. Using casting for "instanceOf" is > considered the standard > and correct way to do it. But if you're being paranoid about > the possibility > of a conversion being defined with opCast or alias this, then > yes, you need to > use typeid. > > - Jonathan M Davis import std.stdio; bool instanceOf(A, B)(B value) { return !!cast(A)value; } class e { } class f : e { } class g { } void main() { int a; float b; char c; e E; f F; g G; assert( 1.instanceOf!int, "1"); assert( a.instanceOf!int, "a"); // fails here ?!? assert( b.instanceOf!int, "b"); assert( c.instanceOf!int, "c"); assert( E.instanceOf!e , "e"); // fails here !?? assert( F.instanceOf!e , "f"); assert( G.instanceOf!e , "g"); // fails as expected } Seems to be problems, at least with quick testing using rdmd. Using casts seems terribly hackish, I would think that some sort of reflection should be much safer/correct way todo this. Two things: 1. Casting to determine the type of a variable only makes sense with classes. The idea is that casting a reference to a particular class will result in null if the cast fails. That doesn't work at all with types that aren't classes. 2. All of your objects are null. Of course the cast is going to fail. You need to be operating on actual instances. The whole point of casting is to check the actual type of an object at runtime. It's a completely different use case from using compile-time reflection on two types to see whether one is a base class of the other. And usually all that's done for that is to see whether one implicitly converts to the other, which is(DerivedClass : BaseClass) will do for you. The only reason to use compile-time reflection is if you're want to make sure that DerivedClass doesn't implicitly convert to BaseClass via alias this instead of by actually being a class derived from BaseClass. I'd also change the implementation of instanceOf to something like bool instanceOf(A, B)(B value) if(is(A == class) && is(B == class)) { return cast(A)value !is null; } since it doesn't rely on the conversion to bool that ! does and is more explicit that way, but the other version will work. - Jonathan M Davis The inability to handle null is pretty big, specially considering that at not point is the class instance itself cared about!, Again this should be done via reflection, this method above is hackish at best. perhaps, bool instanceOf(A, B)( ) if( is( A == class ) && is( B == class ) ) { if( __traits( isSame, A, B ) ) return true; foreach( k, v ; BaseClassesTuple!A ) { if( __traits(isSame, B, v ) ) return true; } return false; }
Re: My design need friends
On Sunday, 6 October 2013 at 13:11:02 UTC, Andrej Mitrovic wrote: On 10/6/13, Namespace wrote: And I should write a blog post about your and my solution. :) Let me try to hack on __PRETTY_FUNCTION__ first and I'll post a working example here soon. Is there something new?
Re: Linker error: Symbol Undefined
On Friday, 11 October 2013 at 21:16:38 UTC, Brad Roberts wrote: It's due to having the destructor versioned out when building foo and visible when building bar. When brought together, you've created an incompatible whole. There's no destructor actually included in foo's .o file that you told it it could expect to find. There's no bug in the compiler or linker, just your usage of mis-matched code. On 10/11/13 11:39 AM, Namespace wrote: Hey, I'm curious about this linker error: OPTLINK (R) for Win32 Release 8.00.13 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html bar.obj(bar) Error 42: Symbol Undefined _D3foo1A6__dtorMFZv --- errorlevel 1 foo.d: debug import std.stdio; struct A { public: int id; this(int id) { debug writeln("CTor A with ", id); this.id = id; } debug ~this() { writeln("DTor A with ", id); } } bar.d import foo; void test(A a) { a.id++; } void main() { test(A(42)); A a = A(23); test(a); } Usage: C:\Users\Besitzer\Desktop>dmd -lib foo.d C:\Users\Besitzer\Desktop>dmd bar.d foo.lib -debug OPTLINK (R) for Win32 Release 8.00.13 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html bar.obj(bar) Error 42: Symbol Undefined _D3foo1A6__dtorMFZv --- errorlevel 1 Without -debug or with 'debug' _in_ the DTor (before writeln) instead before the DTor works fine. Another question: Is there a way that the DTor is only generated if I compile foo with -debug? So that if I compile and link bar.d and foo.lib, even with -debug, but compiled foo.d without, the DTor is automatically generated? Hope that is not to weird. :D
Re: Linker error: Symbol Undefined
Ok, that is what I wanted to hear.
Re: Traits
On Friday, October 11, 2013 23:06:53 luminousone wrote: > On Friday, 11 October 2013 at 19:54:39 UTC, Jonathan M Davis > > wrote: > > On Friday, October 11, 2013 21:19:29 luminousone wrote: > >> Using casts that way won't always be correct, it would be > >> better > >> to use reflection in some way if possible. > > > > The only reason that the casts wouldn't be correct would be if > > the class > > overrode opCast for the type that you're casting to or had an > > alias this > > declaration for it. Using casting for "instanceOf" is > > considered the standard > > and correct way to do it. But if you're being paranoid about > > the possibility > > of a conversion being defined with opCast or alias this, then > > yes, you need to > > use typeid. > > > > - Jonathan M Davis > > import std.stdio; > > bool instanceOf(A, B)(B value) { > return !!cast(A)value; > } > > class e { > } > > class f : e { > > } > > class g { > > } > > > void main() { > int a; > float b; > char c; > > e E; > f F; > g G; > > assert( 1.instanceOf!int, "1"); > assert( a.instanceOf!int, "a"); // fails here ?!? > assert( b.instanceOf!int, "b"); > assert( c.instanceOf!int, "c"); > > assert( E.instanceOf!e , "e"); // fails here !?? > assert( F.instanceOf!e , "f"); > assert( G.instanceOf!e , "g"); // fails as expected > } > > > Seems to be problems, at least with quick testing using rdmd. > Using casts seems terribly hackish, I would think that some sort > of reflection should be much safer/correct way todo this. Two things: 1. Casting to determine the type of a variable only makes sense with classes. The idea is that casting a reference to a particular class will result in null if the cast fails. That doesn't work at all with types that aren't classes. 2. All of your objects are null. Of course the cast is going to fail. You need to be operating on actual instances. The whole point of casting is to check the actual type of an object at runtime. It's a completely different use case from using compile-time reflection on two types to see whether one is a base class of the other. And usually all that's done for that is to see whether one implicitly converts to the other, which is(DerivedClass : BaseClass) will do for you. The only reason to use compile-time reflection is if you're want to make sure that DerivedClass doesn't implicitly convert to BaseClass via alias this instead of by actually being a class derived from BaseClass. I'd also change the implementation of instanceOf to something like bool instanceOf(A, B)(B value) if(is(A == class) && is(B == class)) { return cast(A)value !is null; } since it doesn't rely on the conversion to bool that ! does and is more explicit that way, but the other version will work. - Jonathan M Davis
Re: Linker error: Symbol Undefined
It's due to having the destructor versioned out when building foo and visible when building bar. When brought together, you've created an incompatible whole. There's no destructor actually included in foo's .o file that you told it it could expect to find. There's no bug in the compiler or linker, just your usage of mis-matched code. On 10/11/13 11:39 AM, Namespace wrote: Hey, I'm curious about this linker error: OPTLINK (R) for Win32 Release 8.00.13 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html bar.obj(bar) Error 42: Symbol Undefined _D3foo1A6__dtorMFZv --- errorlevel 1 foo.d: debug import std.stdio; struct A { public: int id; this(int id) { debug writeln("CTor A with ", id); this.id = id; } debug ~this() { writeln("DTor A with ", id); } } bar.d import foo; void test(A a) { a.id++; } void main() { test(A(42)); A a = A(23); test(a); } Usage: C:\Users\Besitzer\Desktop>dmd -lib foo.d C:\Users\Besitzer\Desktop>dmd bar.d foo.lib -debug OPTLINK (R) for Win32 Release 8.00.13 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html bar.obj(bar) Error 42: Symbol Undefined _D3foo1A6__dtorMFZv --- errorlevel 1 Without -debug or with 'debug' _in_ the DTor (before writeln) instead before the DTor works fine.
Re: Traits
On Friday, 11 October 2013 at 19:54:39 UTC, Jonathan M Davis wrote: On Friday, October 11, 2013 21:19:29 luminousone wrote: Using casts that way won't always be correct, it would be better to use reflection in some way if possible. The only reason that the casts wouldn't be correct would be if the class overrode opCast for the type that you're casting to or had an alias this declaration for it. Using casting for "instanceOf" is considered the standard and correct way to do it. But if you're being paranoid about the possibility of a conversion being defined with opCast or alias this, then yes, you need to use typeid. - Jonathan M Davis import std.stdio; bool instanceOf(A, B)(B value) { return !!cast(A)value; } class e { } class f : e { } class g { } void main() { int a; float b; char c; e E; f F; g G; assert( 1.instanceOf!int, "1"); assert( a.instanceOf!int, "a"); // fails here ?!? assert( b.instanceOf!int, "b"); assert( c.instanceOf!int, "c"); assert( E.instanceOf!e , "e"); // fails here !?? assert( F.instanceOf!e , "f"); assert( G.instanceOf!e , "g"); // fails as expected } Seems to be problems, at least with quick testing using rdmd. Using casts seems terribly hackish, I would think that some sort of reflection should be much safer/correct way todo this.
Re: Traits
On Friday, 11 October 2013 at 19:19:31 UTC, luminousone wrote: On Friday, 11 October 2013 at 14:09:09 UTC, Gary Willoughby wrote: On Friday, 11 October 2013 at 05:49:38 UTC, luminousone wrote: On Friday, 11 October 2013 at 04:13:55 UTC, Agustin wrote: I have a function that needs to check if the template provided inherit a class. For example: public void function(T, A...)(auto ref A values) { // static assert(IsBaseOf(L, T)); } Check if T inherit class "L". Same result that std::is_base_of::value using C++. Any clean way to do it, without a dirty hack. import std.traits; bool ChildInheritsFromParent( parent, child )( ) { foreach ( k, t; BaseClassesTuple!child ) { if( typeid(t) == typeid(parent) ) return true; } return false; } A simpler way: import std.stdio; bool instanceOf(A, B)(B value) { return !!cast(A)value; } void main() { assert(1.instanceOf!(int)); } Using casts that way won't always be correct, it would be better to use reflection in some way if possible. This is wrong for me because i don't have a value, i just wanted to check if a template parameter inherit a class at compile time. bool instanceOf(A, B)();
Re: Starting D with a project in mind.
On Friday, 11 October 2013 at 07:09:17 UTC, Andrew wrote: As Adam already said D on Pi is adventurous. For MongoDB and web stuff, you should look into Vibe.d [0]. For parsing I would suggest Pegged [1]. Welcome to D and Happy Hacking! :) [0] http://vibed.org/ [1] https://github.com/PhilippeSigaud/Pegged Thanks both. Well after several hours of hacking I have spectacularly failed to build GDC on any arm based debian environment - tried both my RPi and Cubieboard. In both cases it fails with a pile of compilation errors. I'm guessing that D just isn't mainstream enough at the moment to be properly supported on Debian and yet it's too big and complicated to build easily yourself and so it's probably a non-starter for me at the moment. There is a pre-built package on debian gdc-4.4 but it's too old to build vibe or dub from my experimentation. I guess I'll go back to plain old C. Thanks anyway - I'll check back in a few years. Hi, I don't know which instructions you followed, but building GDC for the Pi was slow (overnight job) but in the end relatively pain free for me using these instructions: http://gdcproject.org/wiki/Raspberry%20Pi/build/Raspbian%28Hardfloat%29/GCC-Devel. This was some time ago however (more than a year by now, wow), so I don't know if some change has broken the process since. I don't think I have the SD card with GDC installed anymore so I don't know for sure which version I built at the time. I think it was based on 2.0.59 still. See also http://forum.dlang.org/thread/kpdcgoynlofeosxaj...@forum.dlang.org. When I have some free time I will fire up one of my Pis and give it a try again and report back. Cheers, Stefan
Re: fast floor
On 11/10/2013 07:25, monarch_dodra wrote:> On Thursday, 10 October 2013 at 22:27:14 UTC, Spacen Jasset wrote: >> Hello, >> >> I am after a fast floor function; In fact a fast truncation and >> conversion to integer. I see that std.math takes a real, and that >> std.c.math takes a double. >> >> Is there a quicker function, and what might cast(int)1.5f do? >> >> Regards, >> >> Spacen. > > casting to int does't "floor" a floating type. It truncates it > towards 0. eg: > cast(int)-2.5 => 2. > > Keep that in mind, and ask yourself which you require (in > particular, do you even care about negatives at all)? > > AFAIK, the "point" of floor is to have a double "end to end": if > you use: > double df = cast(int)mydouble; > Then: > a) You'll lose performance by transforming to int, when floor is > smart enough not to. > b) if mydouble doesn't fit in an int, it'll fail (in this case, > floor does nothing, but it doesn't clobber your mydouble either. > > So, if you don't need a double at the end, I *think* using > cast(int) is probably faster. > > To protecte yourself from overflow/underflow problems, you can > also use "to", eg: > int myInt = to!int(myDouble); > > As long as you are in positive space, this is probably what you > want, and probably as fast as it gets. > > If you have to take into account negative numbers, things get > more hairy. I'd use either of: > to!int(foor(x)); //As suggested by JRW > or > (x < 0) ? -to!int(-x) : to!int(x) > > However, you'd have to bench to *really* know which is fastest. > > Honestly, at the end of the day, I'd just use > to!int(foor(x)); > > THEN I'd profile, and then I'd see if it's worth trying to throw > optimizations at it. I will have to learn about what "to" does exactly. It wasn't around when I looked at D x years ago. My rounding-truncation is for a graphical demo, nothing serious or accurate, but it's important it be fast. I've found that for my purposes cast(int) some_float causes the program to run 47% faster, which is what I was looking for. I am just reading up on the D floating point pages which I have discovered to see how this works. It is, incidentally a similar story for C++.
Re: Linker error: Symbol Undefined
It's annoying and I don't get it. What is the problem of Optlink? I tried version(unittest) instead of debug. It works then with -debug, but if you compile with -unittest you get the same error.
Re: Traits
On Friday, October 11, 2013 21:19:29 luminousone wrote: > Using casts that way won't always be correct, it would be better > to use reflection in some way if possible. The only reason that the casts wouldn't be correct would be if the class overrode opCast for the type that you're casting to or had an alias this declaration for it. Using casting for "instanceOf" is considered the standard and correct way to do it. But if you're being paranoid about the possibility of a conversion being defined with opCast or alias this, then yes, you need to use typeid. - Jonathan M Davis
Re: Traits
On Friday, 11 October 2013 at 14:09:09 UTC, Gary Willoughby wrote: On Friday, 11 October 2013 at 05:49:38 UTC, luminousone wrote: On Friday, 11 October 2013 at 04:13:55 UTC, Agustin wrote: I have a function that needs to check if the template provided inherit a class. For example: public void function(T, A...)(auto ref A values) { // static assert(IsBaseOf(L, T)); } Check if T inherit class "L". Same result that std::is_base_of::value using C++. Any clean way to do it, without a dirty hack. import std.traits; bool ChildInheritsFromParent( parent, child )( ) { foreach ( k, t; BaseClassesTuple!child ) { if( typeid(t) == typeid(parent) ) return true; } return false; } A simpler way: import std.stdio; bool instanceOf(A, B)(B value) { return !!cast(A)value; } void main() { assert(1.instanceOf!(int)); } Using casts that way won't always be correct, it would be better to use reflection in some way if possible.
Re: Traits
On Friday, October 11, 2013 15:34:28 Jacob Carlborg wrote: > On 2013-10-11 11:49, luminousone wrote: > > Is is just the typeid call that makes it unable to be ran at compile > > time or is their something else wrong in their?, > > > > Would a string compare with type.classInfo.name fix that, or is their > > not a tool yet in place for that? > > Hmm, it may actually be possible to run this at compile time. I don't > remember. I was thinking that "typeid" doesn't work at compile time, but > I might be wrong. If typeid works at compile time, it's only because you're using CTFE. It returns the type of the instance when the code runs, not statically. So, it's intended as a runtime check, not a compile time check. - Jonathan M Davis
Linker error: Symbol Undefined
Hey, I'm curious about this linker error: OPTLINK (R) for Win32 Release 8.00.13 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html bar.obj(bar) Error 42: Symbol Undefined _D3foo1A6__dtorMFZv --- errorlevel 1 foo.d: debug import std.stdio; struct A { public: int id; this(int id) { debug writeln("CTor A with ", id); this.id = id; } debug ~this() { writeln("DTor A with ", id); } } bar.d import foo; void test(A a) { a.id++; } void main() { test(A(42)); A a = A(23); test(a); } Usage: C:\Users\Besitzer\Desktop>dmd -lib foo.d C:\Users\Besitzer\Desktop>dmd bar.d foo.lib -debug OPTLINK (R) for Win32 Release 8.00.13 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html bar.obj(bar) Error 42: Symbol Undefined _D3foo1A6__dtorMFZv --- errorlevel 1 Without -debug or with 'debug' _in_ the DTor (before writeln) instead before the DTor works fine.
Re: Call a function with a function pointer
On Friday, 11 October 2013 at 15:55:17 UTC, Artur Skawina wrote: It's probably not just "incompetence" (the compiler is able to figure this out in other contexts), but a deliberate choice. Having function types depend on their bodies would not be a good idea. Eg int c; auto f() { int a = 42; int f1() { return a; } int f2() { return 0; } return !c?&f1:&f2; } Mark f2 as 'static' and this code will no longer compile. If that would be done automatically then you'd have to 'undo' it manually, which would cause even more problems (consider generic code, which isn't prepared to handle this). artur [1] at least without other language improvements; enabling overloading on 'static', plus a few other enhancements, would change the picture. Agreed. However, I do feel uncomfortable with new habit to put `static` everywhere to avoid hidden compiler "help" :(
Re: Call a function with a function pointer
On 10/10/13 20:54, Dicebot wrote: > On Thursday, 10 October 2013 at 17:47:54 UTC, Namespace wrote: >> >> import std.stdio; >> >> void foo1(void function(void*) fp) { } >> void foo2(void function(int) fp) { } >> void foo3(void*) { } >> >> void main() >> { >> foo1((void* ptr) => ( assert(ptr is null) )); >> foo2((int a) => ( a + 1 )); /// Fails: Error: function foo2 (void >> function(int) fp) is not callable using argument types (int function(int a) >> pure nothrow @safe) >> >> foo1(&foo3); >> >> void foo4(void function(void*) fp) { } >> foo1(&foo4); /// Fails: Error: function foo1 (void function(void*) fp) >> is not callable using argument types (void delegate(void function(void*) fp)) >> } >> > > You are using short lambda syntax "a => b". Here `b` is always return > statement. It is equivalent to "(a) { return b; }". And your `foo2` signature > expects lambda returning void, like "(a) { return; }" > > Second error is DMD incompetence in deducing minimal required type of nested > function. It always treats them as delegates (== having hidden context > pointer) even if those do not refer any actual context. And plain lambdas are > of course binary incompatible with delegates (closures) because of that extra > pointer field. It's probably not just "incompetence" (the compiler is able to figure this out in other contexts), but a deliberate choice. Having function types depend on their bodies would not be a good idea. Eg int c; auto f() { int a = 42; int f1() { return a; } int f2() { return 0; } return !c?&f1:&f2; } Mark f2 as 'static' and this code will no longer compile. If that would be done automatically then you'd have to 'undo' it manually, which would cause even more problems (consider generic code, which isn't prepared to handle this). artur [1] at least without other language improvements; enabling overloading on 'static', plus a few other enhancements, would change the picture.
Re: Traits
On Friday, 11 October 2013 at 04:35:38 UTC, Ali Çehreli wrote: On 10/10/2013 09:13 PM, Agustin wrote: > I have a function that needs to check if the template provided inherit a > class. > > For example: > > public void function(T, A...)(auto ref A values) function happens to be a keyword. :) > { >// static assert(IsBaseOf(L, T)); > } > > Check if T inherit class "L". Same result that std::is_base_of T>::value using C++. Any clean way to do it, without a dirty hack. One of the uses of the is expression determines "whether implicitly convertible to". It may work for you: public void foo(T, A...)(auto ref A values) { static assert(is (T : L)); } class L {} class LL : L {} void main() { foo!LL(1, 2.3, "4"); } Ali On Friday, 11 October 2013 at 05:45:00 UTC, Jonathan M Davis wrote: On Thursday, October 10, 2013 21:35:37 Ali Çehreli wrote: One of the uses of the is expression determines "whether implicitly convertible to". It may work for you: public void foo(T, A...)(auto ref A values) { static assert(is (T : L)); } Actually, checking for implicit conversion will work directly in the template signature without a template constraint or static assertion. e.g. public void foo(T : L, A...)auto ref A values) { } - Jonathan M Davis Those work great, thanks a lot!
Re: Traits
On Friday, 11 October 2013 at 05:49:38 UTC, luminousone wrote: On Friday, 11 October 2013 at 04:13:55 UTC, Agustin wrote: I have a function that needs to check if the template provided inherit a class. For example: public void function(T, A...)(auto ref A values) { // static assert(IsBaseOf(L, T)); } Check if T inherit class "L". Same result that std::is_base_of::value using C++. Any clean way to do it, without a dirty hack. import std.traits; bool ChildInheritsFromParent( parent, child )( ) { foreach ( k, t; BaseClassesTuple!child ) { if( typeid(t) == typeid(parent) ) return true; } return false; } A simpler way: import std.stdio; bool instanceOf(A, B)(B value) { return !!cast(A)value; } void main() { assert(1.instanceOf!(int)); }
Re: Traits
On 2013-10-11 11:49, luminousone wrote: Is is just the typeid call that makes it unable to be ran at compile time or is their something else wrong in their?, Would a string compare with type.classInfo.name fix that, or is their not a tool yet in place for that? Hmm, it may actually be possible to run this at compile time. I don't remember. I was thinking that "typeid" doesn't work at compile time, but I might be wrong. -- /Jacob Carlborg
Re: How to check for instantiation of specific template?
This is actually a very interesting question. Usual approach is to use pattern matching on types but template instance symbol is not a type on its own, it is just a symbol. (with typeof == void) My second guess was to check __traits(identifier, AliasParam) but it looks like for aliased instance (contrary to aliased template symbol) identifier is its mangled name. I can't imagine really clean way to do it but comparing __traits(identifier) to that specific mangled name can be a reliable enough hack (better than stringof which has undefined format).
Re: fast floor
Am 11.10.2013 00:27, schrieb Spacen Jasset: Hello, I am after a fast floor function; In fact a fast truncation and conversion to integer. I see that std.math takes a real, and that std.c.math takes a double. Is there a quicker function, and what might cast(int)1.5f do? Regards, Spacen. For a noise generator I wrote some little assembler routines for that some years ago. It's main speed advantage comes from the fact that it allows to set the rounding mode once (ftoi_init) instead of for every conversion (as a cast(int) does for example). However, it requires great care that the rounding mode isn't accidentally changed during the computation by some function. Today I would use core.simd instead, though (using XMM.CVTSS2SI), but that requires that the whole algorithm is in SIMD for optimal performance. This is the old code: void ftoi_init() { fesetround(FE_DOWNWARD); } void ftoi_toint2(int* dst, float src) { asm { mov EAX, dst; fld src; fistp [EAX]; } } void ftio_fracint(int* int_part, float* frac_part, float src) { asm { mov EAX, int_part; mov EBX, frac_part; fld src; frndint; fist [EAX]; fld src; fsubr; fstp [EBX]; } } void ftoi_round(float* dst, float src) { asm { mov EAX, dst; fld src; frndint; fstp [EAX]; } }
Re: Traits
On Friday, 11 October 2013 at 09:37:33 UTC, Jacob Carlborg wrote: On 2013-10-11 07:49, luminousone wrote: import std.traits; bool ChildInheritsFromParent( parent, child )( ) { foreach ( k, t; BaseClassesTuple!child ) { if( typeid(t) == typeid(parent) ) return true; } return false; } That will perform a runtime check and not a compile time check. Is is just the typeid call that makes it unable to be ran at compile time or is their something else wrong in their?, Would a string compare with type.classInfo.name fix that, or is their not a tool yet in place for that?
Re: Traits
On 2013-10-11 07:49, luminousone wrote: import std.traits; bool ChildInheritsFromParent( parent, child )( ) { foreach ( k, t; BaseClassesTuple!child ) { if( typeid(t) == typeid(parent) ) return true; } return false; } That will perform a runtime check and not a compile time check. -- /Jacob Carlborg
Re: std.process spawnShell/pipeShell dont capture output of the shell
On Thursday, 10 October 2013 at 01:24:03 UTC, Jesse Phillips wrote: On Wednesday, 9 October 2013 at 14:54:32 UTC, Colin Grogan wrote: is blocking. However, its not meant to be blocking is it not? That new /bin/bash process is meant to run in parallel to the main process? I'm not sure exactly the implementation. But if you're asking to run bash and then print its output, wouldn't it have to block because the output won't be complete until the program has finished running? And since bash will run until you exit the program will block for ever. From what I understood in the documentation, I didnt think it should block. I understood it's meant to run the child process in the background and you communicate with it via the stdin/stdout/stderr pipes. But, from experimentation I can see that running /bin/bash does appear to block. Ill have to do some more digging when I have the time...
Re: How to check for instantiation of specific template?
On 2013-10-10 19:23, H. S. Teoh wrote: I have a template used for storing compile-time values: template Def(int x, string y) { alias impl = TypeTuple!(x,y); } How do I define a template isDef that, given some template alias A, evaluates to true if A is some instantiation of Def? template isDef(alias A) { enum A = ... /* what to put here? */ } The intent is to be able to write signature constraints like this: auto myFunc(alias def)(...) if (isDef!def) { ... } ... // Pass an instantiation of Def to myFunc auto x = myFunc!(Def!(1, "abc"))(args); I tried using std.traits.isInstanceOf but apparently it expects the second argument to be an actual type, which doesn't work in this case because Def is a typetuple of compile-time values, not an actual type. I found this old thread http://forum.dlang.org/thread/mailman.1382.1371938670.13711.digitalmar...@puremagic.com With this code: template getTemplate(alias T : TI!TP, alias TI, TP...) { alias getTemplate = TI; } But I haven't figured out how to do the comparison. -- /Jacob Carlborg
Re: Starting D with a project in mind.
As Adam already said D on Pi is adventurous. For MongoDB and web stuff, you should look into Vibe.d [0]. For parsing I would suggest Pegged [1]. Welcome to D and Happy Hacking! :) [0] http://vibed.org/ [1] https://github.com/PhilippeSigaud/Pegged Thanks both. Well after several hours of hacking I have spectacularly failed to build GDC on any arm based debian environment - tried both my RPi and Cubieboard. In both cases it fails with a pile of compilation errors. I'm guessing that D just isn't mainstream enough at the moment to be properly supported on Debian and yet it's too big and complicated to build easily yourself and so it's probably a non-starter for me at the moment. There is a pre-built package on debian gdc-4.4 but it's too old to build vibe or dub from my experimentation. I guess I'll go back to plain old C. Thanks anyway - I'll check back in a few years.