Re: cannot cast
On Thu, 03 May 2012 00:38:35 +0200, Namespace rswhi...@googlemail.com wrote: I'm not very skillful in such template stories. Maybe someone can help me? The main problem here is your opCast is non-const. (it's always an indication of const problems when DMD says X is not callable using argument types ()) Solution: class A { int val; alias val this; T opCast(T : Object)() { writeln(FOO); return to!(T)(this); } // Add this T opCast(T : Object)() const { writeln(FOO); return to!(T)(this); } }
Re: Transforming a range back to the original type?
On Wed, 02 May 2012 23:01:21 +0200, Jacob Carlborg d...@me.com wrote: Is there a general function for transforming a range back to the original type? If not, would it be possible to create one? In addition to std.array.array, as others have pointed out, there is also std.range.InputRangeObject.
Re: cannot cast
On Thursday, May 03, 2012 09:33:01 Namespace wrote: On Wednesday, 2 May 2012 at 22:38:36 UTC, Namespace wrote: Other, shorter example: [code] import std.stdio, std.traits; class A { int val; alias val this; T opCast(T : Object)() { writeln(FOO); return to!(T)(this); } } class B : A { } T to(T : Object, U : Object)(const U obj) { return *(cast(T*) obj); } T const_cast(T)(const T obj) { return cast(T) obj; } void main () { A a = new B(); a.val = 42; writefln(a.val: %d, a.val); B* b = cast(B*) a; writefln(*b.val: %d, b.val); B b1 = to!(B)(a); writefln(b1.val: %d, b1.val); B b2 = cast(B) a; writefln(b2.val: %d, b2.val); const B b3 = cast(B) a; B b4 = const_cast(b3); } [/code] print: alias_this_impl.d(24): Error: function alias_this_impl.A.opCast!(B).opCast () is not callable using argument types () alias_this_impl.d(44): Error: template instance alias_this_impl.const_cast!(B) e rror instantiating I'm not very skillful in such template stories. Maybe someone can help me? Solved with T const_cast(T)(const T obj) { return to!(T)(obj); } But i think that there must exist a more nicer way to cast away const, isn't there? To cast away const with a simple cast to T fails (see my post above), because i have no idea, how i can restrict my opCast. So i have to convert it again with to. Do some of you have any ideas how i can restrict my opCast, so my const_cast doesn't match it, e.g. with some template magic? If you want to restrict opCast, then use a template constraint, constraining it to what you want to work with it. Also, casting away const is generally a bad idea in D. Casting away const and mutating a variable is an _extremely_ bad idea. You _really_ shouldn't be doing it. So, the fact that you _have_ a function which is specifically trying to cast away const is almost certainly _not_ a good idea. http://stackoverflow.com/questions/4219600/logical-const-in-d - Jonathan M Davis
Re: cannot cast
On Thursday, 3 May 2012 at 07:41:32 UTC, Simen Kjaeraas wrote: On Thu, 03 May 2012 00:38:35 +0200, Namespace rswhi...@googlemail.com wrote: I'm not very skillful in such template stories. Maybe someone can help me? The main problem here is your opCast is non-const. (it's always an indication of const problems when DMD says X is not callable using argument types ()) Solution: class A { int val; alias val this; T opCast(T : Object)() { writeln(FOO); return to!(T)(this); } // Add this T opCast(T : Object)() const { writeln(FOO); return to!(T)(this); } } Hm, simple. Thank you, as long as the bug isn't fixed, this has to be enough. :)
Re: Transforming a range back to the original type?
On 2012-05-02 23:07, Matt Soucy wrote: On 05/02/2012 05:01 PM, Jacob Carlborg wrote: Is there a general function for transforming a range back to the original type? If not, would it be possible to create one? I believe std.array's array function does what you want. -Matt I was thinking of a generic function that works for all types of collections and not arrays. -- /Jacob Carlborg
Re: cannot cast
If you want to restrict opCast, then use a template constraint, constraining it to what you want to work with it. Also, casting away const is generally a bad idea in D. Casting away const and mutating a variable is an _extremely_ bad idea. You _really_ shouldn't be doing it. So, the fact that you _have_ a function which is specifically trying to cast away const is almost certainly _not_ a good idea. http://stackoverflow.com/questions/4219600/logical-const-in-d - Jonathan M Davis So, you mean that if i declared any parameter as const, it have to stay const all the time? What would you do, if you need in a special case a mutable version or must change the object itself? Because there is no mutable keyword in D you have to cast away the constness.
Re: cannot cast
On Thursday, 3 May 2012 at 07:41:32 UTC, Simen Kjaeraas wrote: On Thu, 03 May 2012 00:38:35 +0200, Namespace rswhi...@googlemail.com wrote: I'm not very skillful in such template stories. Maybe someone can help me? The main problem here is your opCast is non-const. (it's always an indication of const problems when DMD says X is not callable using argument types ()) Solution: class A { int val; alias val this; T opCast(T : Object)() { writeln(FOO); return to!(T)(this); } // Add this T opCast(T : Object)() const { writeln(FOO); return to!(T)(this); } } My tests are failed, but isn't it possible, to reduce both methods to one with the inout keyword?
Re: cannot cast
On 05/03/2012 09:33 AM, Namespace wrote: On Wednesday, 2 May 2012 at 22:38:36 UTC, Namespace wrote: Other, shorter example: [code] import std.stdio, std.traits; class A { int val; alias val this; T opCast(T : Object)() { writeln(FOO); return to!(T)(this); } } class B : A { } T to(T : Object, U : Object)(const U obj) { return *(cast(T*) obj); } T const_cast(T)(const T obj) { return cast(T) obj; } void main () { A a = new B(); a.val = 42; writefln(a.val: %d, a.val); B* b = cast(B*) a; writefln(*b.val: %d, b.val); B b1 = to!(B)(a); writefln(b1.val: %d, b1.val); B b2 = cast(B) a; writefln(b2.val: %d, b2.val); const B b3 = cast(B) a; B b4 = const_cast(b3); } [/code] print: alias_this_impl.d(24): Error: function alias_this_impl.A.opCast!(B).opCast () is not callable using argument types () alias_this_impl.d(44): Error: template instance alias_this_impl.const_cast!(B) e rror instantiating I'm not very skillful in such template stories. Maybe someone can help me? Solved with T const_cast(T)(const T obj) { return to!(T)(obj); } But i think that there must exist a more nicer way to cast away const, isn't there? To cast away const with a simple cast to T fails (see my post above), because i have no idea, how i can restrict my opCast. So i have to convert it again with to. Do some of you have any ideas how i can restrict my opCast, so my const_cast doesn't match it, e.g. with some template magic? Unqual können Sie finden in std.traits. template Unqual(T) { version (none) // Error: recursive alias declaration @@@BUG1308@@@ { static if (is(T U == const U)) alias Unqual!U Unqual; else static if (is(T U == immutable U)) alias Unqual!U Unqual; else static if (is(T U == inout U)) alias Unqual!U Unqual; else static if (is(T U == shared U)) alias Unqual!U Unqual; else alias T Unqual; } else // workaround { static if (is(T U == shared(const U))) alias U Unqual; else static if (is(T U == const U )) alias U Unqual; else static if (is(T U == immutable U )) alias U Unqual; else static if (is(T U == inout U )) alias U Unqual; else static if (is(T U == shared U )) alias U Unqual; else alias T Unqual; } } unittest { static assert(is(Unqual!(int) == int)); static assert(is(Unqual!(const int) == int)); static assert(is(Unqual!(immutable int) == int)); static assert(is(Unqual!(inout int) == int)); static assert(is(Unqual!(shared int) == int)); static assert(is(Unqual!(shared(const int)) == int)); alias immutable(int[]) ImmIntArr; static assert(is(Unqual!(ImmIntArr) == immutable(int)[])); }
Re: Transforming a range back to the original type?
On 2012-05-02 23:40, Jonathan M Davis wrote: On Wednesday, May 02, 2012 23:01:21 Jacob Carlborg wrote: Is there a general function for transforming a range back to the original type? If not, would it be possible to create one? You mean that if you have something like auto range = getRangeFromSomewhere(); auto newRange = find(filter!func(range), value); you want to transform newRange back to the same type as range? No, I want to transform newRange back to a collection, the same type as the original collection. I was thinking something like this: Collection c = new Collection(); c = c.filter!(x = x 3).toCollection(); -- /Jacob Carlborg
Re: cannot cast
On Thursday, 3 May 2012 at 08:00:43 UTC, Namespace wrote: So, you mean that if i declared any parameter as const, it have to stay const all the time? Yes. const = you can't change. Changing it is invalid behavior. Imagine const/immutable as bits in readonly memory and you'll have to right mindset. What would you do, if you need in a special case a mutable version or must change the object itself? Because there is no mutable keyword in D you have to cast away the constness. In what way do you mean? If it's something you honestly _need_ to change and it's const, then maybe throwing an exception would be appropriate.
Re: extern and opaque structs
On 2012-05-03 07:00, James Miller wrote: I'm doing C bindings and I have an opaque struct and an extern'd variable of the type of that struct. The problem is that dmd is complaining that the struct has no definition (which is true). Making it a pointer works (expected) but i can't do that because the interface is expecting an full struct. Adding __gshared doesn't help. I assume this is bug, since usage of extern means that I don't need to know the size, since it will be allocated in the C code, not the D code. -- James Miller This doesn't work: struct Foo; extern (C) extern Foo foo; -- /Jacob Carlborg
Re: ref semantics with hashes
On 05/03/12 00:38, Andrej Mitrovic wrote: In fact what would *actually* solve this problem (for me) is if/when we have aliases implemented for this scenario: import std.stdio; struct Foo { int[] hash; } void main() { Foo foo; alias foo.hash hash2; hash2[0] = 1; writeln(foo.hash); // [1:1] writeln(hash2); // [1:1] } Hopefully we get that one day. Until then, you can use @property ref hash2() { return foo.hash; } which is a bit more verbose, but functionally equivalent. Your new alias syntax would be just sugar, and would (a) hide the complexity of the operation and (b) have to be artificially restricted. alias p1.p2.p3.p4.p5.p6.hash hash3; alias p1.p2?p1.p2.hash:p3.p4.hash hash4; alias getfoo().hash hash5; etc would also be possible otherwise and that isn't necessarily a good idea. artur
Re: Transforming a range back to the original type?
On 2012-05-03 09:43, Simen Kjaeraas wrote: In addition to std.array.array, as others have pointed out, there is also std.range.InputRangeObject. I'm not sure if I understand what InputRangeObject does. But I don't think it does what I want. -- /Jacob Carlborg
Fixed-size arrays and randomShuffle()
May be that this works as intended, but it fooled me: --- import std.random; import std.stdio; void main() { int[5] a = 0; a[0] = 1; int[] b = [1, 0, 0, 0, 0]; randomShuffle(a); writeln(a); randomShuffle(b); writeln(b); } --- In DMD 2.0.59 the fixed-size array a won't be shuffled (the dynamic array b will), and you won't get any warning about it. I'm not sure whether this counts as something that should be reported as a bug/improvement, nor if only randomShuffle() displays this behaviour, perhaps you could enlighten me.
Re: Fixed-size arrays and randomShuffle()
On 05/03/2012 06:30 AM, Vidar Wahlberg wrote: May be that this works as intended, but it fooled me: --- import std.random; import std.stdio; void main() { int[5] a = 0; a[0] = 1; int[] b = [1, 0, 0, 0, 0]; randomShuffle(a); Fixed-length arrays are value types. 'a' is copied to randomShuffle() so its copy is shuffled. Passing a slice of the whole array works: randomShuffle(a[]); writeln(a); randomShuffle(b); writeln(b); } --- In DMD 2.0.59 the fixed-size array a won't be shuffled (the dynamic array b will), and you won't get any warning about it. I'm not sure whether this counts as something that should be reported as a bug/improvement, nor if only randomShuffle() displays this behaviour, perhaps you could enlighten me. Ali
Re: Fixed-size arrays and randomShuffle()
On 2012-05-03 15:34, Ali Çehreli wrote: Fixed-length arrays are value types. 'a' is copied to randomShuffle() so its copy is shuffled. Passing a slice of the whole array works: randomShuffle(a[]); True, it is however still not exceptionally newbie (or perhaps even user?) friendly (my question was more of does it have to be this way? rather than how do you do this?, even though I appreciate the answer on how to do it). Is it not possible for the compilator to let you know that what you're doing doesn't make any sense? A quick follow-up: I've tried some various random number engines, but neither come even close to the performance of whatever is used for Java's Collection.shuffle() method. Perhaps someone can shed some light on this?
Re: Fixed-size arrays and randomShuffle()
On 05/03/2012 06:55 AM, Vidar Wahlberg wrote: On 2012-05-03 15:34, Ali Çehreli wrote: Fixed-length arrays are value types. 'a' is copied to randomShuffle() so its copy is shuffled. Passing a slice of the whole array works: randomShuffle(a[]); True, it is however still not exceptionally newbie (or perhaps even user?) friendly (my question was more of does it have to be this way? rather than how do you do this?, even though I appreciate the answer on how to do it). Is it not possible for the compilator to let you know that what you're doing doesn't make any sense? Random shuffle can work on a fixed-length array and there is a way for the implementation to know: import std.traits; // ... __traits(isStaticArray, a) That can be used in a template constraint. A quick follow-up: I've tried some various random number engines, but neither come even close to the performance of whatever is used for Java's Collection.shuffle() method. Perhaps someone can shed some light on this? I have no idea with that one. Ali
Re: Passing array as const slows down code?
On Wed, 02 May 2012 16:05:13 -0400, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 30/04/12 16:03, Steven Schveighoffer wrote: Try removing the ref and see if it goes back. That usage of ref should not affect anything (if anything it should be slower, since it's an extra level of indirection). Removing the ref ups the time as described before, but only with GDC (DMD the runtime is the same). It's a real effect. I'm not familiar with GDC, but as bearophile says, it sounds like a compiler bug. Maybe GDC is making an optimization in one case and not in the other, but both should be equivalently able to get the optimization. There is no implicit local copy for const. I have a suspicion that you changed two things and forgot about one of them when running your tests. Really don't think so. You can even check the version history of changes if you like! IIRC, your original post concerned not-checked in code. Anyway, if you've re-run the tests, this is a confirmation. I'd go ahead and file a bug against GDC. Rest assured, const should not *slow down* anything. -Steve
Re: Access Violation in callback from sort
On Wed, 02 May 2012 11:27:57 -0400, Jabb jj.jabba...@gmail.com wrote: Just got the TDPL book and it's a great read! I learn best when typing out the code myself, so I decided to make a single VisualD project and put the different exercises in separate modules. I am having problems with sort in std.algorithms - well, actually it appears to be a closure problem when sort calls my delegate. There shouldn't be any closure here, sort is not storing the delegate pointer. Here's a sample of the problem - in main.d I have //-- module main; import std.algorithm; void main() { uint[string] counts = [ a:4, b:5, c:3, d:1 ]; string[] keys = counts.keys; sort!((a, b) { return counts[a] counts[b]; })(keys); } //-- Alone this works just fine. But if I add another file called myalgs.d, and put the following in it: //-- module myalgs; import std.algorithm; //-- Then I get the following exception: object.Error: Access Violation C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(7112): mainmain__T8sortImplS14main9__lambda3VE3std9algorithm12SwapStrategy0TAAyaZsortImpl Steping through the code it appears that the Access Violation occurs when accessing counts[a]. I am using DMD32 v2.059; my compilation command line looks like: dmd -g -debug -X -Xf$(IntDir)\$(TargetName).json -deps=$(OutDir)\$(ProjectName).dep -of$(OutDir)\$(ProjectName).exe_cv -map $(INTDIR)\$(SAFEPROJECTNAME).map -L/NOMAP I can't see any errors, I think this is worthy of a bug report, it's nice and small and self-contained. http://d.puremagic.com/issues -Steve
Re: ref semantics with hashes
On Wed, 02 May 2012 16:32:04 -0400, H. S. Teoh hst...@quickfur.ath.cx wrote: On Wed, May 02, 2012 at 09:38:35PM +0200, Andrej Mitrovic wrote: [...] So if the hash wasn't already initialized then the reference in the Foo struct is a reference to null, and if you duplicate that reference and add a key the old reference still points to null. The only way to ensure a proper link with a hash is to initialize it with a key and then immediately remove that key, which makes the hash not-null but empty: [...] Why do we have such error-prone semantics? I was told that this was expected behaviour. Should the new AA implementation change this, so that it always allocates an empty AA upon instantiation? This can't be done. You can always create a struct without calling any code. What I'd like to see is an initializer function/property, e.g.: auto a = int[int].create(); // static property that allocates a new empty AA. -Steve
string find and replace
Forgive me if I am missing something obvious, but is there a simple option for finding all instances of a particular character in a string or char[] and replacing them with another character? I can do this with std.regex, but it seems overkill, when all I want is the equivalent of PHP's str_replace() function. Many thanks!
Re: Fixed-size arrays and randomShuffle()
On 03.05.2012 18:02, Ali Çehreli wrote: A quick follow-up: I've tried some various random number engines, but neither come even close to the performance of whatever is used for Java's Collection.shuffle() method. Perhaps someone can shed some light on this? I have no idea with that one. It's all about RNG used behind the scenes. Default one is Mersane Twister which (AFAIK) is not particularly fast. But has a period of 2^19937 elements. You should probably use XorShift or MinstdRand generator and a version of shuffle with 2nd parameter. -- Dmitry Olshansky
Re: string find and replace
On Thursday, 3 May 2012 at 14:22:57 UTC, Iain wrote: Forgive me if I am missing something obvious, but is there a simple option for finding all instances of a particular character in a string or char[] and replacing them with another character? I can do this with std.regex, but it seems overkill, when all I want is the equivalent of PHP's str_replace() function. Many thanks! Apologies, after half an hour searching, I post, then five minutes later figure it out. myString = replace(myString, to, from); // from std.array
Re: Fixed-size arrays and randomShuffle()
On 2012-05-03 16:26, Dmitry Olshansky wrote: It's all about RNG used behind the scenes. Default one is Mersane Twister which (AFAIK) is not particularly fast. But has a period of 2^19937 elements. You should probably use XorShift or MinstdRand generator and a version of shuffle with 2nd parameter. I tried those two as well. Still significantly slower than what I can achieve in Java.
Re: Passing array as const slows down code?
On 05/03/12 16:07, Steven Schveighoffer wrote: On Wed, 02 May 2012 16:05:13 -0400, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 30/04/12 16:03, Steven Schveighoffer wrote: Try removing the ref and see if it goes back. That usage of ref should not affect anything (if anything it should be slower, since it's an extra level of indirection). Removing the ref ups the time as described before, but only with GDC (DMD the runtime is the same). It's a real effect. I'm not familiar with GDC, but as bearophile says, it sounds like a compiler bug. Maybe GDC is making an optimization in one case and not in the other, but both should be equivalently able to get the optimization. There is no implicit local copy for const. I have a suspicion that you changed two things and forgot about one of them when running your tests. Really don't think so. You can even check the version history of changes if you like! IIRC, your original post concerned not-checked in code. Anyway, if you've re-run the tests, this is a confirmation. I'd go ahead and file a bug against GDC. Rest assured, const should not *slow down* anything. There *was* a GDC bug some time ago, where a 'const' or 'in' function argument prevented inlining. Iain fixed it, so unless an old GDC version is used, it's probably not related. http://forum.dlang.org/thread/jdhb57$10vf$1...@digitalmars.com?page=16#post-mailman.33.1325763631.16222.d.gnu:40puremagic.com artur
Re: Compute in one pass 3 tokens position
Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit : Hi, I would like to know how compute in on pass 3 tokens position in a sequence. curently i do: File f = File( reader.d, r ); scope(exit) f.close(); char[1024] buffer; char[] content = f.rawRead(buffer); char[sizediff_t] token = ['(', '{', ';']; auto position = map!( a = content.countUntil( a ) )( [ ['('], ['{'], [';'] ] ); if i use reduce instead map the build fail - CODE --- import std.stdio; import std.conv; import std.c.process; sizediff_t[string] counter( in char[] sequence, string[] token...) in{ assert(sequence !is null, Error given sequence is null); } body{ bool isComputing = true; size_t index = 0; size_t flag= 0; sizediff_t[string] result; foreach( tok; token) result[tok] = -1; while(isComputing){ if( index = sequence.length ) isComputing = false; else if( flag == token.length ) isComputing = false; else{ foreach( tok; token){ if( sequence.length - index = tok.length ){ string currentToken = to!string(sequence[index .. index + tok.length]); if( currentToken in result result[currentToken] == -1 ){ result[currentToken] = index; flag++; } } } index++; } } return result; } void main( string[] args ){ if( args.length == 1 ){ writefln( Usage %s token1 token2 token3 token4..., args[0] ); exit(0); } writeln( counter( This a cool statement such as D is fun. Use it and ot the D power. Oh yeah! Are you ready? Try it!! Have fun., args[1..$]) ); } -- END CODE --- $ ./test This D ! [D:30, !:74, This:0] import std.string; if all token is found befoore reach end sequence it stop and save us from some loop it works too if token do not has same length as shown in example
Re: Fixed-size arrays and randomShuffle()
On Thursday, 3 May 2012 at 14:41:20 UTC, Vidar Wahlberg wrote: I tried those two as well. Still significantly slower than what I can achieve in Java. You might want to post your code... I wrote this code in D: -=-=-=- import std.random, std.stdio, std.datetime; void main() { int[] arr = new int[5_000_000]; foreach(i, ref e; arr) e = i; StopWatch sw = AutoStart.yes; arr.randomShuffle(); sw.stop(); writeln(Took , sw.peek().to!(msecs, double)(), ms); } -=-=-=- And it performed _identically_ to this in Java: -=-=-=- import java.util.ArrayList; import java.util.Collections; public class Main { public static void main(String[] args) { ArrayListInteger ints = new ArrayList(5000); for(int i = 0; i 5_000_000; ++i) ints.add(i); long startTime = System.currentTimeMillis(); Collections.shuffle(ints); long endTime = System.currentTimeMillis(); System.out.println(Took + (endTime - startTime) + ms); } } -=-=-=-
Re: Compute in one pass 3 tokens position
Le lundi 30 avril 2012 à 14:52 +0200, bioinfornatics a écrit : Hi, I would like to know how compute in on pass 3 tokens position in a sequence. curently i do: File f = File( reader.d, r ); scope(exit) f.close(); char[1024] buffer; char[] content = f.rawRead(buffer); char[sizediff_t] token = ['(', '{', ';']; auto position = map!( a = content.countUntil( a ) )( [ ['('], ['{'], [';'] ] ); if i use reduce instead map the build fail update code for add attribute poure notrhow nd safe :) -- import std.string; import std.stdio; import std.conv; import std.c.process; /** * searchIndex * search at wich index is located each token in given sequence. * It compute it in one pass. * Returns: * An ssociative array: * key = token and value first index where is found * value take -1 if not found in given sequence. */ @safe nothrow pure sizediff_t[char[]] searchIndex( in char[] sequence, in char[][] token...) in{ assert(sequence !is null, Error given sequence is null); } body{ bool isComputing = true; size_t index = 0; size_t flag= 0; sizediff_t[char[]] result; foreach( tok; token) result[tok] = -1; while(isComputing){ if( index = sequence.length ) isComputing = false; else if( flag == token.length ) isComputing = false; else{ foreach( tok; token){ if( sequence.length - index = tok.length ){ const(char)[] currentToken = (tok.length 1) ? sequence[index .. index + tok.length] : [sequence[index]]; if( currentToken in result result[currentToken] == -1 ){ result[currentToken] = index; flag++; } } } index++; } } return result; } void main( string[] args ){ if( args.length == 1 ){ writefln( Usage %s token1 token2 token3 token4..., args[0] ); exit(0); } writeln( searchIndex( This a cool statement such as D is fun. Use it and got the D power. Oh yeah! Are you ready? Try it!! Have fun., args[1..$]) ); }
Re: Fixed-size arrays and randomShuffle()
On 2012-05-03 17:31, Chris Cain wrote: You might want to post your code... Sure! D: --- import std.random; import std.stdio; void main() { auto iterations = 1000; int[] a; for (int i = 0; i 42; ++i) a ~= i; for (int i = 0; i iterations; ++i) randomShuffle(a); } naushika:~/projects dmd random.d time ./random ./random 38,35s user 0,05s system 99% cpu 38,420 total --- Java (7): --- import java.util.ArrayList; import java.util.Collections; public class Rnd { public static void main(String... args) { int iterations = 1000; ArrayListInteger a = new ArrayListInteger(); for (int i = 0; i 42; ++i) a.add(i); for (int i = 0; i iterations; ++i) Collections.shuffle(a); } } naushika:~/projects javac Rnd.java time java Rnd java Rnd 9,92s user 0,03s system 100% cpu 9,922 total ---
Re: Fixed-size arrays and randomShuffle()
On a related note, how did you get the other random generators working? I tried to compile this and it gives me an error: -=-=-=- import std.random, std.stdio, std.datetime; void main() { int[] arr = new int[5_000_000]; foreach(i, ref e; arr) e = i; auto rng = MinstdRand0(1); rng.seed(unpredictableSeed); StopWatch sw = AutoStart.yes; randomShuffle(arr, rng); sw.stop(); writeln(Took , sw.peek().to!(msecs, double)(), ms); } -=-=-=- The error: -=-=-=- C:\D\dmd2\windows\bin\..\..\src\phobos\std\random.d(1263): Error: cannot implicitly convert expression (rndGen()) of type MersenneTwisterEngine!(uint,32,624,397,31,-1727483681u,11,7,-1658038656u,15,-272236544u,18) to LinearCongruentialEngine!(uint,16807,0,2147483647) -=-=-=- Is this a bug in 2.059? Or am I doing something wrong?
Re: string find and replace
On 5/3/12 9:30 PM, Iain wrote: On Thursday, 3 May 2012 at 14:22:57 UTC, Iain wrote: Forgive me if I am missing something obvious, but is there a simple option for finding all instances of a particular character in a string or char[] and replacing them with another character? I can do this with std.regex, but it seems overkill, when all I want is the equivalent of PHP's str_replace() function. Many thanks! Apologies, after half an hour searching, I post, then five minutes later figure it out. myString = replace(myString, to, from); // from std.array Note that you can also do: myString = myString.replace(to, from) I'd point you to the reference on the official page (UFCS: unified function call syntax), but I can't find it...
Re: string find and replace
On 5/3/12 11:01 PM, Ary Manzana wrote: On 5/3/12 9:30 PM, Iain wrote: On Thursday, 3 May 2012 at 14:22:57 UTC, Iain wrote: Forgive me if I am missing something obvious, but is there a simple option for finding all instances of a particular character in a string or char[] and replacing them with another character? I can do this with std.regex, but it seems overkill, when all I want is the equivalent of PHP's str_replace() function. Many thanks! Apologies, after half an hour searching, I post, then five minutes later figure it out. myString = replace(myString, to, from); // from std.array Note that you can also do: myString = myString.replace(to, from) I'd point you to the reference on the official page (UFCS: unified function call syntax), but I can't find it... and it should be replace(from, to)
Re: cannot cast
On Thursday, May 03, 2012 10:54:47 Namespace wrote: On Thursday, 3 May 2012 at 08:46:26 UTC, Chris Cain wrote: On Thursday, 3 May 2012 at 08:00:43 UTC, Namespace wrote: So, you mean that if i declared any parameter as const, it have to stay const all the time? Yes. const = you can't change. Changing it is invalid behavior. Imagine const/immutable as bits in readonly memory and you'll have to right mindset. What would you do, if you need in a special case a mutable version or must change the object itself? Because there is no mutable keyword in D you have to cast away the constness. In what way do you mean? If it's something you honestly _need_ to change and it's const, then maybe throwing an exception would be appropriate. I thought that const = cannot change directly and immutable stands for cannot change all the time. If not, why exist both storage classes beside? An immutable variable can never be changed by any reference to that data. It's also implicitly shared across threads (since it can never change). If a const variable is a value type, then there really isn't any difference between const and immutable. If it's a reference type, then it just indicates that that particular reference cannot alter the data. Another reference may or may not be able to (and const is _not_ implicitly shared across threads, because the data _can_ change if there are mutable references to it). But if a reference is const, it's breaking the type system to cast away const and alter the data precisely because the compiler can't know whether that data is actually mutable or not. For instance, what if if you did something like const var = new immutable(A); var may be const, but it refers to a value which is actually immutable. Depending on what the compiler does, mutating var could result in nasty stuff like segfaults. In the general case, the compiler has no way of knowing whether a const variable is really mutable or immutable underneath. So, casting away const and mutating a variable is undefined behavior. As far as the compiler is concerned, a variable is _never_ mutated through a const reference, and it will optimize code based on that. So, casting away const can not only result in segfaults if the data is actually immutable, but it can result in incorrect behavior due to optimizations that the compiler makes based on the assumption that the variable wouldn't change but which you violated by casting away const and mutating the variable. Unlike immutable, _other_ references to the data may mutate it (and the compiler must take that into account when optimizing), but you should never try and mutate a const variable. Once something is const, _leave_ it that way. If you need a mutable reference to it, then you need to get one which was mutable in the first place rather than coming from the const reference through casting. Casting away const is legal, because D is a systems language, but actually mutating the variable after casting away const is undefined behavior, so you should never do it unless you really know what you're doing. http://stackoverflow.com/questions/4219600/logical-const-in-d - Jonathan M Davis
Re: ptrace (process trace system call) on Linux from D
Thank you for the reply, your recommendation works. I could however not find ptrace anywhere in druntime. There is only one mention of it in std.process, in a comment. But I do have some other questions: (1) Can I declare a ptrace function which calls the original ptrace? (I would like to check the return value and errno for exception throwing and such). I essentially want to shadow the original. (2) Is it more D-ish to use something like enum PTRequest { traceMe = 0, ... } instead of the fully capitalised originals? It doesn't seem to affect the working of things. (3) wait() is declared as returning a pid_t in the manpage, and is declared as such in core.sys.posix.sys.wait. In std.c.process however, it returns an int. I can't even find a process.h in my Linux install. What am I supposed to use? I know it essentially doesn't matter, as pid_t is aliased as int. Are there D alternatives to wait() and fork() that I could use with ptrace() instead of the C posix system functions? (4) Some things are declared only in core.*, not in std.*. Will they be added at some point or is this how it's supposed to be?
Re: Fixed-size arrays and randomShuffle()
OK, I took a look at your example, and I saw the kind of performance you were seeing. I performed an investigation on what could cause such a disparity and came up with a conclusion. The answer is two things: First of all, as noted above, D's default generator is a mersenne twister RNG. You can emulate Java's RNG like so: auto rng = LinearCongruentialEngine!(ulong, 25214903917uL, 11uL, 2uL^^48uL)(); Once I equalized that, I looked into the various methods that are called and settled in on uniform. https://github.com/D-Programming-Language/phobos/blob/master/std/random.d#L1154 As you can see, there's a division at line 1154 and another at line 1158. This means there's a minimum of two division operations every time uniform is called. Now, normally this isn't a big deal, but if we really want maximum performance, we need to eliminate at least one. If you replace lines 1154-1161 (auto bucketSize ... to return...) with: CountType rnum, result; do { rnum = cast(CountType) uniform!CountType(urng); result = rnum % count; } while (rnum count (rnum - result + (count - 1)) (rnum - result - 1)); return cast(typeof(return)) (min + result); Then the time taken shrinks down to roughly the same (within a tenth of a second) as Java. I'll probably clean this up (and write some comments on how this works) and see about submitting it as a patch unless anyone sees anything wrong with this approach.
How to prevent direct public creation of a struct?
I want to do something like this: -- module moduleFoo; // Only allow certain values of str template foo(string str) { static assert(str == a || str == b || str == c); immutable foo = Foo(str); } struct Foo { // Only a, b, and c should be allowed, // checked at compile-time via template foo. // Also, not modifyable. private string _str; @property string str() { return _str; } } -- I want struct Foo itself to be public, but I want to *force* all code outside moduleFoo to *create* Foo via the foo template. Copying should be allowed though. Ie: -- auto a = foo!a; // ok a.str = b; // Error: str is a read-only property auto z = foo!z; // Error: fails static assert auto a2 = a; // Copy it: ok auto b = Foo(b); // Error: I want to *force* the usage of template foo Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, but I don't think that's possible. If it's indeed impossible, I know I can just declare Foo.str as (string str = a;) so that's not a big problem. -- The *key* thing here that I'm not sure how to do is: How do I disallow this?: auto b = Foo(b); // Error: I want to *force* the usage of template foo
Re: How to prevent direct public creation of a struct?
On Thu, 03 May 2012 17:37:47 -0400, Nick Sabalausky wrote: The *key* thing here that I'm not sure how to do is: How do I disallow this?: auto b = Foo(b); // Error: I want to *force* the usage of template foo The @disable annotation can do this, I believe: struct Foo { @disable this(); // Cannot use default constructor } But this disables it for code within the module as well as outside, so you may wish to also add a private constructor.
Re: How to prevent direct public creation of a struct?
On Thursday, 3 May 2012 at 21:36:53 UTC, Nick Sabalausky wrote: I want to do something like this: -- module moduleFoo; // Only allow certain values of str template foo(string str) { static assert(str == a || str == b || str == c); immutable foo = Foo(str); } struct Foo { // Only a, b, and c should be allowed, // checked at compile-time via template foo. // Also, not modifyable. private string _str; @property string str() { return _str; } } -- I want struct Foo itself to be public, but I want to *force* all code outside moduleFoo to *create* Foo via the foo template. Copying should be allowed though. Ie: -- auto a = foo!a; // ok a.str = b; // Error: str is a read-only property auto z = foo!z; // Error: fails static assert auto a2 = a; // Copy it: ok auto b = Foo(b); // Error: I want to *force* the usage of template foo Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, but I don't think that's possible. If it's indeed impossible, I know I can just declare Foo.str as (string str = a;) so that's not a big problem. -- The *key* thing here that I'm not sure how to do is: How do I disallow this?: auto b = Foo(b); // Error: I want to *force* the usage of template foo I would have thought adding a private this(string str) constructor would work but then foo can't be called from a separate module (privcons.d(5): Error: struct privcons.Foo member this is not accessible which is the same but desirable error it gives if you do auto b = Foo(b);). I thought all module members had access to private members of the same module but I guess that's not the case with template functions.
Re: Mixins are not inherited?
On Thursday, May 03, 2012 23:32:50 Namespace wrote: By the following code i get these error messages: Error: template RefTest.Ref.__unittest1.instanceof(T : Object,U : Object) cannot deduce template function from argument types !(A)(B) Error: template RefTest.Ref.__unittest1.instanceof does not match any function template declaration Error: template instance instanceof!(A) errors instantiating template How is this possible? I thougth that the mixin would be inherited and so every subclass would be implicit cast to his super type. Isn't that so? If i write mixin TRef!(B); in class B, it works fine. Can anyone explain me why do i have to write it in class B? [code] unittest { bool instanceof(T : Object, U : Object)(const Ref!U obj) { const U o = obj.access; return const_cast(o).toString() == typeid(T).toString(); } class A { mixin TRef!(A); } class B : A { //mixin TRef!(B); } class C : B { //mixin TRef!(C); } A a1 = new B(); A a2 = new C(); assert(instanceof!(A)(a1) == false); assert(instanceof!(B)(a1)); assert(instanceof!(C)(a1) == false); writeln(a1); B b1 = cast(B) a1; assert(instanceof!(A)(b1) == false); // -- fails writeln(b1); writeln(); } [/code] TRef is the same mixin template and Ref the same template struct as in my last threads. Nothing you put in a base class is automatically in a derived class. If you put a member variable or member function in a base class, it's not in the derived class. It's just that the derived class has access to it as long as it's protected or public. In the case of a mixin, you're essentially copying and pasting code. So, it's in the base class similarly to if you typed it there yourself. However, templated functions aren't virtual, so unlike if you typed them yourself, they won't be virtual if you use a template mixin. So, if you want to mixin something into every class in a hierarchy, you must mix it in to every class in the hierarchy, not just the base class. And if you want to test whether an object is an instance of a specific class, then cast it and check whether the result is null. You don't need to create a function to figure it out for you. e.g. auto c = cast(MyClass)object; if(c is null) writeln(c is NOT an instance of MyClass); else writeln(c IS an instance of MyClass); - Jonathan M Davis
Re: How to prevent direct public creation of a struct?
On Thursday, May 03, 2012 17:37:47 Nick Sabalausky wrote: I want to do something like this: -- module moduleFoo; // Only allow certain values of str template foo(string str) { static assert(str == a || str == b || str == c); immutable foo = Foo(str); } struct Foo { // Only a, b, and c should be allowed, // checked at compile-time via template foo. // Also, not modifyable. private string _str; @property string str() { return _str; } } -- I want struct Foo itself to be public, but I want to *force* all code outside moduleFoo to *create* Foo via the foo template. Copying should be allowed though. Ie: -- auto a = foo!a; // ok a.str = b; // Error: str is a read-only property auto z = foo!z; // Error: fails static assert auto a2 = a; // Copy it: ok auto b = Foo(b); // Error: I want to *force* the usage of template foo Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, but I don't think that's possible. If it's indeed impossible, I know I can just declare Foo.str as (string str = a;) so that's not a big problem. -- The *key* thing here that I'm not sure how to do is: How do I disallow this?: auto b = Foo(b); // Error: I want to *force* the usage of template foo Make all constructors private. Then the only way to construct the struct would be through it's init value. If you use @disable this(); you can also prevent the use of init, but that disables init completely, not just outside of the module that the struct is in. It looks like you're relying on the default-generated constructor for POD structs, and that isn't going to cut it, since it's public. You'll have to declare the appropriate constructor and make it private. - Jonathan M Davis
Re: Mixins are not inherited?
Very sad, i thougth that was possible. As regards to instanceof Try this code: unittest { class A { mixin TRef!(typeof(this)); } class B : A { } class C : B { } A a1 = new B(); A a2 = new C(); assert(instanceof!(A)(a1) == false); assert(instanceof!(B)(a1)); assert(instanceof!(C)(a1) == false); } with my instanceof and then with your version.
Re: Transforming a range back to the original type?
On 02/05/2012 22:01, Jacob Carlborg wrote: Is there a general function for transforming a range back to the original type? If not, would it be possible to create one? To sum it up, it can't be done in the general case. The range API doesn't know or care about the underlying data structure. That's half the point of it. The underlying data structure might not even exist. An example is a range used as a file stream, a random number generator or to lazily generate a mathematical sequence. Moreover, what would you want such a function to return if the range is: - a file stream with a cache - an array wrapper to loop infinitely through it? - a concatenation of ranges that may be of different types? Moreover, even if there were some range with an underlying container classification, it would be an extra burden on the writer of the range wrapper to implement this. If you want to generate a range that views a container in a certain way, and then construct a container of the original type (or indeed any type) from that range, then create the container and then use a foreach loop on the range (or a .save of it, if you want to keep the range afterwards) to put the data into the container. Stewart.
Re: How to prevent direct public creation of a struct?
Brad Anderson e...@gnuk.net wrote in message news:jhsccvjskiqqzzqbd...@forum.dlang.org... On Thursday, 3 May 2012 at 21:36:53 UTC, Nick Sabalausky wrote: I want to do something like this: -- module moduleFoo; // Only allow certain values of str template foo(string str) { static assert(str == a || str == b || str == c); immutable foo = Foo(str); } struct Foo { // Only a, b, and c should be allowed, // checked at compile-time via template foo. // Also, not modifyable. private string _str; @property string str() { return _str; } } -- I want struct Foo itself to be public, but I want to *force* all code outside moduleFoo to *create* Foo via the foo template. Copying should be allowed though. Ie: -- auto a = foo!a; // ok a.str = b; // Error: str is a read-only property auto z = foo!z; // Error: fails static assert auto a2 = a; // Copy it: ok auto b = Foo(b); // Error: I want to *force* the usage of template foo Foo x; // Kinda ambivalent about this: I'd prefer if it were disallowed, but I don't think that's possible. If it's indeed impossible, I know I can just declare Foo.str as (string str = a;) so that's not a big problem. -- The *key* thing here that I'm not sure how to do is: How do I disallow this?: auto b = Foo(b); // Error: I want to *force* the usage of template foo I would have thought adding a private this(string str) constructor would work but then foo can't be called from a separate module (privcons.d(5): Error: struct privcons.Foo member this is not accessible which is the same but desirable error it gives if you do auto b = Foo(b);). I thought all module members had access to private members of the same module but I guess that's not the case with template functions. Hmm, interestingly, it works if the template calls through an intermediary private function: http://d.puremagic.com/issues/show_bug.cgi?id=8028 I don't know if I'm relying on a bug or working around a bug, but this seems to work, *and* disallows Foo b; which is nice: --- template foo(string str) { static assert([a, b, c].find(str), Invalid str: '~str~'); immutable foo = _foo(name); } private Foo _foo(string str) { return Foo(str); } struct Foo { immutable string str; private this(string str) { this.str = str; } @disable this(); } --- // In a serparate module: Foo a = foo!a; // Ok auto a2 = a; // Ok a.str = b; // Error: can only initialize const member name inside constructor auto z = foo!z; // Error: static assert Invalid str: 'z' instantiated from here: foo!(z) auto b = Foo(b); // Error: struct test2.Foo member this is not accessible Foo x; // Error: variable test1.main.x initializer required for type Foo --- So that's awesome, everything as I wanted :)
opAssign and const?
I have the following dilemma. Hopefully I have this right. struct X { ref X opAssign(X x2); ref X opAssign(ref X x2); } X fn(); void func(){ X x, x2; x = x2; //uses ref x = fn(); //without ref } According to the book, this is how it is suppose to be. const is a added promise not to modify anything. So... if i changed the ref to ref const... it won't call unless the item input was const as well. //same as above except.. struct X { ref X opAssign(X x2); ref X opAssign(ref const X x2); //const added } void func(){ X x, x2; const X x3; x = x2; //without ref??? x = x3; //ref } Since the input is intended to be read only anyways, why won't it work as expected with x = x2? This seems like a bug. If it's not, then I need to make two ref versions so it will behave properly. (If you need I can past actual working example)