Rust style memory management in D?
I've been looking into alternatives to C++ and have been following D since back in the D1 Tango/Phobos days, and recently started digging in again. I'm quite impressed with the progress, and I've started a simple toy game project to test out some of the language features. One thing that really bothers me as someone who works on applications where responsiveness is critical and even 50ms delays can cause problems is the GC though - It seems to be that the only really good answer is to to just use malloc free from the standard library, but that seems really awful for such an elegant language. Every area but memory management is beautiful and can do what you like, but trying to avoid the GC is downright painful and forces you to ditch much of the safety D provides. Given that it is designed to be a systems programming language in such applications memory management is so important, this seems like a tremendous oversight. In my searching, I ran across Rust, which is relatively new and takes a rather different approach to a lot of things, including memory management - making unique shared pointers(~ is used to denote them) a language feature along side garbage collection so that the compiler can enforce ownership rules. One of the main language developers has noted that the unique pointer with ownership transfer rules is used so much more than the GC option that he's trying to get GC removed from the language and placed in the standard library. Given D's target domain of high performance systems programming, this memory management model seems like a radically better fit than screw it, we'll GC everything. I've seen a few other people talk about this issue, and the difficulty of avoiding the GC seems to be THE argument against D that I wind up seeing. Has such a model been considered, and is there a reason (besides the fact that the entire standard library would probably have to be rewritten) that it isn't used?
Re: [Windows DMD] No callstack when crash with Access violation reading location 0x00000000
Am 12.01.2014 00:47, schrieb Xavier Bigand: I didn't know this menu settings, but activate Access Violation don't change anything. It seems that your crash happens inside the OpenGL part of the graphics driver. It is caused by DQuick\src\dquick\renderer3D\openGL\mesh.d line 125 I assume that you setup a few OpenGL parameters invalid and thus the driver reads from a null pointer. I found it by single stepping. I started the application, then set the breakpoint like shown below and single steppt into the draw() method. debug { if (mRebuildDebugMeshes) updateDebugMesh(); // put breakpoint here mDebugMesh.draw(); if ((implicitWidth != float.nan implicitHeight != float.nan) (implicitWidth != mSize.x implicitHeight != mSize.y)) mDebugImplicitMesh.draw(); } Have fun debugging ;-) Kind Regards Benjamin Thaut
Re: Compile/link Win64
On Friday, 10 January 2014 at 20:18:55 UTC, Nick Sabalausky wrote: On 1/10/2014 3:06 PM, Vladimir Panteleev wrote: On Friday, 10 January 2014 at 20:02:49 UTC, Nick Sabalausky wrote: LINK : fatal error LNK1104: cannot open file 'shell32.lib' What are your LIB and LIBPATH environment variables set to? echo %LIB% C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\LIB;C:\Program Files (x86)\Microsoft Visual Studio 8\VC\LIB;C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\lib;C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\lib; echo %LIBPATH% C:\Windows\Microsoft.NET\Framework\v2.0.50727;C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\LIB That's not right. If you're building for x64, the LIB paths should contain amd64 library directories. Are you running the vcvarsall batch file with the right parameter (amd64)?
Re: WeakRefs for a CPP-D wrapper
No, try this: import std.stdio; class X {} void foo(X x) { writeln(cast(void*) x); } void main() { X x; // null reference by default. writeln(cast(void*) x); foo(x); x = new X; writeln(cast(void*) x); foo(x); } Thanks Tobias that indeed works, unfortunately storing the address as ulong in an AA does not seem to be defeating the garbage collector! I guess I'll have to go for a WeakRef implementation, I'll try Robert's implementation in signals, but I'd really like to know how long it is likely to last as a working weak ref (in terms of the D GC changing etc.) and if I'm taking the right approach.
Re: Rust style memory management in D?
Please post on[0] regarding better memory management. As currently work is being done on rewriting the GC (which really was needed). [0] http://forum.dlang.org/post/lao9fn$1d70$1...@digitalmars.com
Re: WeakRefs for a CPP-D wrapper
On Sunday, 12 January 2014 at 10:48:15 UTC, Abdulhaq wrote: No, try this: import std.stdio; class X {} void foo(X x) { writeln(cast(void*) x); } void main() { X x; // null reference by default. writeln(cast(void*) x); foo(x); x = new X; writeln(cast(void*) x); foo(x); } Thanks Tobias that indeed works, unfortunately storing the address as ulong in an AA does not seem to be defeating the garbage collector! I guess I'll have to go for a WeakRef implementation, I'll try Robert's implementation in signals, but I'd really like to know how long it is likely to last as a working weak ref (in terms of the D GC changing etc.) and if I'm taking the right approach. Sorry to reply to my own message, looking at Robert's InvisibleAddress class I think he's hiding the address from the GC by e.g. rotating the bits in the ulong. He's also made it all thread safe - I certainly don't understand the details but it's given me some ideas.
Re: WeakRefs for a CPP-D wrapper
On Sunday, 12 January 2014 at 10:48:15 UTC, Abdulhaq wrote: No, try this: import std.stdio; class X {} void foo(X x) { writeln(cast(void*) x); } void main() { X x; // null reference by default. writeln(cast(void*) x); foo(x); x = new X; writeln(cast(void*) x); foo(x); } Thanks Tobias that indeed works, unfortunately storing the address as ulong in an AA does not seem to be defeating the garbage collector! I guess I'll have to go for a WeakRef implementation, I'll try Robert's implementation in signals, but I'd really like to know how long it is likely to last as a working weak ref (in terms of the D GC changing etc.) and if I'm taking the right approach. The current GC is imprecise. Everything that looks like a pointer at the bit level, is treated like one. I can't help you create weak references.
Re: WeakRefs for a CPP-D wrapper
On Sunday, 12 January 2014 at 12:12:53 UTC, Tobias Pankrath wrote: On Sunday, 12 January 2014 at 10:48:15 UTC, Abdulhaq wrote: No, try this: import std.stdio; class X {} void foo(X x) { writeln(cast(void*) x); } void main() { X x; // null reference by default. writeln(cast(void*) x); foo(x); x = new X; writeln(cast(void*) x); foo(x); } Thanks Tobias that indeed works, unfortunately storing the address as ulong in an AA does not seem to be defeating the garbage collector! I guess I'll have to go for a WeakRef implementation, I'll try Robert's implementation in signals, but I'd really like to know how long it is likely to last as a working weak ref (in terms of the D GC changing etc.) and if I'm taking the right approach. The current GC is imprecise. Everything that looks like a pointer at the bit level, is treated like one. I can't help you create weak references. No don't worry you've got me past that point of incomprehension, thanks again
Re: WeakRefs for a CPP-D wrapper
Maybe this will be useful in the work: Compile Windows: dmd st1.d Linux: dmd st1.d -L-ldl // --- // MGW 05.01.14 // Model in D a C++ object QByteArray of Qt. // import core.runtime; // Load DLL for Win import std.stdio;// writeln version(linux) { import core.sys.posix.dlfcn; // define dlopen() и dlsym() // On Linux DMD v2.063.2, these functions are not defined in core.runtime, so I had to write to. extern (C) void* rt_loadLibrary(const char* name) { return dlopen(name, RTLD_GLOBAL || RTLD_LAZY); } void* GetProcAddress(void* hLib, string nameFun) { return dlsym(hLib, nameFun.ptr);} } version(Windows) { import std.c.windows.windows; // GetProcAddress for Windows } // Warning!!! // When defining constructors and member functions attribute extern (C) required! alias extern (C) void function(void*, char*) t_QByteArray_QByteArray; t_QByteArray_QByteArray QByteArray_QByteArray; alias extern (C) void* function(void*, char, int) t_QByteArray_fill;t_QByteArray_fill QByteArray_fill; //T he structure of the QByteArray from the file qbytearray.h in the include directory. Because C++ inline functions missing in DLL // there is no possibility to directly call a dozen functions. // If you look in C++ there definition is as follows: // inline char *QByteArray::data() { detach(); return d-data; } where d is the Data* struct Data { void* rref; int alloc; int size; char* data; // That's what we need, a pointer to an array of bytes char array[1]; } // == Experimental class DQByteArray == class DQByteArray { Data* QtObj; // this is object: QtObj - size 4 byte (32 os) // -- // constructor D called of a constructor C++ this(char* buf) { QByteArray_QByteArray(QtObj, buf); } ~this() { // I can find a destructor, and here his record, but too lazy to do it } // As inline function is not stored in a DLL have to model it through the structure of the Data char* data() { return (*QtObj).data; } // D format: Data** == C++ format: QByteArray // so it became clear that such a C++object, looking at it from the D void* fill(char ch, int resize=-1) { return QByteArray_fill(QtObj, ch, resize); } } int main(string[] args) { // These files get QByteArray C++ version(linux) {auto nameQtCore = libQtCore.so; } version(Windows) {auto nameQtCore = QtCore4.dll; } auto h = Runtime.loadLibrary(nameQtCore); // Loading dll or so // Load function constructor QByteArray::QByteArray(char*); QByteArray_QByteArray = cast(t_QByteArray_QByteArray)GetProcAddress(h, _ZN10QByteArrayC1EPKc); // QByteArray::fill(char*, int); QByteArray_fill = cast(t_QByteArray_fill)GetProcAddress(h, _ZN10QByteArray4fillEci); // QByteArray::~QByteArray() // Create our experimental subject and consider its data DQByteArray ba = new DQByteArray(cast(char*)ABC.ptr); printf(\n ba.data() = %s, ba.data()); // Experience the action of the fill() and see the result ba.fill('Z', 5); printf(\n ba.data() = %s, ba.data()); return 0; }
Re: [Windows DMD] No callstack when crash with Access violation reading location 0x00000000
Le 12/01/2014 11:16, Benjamin Thaut a écrit : Am 12.01.2014 00:47, schrieb Xavier Bigand: I didn't know this menu settings, but activate Access Violation don't change anything. It seems that your crash happens inside the OpenGL part of the graphics driver. It is caused by DQuick\src\dquick\renderer3D\openGL\mesh.d line 125 I assume that you setup a few OpenGL parameters invalid and thus the driver reads from a null pointer. I found it by single stepping. I started the application, then set the breakpoint like shown below and single steppt into the draw() method. debug { if (mRebuildDebugMeshes) updateDebugMesh(); // put breakpoint here mDebugMesh.draw(); if ((implicitWidth != float.nan implicitHeight != float.nan) (implicitWidth != mSize.x implicitHeight != mSize.y)) mDebugImplicitMesh.draw(); } Have fun debugging ;-) Kind Regards Benjamin Thaut Thank for your support and your time I already tried to debug opengl with gdebugger is used to find those kind of issues. But it doesn't seems working fine with D binaries.
Re: [Windows DMD] No callstack when crash with Access violation reading location 0x00000000
Am 12.01.2014 17:18, schrieb Xavier Bigand: Le 12/01/2014 11:16, Benjamin Thaut a écrit : Am 12.01.2014 00:47, schrieb Xavier Bigand: I didn't know this menu settings, but activate Access Violation don't change anything. It seems that your crash happens inside the OpenGL part of the graphics driver. It is caused by DQuick\src\dquick\renderer3D\openGL\mesh.d line 125 I assume that you setup a few OpenGL parameters invalid and thus the driver reads from a null pointer. I found it by single stepping. I started the application, then set the breakpoint like shown below and single steppt into the draw() method. debug { if (mRebuildDebugMeshes) updateDebugMesh(); // put breakpoint here mDebugMesh.draw(); if ((implicitWidth != float.nan implicitHeight != float.nan) (implicitWidth != mSize.x implicitHeight != mSize.y)) mDebugImplicitMesh.draw(); } Have fun debugging ;-) Kind Regards Benjamin Thaut Thank for your support and your time I already tried to debug opengl with gdebugger is used to find those kind of issues. But it doesn't seems working fine with D binaries. I higly recommend using either glIntercept (http://code.google.com/p/glintercept/) or glslDevil (http://www.vis.uni-stuttgart.de/glsldevil/) to debug OpenGL applications. If you have a nvidia card you could also use nvidia nsight to debug your application: https://developer.nvidia.com/nvidia-nsight-visual-studio-edition My guess would be that either your vertex buffer or index buffer is no longer valid, thus gets not bound, and as a result the graphics driver reads from client memory at address null. Kind Regards Benjamin Thaut
logical operands on strings
I would like to do this: string one = x315c4eeaa8b5f8aaf9174145bf43e1784b; string two = xc29398f5f3251a0d47e503c66e935de81230b59b7a; string three = one ^ two; The closests I've been able to get is: string three = xor(one, two); string xor(string one, string two) { int len = min(one.length, two.length); string result; for(int i=0; ilen; i++) { result ~= one[i] ^ two[i]; } return cast(string)result; } Question 1: is there a more elegant way to implement the function xor? (foreach-ish or std.algorithm) Then I tried to add operator overloading: string opBinary(string op)(string lhs, string rhs) { static if( op == ^ ) return xor(lhs, rhs); else static assert(false, operator not possible); } But it doesn't invoke this function. Question 2: how would I implement ^ for strings?
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:21:06 UTC, Erik van Velzen wrote: I would like to do this: string one = x315c4eeaa8b5f8aaf9174145bf43e1784b; string two = xc29398f5f3251a0d47e503c66e935de81230b59b7a; string three = one ^ two; The closests I've been able to get is: string three = xor(one, two); string xor(string one, string two) { int len = min(one.length, two.length); string result; for(int i=0; ilen; i++) { result ~= one[i] ^ two[i]; } return cast(string)result; } Question 1: is there a more elegant way to implement the function xor? (foreach-ish or std.algorithm) Then I tried to add operator overloading: string opBinary(string op)(string lhs, string rhs) { static if( op == ^ ) return xor(lhs, rhs); else static assert(false, operator not possible); } But it doesn't invoke this function. Question 2: how would I implement ^ for strings? It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct.
What's the D way of application version numbers?
With C++ and Python, it is idiomatic to put the application version number in a separate file that can then be processed by the build system. For C++ a config file is constructed defining a macro that is then used in the rest of the course. For Python the file is read at runtime to define a variable. The build system itself uses the version number for creating deb, RPM, egg, wheel, etc. packages. D has no macro processing so C++ idioms are not useful. D does create a standalone executable and so the Python approach of reading the file at initialization time seems inappropriate. Is there a known D idiom for this? Thanks. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? It seems I can't even inherit from string. Forgive me for making the comparison, but I believe in C++ i can simply implement this function and be done with it: string operator^(string lhs, string rhs);
When using Win32/x86 in a version block is that the compiler or OS?
When using Win32/x86 in a version block, does that relate to the compiler or OS? for example: version(Win32) { // 32bit Windows or 32bit Compiler? } version(X86) { // 32bit OS or 32bit Compiler? } If these don't relate to the compiler is there any indication that the program is being compiled with a 32bit compiler? I'm primarily asking because i need to use this to constrain dub to build different things depending on what compiler is used and on what architecture.
Re: What's the D way of application version numbers?
On Sunday, 12 January 2014 at 18:36:19 UTC, Russel Winder wrote: With C++ and Python, it is idiomatic to put the application version number in a separate file that can then be processed by the build system. For C++ a config file is constructed defining a macro that is then used in the rest of the course. For Python the file is read at runtime to define a variable. The build system itself uses the version number for creating deb, RPM, egg, wheel, etc. packages. D has no macro processing so C++ idioms are not useful. D does create a standalone executable and so the Python approach of reading the file at initialization time seems inappropriate. Is there a known D idiom for this? Thanks. Unless I'm misunderstanding you, this is what the -version and verion(){} blocks are for. Past that it's really a matter of choice depending on your build system.
Re: When using Win32/x86 in a version block is that the compiler or OS?
On Sunday, 12 January 2014 at 18:47:43 UTC, Gary Willoughby wrote: When using Win32/x86 in a version block, does that relate to the compiler or OS? for example: version(Win32) { // 32bit Windows or 32bit Compiler? } version(X86) { // 32bit OS or 32bit Compiler? } If these don't relate to the compiler is there any indication that the program is being compiled with a 32bit compiler? I'm primarily asking because i need to use this to constrain dub to build different things depending on what compiler is used and on what architecture. version arguments are for the target architecture, not the compiler/build-environment.
Re: When using Win32/x86 in a version block is that the compiler or OS?
On Sunday, 12 January 2014 at 19:01:05 UTC, John Colvin wrote: On Sunday, 12 January 2014 at 18:47:43 UTC, Gary Willoughby wrote: When using Win32/x86 in a version block, does that relate to the compiler or OS? for example: version(Win32) { // 32bit Windows or 32bit Compiler? } version(X86) { // 32bit OS or 32bit Compiler? } If these don't relate to the compiler is there any indication that the program is being compiled with a 32bit compiler? I'm primarily asking because i need to use this to constrain dub to build different things depending on what compiler is used and on what architecture. version arguments are for the target architecture, not the compiler/build-environment. Are there any for the compiler?
Re: What's the D way of application version numbers?
On Sun, 2014-01-12 at 18:59 +, John Colvin wrote: […] Unless I'm misunderstanding you, this is what the -version and verion(){} blocks are for. Past that it's really a matter of choice depending on your build system. I think I may not have explained correctly: version blocks are the way of dealing with platform specific features, basically a compilation switch on Windows, Linux OSX, etc. My problem is about embedding the application version number in the application. E.g 0.0.0-SNAPSHOT being in the executable and available to the build system to create the packages. If I create a D variable this is fine for the D executable but not accessible to the build system. (I may have consumed my pre-supper Ricard to quickly… :-) -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? Well something like this. struct MyString { string value; alias value this; auto opBinary(string op)(string rhs) if( op == ^ ) { string result; foreach(i; 0 .. min(value.length, rhs.length)) result ~= value[i] ^ rhs[i]; return MyString(result); } } auto mstr(string s) { return MyString(s); } auto s = Hello; auto s2 = World; auto res = s.mstr ^ s2; or string res = s.mstr ^ s2; //If you want the result to be a string. While this works it's not that much better then the simple: auto s = Hello; auto s2 = World; auto res = s.xor(s2); It seems I can't even inherit from string. In D a string is not a class its just an immutable array (slice) of char. alias string = immutable(char[]);
Re: What's the D way of application version numbers?
On Sunday, 12 January 2014 at 18:36:19 UTC, Russel Winder wrote: With C++ and Python, it is idiomatic to put the application version number in a separate file that can then be processed by the build system. That's the way I do it in D too: file VERSION says 1.0 dmd -J. myfile.d enum version = import(VERSION); // use it now like any other string in D
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? It seems I can't even inherit from string. Forgive me for making the comparison, but I believe in C++ i can simply implement this function and be done with it: string operator^(string lhs, string rhs); global operator overloads aren't allowed in D. For your particular problem I would construct a wrapper around string using psuedo-inheritance via 'alias this': struct MyString { string nativeStr; alias nativeStr this; auto opBinary(string op)(string rhs) if(op == ^) { return xor(nativeStr, rhs); } void opOpBinary(string op)(string rhs) if(op == ^) { nativeStr = xor(nativeStr, rhs); } } All normal string operations on a MyString will be applied to nativeStr thanks to alias this, except the ^ and ^= whch are intercepted by the opBinary and opOpBinary methods in MyString. The ^= could be more efficient by working in-place. Also, you should pre-allocate the return string in xor as it's a lot quicker than doing repeated append operations.
Re: When using Win32/x86 in a version block is that the compiler or OS?
On Sunday, 12 January 2014 at 19:01:56 UTC, Gary Willoughby wrote: On Sunday, 12 January 2014 at 19:01:05 UTC, John Colvin wrote: On Sunday, 12 January 2014 at 18:47:43 UTC, Gary Willoughby wrote: When using Win32/x86 in a version block, does that relate to the compiler or OS? for example: version(Win32) { // 32bit Windows or 32bit Compiler? } version(X86) { // 32bit OS or 32bit Compiler? } If these don't relate to the compiler is there any indication that the program is being compiled with a 32bit compiler? I'm primarily asking because i need to use this to constrain dub to build different things depending on what compiler is used and on what architecture. version arguments are for the target architecture, not the compiler/build-environment. Are there any for the compiler? http://dlang.org/phobos/std_compiler.html perhaps?
Re: logical operands on strings
On 01/12/2014 10:21 AM, Erik van Velzen wrote: I would like to do this: string one = x315c4eeaa8b5f8aaf9174145bf43e1784b; string two = xc29398f5f3251a0d47e503c66e935de81230b59b7a; string three = one ^ two; The closests I've been able to get is: string three = xor(one, two); string xor(string one, string two) { int len = min(one.length, two.length); string result; for(int i=0; ilen; i++) { result ~= one[i] ^ two[i]; } return cast(string)result; } Question 1: is there a more elegant way to implement the function xor? (foreach-ish or std.algorithm) Then I tried to add operator overloading: string opBinary(string op)(string lhs, string rhs) { static if( op == ^ ) return xor(lhs, rhs); else static assert(false, operator not possible); } But it doesn't invoke this function. Question 2: how would I implement ^ for strings? XOR is not a valid operation on a UTF-8 code unit. ;) It makes more sense to work with ubyte arrays. However, I found two usability issues with it: 1) std.conv.to did not work from string to ubyte[]; so, I wrote a function. 2) Array-wise operations does not support the following syntax auto three = one[] ^ two[]; Otherwise, ^= works with slices: import std.stdio; ubyte[] toBytes(string s) { return cast(ubyte[])s.dup; } void main() { ubyte[] one = x55.toBytes; ubyte[] two = xaa.toBytes; ubyte[] three = one.dup; three[] ^= two[]; assert(one == x55); assert(two == xaa); assert(three == xff); } Ali
Re: logical operands on strings
On Sunday, 12 January 2014 at 19:12:13 UTC, TheFlyingFiddle wrote: On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? Well something like this. struct MyString { string value; alias value this; auto opBinary(string op)(string rhs) if( op == ^ ) { string result; foreach(i; 0 .. min(value.length, rhs.length)) result ~= value[i] ^ rhs[i]; return MyString(result); } } auto mstr(string s) { return MyString(s); } auto s = Hello; auto s2 = World; auto res = s.mstr ^ s2; or string res = s.mstr ^ s2; //If you want the result to be a string. While this works it's not that much better then the simple: auto s = Hello; auto s2 = World; auto res = s.xor(s2); It seems I can't even inherit from string. In D a string is not a class its just an immutable array (slice) of char. alias string = immutable(char[]); You can also use opBinaryRight for when your custom string class is on the right side of the operand, so string ^ MyString also works. This pretty much obviates the need for global operator overloading, at least in this case.
Re: logical operands on strings
On Sunday, 12 January 2014 at 19:22:57 UTC, Ali Çehreli wrote: 2) Array-wise operations does not support the following syntax auto three = one[] ^ two[]; Is this a bug or intended?
Re: logical operands on strings
On Sunday, 12 January 2014 at 19:27:18 UTC, Meta wrote: On Sunday, 12 January 2014 at 19:22:57 UTC, Ali Çehreli wrote: 2) Array-wise operations does not support the following syntax auto three = one[] ^ two[]; Is this a bug or intended? intended. It would require an implicit allocation, which is incongruent with array operations being fast. It's been discussed at length.
Value or Reference Semantics Trait
Is there a trait to check whether a type has value or reference semantics? I need this in a template struct that adaptively (using static if) represent histogram bins as either a dense static array or a sparse associative array.
Re: WeakRefs for a CPP-D wrapper
On Sunday, 12 January 2014 at 16:17:23 UTC, MGW wrote: Maybe this will be useful in the work: Compile Windows: dmd st1.d Linux: dmd st1.d -L-ldl // --- // MGW 05.01.14 // Model in D a C++ object QByteArray of Qt. // import core.runtime; // Load DLL for Win import std.stdio;// writeln version(linux) { import core.sys.posix.dlfcn; // define dlopen() и dlsym() // On Linux DMD v2.063.2, these functions are not defined in core.runtime, so I had to write to. extern (C) void* rt_loadLibrary(const char* name) { return dlopen(name, RTLD_GLOBAL || RTLD_LAZY); } void* GetProcAddress(void* hLib, string nameFun) { return dlsym(hLib, nameFun.ptr);} } version(Windows) { import std.c.windows.windows; // GetProcAddress for Windows } // Warning!!! // When defining constructors and member functions attribute extern (C) required! alias extern (C) void function(void*, char*) t_QByteArray_QByteArray; t_QByteArray_QByteArray QByteArray_QByteArray; alias extern (C) void* function(void*, char, int) t_QByteArray_fill;t_QByteArray_fill QByteArray_fill; //T he structure of the QByteArray from the file qbytearray.h in the include directory. Because C++ inline functions missing in DLL // there is no possibility to directly call a dozen functions. // If you look in C++ there definition is as follows: // inline char *QByteArray::data() { detach(); return d-data; } where d is the Data* struct Data { void* rref; int alloc; int size; char* data; // That's what we need, a pointer to an array of bytes char array[1]; } // == Experimental class DQByteArray == class DQByteArray { Data* QtObj; // this is object: QtObj - size 4 byte (32 os) // -- // constructor D called of a constructor C++ this(char* buf) { QByteArray_QByteArray(QtObj, buf); } ~this() { // I can find a destructor, and here his record, but too lazy to do it } // As inline function is not stored in a DLL have to model it through the structure of the Data char* data() { return (*QtObj).data; } // D format: Data** == C++ format: QByteArray // so it became clear that such a C++object, looking at it from the D void* fill(char ch, int resize=-1) { return QByteArray_fill(QtObj, ch, resize); } } int main(string[] args) { // These files get QByteArray C++ version(linux) {auto nameQtCore = libQtCore.so; } version(Windows) {auto nameQtCore = QtCore4.dll; } auto h = Runtime.loadLibrary(nameQtCore); // Loading dll or so // Load function constructor QByteArray::QByteArray(char*); QByteArray_QByteArray = cast(t_QByteArray_QByteArray)GetProcAddress(h, _ZN10QByteArrayC1EPKc); // QByteArray::fill(char*, int); QByteArray_fill = cast(t_QByteArray_fill)GetProcAddress(h, _ZN10QByteArray4fillEci); // QByteArray::~QByteArray() // Create our experimental subject and consider its data DQByteArray ba = new DQByteArray(cast(char*)ABC.ptr); printf(\n ba.data() = %s, ba.data()); // Experience the action of the fill() and see the result ba.fill('Z', 5); printf(\n ba.data() = %s, ba.data()); return 0; } Hi yes I think noticed in another thread that you were wrapping Qt with dynamic loading of the qt libs, interesting idea - does your code allow subclassing of the Qt classes and overriding the virtual methods? I'm taking a much more traditional approach, but there is method in my madness :-)
Re: What's the D way of application version numbers?
On Sunday, 12 January 2014 at 19:11:12 UTC, Adam D. Ruppe wrote: On Sunday, 12 January 2014 at 18:36:19 UTC, Russel Winder wrote: With C++ and Python, it is idiomatic to put the application version number in a separate file that can then be processed by the build system. That's the way I do it in D too: file VERSION says 1.0 dmd -J. myfile.d enum version = import(VERSION); // use it now like any other string in D I was gonna suggest this but with using dub to generate it off of e.g. git tag pre compile.
Re: Compile/link Win64
On Friday, 10 January 2014 at 21:47:23 UTC, Nick Sabalausky wrote: Hmm, I hadn't ever uninstalled it. Regardless, *now* I've just uninstalled and reinstalled the Windows SDK, and re-ran vcvarsall.bat. The %WindowsSdkDir% is now set, but I'm still getting the same problem. The %WindowsSdkDir% is set to C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A, but there doesn't appear to be much in there (Just a Bootstrapper\Packages directory with not much inside it either). I don't think it installed correctly. There doesn't appear to be any other Windows SDK installation AFAICT either. Stupid f#*^# microsoft tools... The lastest Windows SDK installs to C:\Program Files (x86)\Windows Kits\8.1\
Re: logical operands on strings
On 1/13/2014 3:37 AM, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? It seems I can't even inherit from string. In D, string is not a class. It's an alias for an immutable array of char.