Re: How to avoid code duplication?
Rikki, could you explain? I did not understand where it can help me
Re: How to avoid code duplication?
On 1/04/2015 7:19 p.m., Suliman wrote: Rikki, could you explain? I did not understand where it can help me Here is some example code. While I've only implemented one InputRange!string instance. You would probably have one, for just zip's and another raw text files. Keep in mind it returns only a single line from standard input. In other words, let the range handle reading a line from a file. import std.range; import std.stdio; class Range : InputRange!string { private { string buffer; } this() { popFront; } @property { string front() { return buffer; } bool empty() { return false; } } void popFront() { buffer = readln(); } string moveFront() { string ret = front(); popFront(); return ret; } int opApply(int delegate(string) del) { int result; while(!empty()) { result = del(moveFront()); if (result) break; } return result; } int opApply(int delegate(size_t, string) del) { int result; size_t offset; while(!empty()) { result = del(offset, moveFront()); if (result) break; offset++; } return result; } } void myfunc(InputRange!string input) { foreach(line; input) { writeln(GOT [line]: , line); } } void main() { InputRange!string theRange = new Range(); myfunc(theRange); }
Re: How to avoid code duplication?
On 1/04/2015 6:15 p.m., Suliman wrote: The situation is next: I have got the function that get arrays of lognames and logfullname: void loginsert(string [] lognames, string [] logfullname) { if(logfullname[i].endsWith(txt)) { auto file = File(logfullname[i], r); foreach (line; file.byLine) { // long manupulation with strings } } } But now need add supporting passing to function not only txt files, but also zip archives. The problem that now I see only one way to do adding zip -- add block: if(logfullname[i].endsWith(zip)) And in it do everything with unpacking content of archive like: foreach(ArchiveMember am; zip.directory) { string file = cast(string)zip.expand(am); foreach (line; file.lineSplitter()) { } } and put inside it some same content that I am doing in long manupulation with strings. Maybe there is any better way? But I really can't understand it because auto file = File(logfullname[i], r); can't read unpacked content of archive. Use InputRange!string aka an input range which gives you elements. It can wrap up the behavior for getting the values.
Re: How to avoid code duplication?
Maybe there is way to access of element of archive in the same way as to txt file? I looked, but it's seems that constructor accept only path to file. But I can't understand how to set path to unpacked element of archive.
Re: Maxime's micro allocation benchmark much faster ?
On 2015-03-31 at 22:56, Laeeth Isharc wrote: 1mm allocations 2.066: 0.844s 2.067: 0.19s That is great news, thanks! OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M. :P
Re: Maxime's micro allocation benchmark much faster ?
On Wednesday, 1 April 2015 at 10:09:12 UTC, FG wrote: On 2015-03-31 at 22:56, Laeeth Isharc wrote: 1mm allocations 2.066: 0.844s 2.067: 0.19s That is great news, thanks! OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M. :P Yeah, what's with that? I've never seen it before.
Re: struct variable initialized with void.
On Tuesday, 31 March 2015 at 16:24:02 UTC, John Colvin wrote: On Tuesday, 31 March 2015 at 16:10:07 UTC, Adam D. Ruppe wrote: On Tuesday, 31 March 2015 at 15:59:53 UTC, John Colvin wrote: Like almost never? I can't think of any reason to ever do that. I mentioned it because of this story: https://www.schneier.com/blog/archives/2008/05/random_number_b.html I'm sure there's better ways to do it, but since a similar technique was used in a high profile product, I thought I'd mention it as a possible use. though I'd recommend against trying this at home for anything serious since there's better sources of more random randomness... In general, I can't think of a worse way of choosing a seed other than a fixed value*. It's actually quite interesting thinking of all the ways it's bad :) More fun than I thought: Depending on the OS and toolchain, you might be looking at anything in the current process (at best). That seed might be directly drawn from user data: an attacker could conceivably now choose your seed. The seed might contain sensitive data: an attacker who can measure the output of the PRNG might be able to work backwards to find the seed, exposing the data. You might always seed 0, or some other fixed value, or something almost always fixed depending on the program state: heavily biased towards certain values, bad for randomness. Based on observable state, an observer could conceivably infer or predict the value of the seed and hence predict future values from the PRNG. and so on...
Speed of horizontal flip
Hi, I have a bunch of square r16 and png images which I need to flip horizontally. My flip method looks like this: void hFlip(T)(T[] data, int w) { import std.datetime : StopWatch; StopWatch sw; sw.start(); foreach(int i; 0..w) { auto row = data[i*w..(i+1)*w]; row.reverse(); } sw.stop(); writeln(Img flipped in: , sw.peek().msecs, [ms]); } With simple r16 file format its pretty fast, but with RGB PNG files (2048x2048) I noticed its somewhat slow so I tried to compare it with C# and was pretty surprised by the results. C#: PNG load - 90ms PNG flip - 10ms PNG save - 380ms D using dlib (http://code.dlang.org/packages/dlib): PNG load - 500ms PNG flip - 30ms PNG save - 950ms D using imageformats (http://code.dlang.org/packages/imageformats): PNG load - 230ms PNG flip - 30ms PNG save - 1100ms I used dmd-2.0.67 with -release -inline -O C# was just with debug and VisualStudio attached to process for debugging and even with that it is much faster. I know that System.Drawing is using Windows GDI+, that can be used with D too, but not on linux. If we ignore the PNG loading and saving (didn't tried libpng yet), even flip method itself is 3 times slower - I don't know D enough to be sure if there isn't some more effecient way to make the flip. I like how the slices can be used here. For a C# user who is expecting things to just work as fast as possible from a system level programming language this can be somewhat disappointing to see that pure D version is about 3 times slower. Am I doing something utterly wrong? Note that this example is not critical for me, it's just a simple hobby script I use to move and flip some images - I can wait. But I post it to see if this can be taken somewhat closer to what can be expected from a system level programming language. dlib: auto im = loadPNG(name); hFlip(cast(ubyte[3][])im.data, cast(int)im.width); savePNG(im, newName); imageformats: auto im = read_image(name); hFlip(cast(ubyte[3][])im.pixels, cast(int)im.w); write_image(newName, im.w, im.h, im.pixels); C# code: static void Main(string[] args) { var files = Directory.GetFiles(args[0]); foreach (var f in files) { var sw = Stopwatch.StartNew(); var img = Image.FromFile(f); Debug.WriteLine(Img loaded in {0}[ms], (int)sw.Elapsed.TotalMilliseconds); sw.Restart(); img.RotateFlip(RotateFlipType.RotateNoneFlipX); Debug.WriteLine(Img flipped in {0}[ms], (int)sw.Elapsed.TotalMilliseconds); sw.Restart(); img.Save(Path.Combine(args[0], test_ + Path.GetFileName(f))); Debug.WriteLine(Img saved in {0}[ms], (int)sw.Elapsed.TotalMilliseconds); sw.Stop(); } }
Re: Speed of horizontal flip
tchaloupka: Am I doing something utterly wrong? If you have to perform performance benchmarks then use ldc or gdc. Also disable bound tests with your compilation switches. Sometimes reverse() is not efficient, I think, it should be improved. Try to replace it with a little function written by you. Add the usual pure/nothrow/@nogc/@safe annotations where you can (they don't increase speed much, usually). And you refer to flip as method, so if you are using classes don't forget to make the method final. Profile the code and look for the performance bottlenecks. You can even replace the *w multiplications with an increment of an index each loop, but this time saving is dwarfed by the reverse(). Bye, bearophile
C++ to D
Hi, Please help rewrite this code to D: #include iostream // Peano Arithmetic struct zero; template typename T struct succ { }; template typename T struct increment { using result = succT; }; template typename T struct decrement; template typename T struct decrementsuccT { using result = T; }; template typename A, typename B struct addition; template typename A struct additionA, zero { using result = A; }; template typename A, typename T struct additionA, succT { using result = typename additionsuccA, T::result; }; template typename T struct to_int; template struct to_intzero { static constexpr auto result = 0; }; template typename T struct to_intsuccT { static constexpr auto result = 1 + to_intT::result; }; template typename T using inc = typename incrementT::result; template typename T using dec = typename decrementT::result; template typename A, typename B using add = typename additionA, B::result; class nil; template typename T, typename Rest struct list { using head = T; using tail = Rest; }; template typename T struct length; template struct lengthnil { static constexpr auto result = 0; }; template typename Head, typename Tail struct lengthlistHead, Tail { // pattern-matching static constexpr auto result = 1 + lengthTail::result; }; template template typename class Func, class List struct map; template template typename class Func struct mapFunc, nil { using result = nil; }; template template typename class Func, class Head, class Tail struct mapFunc, listHead, Tail { // first-order function using result = listFuncHead, typename mapFunc, Tail::result; }; template template typename, typename class Func, class Init, class List struct fold; template template typename, typename class Func, class Init struct foldFunc, Init, nil { using result = Init; }; template template typename, typename class Func, class Init, class Head, class Tail struct foldFunc, Init, listHead, Tail { using result = FuncHead, typename foldFunc, Init, Tail::result; }; template class List struct sum { using result = typename foldadd, zero, List::result; }; int main() { using one = inczero; using two = incinczero; using four = incincincinczero; using two_plus_one = addtwo, one; std::cout to_inttwo_plus_one::result std::endl; // prints 3 using l = listone, listtwo, listfour, nil; std::cout lengthl::result std::endl; // prints 3 using res = summapinc, l::result::result; std::cout to_intres::result std::endl; // prints 10 return 0; }
Re: Maxime's micro allocation benchmark much faster ?
On Wednesday, 1 April 2015 at 10:35:05 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 10:09:12 UTC, FG wrote: On 2015-03-31 at 22:56, Laeeth Isharc wrote: 1mm allocations 2.066: 0.844s 2.067: 0.19s That is great news, thanks! OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M. :P Yeah, what's with that? I've never seen it before. One cannot entirely escape déformation professionnelle ;) [People mostly write 1,000 but 1mm although 1m is pedantically correct for 1,000). Better internalize the conventions if one doesn't want to avoid expensive mistakes under pressure.
CURL to get/set cookies
Hello! I’m having issues with setting a cookie via CURL(std.net.curl). I’ve tried several time over the last week but can’t figure it out. I feel like I've tried every suggestion I found searching the web. Basically - I receive the value set-cookie from a GET request (got this), but have no idea how to feed this into next POST request. Can someone point me in the right direction or provide a snippet of code that I could work from? Thank you! Benjamin Houdeshell
Re: CURL to get/set cookies
There's two ways, you can let curl handle it by setting a cookie jar file: http://dlang.org/phobos/std_net_curl.html#setCookieJar Make the HTTP object and set the jar on it before doing any requests. Then it will be done automatically on that object, saving to the file. If you are manually reading the Set-Cookie header, you can also just use this method: http://dlang.org/phobos/std_net_curl.html#setCookie
Re: Maxime's micro allocation benchmark much faster ?
On Wednesday, 1 April 2015 at 14:22:57 UTC, Laeeth Isharc wrote: On Wednesday, 1 April 2015 at 10:35:05 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 10:09:12 UTC, FG wrote: On 2015-03-31 at 22:56, Laeeth Isharc wrote: 1mm allocations 2.066: 0.844s 2.067: 0.19s That is great news, thanks! OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M. :P Yeah, what's with that? I've never seen it before. One cannot entirely escape déformation professionnelle ;) [People mostly write 1,000 but 1mm although 1m is pedantically correct for 1,000). Better internalize the conventions if one doesn't want to avoid expensive mistakes under pressure. well yes, who doesn't always not want to never avoid mistakes? ;) Anyway, as I'm sure you know, the rest of the world assumes SI/metric, or binary in special cases (damn those JEDEC guys!): http://en.wikipedia.org/wiki/Template:Bit_and_byte_prefixes
Re: C++ to D
On Wednesday, 1 April 2015 at 13:59:10 UTC, Dennis Ritchie wrote: snip You can do this: import std.typetuple; //helper for staticReduce template Alias(alias a) { alias Alias = a; } // staticReduce should really be in std.typetuple, or // the soon to arrive std.meta package. template staticReduce(alias F, TL ...) if (TL.length = 2) { static if (TL.length == 2) alias staticReduce = Alias!(F!(TL)); else alias staticReduce = staticReduce!(F, F!(TL[0..2]), TL[2..$]); } enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; alias staticSum(TL ...) = staticReduce!(Add, TL); void main() { //using two_plus_one = addtwo, one; enum two_plus_one = 2 + 1; //std::cout to_inttwo_plus_one::result std::endl; static assert(two_plus_one == 3); //using l = listone, listtwo, listfour, nil; alias l = TypeTuple!(1, 2, 4); //std::cout lengthl::result std::endl; // prints 3 static assert(l.length == 3); //using res = summapinc, l::result::result; enum res = staticSum!(staticMap!(Inc, l)); //std::cout to_intres::result std::endl; // prints 10 static assert(res == 10); } but really, there's no point: import std.algorithm; //All at compile-time: static assert(1+2 == 3); static assert([1,2,4].length == 3); static assert([1,2,4].map!a+1.sum == 10); Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess.
Re: Speed of horizontal flip
On Wednesday, 1 April 2015 at 14:00:52 UTC, bearophile wrote: tchaloupka: Am I doing something utterly wrong? If you have to perform performance benchmarks then use ldc or gdc. I tried it on my slower linux box (i5-2500K vs i7-2600K) without change with these results: C# (mono with its own GDI+ library): Img loaded in 108[ms] Img flipped in 22[ms] Img saved in 492[ms] dmd-2.067: Png loaded in: 150[ms] Img flipped in: 28[ms] Png saved in: 765[ms] gdc-4.8.3: Png loaded in: 121[ms] Img flipped in: 4[ms] Png saved in: 686[ms] ldc2-0_15: Png loaded in: 106[ms] Img flipped in: 4[ms] Png saved in: 610[ms] I'm ok with that, thx.
Re: Speed of horizontal flip
On Wednesday, 1 April 2015 at 16:08:14 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 13:52:06 UTC, tchaloupka wrote: snip I'm pretty sure that the flipping happens in GDI+ as well. You might be writing C#, but the code your calling that's doing all the work is C and/or C++, quite possibly carefully optimised over many years by microsoft. Yes thats right, load, flip and save are all performed by GDI+ so just pinvoke to optimised code from C#.
Re: Speed of horizontal flip
On Wednesday, 1 April 2015 at 13:52:06 UTC, tchaloupka wrote: snip I'm pretty sure that the flipping happens in GDI+ as well. You might be writing C#, but the code your calling that's doing all the work is C and/or C++, quite possibly carefully optimised over many years by microsoft. Are you even sure that your C# code truly performs a flip? It could easily just set the iteration scheme and return (like numpy.ndarray.T does, if you're familiar with python). dmd does not produce particularly fast code. ldc and gdc are much better at that. Sadly, std.algorithm.reserve isn't perhaps as fast as it could be for arrays of static arrays, at least in theory. Try this, but I hope that with a properly optimised build from ldc/gdc it won't make any difference: void reverse(ubyte[3][] r) { immutable last = r.length-1; immutable steps = r.length/2; foreach(immutable i; 0 .. steps) { immutable tmp = r[i]; r[i] = r[last - i]; r[last - i] = tmp; } } unittest { ubyte[3] a = [1,2,3]; ubyte[3] b = [7,6,5]; auto c = [a,b]; c.reverse(); assert(c == [b,a]); ubyte[3] d = [9,4,6]; auto e = [a,b,d]; e.reverse(); assert(e == [d,b,a]); auto f = e.dup; e.reverse; e.reverse; assert(f == e); }
Re: lambda code
On Tue, 31 Mar 2015 13:25:46 +, John Colvin wrote: Short answer: no. .codeof for functions is something I've wanted for ages, but no movement so far. 'cause `.codeof` is a can of worms. it is just a bad replace for AST macros, and having it means that internal string representation should be maintained intact for very long time. that's if i got you right and you mean that `.codeof` should return something like javascript's, `.toString` on functions: rebuild string representation of function source code. besides, it is impossible to write `.codeof` for functions without source. ;-) signature.asc Description: PGP signature
Re: Speed of horizontal flip
std.algorithm.reverse uses ranges, and shamefully DMD is really bad at optimizing away range-induced costs.
Re: lambda code
On Tuesday, 31 March 2015 at 13:25:47 UTC, John Colvin wrote: On Tuesday, 31 March 2015 at 12:49:36 UTC, Vlad Levenfeld wrote: Is there any way (or could there be any way, in the future) of getting the code from lambda expressions as a string? I've noticed that if I have an error with a lambda that looks like, say x=x+a the error message will come up referring to it as (x) = x + a so some level of processing has already been done on the expression. Can I get at any of it during compilation? It would be useful for automatic program rewriting. Short answer: no. .codeof for functions is something I've wanted for ages, but no movement so far. :(
Re: Accessing a field of a containing class from within a nested class
Yess.but there are LOTS of nodes/BTree, and each node would need to check whether the btFile was already initialized, et (ugh!) cetera. So while possible, that's an even worse answer than depending on people closing the BTree properly. I *am* going to separate the close routine from the destructor, so that it can be closed manually, and if not the destructor is going to print a warning message if the file is still open when it's called, but this isn't the best design. This design calls for users of what is essentially a library routine to remember to properly close it...or to hope that the destructor gets called before the program quits. In a practical sense, since I'm probably going to be the only user of the code, making BTree a class should be ok, but it feels like a bad design decision. I don't want to make the file a static member of the Node class (which would answer some of the problems) because that would prevent there being more than one BTree open at a time, and I expect to need at least two of them, and possibly more. Were I to do that I might as well make it a file level variable. So the ways to handle lack of a determinate close to the file are all clumsy, and a bit error prone. But I think having a file handle in each Node would be MUCH worse. How could you *ever* know when to close it, as Nodes are being opened and freed all the time. And most of the time many are open at once. Additionally, all the Nodes being closed doesn't mean the BTree is closed (though that's the most likely reason) so you can't even use a global counter. OTOH, this is still in the design stage, so if a good answer were to be available, now would be the best time to put it in. (FWIW both the Key and the Data will be required to pass !hasIndirections!(T). I'm not planning a truly general BTree. In my test version the Key is a ulong and the Data is a struct containing only ulongs and ints.) On 04/01/2015 03:03 PM, Ali Çehreli via Digitalmars-d-learn wrote: On 04/01/2015 11:25 AM, Charles Hixson via Digitalmars-d-learn wrote: The class Node is contained within the struct BTree. The field btFile is contained within the struct BTree. The statement is within a function within the Node class. I've tried many variations, here are a few: btFile.write(self.nodeId, cast(void*)(self)); results in: need 'this' for 'btFile' of type 'BlockFile' this.btFile.write(self.nodeId, cast(void*)(self)); results in: Error: no property 'btFile' for type 'btplus.BTree.Node' this.BTree.btFile.write(self.nodeId, cast(void*)(self)); results in: Error: constructor btplus.BTree.this (string fName) is not callable using argument types (Node) Perhaps BTree needs to be a class? I made it a struct because I want it to definitely close properly when it goes out of scope. Can you modify the definition of Node? If so, perhaps it's possible construct Node objects with a reference to its btFile: import std.stdio; class Node { int *btFile; this(int *btFile) { this.btFile = btFile; } void foo() { writeln(*btFile); } } struct BTree { int btFile; Node node; this(int btFile) { this.btFile = btFile; this.node = new Node(this.btFile); } } void main() { auto bt = BTree(42); bt.node.foo(); } Ali
Accessing a field of a containing class from within a nested class
The class Node is contained within the struct BTree. The field btFile is contained within the struct BTree. The statement is within a function within the Node class. I've tried many variations, here are a few: btFile.write(self.nodeId, cast(void*)(self)); results in: need 'this' for 'btFile' of type 'BlockFile' this.btFile.write(self.nodeId, cast(void*)(self)); results in: Error: no property 'btFile' for type 'btplus.BTree.Node' this.BTree.btFile.write(self.nodeId, cast(void*)(self)); results in: Error: constructor btplus.BTree.this (string fName) is not callable using argument types (Node) Perhaps BTree needs to be a class? I made it a struct because I want it to definitely close properly when it goes out of scope.
Re: C++ to D
On Wednesday, 1 April 2015 at 15:22:10 UTC, John Colvin wrote: Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess. Yes, CTFE in D really cool. Thanks. I need to implement arithmetic (addition / subtraction) only use the type system. That is, such a design does not suit me: enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; I need a code like this: - #include iostream struct zero; template typename T struct succ { }; template typename T struct increment { using result = succT; }; template typename T struct decrement; template typename T struct decrementsuccT { using result = T; }; template typename A, typename B struct addition; template typename A struct additionA, zero { using result = A; }; template typename A, typename T struct additionA, succT { using result = typename additionsuccA, T::result; }; template typename T struct to_int; template struct to_intzero { static constexpr auto result = 0; }; template typename T struct to_intsuccT { static constexpr auto result = 1 + to_intT::result; }; template typename T using inc = typename incrementT::result; template typename T using dec = typename decrementT::result; template typename A, typename B using add = typename additionA, B::result; int main() { using one = inczero; using two = incinczero; using four = incincincinczero; using two_plus_one = addtwo, one; std::cout to_intfour::result std::endl; // 4 std::cout to_inttwo_plus_one::result std::endl; // 3 return 0; }
Re: C++ to D
On Wednesday, 1 April 2015 at 17:03:34 UTC, Dennis Ritchie wrote: On Wednesday, 1 April 2015 at 15:22:10 UTC, John Colvin wrote: Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess. Yes, CTFE in D really cool. Thanks. I need to implement arithmetic (addition / subtraction) only use the type system. That is, such a design does not suit me: enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; Don't really see the point. Here's a neat thing that's definitely cheating because although it stores the results in the type system, the arithmetic is done in constant-folding: struct Integer(int a){} template Value(T) { static if (is(T == Integer!a, int a)) enum Value = a; else static assert(false, Can't get Value for ~ T.stringof); } alias Inc(T) = Integer!(Value!T + 1); But if you really insist on it being all type-system (until you wan't the answer of course): struct Zero{} template Succ(T) { static if (is(T == Pred!A, A)) alias Succ = A; else struct Succ{} } template Pred(T) { static if (is(T == Succ!A, A)) alias Pred = A; else struct Pred{} } enum isPositive(T) = is(T == Succ!A, A); enum isNegative(T) = is(T == Pred!A, A); enum isZero(T) = is(T == Zero); template Add(A, B) { static if (isZero!B) alias Add = A; else static if (isPositive!B) alias Add = Add!(Succ!A, Pred!B); else alias Add = Add!(Pred!A, Succ!B); } template Value(T, int seed = 0) { static if (isZero!T) enum Value = seed; else static if (isPositive!T) enum Value = Value!(Pred!T, seed+1); else enum Value = Value!(Succ!T, seed-1); } unittest { alias One = Succ!Zero; alias Two = Succ!One; alias MinusThree = Pred!(Pred!(Pred!Zero)); static assert (Value!Zero == 0); static assert (Value!One == 1); static assert (Value!Two == 2); static assert (Value!MinusThree == -3); static assert (Value!(Add!(One, MinusThree)) == -2); static assert (Value!(Add!(One, Two)) == 3); static assert (is(Add!(Add!(One, Two), MinusThree) == Zero)); }
Re: C++ to D
On Wednesday, 1 April 2015 at 17:51:40 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 17:03:34 UTC, Dennis Ritchie wrote: On Wednesday, 1 April 2015 at 15:22:10 UTC, John Colvin wrote: Compile Time Function Evaluation (CTFE) is a very powerful tool to avoid having to enter in to all that C++ style mess. Yes, CTFE in D really cool. Thanks. I need to implement arithmetic (addition / subtraction) only use the type system. That is, such a design does not suit me: enum Add(Args...) = Args[0] + Args[1]; enum Inc(Args...) = Args[0] + 1; Don't really see the point. Here's a neat thing that's definitely cheating because although it stores the results in the type system, the arithmetic is done in constant-folding: struct Integer(int a){} template Value(T) { static if (is(T == Integer!a, int a)) enum Value = a; else static assert(false, Can't get Value for ~ T.stringof); } alias Inc(T) = Integer!(Value!T + 1); But if you really insist on it being all type-system (until you wan't the answer of course): struct Zero{} template Succ(T) { static if (is(T == Pred!A, A)) alias Succ = A; else struct Succ{} } template Pred(T) { static if (is(T == Succ!A, A)) alias Pred = A; else struct Pred{} } enum isPositive(T) = is(T == Succ!A, A); enum isNegative(T) = is(T == Pred!A, A); enum isZero(T) = is(T == Zero); template Add(A, B) { static if (isZero!B) alias Add = A; else static if (isPositive!B) alias Add = Add!(Succ!A, Pred!B); else alias Add = Add!(Pred!A, Succ!B); } template Value(T, int seed = 0) { static if (isZero!T) enum Value = seed; else static if (isPositive!T) enum Value = Value!(Pred!T, seed+1); else enum Value = Value!(Succ!T, seed-1); } unittest { alias One = Succ!Zero; alias Two = Succ!One; alias MinusThree = Pred!(Pred!(Pred!Zero)); static assert (Value!Zero == 0); static assert (Value!One == 1); static assert (Value!Two == 2); static assert (Value!MinusThree == -3); static assert (Value!(Add!(One, MinusThree)) == -2); static assert (Value!(Add!(One, Two)) == 3); static assert (is(Add!(Add!(One, Two), MinusThree) == Zero)); } If the is() expressions are confusing you, in this case they work like this; is (T == B!A, A) means is T the same type as B instantiated with A, for some type A? or more succinctly is T an instantiation of B? See http://dlang.org/expression.html#IsExpression, it's quite reminiscent of some mathematical set notation.
Re: Accessing a field of a containing class from within a nested class
On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote: Perhaps BTree needs to be a class? yes
Re: Maxime's micro allocation benchmark much faster ?
On 2015-04-01 at 16:52, John Colvin wrote: On Wednesday, 1 April 2015 at 14:22:57 UTC, Laeeth Isharc wrote: On Wednesday, 1 April 2015 at 10:35:05 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 10:09:12 UTC, FG wrote: On 2015-03-31 at 22:56, Laeeth Isharc wrote: 1mm allocations 2.066: 0.844s 2.067: 0.19s That is great news, thanks! OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M. :P Yeah, what's with that? I've never seen it before. One cannot entirely escape déformation professionnelle ;) [People mostly write 1,000 but 1mm although 1m is pedantically correct for 1,000). Better internalize the conventions if one doesn't want to avoid expensive mistakes under pressure. well yes, who doesn't always not want to never avoid mistakes? ;) Anyway, as I'm sure you know, the rest of the world assumes SI/metric, or binary in special cases (damn those JEDEC guys!): http://en.wikipedia.org/wiki/Template:Bit_and_byte_prefixes Yeah, there's that, but at least 1024 and 1000 are still in the same ballpark. Bankers are used to the convention and won't mistake M for a million (or you'd read it in every newspaper if they did), but it does create havoc when you see that convention being used outside of the financial context, or worse, being mixed with SI.
Re: Accessing a field of a containing class from within a nested class
On 04/01/2015 11:39 AM, anonymous via Digitalmars-d-learn wrote: On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote: Perhaps BTree needs to be a class? yes Thanks. Sigh. I was hoping to preserve the determinate closing that one gets with a struct.
Re: Accessing a field of a containing class from within a nested class
On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote: Perhaps BTree needs to be a class? I made it a struct because I want it to definitely close properly when it goes out of scope. Maybe `scoped` can help: http://dlang.org/phobos/std_typecons.html#.scoped
some memory allocation/GC benchmarks here - fwiw
(not translated into D yet) http://blog.mgm-tp.com/2013/12/benchmarking-g1-and-other-java-7-garbage-collectors/ http://www.mm-net.org.uk/resources/benchmarks.html http://www.ccs.neu.edu/home/will/GC/sourcecode.html http://yoda.arachsys.com/csharp/benchmark.html it's possible we already have better ones in phobos test suite, but maybe interesting also to be able to compare to other languages/platforms.
Re: Accessing a field of a containing class from within a nested class
On 04/01/2015 11:25 AM, Charles Hixson via Digitalmars-d-learn wrote: The class Node is contained within the struct BTree. The field btFile is contained within the struct BTree. The statement is within a function within the Node class. I've tried many variations, here are a few: btFile.write(self.nodeId, cast(void*)(self)); results in: need 'this' for 'btFile' of type 'BlockFile' this.btFile.write(self.nodeId, cast(void*)(self)); results in: Error: no property 'btFile' for type 'btplus.BTree.Node' this.BTree.btFile.write(self.nodeId, cast(void*)(self)); results in: Error: constructor btplus.BTree.this (string fName) is not callable using argument types (Node) Perhaps BTree needs to be a class? I made it a struct because I want it to definitely close properly when it goes out of scope. Can you modify the definition of Node? If so, perhaps it's possible construct Node objects with a reference to its btFile: import std.stdio; class Node { int *btFile; this(int *btFile) { this.btFile = btFile; } void foo() { writeln(*btFile); } } struct BTree { int btFile; Node node; this(int btFile) { this.btFile = btFile; this.node = new Node(this.btFile); } } void main() { auto bt = BTree(42); bt.node.foo(); } Ali