Re: Accessing __FILE__ and __LINE__ of caller in combination with varargs?
On Saturday, 16 April 2016 at 00:03:59 UTC, Jonathan M Davis wrote: On Friday, April 15, 2016 20:52:42 WebFreak001 via Digitalmars-d-learn wrote: void assertf(string file = __FILE__, size_t line = __LINE__, Args...)(lazy bool condition, in string message, Args args) { Yes, you can do that, but do _not_ do that unless you really have no other choice. What you need to realize is that because the file and line number arguments will be unique for every call to this function, it will generate a new instantiation of it _every_ time it is called. So, you're going to get a lot of code bloat. There are rare cases where such bloat would be acceptable, but in the general case, it's a terrible thing to do. This particular case might be acceptable given how short it is, but in general, using __FILE__ or __LINE__ as template arguments should be avoided like the plague. A few tricks to reduce this bloat: - Write a small wrapper. This will still give bloat, but only of small functions: void assertf(string file = __FILE__, size_t line = __LINE__, Args...)(lazy bool condition, in string message, Args args) { assertfImpl(file, line, condition, message, args); } - Only care about line numbers in debug mode. Makes debug more bloated, code less readable, and you lose out on line numbers in release. Still worth it occasionally: version (debug) { void foo(string file = __FILE__, size_t line = __LINE__, Args...)(Args args) { // Stuffs. } } else { void assertf(Args...)(Args args) { // Stuffs. } } I'd love to have a way to pass the file and line number info as regular parameters, though. Something like: void foo(Args...)(Args args, string file = __FILE__, int line = __LINE__) {} Sadly, currently not possible. Maybe we could overload @disable for this purpose? void foo(Args...)(Args args, @disable string file = __FILE__, @disable int line = __LINE__) {} -- Simen
Re: infer type argument in classe constructor?
On Tuesday, 29 March 2016 at 10:13:28 UTC, Puming wrote: Hi, I'm writing a generic class: ```d struct Message { ... } class Decoder(MsgSrc) { } ``` When using it, I'd have to include the type of its argument: ``` void main() { Message[] src = ...; auto decoder = new Decoder!(Message[])(src); ... } ``` Can it be inferred so that I only need to write? ```d auto decoder = new Decoder(src); // you can infer the type from src. ``` Nope. To see why, consider a class like this: class A(T) { T data; this(int n) { } } void main() { auto a = new A(3); // What is T? } The common solution is a simple 'create' function: Decoder!T decoder(T)(T msg) { return new Decoder!T(msg); } -- Simen
Re: Does something like std.algorithm.iteration:splitter with multiple seperators exist?
On Wednesday, 23 March 2016 at 18:10:05 UTC, ParticlePeter wrote: Thanks Simen, your tokenCounter is inspirational, for the rest I'll take some time for testing. My pleasure. :) Testing it on your example data shows it to work there. However, as stated above, the documentation says it's undefined, so future changes (even optimizations and bugfixes) to Phobos could make it stop working: "This predicate must be an equivalence relation, that is, it must be reflexive (pred(x,x) is always true), symmetric (pred(x,y) == pred(y,x)), and transitive (pred(x,y) && pred(y,z) implies pred(x,z)). If this is not the case, the range returned by chunkBy may assert at runtime or behave erratically." But some additional thoughts from my sided: I get all the lines of the file into one range. Calling array on it should give me an array, but how would I use find to get an index into this array? With the indices I could slice up the array into four slices, no allocation required. If there is no easy way to just get an index instead of an range, I would try to use something like the tokenCounter to find all the indices. The chunkBy example should not allocate. chunkBy itself is lazy, as are its sub-ranges. No copying of string contents is performed. So unless you have very specific reasons to use slicing, I don't see why chunkBy shouldn't be good enough. Full disclosure: There is a malloc call in RefCounted, which is used for optimization purposes when chunkBy is called on a forward range. When chunkBy is called on an array, that's a 6-word allocation (24 bytes on 32-bit, 48 bytes on 64-bit), happening once. There are no other dependencies that allocate. Such is the beauty of D. :) -- Simen
Re: Does something like std.algorithm.iteration:splitter with multiple seperators exist?
On Wednesday, 23 March 2016 at 11:57:49 UTC, ParticlePeter wrote: I need to parse an ascii with multiple tokens. The tokens can be seen as keys. After every token there is a bunch of lines belonging to that token, the values. The order of tokens is unknown. I would like to read the file in as a whole string, and split the string with: splitter(fileString, [token1, token2, ... tokenN]); And would like to get a range of strings each starting with tokenX and ending before the next token. Does something like this exist? I know how to parse the string line by line and create new strings and append the appropriate lines, but I don't know how to do this with a lazy result range and new allocations. Without a bit more detail, it's a bit hard to help. std.algorithm.splitter has an overload that takes a function instead of a separator: import std.algorithm; auto a = "a,b;c"; auto b = a.splitter!(e => e == ';' || e == ','); assert(equal(b, ["a", "b", "c"])); However, not only are the separators lost in the process, it only allows single-element separators. This might be good enough given the information you've divulged, but I'll hazard a guess it isn't. My next stop is std.algorithm.chunkBy: auto a = ["a","b","c", "d", "e"]; auto b = a.chunkBy!(e => e == "a" || e == "d"); auto result = [ tuple(true, ["a"]), tuple(false, ["b", "c"]), tuple(true, ["d"]), tuple(false, ["e"]) ]; No assert here, since the ranges in the tuples are not arrays. My immediate concern is that two consecutive tokens with no intervening values will mess it up. Also, the result looks a bit messy. A little more involved, and according to documentation not guaranteed to work: bool isToken(string s) { return s == "a" || s == "d"; } bool tokenCounter(string s) { static string oldToken; static bool counter = true; if (s.isToken && s != oldToken) { oldToken = s; counter = !counter; } return counter; } unittest { import std.algorithm; import std.stdio; import std.typecons; import std.array; auto a = ["a","b","c", "d", "e", "a", "d"]; auto b = a.chunkBy!tokenCounter.map!(e=>e[1]); auto result = [ ["a", "b", "c"], ["d", "e"], ["a"], ["d"] ]; writeln(b); writeln(result); } Again no assert, but b and result have basically the same contents. Also handles consecutive tokens neatly (but consecutive identical tokens will be grouped together). Hope this helps. -- Simen
Re: How do I extend an enum?
On Saturday, 19 March 2016 at 17:40:27 UTC, Lass Safin wrote: Why: enum Base { A, B, } enum Derived : Base { C, // Gives error, says it can't implicitly convert expression to Base. D = 1, // Same error E = cast(Base)294, // Finally works. Can only be cast(Derived) instead. } void func(Derived d) {} func(Derived.E); // works. func(Derived.A); // Gives error, says it can't call function with Base.A. func(cast(Derived)Derived.A); // Works. So, what's the proper way of extending an enum? There is no way to extend an enum. When you think about it, it's actually the opposite of what you'd generally want. Given two classes: class A {} class B : A {} Every instance of B is a valid A. That is, given a variable of type A, you could assign any B to it. Now consider enums: enum A { x, y, z } enum B : A {} Which values could you put in B? Only those that would be valid for A. That is, only x, y and z. Imagine that we could: enum B : A { w } A foo = B.w; foo now holds a value that is not valid for its type. Hence, you simply cannot. Are there cases where you want to define a new enum that contains all the items in a 'base' enum in addition to some new items? Absolutely, and D lacks a good way to do that. But subtyping would in any case not be the correct way to do it. Are there cases where you want to extend an enum by making a subtype with more items? I would argue that's a strong code smell in D, but I can see why you'd want to. -- Simen
Re: classInstanceSize and vtable
On Friday, 24 October 2014 at 00:21:52 UTC, Etienne Cimon wrote: On 2014-10-23 20:12, bearophile wrote: In D all class instances contain a pointer to the class and a monitor pointer. The table is used for run-time reflection, and for standard virtual methods like toString, etc. Bye, bearophile So what's the point of making a class or methods final? Does it only free some space and allow inline to take place? Like bearophile said the vtable is required for virtual methods. Consider this code: import std.stdio : writeln; class A { void foo() {writeln(A);} } final class B : A { override void foo() {writeln(B);} } void main() { A a = new B(); a.foo(); } In order for the call to foo to run the correct version of foo, B needs to have a vtable. Since all classes in D implicitly inherit from Object, which has some virtual methods, all classes need to have a vtable. -- Simen
Re: this() immutable
On 2013-10-16, 18:54, Daniel Davidson wrote: On Thursday, 13 June 2013 at 12:29:57 UTC, Simen Kjaeraas wrote: On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels stephan_schiff...@mac.com wrote: For example, is there a way of instantiating an object normally (i.e. mutable), and then later freeze it to immutable via a simple cast or so? In std.exception there is assumeUnique. It's basically just a cast, but might be good enough for you. Is there any other recourse here? Why does making `this(...) immutable` fix things below? Shouldn't that immutable designation mean no members of this will be modified? But that is the whole point of an initializer? Why does immutable make sense in this context at all? Immutable in the case of constructors means that the instance will be created using only data implicitly castable to immutable. That way, when construction is finished, it is safe for the type system to mark the result as immutable. My problem is a bit more elaborate and unfortunately to initialize members I need to call standard functions that have not been made pure (but should be). If you're calling functions that are not marked pure in order to create immutable data, you will need to cast to immutable afterwards. If you know this is safe, no problem. It would benefit us all if you reported these functions or created a pull request for Phobos, of course. -- Simen
Re: How to check for instantiation of specific template?
On 2013-10-10, 19:23, H. S. Teoh wrote: I have a template used for storing compile-time values: template Def(int x, string y) { alias impl = TypeTuple!(x,y); } How do I define a template isDef that, given some template alias A, evaluates to true if A is some instantiation of Def? template isDef(alias A) { enum A = ... /* what to put here? */ } This seems to be impossible. The standard way of doing this would be with an isExpression[0], but that only works for types. A solution would be to beef up your Def template by turning it into a struct: struct Def(int x, string y) { alias impl = TypeTuple!(x,y); } With this definition, the following works: template isDef(alias A) { enum isDef = is(A == Def!T, T...); // Or enum isDef = is(A == Def!(x, y), int x, string y); } This is a shortcoming of the language, and I have filed an enhancement request for it[1]. The problems of using an actual type for this, is that someone might instantiate that type (unlikely), and that the compiler will generate TypeInfo for it, which will bloat your executable. A Sufficienctly Smart Compiler[2] would see that the type is never used and thus not include the TypeInfo. Something which the compiler could do without a lot of smarts, is optimize away final abstract classes, which you cannot derive from and cannot instantiate. That oughta be enough. [0]: http://dlang.org/expression#IsExpression [1]: http://d.puremagic.com/issues/show_bug.cgi?id=11219 [2]: http://c2.com/cgi/wiki?SufficientlySmartCompiler -- Simen
Re: fill array using a lambda function
On 2013-10-10, 16:04, bearophile wrote: dominic jones: I want to fill an array with random numbers without resorting to loops, i.e. by doing something like the following, if it were possible: fill!(function double(){ return uniform(0.0, 1.0);})(x[]); Is there a simple way of doing this? Generally it's a good idea to use only pure functions inside the higher order functions of Phobos. using impure functions like uniforms could lead to bugs or performance problems. This is a way to do it (untested): x.copy(x.length.iota.map!(_ = uniform(0.0, 1.0)); You've got the order wrong - copy takes first the source, then the target. Also, is it faster to use .length.iota than simply mapping on x? My solution: x.map!(_=uniform(0.0, 1.0)).copy(x); -- Simen
Re: What's about virtual?
On Tue, 10 Sep 2013 02:28:24 +0200, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 9/9/13 12:47 PM, H. S. Teoh wrote: On Mon, Sep 09, 2013 at 09:37:07PM +0200, Namespace wrote: It's been a while since Manu convinced Walter and Andrei to introduce a virtual Keyword and to change the default from virtual methods to final methods. Anything new? Anybody working on that? I would love to see that soon. This is going to break a lot of code. We'd need some kind of deprecation path. And even then, it may anger a lot of existing users. T After I've seen a pretty cool demo of clang-modernize (http://clang.llvm.org/extra/ModernizerUsage.html), I think the best way to attack this and similar problems is to add a class hierarchy analyzer: a command-line utility that is fed an entire project and adds as many 'final' as possible without changing semantics. Time has come to migrate such functionality to tools. We keep on telling that nobody uses the tools but it seems experience contradicts that belief. So the catastrophe that is virtual by default will not be changed? -- Simen
Re: What is a concise way to test if floating point value is integral?
On 2013-08-29, 10:25, Jonathan M Davis wrote: On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote: On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis wrote: [..] as any integral value in a float will fit in an int. [..] Will it? Most of them will not fit Sure, they will. float has 32 bits, just like int, so it can't possibly hold a value larger than an int can hold. This code passes with flying colors foreach(i; int.min .. int.max) assert(cast(float)i == i); First, that's showing the exact opposite of what you're saying it does. Second, it doesn't even show that. Your code is equivalent to: foreach(i; int.min .. int.max) assert(cast(float)i == cast(float)i); If that does not pass with flying colors, I'd be surprised. Now try this: foreach(i; int.min .. int.max) { float f = i; // DMD optimizes out cast(int)cast(float)int assert(cast(int)f == i); } It will fail for odd numbers in the range 16,777,216-33,554,432, and for numbers not divisible by 4 in the range to the next power of two, then 8, and so on. These numbers are simply not representable by a float. For more information: http://floating-point-gui.de/formats/fp/ -- Simen
Re: Get class size of object
On 2013-08-11, 20:33, JS wrote: I think you're missing the point to some degree(I realize there is a diff between an object and a type, but I should be able to easily get the class size of an object at run time regardless if the object is typed as a base class). The code below does this, but at a cost of verbosity. Here is code that exactly demonstrates what I am essentially trying to do. The only drawback now is having to mixin the template for each class which I would want to automate and it would be nice to wrap the RT and CT methods in subclasses without overhead. It would appear that some information is lost when calling typeid from an interface. I would have expected this to work: interface I { final size_t size() { return typeid(this).init.length; } } class A {} class B : A, I { int a; } void test1() { I i = new B(); assert(i.size 0); // Fails. } A bit more experimentation shows: void test2() { B b = new B(); I i = b; A a = b; assert(typeid(a) == typeid(b)); // Passes. assert(typeid(i) == typeid(b)); // Fails. assert(typeid(b).init.length 0); // Passes. assert(typeid(i).init.length 0); // Fails. } It appears thus that the error is in typeid(interface), which does not give the actual typeid. The workaround is as follows: interface I { final size_t size() { return typeid(cast(Object)this).init.length; } } Is this what you want? Is it good enough? I have no idea, as you're notoriously bad at describing what you want, but pretty good at attacking people. If you're looking for a no-overhead solution, then this might not be good enough. I'm surprised that a virtual function call is fine, though.
Re: Types of regex
On 2013-07-15, 11:32, Larry wrote: Hello, I read the library reference for regex. I really miss python's equivalent of finditer. Sometimes matching is not on purpose and one will want to match all the occurences to iterate over it since it is much more regarding concerning the orders and repetitions. my code : - version(Tango) extern (C) int printf(char *, ...); import std.stdio; import std.regex; import std.file; import std.format; int main(char[][] args) { string fl = readText(testregexd.txt); auto m = match(fl, regex(`(n=(?:hello|goodbye))*`,g)); auto c = m.captures; writeln(c); return 0; } --- Content of testregexd.txt: n=hello n=goodbye Any way to workaround ? Thanks ! Larry Have you tried iterating over m? This works for me: import std.stdio; import std.regex; import std.file; import std.format; int main(char[][] args) { string fl = n=hello n=goodbye ; auto m = match(fl, regex(`(n=(?:hello|goodbye))`,g)); foreach (c; m) writeln(c); return 0; } -- Simen
Re: Conditional Inheritance
On 2013-07-14, 07:00, JS wrote: I need to conditionally inherit: interface A(T) : conditionallyInherit!(isBasicType!T, B); A!(double) will inherit B but A!(mytype) won't. template conditionallyInherit(bool choice, T...) { static if (choice) { alias conditionallyInherit = T; } else { import std.typetuple : TypeTuple; alias conditionallyInherit = TypeTuple!(); } } Should work. -- Simen
Re: Conditional Inheritance
On 2013-07-14, 07:40, JS wrote: On Sunday, 14 July 2013 at 05:30:57 UTC, lomereiter wrote: On Sunday, 14 July 2013 at 05:04:37 UTC, JS wrote: and while I'm at it I need to conditionally constrain types. interface A(T) where(!isBasicType!T, (T : B)); which is suppose to require T to inherit from B if T is not basic type. interface A(T) if (isBasicType!T || is(T : B)) Thanks, works. I remember seeing code like this somewhere but couldn't find any docs about it. Here. I admit there should probably be more examples, and perhaps also some info on the classes/interfaces/structs unions pages. http://dlang.org/template.html#Constraint -- Simen
Re: Style question
On 2013-07-11, 20:22, Namespace wrote: What should he do? As far as I can see he has 3 options: 1. An external file with the enum information. Both classes would import it and could use the same enum. But he cannot change the API, so this is no real option. 2. Change test1 into this: void test1() { B b = cast(B) this.a; MyStaticClass.test2(b); } This works fine. But is it safe? And is it good style? And how is this cast converted? Is it cheap? 3. Change test2 so that it accepts (even) (u)int. But then he lose the Type safety. Does anyone have any advice? This might be an option: version (unittest) { enum A { foo = 1, bar = 2, } enum B { foo = 1, bar = 2, } enum C { foo = 3, bar = 4, } enum D { baz, qux, } } template sameMembers(T, U) { template sameValue(string member) { enum sameValue = __traits(getMember, T, member) == __traits(getMember, U, member); } import std.typetuple : allSatisfy; enum sameMembers = sameMemberNames!(T,U) allSatisfy!(sameValue, __traits(allMembers, T)); } unittest { assert(sameMembers!(A,A)); assert(sameMembers!(A,B)); assert(sameMembers!(B,A)); assert(sameMembers!(B,B)); assert(!sameMembers!(A,C)); assert(!sameMembers!(B,C)); assert(!sameMembers!(C,A)); assert(!sameMembers!(C,B)); } template sameMemberNames(T, U) { template Has(Type) { template Has(string member) { enum Has = __traits(hasMember, Type, member); } } import std.typetuple : allSatisfy; enum sameMemberNames = allSatisfy!(Has!T, __traits(allMembers, U)) allSatisfy!(Has!U, __traits(allMembers, T)); } unittest { assert(sameMemberNames!(A,A)); assert(sameMemberNames!(A,B)); assert(sameMemberNames!(A,C)); assert(sameMemberNames!(B,A)); assert(sameMemberNames!(B,B)); assert(sameMemberNames!(B,C)); assert(sameMemberNames!(C,A)); assert(sameMemberNames!(C,B)); assert(sameMemberNames!(C,C)); assert(sameMemberNames!(D,D)); assert(!sameMemberNames!(A,D)); assert(!sameMemberNames!(B,D)); assert(!sameMemberNames!(C,D)); assert(!sameMemberNames!(D,A)); assert(!sameMemberNames!(D,B)); assert(!sameMemberNames!(D,C)); } T ConvertEnum(T,U)(U value) if (sameMembers!(T,U)) { return cast(T)value; } T ConvertEnum(T,U)(U value) if (sameMemberNames!(T,U) !sameMembers!(T,U)) { final switch (value) { foreach (e; __traits(allMembers, U)) { case __traits(getMember, U, e): return __traits(getMember, T, e); } } assert(false); } unittest { assert(ConvertEnum!A(B.foo) == A.foo); assert(ConvertEnum!A(B.bar) == A.bar); assert(ConvertEnum!A(C.foo) == A.foo); assert(ConvertEnum!A(C.bar) == A.bar); assert(ConvertEnum!B(A.foo) == B.foo); assert(ConvertEnum!B(A.bar) == B.bar); assert(ConvertEnum!B(C.foo) == B.foo); assert(ConvertEnum!B(C.bar) == B.bar); assert(ConvertEnum!C(A.foo) == C.foo); assert(ConvertEnum!C(A.bar) == C.bar); assert(ConvertEnum!C(B.foo) == C.foo); assert(ConvertEnum!C(B.bar) == C.bar); assert(!__traits(compiles, { auto tmp = ConvertEnum!D(A.foo); })); assert(!__traits(compiles, { auto tmp = ConvertEnum!D(B.foo); })); assert(!__traits(compiles, { auto tmp = ConvertEnum!D(C.foo); })); assert(!__traits(compiles, { auto tmp = ConvertEnum!A(D.foo); })); assert(!__traits(compiles, { auto tmp = ConvertEnum!B(D.foo); })); assert(!__traits(compiles, { auto tmp = ConvertEnum!C(D.foo); })); } The function ConvertEnum safely converts from one enum to another, given that the same members exist in both. If the enums are equal (same values for each member), a simple cast is used. If the names are equal, but values are different, a switch/case is built, and A.Foo is converted to B.Foo. -- Simen
Re: for loop parens
On 2013-07-12, 22:38, ixid wrote: On Friday, 12 July 2013 at 20:30:59 UTC, bearophile wrote: ixid: Similarly what are D user's potential issues with Go-like semi-colon rules? And would this be possible as a subset of current D code? Such changes will not happen even in D4. Walter is strongly against the idea of optional semicolons, on the base that semicolons help the parser, so they allow better error recovery and error messages. Bye, bearophile Is there any evidence that these are issues in Go? I'm not sure how much of a problem it is, especially given that Go has a strict style guide, but the objection has come up that these two are very different: if i f() { g() } and if i f() { g() } In the second case, a semicolon is inserted on the same line as the if. However, like I said, in idiomatic Go, this is simply not a done thing. -- Simen
Re: Style question
On 2013-07-11, 20:22, Namespace wrote: What should he do? As far as I can see he has 3 options: 1. An external file with the enum information. Both classes would import it and could use the same enum. But he cannot change the API, so this is no real option. 2. Change test1 into this: void test1() { B b = cast(B) this.a; MyStaticClass.test2(b); } This works fine. But is it safe? And is it good style? And how is this cast converted? Is it cheap? 3. Change test2 so that it accepts (even) (u)int. But then he lose the Type safety. Does anyone have any advice? It seems to me that MyClass has access to MyStaticClass, and thus should also have access to B. If this is the case, why is MyClass using an A instead of a B? One option might be to use alias A = B; This would ensure the two enums are always the same. Last ditch, I would say option #2 is the best. It's not safe, in that if one enum changes and the other does not, the cast will blithely ignore that and use the same uint value. It is however efficient, as it is a simple reinterpretation of the bits. -- Simen
Re: How can i increase max number recursive template expansions?
On 2013-07-08, 11:03, bearophile wrote: Simen Kjaeraas: However, you can amend std.traits.EnumMembers to work with larger enums by using this version: Worth putting in Phobos? Filed: http://d.puremagic.com/issues/show_bug.cgi?id=10569 And created a pull request: https://github.com/D-Programming-Language/phobos/pull/1400 -- Simen
Re: How can i increase max number recursive template expansions?
On 2013-07-07, 21:55, QAston wrote: I have a large enum in my code (opcodes for a protocol) - using std.traits.EnumMembers gives me a recursive template error. How can i increase max number recursive template expansions? You can't. However, you can amend std.traits.EnumMembers to work with larger enums by using this version: import std.typetuple; template EnumMembers(E) if (is(E == enum)) { // Supply the specified identifier to an constant value. template WithIdentifier(string ident) { static if (ident == Symbolize) { template Symbolize(alias value) { enum Symbolize = value; } } else { mixin(template Symbolize(alias ~ ident ~) ~{ ~alias ~ ident ~ Symbolize; ~}); } } template EnumSpecificMembers(names...) { static if (names.length 200) { alias TypeTuple!( EnumSpecificMembers!(names[0..$/2]), EnumSpecificMembers!(names[$/2..$]), ) EnumSpecificMembers; } else static if (names.length 0) { alias TypeTuple!( WithIdentifier!(names[0]) .Symbolize!(__traits(getMember, E, names[0])), EnumSpecificMembers!(names[1 .. $]), ) EnumSpecificMembers; } else { alias TypeTuple!() EnumSpecificMembers; } } alias EnumSpecificMembers!(__traits(allMembers, E)) EnumMembers; } Here, this line: static if (names.length 200) uses divide-and-conquer to reduce the number of template instantiations. -- Simen
Re: ref tuples
On 2013-07-03, 02:22, Brad Anderson wrote: C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 b == 2); Is there any way to do something similar with std.typecons.Tuple? Not that I know of. But, Philippe Sigaud's dranges[1] library includes a RefTuple[2], which should do what you want. [1]: https://github.com/dawgfoto/dranges/ [2]: https://github.com/dawgfoto/dranges/blob/master/reftuple.d -- Simen
Re: Windows parameter
On Sun, 30 Jun 2013 20:24:17 +0200, shuji cravs...@hotmail.com wrote: int setHWND(HWND extHwnd){ hwnd = extHwnd; return 0; } And: extern (C++) { int setHWND(HWND hwnd); } See how these are different? One of them is an extern (C++) function, the other is a D function. In other words, this should work: //funcs.lib //windows includes... HWND hwnd; extern (C++) { // This line! int setHWND(HWND extHwnd){ hwnd = extHwnd; return 0; } } //main.d pragma(lib, gdi32.lib); import core.runtime; import core.sys.windows.windows; extern (C++) { int setHWND(HWND hwnd); } int main(int argc, char **argv) { //windows initializers setHWND(hwnd); return 0; } -- Simen
Re: [Question] Could a function return a list of arguments to call another function?
On Fri, 28 Jun 2013 20:07:23 +0200, MattCoder mattco...@hotmail.com wrote: Hi, I would like to know if it's possible to pass the return of a function as argument to another function as below: import std.stdio; auto foo(int x, int y){ writeln(x, y); return 3, 4; } void main(){ foo(foo(1,2)); } I would like to print: 1 2 3 4 PS: I tried return a tuple but it doesn't works. Thanks, Matheus. Not directly, no. But this should work: import std.stdio; import std.typecons : tuple; auto foo(int x, int y){ writeln(x, y); return tuple(3, 4); } void main(){ foo(foo(1,2).tupleof); } -- Simen
Re: mutable constant?
On Wed, 26 Jun 2013 00:07:38 +0200, Namespace rswhi...@googlemail.com wrote: I want to ask if this code should compile or if it's a bug, because I circumvent the const system: import std.stdio; struct Point { int x, y; } Point*[] points; struct TplPoint(T) { public: Point _point; T x, y; const uint id; this(T x, T y) { this.x = x; this.y = y; points ~= this._point; id = points.length - 1; } @property inout(Point)* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return cast(inout Point*) points[this.id]; } } void main() { const TplPoint!float my = TplPoint!float(42, 23); writeln(my._point, ::, my._point); writeln(*my.ptr, ::, my.ptr); } Or is the fact that it compiles ok and it's only unsafe? This is perfectly fine. -- Simen
Re: Possble bug ? Adding
On 2013-06-24, 22:30, Temtaime wrote: Hello, guys ! http://dpaste.1azy.net/8917c253 I'm not sure I've seen this bug before, but yes, it is one. The cause is that the grammar for the new alias syntax is apparently not complete. Please file: http://d.puremagic.com/issues/enter_bug.cgi -- Simen
Re: Multiple return type from object factory possible?
On Sat, 22 Jun 2013 18:58:22 +0200, deed n...@none.none wrote: class A { ... } class NonContainer : A { ... } class Container : A { A[] container; } class NC1 : NonContainer {} ... class C1 : Container {} ... A getO(string info) { switch (info) { default : return new NonContainer(); case info1: return new C1(); case info2: return new NC1(); case info3: return new Container(); case info4: return new NonContainer(); ... } } void foo() { auto o = getO(some information); if (is(typeof(o) == Container) { ... } // Doesn't work. // Type is always A. ... } Is there a way to make getO return the most specialized type of the instantiated object in the switch statement to enable this pattern? The type of an expression in D is determined at compile time, and getO returns an A. Hence, o will always have static type A, and is(typeof(... only checks the static type. If you want to check the dynamic (run-time) type of o, you should instead see if it is castable to Container: auto o = getO(info3); if (cast(Container)o != null) { ... } -- Simen
Re: A little of coordination for Rosettacode
On 2013-06-18, 05:00, bearophile wrote: With your code I have found a dmd compiler bug, are you able and willing to further reduce this? Tried this with 2.063.2, and there are three errors in the code - deserializeInto should return its buffer, the switch on line 19 needs a default: case, and deserializeInto tries to modify its non-buffer argument (which in this case is a const string. None of these seem to be a compiler bug. -- Simen
Re: this() immutable
On Thu, 13 Jun 2013 14:17:22 +0200, Stephan Schiffels stephan_schiff...@mac.com wrote: For example, is there a way of instantiating an object normally (i.e. mutable), and then later freeze it to immutable via a simple cast or so? In std.exception there is assumeUnique. It's basically just a cast, but might be good enough for you. -- Simen
Re: Why TypeTuple can be assigned to a variable
On Wed, 12 Jun 2013 10:01:59 +0200, Zhenya zh...@list.ru wrote: Hi! I was just surprised when realized, that this code compiles and runs: import std.typetuple; import std.stdio; void main() { auto foo = TypeTuple!(foo,bar); writeln(typeid(typeof(foo))); writeln(foo); } If I were compiler expert,I'd say that it's a bug.But I am not) So, can anybody explain why it's work? It is the equivalent of: TypeTuple!(string, string) foo; foo[0] = foo; foo[1] = bar; The ability to have a tupetuple as a variable is very useful - if that had not been possible one would need something akin to this: struct Tuple(T...) { T[0] head; static if (T.length) { Tuple!(T[1..$]) tail; } } And to access the third element of a tuple one'd need to write: myTuple.tail.tail.head = foo; Clearly this is suboptimal, so D has better ways of doing such things. -- Simen
Re: Why TypeTuple can be assigned to a variable
On Wed, 12 Jun 2013 11:44:19 +0200, Zhenya zh...@list.ru wrote: OK,you say that TypeTuple!(foo,bar) is a cool value of type TypeTuple!(string,string),right? Well, yes and no, not really. It's a bit magical. In your case, it's assigned to an auto variable, and that variable gets that type. There are other ways to use a TypeTuple where it has other semantics, as you write yourself. As explained below, a TypeTuple is just a bag of template parameters, and thus obeys the rules for a bag of template parameters. This behaviour confuses me a bit. Understandable. It's not entirely straightforward, because the concerns of usability weigh heavier than those of consistency. And I just don't understand why do we need TypeTuple's value semantic to implement std.Tuple,because AFAIK it use variadic template parameter pack != TypeTuple. The definition od std.typetuple.TypeTuple is: template TypeTuple(T...){ alias TypeTuple = T; } So a TypeTuple is exactly the same as a variadic template parameter pack. Sorry for my english. No need to be, your English is great. -- Simen
Re: Why there is too many uneccessary casts?
On Tue, 11 Jun 2013 12:12:25 +0200, Temtaime temta...@gmail.com wrote: ubyte k = 10; ubyte c = k + 1; This code fails to compile because of: Error: cannot implicitly convert expression (cast(int)k + 1) of type int to ubyte Why? It's pain in the ass, i think. My code contains only casts then. Because it's unsafe. The compiler does not know if k+1 fits in a ubyte. (True, in this case it could know it, but it does not, and in the general case it can't know) -- Simen
Re: Why there is too many uneccessary casts?
On Tue, 11 Jun 2013 12:39:47 +0200, Temtaime temta...@gmail.com wrote: There is overflow and it can be with int too. It's standard behavior. Indeed. And a class is a void* is an int is a char is a double? That's perfectly possible - it's all just memory anyway. D has chosen to do it like this to prevent common errors. If you think the cast stands out like a sore thumb, use: ubyte k = 10; ubyte c = (k + 1) 0xFF; That way, value range propagation ensures the result fits in a ubyte, and the code compiles happily. -- Simen
Re: Why there is too many uneccessary casts?
On Tue, 11 Jun 2013 13:15:11 +0200, Simen Kjaeraas simen.kja...@gmail.com wrote: On Tue, 11 Jun 2013 12:39:47 +0200, Temtaime temta...@gmail.com wrote: There is overflow and it can be with int too. It's standard behavior. Indeed. And a class is a void* is an int is a char is a double? That's perfectly possible - it's all just memory anyway. D has chosen to do it like this to prevent common errors. If you think the cast stands out like a sore thumb, use: ubyte k = 10; ubyte c = (k + 1) 0xFF; That way, value range propagation ensures the result fits in a ubyte, and the code compiles happily. Also worth noting: both 0xFF and cast(ubyte) shows that the programmer has considered the possibility of overflow (or just programmed blindly, but let's assume a rational programmer), something your original code did not. Looking at this code: ubyte a = foo(); ubyte b = a + 1; doSomethingWith(b); It's not possible for me to know if that code works correctly if foo() returns 255 - perhaps it should actually be saturated (255+1 == 255), perhaps it should even throw an exception. With this code: ubyte a = foo(); ubyte b = cast(ubyte)(a + 1); // or (a + 1) 0xFF; doSomethingWith(b); The programmer has documented something: If this causes an overflow, the value in b is still correct. Explicit is better than implicit. -- Simen
Re: Why there is too many uneccessary casts?
On Tue, 11 Jun 2013 13:46:11 +0200, Temtaime temta...@gmail.com wrote: No. I means, that uint a = uint.max; uint b = a + 1; writeln(b); Works OK. Why? Compiler doesn't know if a + b fits in uint, right? Then why overflow with ints are accepted? Because there's a limit to how far this goes without introducing arbitrary-precision numbers. There is indeed an argument for uint+uint giving a ulong answer, and I'm confused myself at why this is not the case. So your example is meaningless. No. -- Simen
Re: alias this
On 2013-05-31, 14:12, Namespace wrote: I thougth that in dmd 2.063 alias this : foo; would be allowed. That was what the preview of dmd 2.063 said: http://dlang.org/changelog.html#new2_062 Why wasn't it implemented? Probably not enough time. I've not read anything about it no longer being planned. -- Simen
Re: Are heap objects never moved by the garbage collector?
On 2013-05-31, 18:31, Carl Sturtivant wrote: The D Programming Language (TDPL) p.178 asserts the following. The objects themselves stay put, that is their locations in memory never change after creation. I take this to mean that the D garbage collector doesn't move live objects and adjust all references to them the way that some garbage collectors do. That is to say, the addresses of objects are not changed by the garbage collector. Does D guarantee this? The current D GC does guarantee this. Some future collectors might not, but there will always be implementations that guarantee it. -- Simen
Re: and/or/not/xor operators
On 2013-05-30, 13:56, Shriramana Sharma wrote: Hello. I have always loved the readability of C++'s and/or/not/xor word-like logical operators but It doesn't seem to be available in D. Isn't this possible in D? I tried doing: alias and ; import std.stdio ; void main () { writeln ( true and true ) ; } but I get errors: $ dmd foo.d foo.d(1): Error: basic type expected, not foo.d(1): Error: no identifier for declarator int foo.d(1): Error: semicolon expected to close alias declaration foo.d(1): Error: Declaration expected, not '' foo.d(7): Error: found 'and' when expecting ', Thanks. While that's not possible, D's operator overloading allows you to implement it yourself: struct And { struct AndImpl { private bool payload; this( bool value ) { payload = value; } bool opBinary(string op : /)(bool value) const { return payload value; } } AndImpl opBinaryRight(string op : /)(bool value) { return AndImpl( value ); } } struct Or { struct OrImpl { private bool payload; this( bool value ) { payload = value; } bool opBinary(string op : /)(bool value) const { return payload || value; } } OrImpl opBinaryRight(string op : /)(bool value) { return OrImpl( value ); } } And and; Or or; void main( ) { assert( true /and/ true ); assert( true /or/ false ); } Of course, if you ever use this, watch out for the flood of WTFs and curse words. -- Simen
Re: Passing large or complex data structures to threads
On Mon, 27 May 2013 14:08:12 +0200, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 05/26/2013 05:59 PM, Ali Çehreli wrote: On 05/26/2013 05:38 AM, Simen Kjaeraas wrote: Tuple!(size_t, size_t)[][] data = createData(); immutable dataImm = assumeUnique(data); data = null; // Simply to ensure no mutable references exist. The last line is not needed. assumeUnique already does that. :) That's fantastic, thank you both very much. Does that also work for arbitrary data structures (e.g. also associative arrays, complex structs/classes etc.)? Absolutely. So long as your code does not squirrel away other, mutable references to the data, assumeUnique is perfectly safe. Related question -- assume that I now want to store that immutable data inside a broader storage class, but I want that storage class to be agnostic as to whether the data is immutable, const or mutable. Something like this: class MyDataStore { float[] someData; uint[] someMoreData; Tuple!(size_t, size_t)[][] importedData; this(float[] sd, uint[] smd, Tuple!(size_t, size_t)[][] id) { someData = sd; someMoreData = smd; importedData = id; } } ... which of course fails if you try passing it immutable data for any of the parameters. So, is there a way to make this broader storage class type-qualifier-agnostic? I guess applying inout to the input parameters is necessary, but it's clearly not sufficient as the code then fails when trying to assign to the class' internal variables. A few questions: Why use a class? Will MyDataStore be subclassed? Will you have some instances of MyDataStore that will be mutated, and others that will always stay the same? If the answer was yes, will these be in the same array? Short answer: If you will have mixed arrays, no. There's no way to make that safe. If you don't have mixed arrays, there are ways. This will work: import std.stdio : writeln; import std.exception : assumeUnique; import std.typecons : Tuple, tuple; class MyDataStore { float[] someData; uint[] someMoreData; Tuple!(size_t, size_t)[][] importedData; inout this(inout float[] sd, inout uint[] smd, inout Tuple!(size_t, size_t)[][] id) { someData = sd; someMoreData = smd; importedData = id; } } void main( ) { float[] sdMut = [1,2,3]; uint[] smdMut = [4,5,6]; Tuple!(size_t, size_t)[][] idMut = [[tuple(0u, 0u), tuple(0u, 1u)],[tuple(1u, 0u), tuple(1u, 1u)]]; immutable float[] sdImm = [1,2,3]; immutable uint[] smdImm = [4,5,6]; immutable Tuple!(size_t, size_t)[][] idImm = [[tuple(0u, 0u), tuple(0u, 1u)],[tuple(1u, 0u), tuple(1u, 1u)]]; auto a = new MyDataStore(sdMut, smdMut, idMut); immutable b = new immutable MyDataStore(sdImm, smdImm, idImm); const c = new const MyDataStore(sdImm, smdMut, idImm); } (Tested with 2.063 beta, it's possible there are complications in 2.062) -- Simen
Re: Passing large or complex data structures to threads
On Sun, 26 May 2013 14:06:39 +0200, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 05/24/2013 04:39 PM, Simen Kjaeraas wrote: First, *is* it read-only? If so, store it as immutable and enjoy free sharing. If not, how and why not? I can confess that it's as simple as feeling extremely uncomfortable dealing with immutable where it relates to any kind of complex data structure. I mean, for that double array structure I'd have to do something like, Tuple!(size_t, size_t)[][] dataCopy; foreach(x; data) { Tuple!(size_t, size_t)[] xCopy; foreach(y; x) { immutable(Tuple!(size_t, size_t)) yCopy = y.idup; xCopy ~= cast(Tuple!(size_t, size_t)) yCopy; } immutable xImm = assumeUnique(xCopy); dataCopy ~= cast(Tuple!(size_t, size_t)[]) xImm; } immutable dataImm = assumeUnique(dataCopy); ... no? Which feels like a lot of hassle compared to just being able to pass each thread the information to independently load the required data. I'd be delighted to discover I'm wrong about the hassle of converting the data to immutable -- I don't think I understand how to use it at all well, bad experiences in the past have meant that I've tended to avoid it. That looks very complex for what it purports to do. I understand data is the original data before sharing? If so, will that a -- Simen
Re: Passing large or complex data structures to threads
On Sun, 26 May 2013 14:06:39 +0200, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: On 05/24/2013 04:39 PM, Simen Kjaeraas wrote: First, *is* it read-only? If so, store it as immutable and enjoy free sharing. If not, how and why not? I can confess that it's as simple as feeling extremely uncomfortable dealing with immutable where it relates to any kind of complex data structure. I mean, for that double array structure I'd have to do something like, Tuple!(size_t, size_t)[][] dataCopy; foreach(x; data) { Tuple!(size_t, size_t)[] xCopy; foreach(y; x) { immutable(Tuple!(size_t, size_t)) yCopy = y.idup; xCopy ~= cast(Tuple!(size_t, size_t)) yCopy; } immutable xImm = assumeUnique(xCopy); dataCopy ~= cast(Tuple!(size_t, size_t)[]) xImm; } immutable dataImm = assumeUnique(dataCopy); ... no? Which feels like a lot of hassle compared to just being able to pass each thread the information to independently load the required data. I'd be delighted to discover I'm wrong about the hassle of converting the data to immutable -- I don't think I understand how to use it at all well, bad experiences in the past have meant that I've tended to avoid it. That looks very complex for what it purports to do. I understand data is the original data before sharing? If so, will that array ever change again? I think a bit more information is needed. I'm going to assume this is (roughly) how things work: 1. Read from file/generate/load from database/create data. 2. Share data with other threads. 3. Never change data again. If this is correct, this should work: Tuple!(size_t, size_t)[][] data = createData(); immutable dataImm = assumeUnique(data); data = null; // Simply to ensure no mutable references exist. sendToOtherThreads(dataImm); And that's it. If nobody's going to change the data again, it's perfectly safe to tell the compiler 'this is now immutable'. No copies need to be made, no idup, no explicit casting (except that done internally by assumeUnique), no troubles. -- Simen
Re: Passing large or complex data structures to threads
On Sun, 26 May 2013 17:59:32 +0200, Ali Çehreli acehr...@yahoo.com wrote: On 05/26/2013 05:38 AM, Simen Kjaeraas wrote: Tuple!(size_t, size_t)[][] data = createData(); immutable dataImm = assumeUnique(data); data = null; // Simply to ensure no mutable references exist. The last line is not needed. assumeUnique already does that. :) Cool. I thought it might. -- Simen
Re: Passing large or complex data structures to threads
On 2013-05-24, 15:26, Joseph Rushton Wakeling wrote: Hello all, Are there any recommended strategies for passing large or complex data structures (particularly reference types) to threads? For the purpose of this discussion we can assume that it's read-only data, so if we're talking about just an array (albeit perhaps a large one) I guess just passing an .idup copy would be best. However, the practical situation I have is a data structure of the form, Tuple!(size_t, size_t)[][] ... which I _could_ .idup, but it's a little bit of a hassle to do so, so I'm wondering if there are alternative ways or suggestions. First, *is* it read-only? If so, store it as immutable and enjoy free sharing. If not, how and why not? -- Simen
Re: class MyClass(T) : Base if (ConstraintExpression) {} compilation error
On 2013-05-24, 16:49, ref2401 wrote: Version D 2.062 Please explain what is causing the error class Base { } class Class(T) : Base if (is(T == int)) { } Error: unrecognized declaration Error: members expected Error: Declaration expected, not 'if' Error: { } expected following aggregate declaration I'm confused too. This works: class Base { } class Class(T) if (is(T == int)) : Base { } void foo() { Base a = new Class!int; } -- Simen
Re: Copy instead of reference?
On Thu, 23 May 2013 13:29:49 +0200, Namespace rswhi...@googlemail.com wrote: That was what I also expected. But opAssign is not called. Because you have a postblit. It's called instead of opAssign. -- Simen
Re: WindowProc in a class - function and pointer problem
On 2013-05-22, 21:30, D-sturbed wrote: Hello, is there a way to wrap a WindowProc (so LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow) in a class and to link it to a WindowClass without puting it as static ? Because defacto every datum used in the WindowProc must also be static. The problem technically is that if static is not specified, the compiler won't allow this: MyWinClass.lpfnWndProc = TheWindowProcInMyClass. I've also tried this: MyWinClass.lpfnWndProc = (TheWindowProcInMyClass).funcptr but, while it compiles, it drastically fails at the run-time... Not possible, no. What you *can* do is have some way to translate from hwnd to class instance, and fetch the right instance inside the static wndProc to call a member function on that. -- Simen
Re: how to have alias this with an unaccessible member?
On Sat, 18 May 2013 02:12:00 +0200, Timothee Cour thelastmamm...@gmail.com wrote: so in what you suggest, the exact same problem remains with 'get' being exposed instead of 'x', so the situation didn't improve... looks like it's impossible to achieve this? Well, there is also opDot: struct A(T) { private T x; T opDot() { return x; } } void main(){ auto a = A!int; a++; //should do a.x++; static assert(!__traits(compiles, a.x)); // This now holds! } However, now A!int is not an int (you can't pass it to functions taking int). -- Simen
Re: how to have alias this with an unaccessible member?
On Sat, 18 May 2013 01:13:00 +0200, Timothee Cour thelastmamm...@gmail.com wrote: How to have alias this with an unaccessible member (x below). Making the member private won't work as it'll disable all operations on said member. struct A(T){ T x; //private T x would prevent alias this from doing anything useful alias x this; } void main(){ auto a=A!int; a++;//should do a.x++; static assert(!__traits(compiles,a.x)); // I want this to hold } The common way to do it is with a read-only property: struct A(T) { private T x; @property T get() { return x; } alias get this; } void main(){ auto a = A!int; a++; //should do a.x++; static assert(!__traits(compiles, a.x)); // This now holds! static assert(__traits(compiles, a.get)); // As does this, which may or may not be palatable. :( } This has been discussed numerous times before, but I believe the current behavior is here to stay. -- Simen
Re: Recursive mixin templates
On Thu, 16 May 2013 17:01:54 +0200, Sebastian Graf sebastiang...@t-online.de wrote: I aim to use a simplistic, rough edged property generator, but I'm having issues. See http://dpaste.dzfl.pl/72837a7a. My code and mixin logic seems to work basically, but it gets hairy when using mixinMap to generate getters and setters from a list in a recursive template fashion. It won't work if I generate both getters and setters with mixinMap, but it compiles fine if I e.g. want only getters. Any help? I smell a compiler bug if I haven't done something stupid. This is one of those weird things. I believe it is intentional, but I feel it should be a bug. Basically, overload sets cannot cross mixin borders. So if two mixins create a function with the same name, they don't overload properly. I'd say add it to BugZilla if it's not already there. Comment on the relevant bug if it is - this is not good for the language. -- Simen
Re: Cross product template
On Wed, 15 May 2013 03:31:40 +0200, Diggory digg...@googlemail.com wrote: I have a vector struct, Vector(T, uint N) templated on the type T and number of components, N. I'm trying to write a function cross which will calculate the cross product of a number of vectors. For a given number of components, N, the cross function should take N-1 arguments, each one a Vector!(?, N) and will return a vector perpendicular to the vectors passed in. The ? means the type is free to be anything. The problem is that however I try to write it, the template argument deduction isn't powerful enough to work out which instantiation to use. I thought something like this would work to deduce the parameters and then I could use constraints to enforce the other rules, but no: auto cross(T, N, U...)(Vector!(T, N) a, U b) { return 0; } auto cross(T, uint N, U...)(Vector!(T,N) a, U b) { return 0; } Oughta work. -- Simen
Re: Structure's inheritance
On 2013-05-12, 14:00, evilrat wrote: On Sunday, 12 May 2013 at 11:56:53 UTC, Maxim Fomin wrote: You can place base struct instance inside nested and use alias this. Note that currently multiple alias this are not supported. Also note that you cannot override functions because there are no virtual table for structs. why multiple alias this not supported? i know it was broken in 2.060 but with 2.061 it was fixed right? It's simply never been implemented. -- Simen
Re: Check if tuple contains value at compile time
On 2013-05-05, 01:42, Diggory wrote: I'm trying to test using a static if statement if a tuple of strings contains a particular string. What's the easiest/best way to do this? http://dlang.org/phobos/std_typetuple#.staticIndexOf -- Simen
Re: a FOR loop and floating variables
On 2013-05-02, 20:14, Carlos wrote: I have this code : import std.stdio; import std.c.stdlib; void main() { int fahr; write(F\tC\n); for (fahr = 0; fahr = 300; fahr = fahr + 20) write(fahr, \t, (5.0/9.0)*(fahr-32), \n); write(Done!\n); exit (0); } Which works. but if I change the 5.0 for 5 I get cero on the celsius side. import std.stdio; import std.c.stdlib; void main() { int fahr; write(F\tC\n); for (fahr = 0; fahr = 300; fahr = fahr + 20) write(fahr, \t, (5/9)*(fahr-32), \n); write(Done!\n); exit (0); } So why is this ? Both 5 and 9 in the second example are integers (int). When you divide one int by another, the result is an int, and hence (5/9) is 0. -- Simen
Re: Calculation differences between Debug and Release mode
On Sat, 13 Apr 2013 18:36:21 +0200, Jeremy DeHaan dehaan.jerem...@gmail.com wrote: I'm on Windows, and I my compilation was nothing more than dmd -O -release main.d to get the issue I described. Turns out, the problem starts here: static const(float) pi = 3.141592654f; If we compare that to std.math.PI, we see that they're different: writeln( 3.141592654f - std.math.PI ); 4.10207e-10 If, however, we assign these values to some temporary floats, we see that they're equal: float a = 3.141592654f; float b = std.math.PI; writeln( a - b ); 0 Replace float with double or real in the above, and the difference reappears. So, we have established that 3.141592654f is a valid approximation to pi for a float. The problem thus has to be one of precision. I'm not sure if it's a valid optimization for the compiler to use doubles instead of floats (it certainly seem innocuous enough). I'd say file a bug on it. Worst case, it gets closed as invalid. -- Simen
Re: Why are fixed length arrays passed by value while variable are passed by reference?
On 2013-04-18, 16:20, ixid wrote: An array is represent using a struct with a pointer to the array data and the length, like this: struct Array { void* ptr; size_t length; } The struct is passed by value, but since it contains a pointer to the data it will be passed by reference. Note that if you do: void foo (int[] a) { a ~= 3; } auto b = [3, 4]; foo(b); The caller will not see the change made by foo. Don't know if this explanation helped you to understand. What does a fixed length array look like when passed, doesn't it have a similar payload of data and length? I take it you mean the struct method is the variable length array. The fixed length array is much more similar to a struct. An int[2], for instance, is in many ways equivalent to struct { int a; int b; }. Two ways this is visible is that static arrays are allocated on the stack, and take up space in a struct or class the same way a struct would: struct S1 { int[] a; } static assert( S1.sizeof == int[].sizeof ); struct S2 { int[17] a; } static assert( S2.sizeof == 17 * int.sizeof ); Also, like Jacob wrote, there is the difference of ref/value semantics when embedded in a struct/class. If I have these two functions: void foo1( S1 s ) { s.a[0] = 7; } void foo2( S2 s ) { s.a[0] = 7; } void test( ) { S1 s1 = S1(new int[4]); S2 s2 = S2(); foo1(s1); foo2(s2); } The values in s1 will have changed, while those in s2 will not. All in all, static arrays are treated as value types everywhere else, and so treating them as value types when passed to a function makes more sense. -- Simen
Re: Use enum base type?
On 2013-04-17, 19:15, Janissary wrote: Is it possible to evaluate an enum's base type? Ideally something like: enum somestrs : string { ... } enum d = 0.0; template EnumBaseType(E) if (is(E==enum)) { ... } unittest { static assert( is(EnumBaseType!somestrs == string) ); static assert( is(EnumBaseType!d : float) ); static assert(!is(EnumBaseType!d == float) ); } A template like this would make at least my life easier. Whenever you want to do weird stuff with types, std.traits[1] should be your #1 stop. And quite correctly, std.traits.OriginalType[2] does what you want: enum E : int { a } typedef E F; typedef const F G; static assert(is(OriginalType!G == const int)); [1]: http://dlang.org/phobos/std_traits [2]: http://dlang.org/phobos/std_traits#.OriginalType -- Simen
Re: Calculation differences between Debug and Release mode
On Sat, 13 Apr 2013 08:07:39 +0200, Jeremy DeHaan dehaan.jerem...@gmail.com wrote: In debug mode this works as expected. Let's say the radius is 50. getPoint(0) returns a vector that prints X: 50 Y: 0. For some reason, the same function will return a vector that prints X: 50 Y: 4.77673e-14. Now, 4.77673e-14 is a crazy small number that might as well be 0, but why the difference? Sounds to me like a bug. I've tried recreating the problem on my machine (Win7, dmd 2.062 32-bit, no flags other than debug/release), but can't see it happen here. My (perceived) version of your code: import std.stdio : writeln; import std.math : sin, cos; struct Vector2f { float x,y; } int m_pointCount = 25; float m_radius = 50; Vector2f getPoint(uint index) { static const(float) pi = 3.141592654f; float angle = index * 2 * pi / m_pointCount - pi / 2; float x = cos(angle) * m_radius; float y = sin(angle) * m_radius; return Vector2f(m_radius + x, m_radius + y); } void main( string[] args ) { writeln( getPoint( 0 ) ); } Could you please post here the minimum code necessary to get the behavior you describe, as well as the platform and compiler flags you're using? -- Simen
Re: operator +=
On 2013-04-08, 14:23, Minas Mina wrote: How can I define operator += for a struct? http://dlang.org/operatoroverloading.html In short: struct S { auto opOpAssign( string op : + )( S other ) { // Do stuff here. } } -- Simen
Re: Variadic constructor conflict
On 2013-01-30, 17:08, andrea9940 wrote: This code compiles fine: struct Vector(T, uint SIZE) { T[SIZE] vector; this(T value) { foreach (ref v; vector) v = value; } } alias Vector!(int, 3) Vec3i; but if I add a variadic constructor: struct Vector(T, uint SIZE) { [...] this(T...)(T values) if (values.length == SIZE) { foreach (i, v; values) vector[i] = v; } } alias Vector!(int, 3) Vec3i; I get: main.d(54): Error: template main.Vector!(int, 3).Vector.__ctor(T...)(T values) if (values.length == SIZE) conflicts with constructor main.Vector!(int, 3).Vector.this at main.d(46) main.d(111): Error: template instance main.Vector!(int, 3) error instantiating I think that should not happen because when there is a conflict call like Vec3i(3) the compiler must(?) use the specialized function... Known bug. For the moment, the workaround is to templatize all constructors: struct Vector(...) { this()(T value ) { ... -- Simen
Re: UFCS opDispatch
On 2013-01-16, 22:02, Nick Sabalausky wrote: Unfortunately, opDispatch [silently] takes precedence over UFCS. I don't suppose there's any way to make a UFCS function call override opDispatch without either ditching UFCS or altering/removing the opDispatch itself? Only solution I know of is to use constraints on opDispatch. -- Simen
Re: Does the new alias syntax not support extern for function types?
On 2013-04-15 13:01, Mike Parker aldac...@gmail.com wrote: On Monday, 14 January 2013 at 21:00:12 UTC, Simen Kjaeraas wrote: alias foo = extern(System) void function(); Gives me an error about expecting basic type, not extern. extern(System) alias void function() foo; But that's the old syntax, with which one can do this: alias extern(System) void function() foo; I'm talking about the new syntax, with =. Apparently, this does support prefix extern, as you show: extern(System) alias foo = void function(); I guess that's the solution, but it seems weird to me that it does not support extern where the old syntax does. -- Simen
Re: Specifying eponymous template internal parameter
On 2013-55-08 09:01, monarch_dodra monarchdo...@gmail.com wrote: Sometimes (especially in phobos), one defines a parametrized template, that resolves to a templated function. This is a nifty trick, because it allows specifying a vararg before the current type parameter, eg: // auto r = [1, 2, 3]; auto m = map!(++a, --a)(r); // As you can see, the template guessed the type of r, even though we used a vararg. This would not have worked with a single template function. My question though: I have a similar use case, but I NEED to be able to explicitly specify the type of r: as such: // auto m = fun!(++a, --a, ubyte)(1); auto m = fun!(++a, --a)!(ubyte)(1); auto m = fun!(++a, --a).fun!ubyte(1); // None of them work. In this specific case, I *need* to specify that 1 is of type ubyte, but I really can't do it :/ Simplified example: in my use case, it is a immutable(int[]): Failure to specify the type means the compiler strips tail immutability... The only workaround I can find to make such a thing, is to *not* use eponymous temples, and explicitly call an inner function. This is ugly as sin, and it makes specifying the internal parameter mandatory. Any thoughts? A non-eponymous template is currently the only way to do this. Strangely, this works: alias fun2 = fun!(++a, --a); auto m = fun2!(ubyte)(1); -- Simen
Re: Specifying eponymous template internal parameter
On 2013-16-08 11:01, monarch_dodra monarchdo...@gmail.com wrote: On Tuesday, 8 January 2013 at 09:59:26 UTC, Simen Kjaeraas wrote: alias fun2 = fun!(++a, --a); auto m = fun2!(ubyte)(1); Nice! And now, for the 1M$ question: Can I rely on this behavior, or is this an accepts invalid...? You can rely on it. -- Simen
Re: Why is immutable not possible as a result of a reduce expression?
On 2013-52-05 20:01, Michael Engelhardt m...@mindcrime-ilab.de wrote: Hi, just playing around with the functional capabilities of D. One concept of the pure functional programming is that variables should not be reassigned, so the best(?) way to assure this is using immutable: immutable auto gen = sequence!(n); immutable auto seq = take(gen,10); immutable auto filtered = filter!(a % 3 == 0 || a % 5 ==0)(seq); immutable auto sum = reduce!(a+b)(filtered); but the last line gives a compiler error: Error: template instance std.algorithm.reduce!(a+b).reduce!(immutable(FilterResult!(unaryFun,immutable(Take!(immutable(Sequence!(n,Tuple!( error instantiating It compiles and run as expected if I remove the immutable constraint on the reduce expression. So what is happening here? I thought reduce will create a new data structure containing the resulting values like filter and other operations too? That seems not to be the case, maybe someone could give me a deeper understanding of this. The reason is that ranges may not be immutable or const. Ranges need to be mutated (popFront) to be iterable, and your filtered range cannot be mutated, by virtue of being immutable. I'm surprised that seq and filtered work, but I guess there may be specializations that circumvent the problem. In other words, remove immutable from the first three lines, and the program should compile. A little details is that immutable auto is unnecessary, as immutable implies auto (the details are more complex, but that's the short version). -- Simen
Re: std.range lockstep is not input range but opApply entity. Workarounds?
On 2012-48-29 14:12, mist n...@none.none wrote: I basically want to be able to do stuff like this: auto result = map!( (a, b) = a+b )( lockstep(range1, range2) ); Are there any standard short ways to wrap an input range around struct with opApply (which Lockstep is)? Also what about redesigning Lockstep as a proper range? I could do a pull request but not sure about current intentions. Use std.range.zip instead: auto result = map!( (a, b) = a+b )( zip(range1, range2) ); The reason there are two ways is lockstep works better with foreach: foreach (a, b; lockstep(A, B) ) { // Use a and b here. } Contrast with zip: foreach (a; zip(A, B) ) { // Use a[0] and a[1] here. } There have been suggestions to better integrate tuples in the language, so in the future zip may have all the advantages of lockstep (and vice versa), but don't cross your fingers. -- Simen
Re: std.range lockstep is not input range but opApply entity. Workarounds?
On 2012-52-29 20:12, mist n...@none.none wrote: Not clever enough to expand like this though: map!( (a, b) = a+b )( zip(Range1, Range2) ); Using a = a[0]+a[1] is not that big deal though. That oughta be doable. However, seeing as std.functional only contains unaryFun and binaryFun (dranges has naryFun), this approach cannot currently extend to tuples with more than two fields. -- Simen
Re: checking whether the number is NaN
On 2012-42-28 16:12, Zhenya zh...@list.ru wrote: Hi! Tell me please,are there any way to check whether number is NaN? us std.math.isNaN. But if you really don't want to: float x = ...; if (x != x) { writeln( x is NaN ); } I'm unsure how aggressive the optimizer is allowed to be in cases like this. Theoretically it could assume x is always equal to x, but I'd think it's not allowed to for floats. If you're wondering how a float value could compare different to the exact same value, consider that this would otherwise be true: sqrt(-1) == 0/0 -- Simen
Re: bio parser
On 2012-09-16 17:12, bioinfornatics bioinfornat...@fedoraproject.org wrote: Dear, I wrote a fasta format parser and fastq format parser. These parser used MmFile and do not load all file these will save memory. Fastq http://dpaste.dzfl.pl/9b23574d Fasta http://dpaste.dzfl.pl/228dba11 The way to iterate over it is really close and i search a way to have one struct bySection one template doIndex for both file format. If you have any suggestion to improve this, please tell to me. As this is something that might be useful to others, you should probably post it to digitalmars.D.announce. I'd also advice setting up a github rep for it and placing a link on wiki.dlang.org. -- Simen
Re: Operator overloading of native types?
On 2012-12-14, 00:19, H. S. Teoh wrote: I'd like to overload the '*' operator to work with string arguments. Is it possible? I tried the following, but apparently operator overloading doesn't work at the package level? string opBinary(string op)(string repeatMe, int thisManyTimes) if (op==*) { auto app = appender!string(); while (thisManyTimes 0) { app.put(repeatMe); thisManyTimes--; } return app.data; } void main() { writeln(spam * 3); // compile error } Or is this just a very bad idea? ;-) Like bearophile said, overloaded operators need to be defined inside one of the types on which they should operate. Since built-in types cannot be modified, one cannot overload operators on them. -- Simen
Re: constructor is not callable using argument types ()
On 2012-12-06, 20:17, Suliman wrote: I am learning D classes and I am getting error when I am try to make instance of class. erorr: C:\code\main.d(9): Error: constructor GetFileName.GetFileName.this (string name) is not callable using argument types () http://www.everfall.com/paste/id.php?xie09xz9upth You have supplied the string you promised to. You have this constructor: this(string name) And call it like this: new GetFileName(); Where's the string the constructor expects? Instead, you should call it like thus: new GetFileName(test); -- Simen
Re: constructor is not callable using argument types ()
On 2012-12-06, 20:48, Suliman wrote: When I should use keyword this? I dropped it from my class and now I can make instance of class without in sych way: auto file = new GetFileName(); file.name = test; Indeed. If you have not defined a constructor, the language defines one for you, which is parameterless. It does nothing but allocate and initialize memory. The moment you define a constructor of your own, the compiler decides you probably want to define the parameterless constructor yourself, or not at all, and thus does not define it for you. If you want both, then define both: class MyClass { string name; this() { name = Foo!; } this(string name) { this.name = name; } } -- Simen
Re: Getting memory size of class
On 2012-12-05, 20:03, js.mdnq wrote: sizeof always returns 4 or 8 regardless of size of class: class myclass(T) { public: T v1; T v2; T v3; T v4; T v5; T v6; } writeln((myclass!byte).sizeof, (myclass!double).sizeof); or even writeln((myclass!int).classinfo.init.sizeof, (myclass!double).classinfo.init.sizeof); from http://forum.dlang.org/thread/dp9hct$nuf$1...@digitaldaemon.com So how does one get the actual memory usage of a class? __traits( classInstanceSize, myclass!int ) http://dlang.org/traits.html -- Simen
Re: Can operators return type?
On 2012-11-29, 17:33, Zhenya wrote: Hi! It would useful for some my project,if operators could be a template,that return type.Something like alias TypeTuple!(int,char) types; static assert(types[1] == char) //opIndex So can I define something like that? This works out of the box. If you want to define your own TypeTuple-like construct, the answer is most likely going to be no. -- Simen
Re: how to count number of letters with std.algorithm.count / std.algorithm.reduce / std.algorithm.map ?
On 2012-11-16, 16:49, bioinfornatics wrote: hi, I would like to count number of one ore more letter into a string or list of string (string[]) without use a for loop but instead using std.algorithm to compute efficiently. if you have: string seq1 = ACGATCGATCGATCGCGCTAGCTAGCTAG; string[] seq2 = [ACGATCGATCGATCGCGCTAGCTAGCTAG, ACGATGACGATCGATGCTAGCTAG]; i try : reduce!( (seq) = seq.count(G), seq.count(C))(tuple(0LU,0LU),seq1) and got: Error: undefined identifier seq, did you mean import std? in morre count seem to request a range then to do multiple count into one string it is not easy. Thanks to show to me how do this There are several problems here. First, as the compiler is trying to tell you, the part after the comma is not a valid delegate. It should look like this: reduce!( (seq) = seq.count(G), (seq) = seq.count(C))(tuple(0LU,0LU),seq1) Now, that's not really all that closer to the goal. The parameters to these delegates (seq) are characters, not arrays of characters. Thus, seq.count does not do what you want. Next iteration would be: reduce!( (seq) = seq == G, (seq) = seq == C )(tuple, 0LU, 0LU, seq1) Not there yet. seq is an element, G is a string - an array. One more: reduce!( (seq) = seq == 'G', (seq) = seq == 'G' )(tuple, 0LU, 0LU, seq1) Lastly, reduce expects delegates that take two parameters - the current value of the accumulator, and the value to be considered: reduce!( (acc, seq) = acc + (seq == 'G'), (acc, seq) = acc + (seq == 'C') )(tuple(0LU, 0LU), seq1) There. Now it works, and returns a Tuple!(ulong,ulong)(8, 8). One thing I think is ugly in my implementation is acc + (seq == 'G'). This adds a bool and a ulong together. For more points, replace that with acc + (seq == 'G' ? 1 : 0). -- Simen
Re: how to count number of letters with std.algorithm.count / std.algorithm.reduce / std.algorithm.map ?
On 2012-11-16, 17:37, bearophile wrote: Simen Kjaeraas: There. Now it works, and returns a Tuple!(ulong,ulong)(8, 8). One thing I think is ugly in my implementation is acc + (seq == 'G'). This adds a bool and a ulong together. For more points, replace that with acc + (seq == 'G' ? 1 : 0). I use a pragmatic approach: I use such higher order functions when they give me some advantage, like more compact code, or less-bug-prone code, etc (because they usually don't give me faster code). In this case a normal loop that increments two counters is faster and far more easy to read and understand :-) Absolutely. But after trying to make sense of the mess presented in the OP, I wanted to document the voyage. -- Simen
Re: shouldn't const cast always be allowed (even if shunned)
On 2012-23-15 15:11, Dan dbdavid...@yahoo.com wrote: There are times when casting away const is needed. Structs that define opCast can get in the way of this. For instance, the cast below fails, but I think it should always be allowed. So, if the source type and cast type are the same except for const qualifiers, there is no need to consider custom opCast members. Is a reasonable suggestion for the language? The cast here fails because it is considering custom opCast methods, but that is not helpful. Thanks Dan - import std.bitmanip; void main() { const(BitArray) cba; cast()cba; } That does indeed seem reasonable. File an enhancement request. -- Simen
Re: Fasta parser
On 2012-34-11 18:11, bioinfornatics bioinfornat...@fedoraproject.org wrote: Hi, I wrote a fasta parser for biology computing http://pastebin.geany.org/yheQN/ I would like to get your experience to know if the writer could be better. The given parser use MmFile and Phobos range. fasta specification format = http://en.wikipedia.org/wiki/FASTA_format Not available (anymore). That's a bummer. Also, obligatory 'Red unz go fasta!' -- Simen
Re: Extracting template parameters
On 2012-11-06, 16:20, Joseph Rushton Wakeling wrote: Suppose that I have two struct templates which take identical parameter lists: struct Foo(T1, T2, T3) { ... } struct Bar(T1, T2, T3) { ... } Now suppose that I have a Foo which has been instantiated with a given set of parameters. Is there any way for me to say, now instantiate a Bar with the same parameters? The use-case I'm thinking of is a function something like this (somewhat pseudo-code-y): auto fooToBar(FooInstance f) { Bar!(f.T1, f.T2, f.T3) b; // set values etc. return b; } Of course the f.T1 notation is my fiction, but it gives the idea of what is needed -- is there a means to extract and use template parameters in this way? I assume something from std.traits but it's not entirely clear what or how ... In addition to Dan's answer, let me present a general solution: template InstantiationInfo( T ) { static if ( is( T t == U!V, alias U, V... ) ) { alias U Template; alias V Parameters; } else { static assert(false, T.stringof ~ is not a template type instantiation.); } } With this, you can extract the parameters to a template (InstantiationInfo!Foo.Parameters) or the template used (InstantiationInfo!Foo.Template). -- Simen
Re: Tuples and variable-length template parameter lists
On 2012-11-05, 15:53, Joseph Rushton Wakeling wrote: Hello all, Suppose I want to define a tuple type which may have a variable length, e.g.: template Tup(ID, Properties...) { static if(Properties.length == 0) alias Tuple!(ID, id) Tup; else alias Tuple!(ID, id, Properties) Tup; } Now, it's trivial to include an arbitrary selection of named values in this, e.g. auto t1 = Tup!(size_t, real, value)(3, 4.5); writeln(t1); writeln(t1.id, , t1.value); auto t2 = Tup!(size_t, real, value, bool, active)(3, 4.5, true); writeln(t2); writeln(t2.id, , t2.value, , t2.active); However, suppose now I want to define a container struct which holds an array of tuples of the specified type. Here's what I came up with: struct Container(ID, Properties...) { Tup!(ID, Properties)[] contents; void add(ID i, Properties p) { static if(Properties.length == 0) contents ~= Tup!(ID)(i); else contents ~= Tup!(ID, Properties)(i, p); } } Now, if I make properties empty, this works just fine: auto c1 = Container!(size_t)(); c1.add(3); c1.add(7); c1.add(2); writeln(c1); foreach(t, tup; c1.contents) writeln([, t, ] , tup.id); writeln(); ... and likewise if I pass the container a list of value types without value names: auto c2 = Container!(size_t, real, real)(); c2.add(5, 3.2, 5.6); writeln(c2); writeln(); ... but if I try asking the container to store a tuple with _named_ values, e.g. auto c3 = Container!(size_t, real, value)(); then compilation fails with the following error message: tupcontainer.d(7): Error: tuple Properties is used as a type tupcontainer.d(12): Error: template std.typecons.Tuple!(ulong,id,real,value).Tuple.__ctor does not match any function template declaration /usr/local/include/d2/std/typecons.d(406): Error: template std.typecons.Tuple!(ulong,id,real,value).Tuple.__ctor cannot deduce template function from argument types !()(ulong,_error_) tupcontainer.d(51): Error: template instance tupcontainer.Container!(ulong,real,value) error instantiating I'm confused as to why the Container struct cannot take these template parameters when the corresponding parameters work just fine for Tup. Can anyone advise what the problem is and if it's possible to get the Container working as envisioned? std.typecons.Tuple does a bit of magic behind the scenes. This includes ridding itself of non-type parameters. Simply put, you can imagine inserting the type tuple directly into the function definition: void add(ID id, size_t arg0, real arg1, value arg2); as you probably notice, the last argument looks weird. Now, Phobos does not currently have a staticFilter template, nor does it have an isType template, so here are implementations of those: template staticFilter( alias pred, T... ) { static if ( T.length == 0 ) { alias TypeTuple!( ) staticFilter; } else static if ( pred!( T[0] ) ) { alias TypeTuple!( T[0], staticFilter!( pred, T[1..$] ) ) staticFilter; } else { alias staticFilter!( pred, T[1..$] ) staticFilter; } } unittest { static struct S(T...){} assert( is( S!(staticFilter!(isType, int, float)) == S!(int, float) ) ); assert( is( S!(staticFilter!(isType, int, foo, float)) == S!(int, float) ) ); assert( is( S!(staticFilter!(isType, foo, bar)) == S!() ) ); } template isType( T... ) if ( T.length == 1 ) { enum isType = !is( typeof( T[0] ) ); } unittest { struct S {} class C {} assert( isType!int ); assert( isType!string ); assert( isType!S ); assert( isType!C ); assert( !isType!1 ); assert( !isType! ); assert( !isType!(S( )) ); } add would then have this signature: void add(ID id, staticFilter!(isType, Properties)); -- Simen
Re: SList of chars not possible?
On 2012-18-01 23:11, They call me Mr. D khea...@eapl.org wrote: auto i = SList!int(1, 2, 3, 4, 5, 6, 7); auto f = SList!float(1.1, 2.234, 3.21, 4.3, 5.001, 6.2, 7.0); auto s = SList!string([I, Hello, World]); auto c = SList!char('a', 'b' ,'c'); // doesn't compile, get the following C:\D\dmd2\windows\bin\..\..\src\phobos\std\container.d(905): Error: template std.container.SList!(char).SList.insertFront does not match any function template eclaration C:\D\dmd2\windows\bin\..\..\src\phobos\std\container.d(1096): Error: template std.container.SList!(char).SList.insertFront cannot deduce template function from argument types !()(char[]) Container.d(19): Error: template instance std.container.SList!(char).SList.__ctor!(char) error instantiating auto c = SList!char(['a', 'b' ,'c']); // doesn't compile either. Seems to me a Slist of char nodes should be pretty innocuous. Not sure of the exact reasons, but I think Ali is probably right. A char cannot hold all possible values for a unicode character, so having a range with that element type is not really a good idea. -- Simen
Re: How to add n items to TypeTuple?
On 2012-11-01, 19:52, Justin Whear wrote: On Thu, 01 Nov 2012 19:42:07 +0100, denizzzka wrote: For example, adding 3 strings to type tuple t: foreach( i; 0..2 ) alias TypeTuple!( t, string ) t; // this is wrong code and result should be: TypeTuple!( string, string, string ); Use a recursive template. Here's one that repeats a given type N times: template Repeat(Type, size_t Times) { static if (Times == 0) alias TypeTuple!() Repeat; else alias TypeTuple!(Type, Repeat!(Type, Times - 1)) Repeat; } Invoke like so: Repeat!(string, 3) threeStrings; I've always preferred the opposite order of arguments, as that allows repetition of more complex things: template Repeat(size_t times, T...) { static if ( times == 0 ) { alias TypeTuple!() Repeat; } else { alias TypeTuple!( T, Repeat!( times - 1, T ) ) Repeat; } } Invoke like so: alias Repeat!(4, string, int, Hello, template world!) YeahThisIsGonnaBeUseful; Or: alias Repeat!(3, string) ThreeStrings; -- Simen
Re: What is the proper way to handle pointers in variable arguments list?
On 2012-08-28 22:10, Tyro[17] nos...@home.com wrote: On 10/28/12 4:44 PM, Dmitry Olshansky wrote: On 29-Oct-12 00:36, Tyro[17] wrote: The following fails because the compiler assumes I am trying to dereference non-pointer variables. Can this be done? void main() { int i; int* pi; double d; double* pd; char c; char* pc; scan(i, pi, d, pd, c, pc); } void scan(A...)(ref A data) { import std.traits; foreach (element; data) { if(isPointer!(typeof(element)) isIntegral!(typeof(*element))) { *element = 10; } } } Thanks Well, first things first: if --- static if Changing it to static allows compilation, however I get the following runtime error: Segmentation fault: 11 This happens whether I try to read from *element or modify it. I assume you've actually initialized the pointers to something? Given the above code, all the pointers point to null, and a segfault would be a reasonable reaction. -- Simen
Re: Narrow string is not a random access range
On 2012-41-24 01:10, Adam D. Ruppe destructiona...@gmail.com wrote: On Tuesday, 23 October 2012 at 23:07:28 UTC, Jonathan M Davis wrote: I think that Andrei was arguing for changing how the compiler itself handles arrays of char and wchar so that they wouldn't As I said last time this came up, we could actually do this today without changing the compiler. Since string is a user defined type anyway, we could just define it differently. http://arsdnet.net/dcode/test99.d I'm pretty sure that changes to Phobos are even required. (The reason I called it String there instead of string is simply so it doesn't conflict with the string in object.d) As long as typeof() != String, this is not going t work: auto s = ; -- Simen
Re: Narrow string is not a random access range
On 2012-10-23, 19:21, mist wrote: Hm, and all phobos functions should operate on narrow strings as if they where not random-acessible? I am thinking about something like commonPrefix from std.algorithm, which operates on code points for strings. Preferably, yes. If there are performance (or other) benefits from operating on code units, and it's just as safe, then operating on code units is ok. -- Simen
Re: Reordered class fields?
On 2012-36-22 01:10, bearophile bearophileh...@lycos.com wrote: This benchmark shows that if you allocate the class instances on the heap one at a time the total amount of memory used is the same for the various Bar (maybe because of the GC), so that optimization is useful for emplace() only and similar in-place allocations The current GC always allocates a power of two, with a minimum of 16 bytes. You should see an effect if you make a class that will be above such a threshold without reordering, and below with. So is such class field reordering worth an enhancement request in Bugzilla? Nothing bad can come of it. -- Simen
Re: opCast using in template struct
On 2012-10-18, 17:45, Oleg wrote: Sorry. My problem more complex and my simplification is not correct. I want use mixin for math operations. mixin template vectOp( string DataName, int DataLen, T, vecType ) { mixin( alias ~ DataName ~ this; ); auto opBinary(string op,E)( E[DataLen] b ) auto opBinary(string op,E)( E[] b ) auto opOpBinary(string op,E)( E[] b ) auto opOpBinary(string op,E)( E[DataLen] b ) } struct vec(string S,T=double) { T[S.length] data; mixin vectOp( data, S.length, T, vec!(S,T) ); } unittest{ vec!xyz a; vec!xyz b; a += b; } and it isn't work Error: 'a += b' is not a scalar, it is a vec!(xyz) Error: 'a._data' is not of arithmetic type, it is a double[3LU] Error: 'b._data' is not of arithmetic type, it is a double[3LU] I see you have opOpBinary there - should those be opOpAssign? -- Simen
Re: Returning dynamic array from the function
On 2012-10-17, 21:17, m0rph wrote: I tryed to learn how arrays works and found another strange thing: import std.stdio; int[] create() { int[5] a1 = [ 10, 20, 30, 40, 50 ]; int[] b1 = a1; writeln(b1: , b1); return b1; } void main() { int[] a2 = create(); writeln(a2: , a2); } Result of execution: b1: [10, 20, 30, 40, 50] a2: [-142625792, 32767, 4358059, 0, 5] Please explain what's wrong with this code? Why variable a2 contains crap? Is this another dmd/druntime bug or I missed something? b1 points to the exact same data as does a1. This data is stack- allocated, and thus a2 points to an overwritten stack frame. -- Simen
Re: templated static array
On 2012-05-15 16:10, Namespace rswhi...@googlemail.com wrote: How can I do this? I have this code: http://dpaste.dzfl.pl/d9165502 And as you can see, the templated function 'receive2' take automatically dynamic arrays. But how can I tell the compiler, that this function takes (preferably) static arrays? My little hack function 'receive' take the type and the number of elements. So the compiler know: it's a static array. But is there no simpler trick to do this? Maybe something like 'void receive(T)(static T vals) {'. Nope. That's the way to do it. -- Simen
Re: templated static array
On 2012-23-15 16:10, Simen Kjaeraas simen.kja...@gmail.com wrote: On 2012-05-15 16:10, Namespace rswhi...@googlemail.com wrote: How can I do this? I have this code: http://dpaste.dzfl.pl/d9165502 And as you can see, the templated function 'receive2' take automatically dynamic arrays. But how can I tell the compiler, that this function takes (preferably) static arrays? My little hack function 'receive' take the type and the number of elements. So the compiler know: it's a static array. But is there no simpler trick to do this? Maybe something like 'void receive(T)(static T vals) {'. Nope. That's the way to do it. No, wait, sorry. You don't need to specify those things when calling the function. This works: void bar(T, size_t n)(T[n] a) {} void main(){ int[3] a; bar(a); } -- Simen
Re: templated static array
On 2012-35-15 17:10, Namespace rswhi...@googlemail.com wrote: But bar([1, 2, 3]); not. The compiler does not realize that [1, 2, 3] means a static array in this context. You have to write bar(cast(int[3]) [1, 2, 3]); but I think the compiler have to recognize this on it's own. This is true. The problem is, as you say, that the compiler treats array literals as dynamic rather than static arrays. I would argue this is the correct default, but it's obviously not the default you want here. bearophile has posted about this on numerous occasions, and it's among his top thousand wanted features. :p -- Simen
Re: What am I doing wrong here?
On 2012-10-14, 14:28, Martin wrote: Hey everyone, I'm new to D so bare with me please. I've been trying to figure out what's up with the strange forward refernce errors the compiler (DMD 2.060) is giving me. Here's a code snippet that's generating a forward reference error: public class AliasTestClass(alias func) { static assert(__traits(isStaticFunction, func)); } public class TestClass { private AliasTestClass!(randomFunction) test; // - public static void randomFunction() { } } The strange part about it is that if I surround the randomFunction parameter with another pair of paranthesis like so private AliasTestClass!((randomFunction)) test; It works just fine. If I don't, however, I get a forward reference error: Error: template instance main.AliasTestClass!(randomFunction) forward reference of randomFunction Am I doing anything wrong or is this some kind of bug? It's a bug. Maybe it's already in Bugzilla (there are some forward-ref bugs there already). Please file: http://d.puremagic.com/issues/enter_bug.cgi -- Simen
Re: Detect if running 32 bit program on 64 bit Windows OS
On 2012-01-10 02:10, Josh moonbur...@gmail.com wrote: Is there a way to do that? I've tried getenv(PROCESSOR_ARCHITECTURE) and shell(echo %PROCESSOR_ARCHITECTURE%), and both of them return x86 instead of AMD64 like cmd. I want to use this to run a 64 bit version of an external program if the OS is 64 bit, and the 32 bit version if not. http://msdn.microsoft.com/en-us/library/ms684139(v=vs.85).aspx -- Simen
Re: enum of tuples
On 2012-09-27, 00:02, Jonathan M Davis wrote: Classes will not work for the same reason that you can never use a class object as an enum with manifest constants. Has a decision been made as to whether or not this will be possible in the future? -- Simen
Re: move object from heap to stack
On Wed, 19 Sep 2012 15:45:21 +0200, Namespace rswhi...@googlemail.com wrote: On Wednesday, 19 September 2012 at 13:32:42 UTC, Namespace wrote: Is that possible? I can initialize an object with scope or, in feature, with scoped, directly on the stack but is it also possible to move an existing object from the heap to the stack? I tried this: http://dpaste.dzfl.pl/2955ff41 But as you can see in line 25/26, after I destroyed the heap object, the stack object seems to be corrupted. The problem here is that A.sizeof returns the size of the reference, not the instance. Instead you should use __traits(classInstanceSize, A). Also, do have a look at the internals of std.typecons.scoped, it likely contains some good ideas. -- Simen
Re: static init cycle detection problem
On Wed, 19 Sep 2012 22:25:46 +0200, Øivind oivind@gmail.com wrote: I am struggeling to get around the cycle detection kicking in when I have static init in modules that depend on eachother. I have seen some threads on 'fixes' for this, e.g. adding a @standalone property to the module or similar. Has there been any progress on this? If not would it be possible in e.g. main() to get a list of all compiled-in modules, and then iterate over them and call an init function where it exists? As long as there is a way to list the name of the modules at compile-time, this should be pretty easy..? There's no way to get that list at compile-time, because object files may be added at link-time. However, D has a ModuleInfo object, which contains information on all modules in the program: import std.stdio; void main( ) { foreach( m; ModuleInfo ) { writeln( m.name ); } } For details on how this object works, have a look-see at src/druntime/src/object_.d in your DMD installation folder. I'm not sure what you're asking for is possible even given this object, but it's probably the closest you'll (easily) get. -- Simen
Re: Quick int pointer allocation question
On Fri, 14 Sep 2012 16:27:55 +0200, monarch_dodra monarchdo...@gmail.com wrote: On Friday, 14 September 2012 at 11:17:55 UTC, Jacob Carlborg wrote: On 2012-09-14 12:52, monarch_dodra wrote: int x = void; http://dpaste.dzfl.pl/24c1baa9 Hum, but that is a stack allocated variable. Perhaps using GC.malloc? Hum, apparently, there is a second (default aka-hidden) argument that is a bitmask applied to the allocated memory. So not much gain there. I'm allocating an array of 500_000 ulongs, and afterwards, I'm initializing them all by hand, making the default allocation useless. I'm not going to lose any sleep over this, but there is no way in D to get (garbage collected) un-initialized memory/allocations? What's wrong with GC.malloc? The bitmask is there to... well, many things. Pass it BlkAttr.NO_SCAN to ensure memory is not initialized. I think that's all what's needed. -- Simen
Re: auto limitation?
On Tue, 11 Sep 2012 20:48:25 +0200, Ali Çehreli acehr...@yahoo.com wrote: Or you can write or find a template that produces the largest type among the members of a union. std.traits.CommonType. -- Simen
Re: How to have strongly typed numerical values?
On Wed, 05 Sep 2012 02:55:45 +0200, Nicholas Londey lon...@gmail.com wrote: Hello. I am trying to work out if there is existing support for strongly typed numerical values for example degrees west and kilograms such that they cannot be accidentally mixed in an expression. I have vague recollection of seeing a presentation by Walter talking about this but I cannot seem to find it. I have looked at std.typecons.Typedef and Proxy but neither seem to do what I want or at least fail to compile for the expression n = n + n;. I could easily implement my own as I have done in C++ in the past but assume there is a standard implementation which I would prefer. Any help or links to examples much appreciated. Regards, Nicholas Not mine, but this is the implementation I use: https://github.com/klickverbot/phobos/tree/units/std Files are units.d and si.d. Documentation: http://klickverbot.at/code/units/std_units.html http://klickverbot.at/code/units/std_si.html -- Simen
Re: popFront with input variables
On Fri, 31 Aug 2012 16:56:32 +0200, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: Hello all, Is it considered legit in any circumstances for popFront to take an input variable (e.g. a random number generator)? Or is it required always to have no input variables? No parameters, or at least it should be callable with no parameters. Might I ask why you'd want this? -- Simen
Re: static struct definition
On Tue, 28 Aug 2012 12:10:47 +0200, monarch_dodra monarchdo...@gmail.com wrote: From TDPL: 7.18: Unlike classes nested within classes, nested structs and nested classes within structs don’t contain any hidden member outer—there is no special code generated. The main design goal of nesting such types is to enforce the desired access control. I suppose this has become obsolete then? ...Or is it the other way around? TDPL trumps most everything else, I believe. -- Simen
Re: struct with @disable(d) default constructor doesn't work with arrays?
On Wed, 22 Aug 2012 13:09:49 +0200, bearophile bearophileh...@lycos.com wrote: Minas Mina: I think it's a bug, what do you think? Search for it in Bugzilla. Maybe it's there already. Bye, bearophile It is. #7021/#8457 -- Simen