Re: recursive definition error
On Friday, 4 July 2014 at 16:28:48 UTC, Frustrated wrote: On Friday, 4 July 2014 at 15:42:36 UTC, bearophile wrote: Frustrated: I'm not using 2.066 though... I will revert back to the dmd version I was using when it worked... Hopefully someone can make sure this is not a regression in the mean time... (seems like it is and I don't want to get bit again later on when I upgrade) That template and its instantiation work fine for me on both 2.065 and 2.066b1.
Re: Use of "T"
On Wednesday, 12 April 2017 at 22:56:25 UTC, solidstate1991 wrote: I know the existence of those and I'm frequently using them, however I need a two-way one. (Might be using two hash-tables instead if I can't find a better solution) So, you're looking for a generic way to store objects of arbitrary types in a file, and later retrieve those objects from that file? If that's the case, try looking at some existing serialization solutions (i.e. https://wiki.dlang.org/Serialization_Libraries).
Re: Can't pass data from filter to each
On Monday, 17 April 2017 at 10:02:22 UTC, Suliman wrote: New question. Can I put result of filtering in itself without creation of new variables like x: auto x = MySQLTablesRange.array.filter!(a=>a[0].coerce!string.canFind("_")); No. filter is simply a wrapper around the source range, it does not modify it. As for the problems you are having with ranges seeming empty, they are all due to the fact that the ResultRange in mysql-native isn't designed to support such chaining of calls. It's probably best to first exhaust a ResultRange and put it into an array.
Re: Can we disallow appending integer to string?
On Wednesday, 19 April 2017 at 14:36:13 UTC, Nick Treleaven wrote: This bug is fixed as the code no longer segfaults but throws instead: https://issues.dlang.org/show_bug.cgi?id=5995 void main(){ string ret; int i = -1; ret ~= i; } Why is it legal to append an integer? Because integrals implicitly convert to characters of same width (byte -> char, short -> wchar, int -> dchar).
Re: Can we disallow appending integer to string?
On Thursday, 20 April 2017 at 19:20:28 UTC, H. S. Teoh wrote: Another pernicious thing I encountered recently, related to implicit conversions, is this: https://issues.dlang.org/show_bug.cgi?id=17336 It drew a very enunciated "WAT?!" from me. Yeah, that one is annoying. I've dealt with this before with: alias OpResult(string op, A, B) = typeof((){ A* a; B* b; return mixin("*a"~op~"*b"); }());
Re: Can we disallow appending integer to string?
On Wednesday, 19 April 2017 at 17:34:01 UTC, Jonathan M Davis wrote: Personally, I think that we should have taken the stricter approach and not had integral types implicit convert to character types, but from what I recall, Walter feels pretty strongly about the conversion rules being the way that they are. Yep, me too. Generally, I don't think that an implicit conversion (T : U) should be allowed if T.init is not equivalent to U.init.
Re: The app hanging after reach 1750MB of RAM
On Wednesday, 19 April 2017 at 07:28:32 UTC, Suliman wrote: 1. You're measuring it wrong. Array length is already measured in terms of type size. So should I do: cargpspoints.length * cargpspoints[0].sizeof ? No. .sizeof is the statically known size of a type, it can't take into account dynamically allocated memory. cargpspoint.length * cargpspoints[0].sizeof will tell you the estimate size of the array, in bytes. But each of the elements also has strings - dynamic arrays that are allocated elsewhere, their length is not included in that calculation. So you could iterate over the array and sum up lengths of all strings to get an estimate. Even then, that's just that: an estimate. Actual amount of memory allocated for a dynamic array T[] *may* be greater than length * T.sizeof. The only way to know that is to query the allocator used (in this case, GC).
Re: Can we disallow appending integer to string?
On Wednesday, 19 April 2017 at 18:40:23 UTC, H. S. Teoh wrote: A few extra keystrokes to type cast(int) or cast(char) ain't gonna kill nobody. In fact, it might even save a few people by preventing certain kinds of bugs. Yup. Not to mention one could have @property auto numeric(Flag!"unsigned" unsigned = No.unsigned, C)(C c) if(isSomeChar!C) { return cast(IntOfSize!(C.sizeof, unsigned))c; } auto v = 'a'.numeric; ...or even have an equivalent as a built-in property of character types...
Re: Cleaning up Dub/Dmd builds
On Tuesday, 18 April 2017 at 15:07:27 UTC, WhatMeWorry wrote: When I try to upload these files to my new repo, GitHub (rightfully so) complains that I have too many files. Since I'm using sdl and not json, can I safely delete all the files that pertain to json? Can I do this some way at the command line? You shouldn't upload files from the .dub directory, that's local build cache that shouldn't be published. You can simply add the .dub directory to your .gitignore file.
Re: The app hanging after reach 1750MB of RAM
On Tuesday, 18 April 2017 at 13:28:57 UTC, Suliman wrote: Also I can't understand why app take so much memory? I checked array of structures size with this code: auto mymem = cargpspoints.length * typeof(cargpspoints[0]).sizeof; writeln(mymem); And it's print: 16963440 it's about 16MB... What is takes all other memory? 1. You're measuring it wrong. Array length is already measured in terms of type size. But remember that every call result.array will allocate, and very call coerce!string will also allocate. 2. Since you're iterating over every result once, there's no point in converting it to an array first. 3. Consider using the Row.toStruct() method for conversion. 4. Consider using std.array.appender instead of ~=. void getSingleTrackInfo() { foreach(item; getTablesGPSSensorList) { ResultRange result = mysqlconnection.query(sqlquery); carGPSPoint cargpspoint; // create struct auto arr = appender!(carGPSPoint[]); // create array of structures foreach(row; result) { arr ~= row.toStruct(cargpspoint); } // arr.data should hold the array of structures } }
Re: The app hanging after reach 1750MB of RAM
On Tuesday, 18 April 2017 at 14:09:28 UTC, Stanislav Blinov wrote: foreach(row; result) { arr ~= row.toStruct(cargpspoint); } Sorry, this should be foreach(row; result) { row.toStruct(cargpspoint); arr ~= cargpspoint; }
Re: hidden passing of __FILE__ and __LINE__ into function
On Tuesday, 18 April 2017 at 13:28:06 UTC, Solomon E wrote: I tried to produce an example of calling a function with variadic template arguments using special tokens __FILE__ and __LINE__. This compiles and runs, producing the output shown, using the default gdc provided by Ubuntu 17.04. This appears to be a workaround for Issue 8687... There's a much more concise workaround, both in code written and generated ;) import std.stdio; template func(string file = __FILE__, int line = __LINE__) { auto func(T...)(auto ref T args) { writeln("called func with ", T.length, " args at ", file, ":", line); } } void main() { func(); func(1, 2, 3); }
Re: Get name of current function
On Sunday, 23 April 2017 at 20:34:12 UTC, Mike B Johnson wrote: I'd like to get the symbolic name of the current function I'm in void foo() { writeln(thisFunc.stringof()); // prints foo } I need something short, elegant and doesn't require modifying preexisting code... I'm sure D has something along those lines? __FUNCTION__ and __PRETTY_FUNCTION__ both will give qualified name though (e.g. module.foo), so, if necessary, that has to be stripped out manually.
Re: using shared effectively in a producer/consumer situation.
On Sunday, 23 April 2017 at 20:33:48 UTC, Kevin Balbas wrote: I guess the follow up here is: Is this the correct way to do it? cast to shared, send to main thread, cast away shared? At the moment, pretty much yes. Either that or make the (unnecessary) immutable copies. There are no ownership primitives in Phobos yet, and shared itself is still... not quite there.
Re: refRange with non copyable struct
On Monday, 17 April 2017 at 19:00:44 UTC, Jonathan M Davis wrote: Because otherwise, it's not acting like a reference to the original range, which is the whole point of RefRange. The correct solution would probably be to @disable opAssign in the case where the original range can't be overwritten by another range. This doesn't look quite right. References in D are rebindable. That is, assigning a reference to a reference does not copy referenced object, only the reference itself. It seems that RefRange is trying to impersonate a C++ reference.
Re: if auto and method call
Would be prettier as a language feature, but still: template test(alias pred) { import std.functional : unaryFun; alias P = unaryFun!pred; auto test(R)(R r) { struct Test { R v; string toString() { import std.conv : to; return v.to!string; } bool opCast(B : bool)() const { return P(v); } ref inout(R) get() inout { return v; } alias get this; } import std.algorithm : move; return Test(move(r)); } } void main() { import std.regex; import std.stdio; string s1 = "hello"; string s2 = "world"; if (auto x = test!"!a.empty"(match(s1, "hello"))) { writeln(x.captures[0]); } if (auto x = test!"!a.empty"(match(s2, "hello"))) { writeln(x.captures[0]); assert(0); } // UFCS: if (auto x = s1.match("world").test!"!a.empty") { writeln(x.captures[0]); assert(0); } if (auto x = s2.match("world").test!"!a.empty") { writeln(x.captures[0]); } if (auto x = 3.test!"a == 3") { writeln(x, " equals 3, huh?"); } }
Re: scoped classes
On Thursday, 27 April 2017 at 06:40:49 UTC, Alex wrote: Hi all, a short question about an example. having read this: https://dlang.org/library/std/typecons/scoped.html There is a struct B defined in the middle of the example, with a scoped class member. How to define an array of such members (and to put some items to it)? So, I want to have something like // Use as member variable struct B { typeof(scoped!A())[] a; // note the trailing parentheses this(int i) { // construct member a.length = 5; // doesn't work, as the default constructor is disabled. a ~= scoped!A(i); // doesn't work, as the type is not copyable // ??? } } The only "possible" way would be like this: typeof(scoped!A())[] a; a = [ scoped!A(1), scoped!A(2), scoped!A(3) ]; But even so, you shouldn't do that. scoped isn't designed for it.
Re: scoped classes
On Thursday, 27 April 2017 at 15:47:38 UTC, Alex wrote: struct S { @disable this(); @disable this(this); this(size_t dummy){} } Given a struct with an explicit constructor and a postblit. How to make an array of it? You mean with a disabled default ctor and postblit? You can't with built-in arrays. They expect that elements can be default-constructed and copied. Even std.container.Array in its current implementation won't help you there. The only way to get around that is to devise your own array type that carefully deals with uninitialized storage and uses emplace/move/moveEmplace to store elements.
Re: scoped classes
On Thursday, 27 April 2017 at 17:07:05 UTC, Ali Çehreli wrote: I haven't used it yet but it's worth noting that there is EMSI's container library as well: http://code.dlang.org/packages/emsi_containers A brief glance at the source of dynamicarray there suggests that it won't help with non-copyables either.
Re: scoped classes
On Thursday, 27 April 2017 at 18:36:08 UTC, Alex wrote: * I'm pretty sure that the code is going to be invalid when you're dealing with const/immutable data. Ok... this is important... I tried this out, and the value of the immutable data even remains the same. But for safety reasons, I would reconstruct the structs inside the array anyway, so I can live with this, I think... move() is only destructive if the type has custom postblit or destructor, otherwise it's just a bitwise copy. But, as mentioned, there's an issue with it at the moment: it doesn't really care if the type being moved has const/immutable members. uninitializedArray is scary. If you do use it, probably best to localize the usage as much as possible and be very very VERY careful with it ;) Here's a sketch of something that's a little bit more convenient: https://dpaste.dzfl.pl/ee472fd872a5 But I'm not going to pretend it'd survive a review. Also note that, going back to your original question, docs for scoped state that it's illegal to move it, so that particular type you can't really store in any of these arrays.
Re: get parameters of a function
On Friday, 28 April 2017 at 20:43:50 UTC, Alex wrote: Hi all, I have a question about the Parameters trait from https://dlang.org/phobos/std_traits.html#Parameters The following code does not compile. Why? Is it mainly assumed to use it with functions without overloads? Rather, it is to be used on a concrete overload. If you want to check if two structs are callable with the same parameters, you'll need to iterate opCall overloads for both and look for a match, e.g. like this: void main() { foreach(o1; __traits(getOverloads, S1, "opCall")) { alias P1 = Parameters!o1; foreach(o2; __traits(getOverloads, S2, "opCall")) { alias P2 = Parameters!o2; static if (is(P1 == P2)) { pragma(msg, "Matching params: "~P1.stringof); } } } }
Re: get parameters of a function
On Saturday, 29 April 2017 at 06:18:34 UTC, Alex wrote: The problem is another one: say I have something like this: import std.traits; struct A(alias T) if(isCallable!T) { auto opCall(U...)(U args) if(is(Parameters!T == U)) //if(__traits(compiles, T(args))) { return T(args); } } void main() { S s; A!s c; assert(c(4) == 42); } struct S { auto opCall(){ return 42; } auto opCall(int i){return 42; } } This doesn't work because of Parameters trait and the both opCalls defined. However, I see the point... If I take the compiles-trait, it works as expected: In this case the constrained is fulfilled, and with the second opCall commented out - it isn't. Thanks :) Ah, that calls for something like a isCallableWith template. Pay extra care to how you pass parameters in that variadic opCall template though. Doing it like in the code above will pass everything by value, even though the original S.opCall might've expected a reference. To avoid that, auto ref + std.functional.forward can be used. The following code illustrates the difference. import std.traits; import std.functional : forward; /** Evaluates true if `func` is callable with arguments `args`. Can only be used as a function template constraint. */ enum isCallableWith(alias func, args...) = is(typeof(func(forward!args))); // Your original A struct A(alias func) if (isCallable!func) { auto opCall(Args...)(Args args) if (__traits(compiles, func(args))) { // all arguments are copied, any "ref/out" semantics are lost return func(args); } } // Modified to forward arguments struct B(alias func) if (isCallable!func) { // auto ref: preserve lvalues auto opCall(Args...)(auto ref Args args) if (isCallableWith!(func, args)) { // forward: preserve lvalues return func(forward!args); } } struct S { auto opCall() { return 42; } auto opCall(int i) { return 42; } // Note: parameter passed by reference! auto opCall(out float f) { f = 42.0f; } } void main() { S s; { A!s c; int i = 4; static assert(is(typeof(c(i; static assert(is(typeof(c(4; static assert(is(typeof(c(; assert(c(i) == 42); assert(c(4) == 42); assert(c() == 42); // Should pass but doesn't. //static assert(!is(typeof(c(3.5f; float f; static assert(is(typeof(c(f; c(f); // Will assert: assert(f == 42.0f); } { B!s c; int i = 4; static assert(is(typeof(c(i; static assert(is(typeof(c(4; static assert(is(typeof(c(; assert(c(i) == 42); assert(c(4) == 42); assert(c() == 42); // Passes static assert(!is(typeof(c(3.5f; float f; static assert(is(typeof(c(f; c(f); // Won't assert assert(f == 42.0f); } }
Re: Equivalent to nullptr
On Thursday, 4 May 2017 at 03:59:36 UTC, Leonardo wrote: On Thursday, 4 May 2017 at 02:45:30 UTC, Adam D. Ruppe wrote: On Thursday, 4 May 2017 at 02:12:13 UTC, Leonardo wrote: nullptr word. How I use this? Does it work if you just use `null` ? No. First I got: source/app.d(45,69): Error: expression (*SDL_EnclosePoints)(& mousePos, 1, , null) of type void does not have a boolean value then I change to: event.button.button == SDL_BUTTON_LEFT && SDL_TRUE == SDL_EnclosePoints(, 1, , null) and got: source/app.d(45,81): Error: void has no value source/app.d(45,52): Error: incompatible types for ((SDL_TRUE) == ((*SDL_EnclosePoints)(& mousePos, 1, , null))): 'int' and 'void' Ahh, looks to be a bug in DerelictSDL2. null will work for that last parameter, the problem is that the function should be returning an SDL_bool, but in Derelict it's declared as returning void: that's what the error message is saying. I'll file a report, but with the conference underway, it may take a while to get fixed.
Re: avoid extra variable during void pointer cast
On the point of "not possible...", "only a symbol...", etc: T* ptrCast(T, alias ptr)() { return cast(T*)ptr; } void addInt(void* state, void* data) { alias _state = ptrCast!(int, state); alias _data = ptrCast!(int, data); static assert(!is(typeof(_state) == int*)); static assert(!is(typeof(_data) == int*)); *_state += *_data; } But take heed to the compiler optimization advice. DMD generates pretty horrendous code for this. LDC does rather well though. Since speed matters, always look at the assembly. Look at it even if it doesn't ;)
Re: avoid extra variable during void pointer cast
On Sunday, 14 May 2017 at 21:55:01 UTC, ag0aep6g wrote: On 05/14/2017 11:35 PM, Moritz Maxeiner wrote: On Sunday, 14 May 2017 at 21:16:04 UTC, Stanislav Blinov wrote: [...] T* ptrCast(T, alias ptr)() { return cast(T*)ptr; } [...] alias _state = ptrCast!(int, state); [...] That's a pretty cool workaround, but not an alias to the cast, but an alias to a parametrized function template (a type), Not sure if I'm reading that right, but `_state` is not an alias of a (parametrized function) template. The template instantiation results in a function. `_state` is an alias of that function. `alias foo = ptrCast;` would make an alias of the template. Neither of them is a type. Yep, it's an alias to template function instantiation, that is, concrete function - a symbol. But of course, it *is* going to be called on every "dereference". GDC optimizes the call away starting at -O1, LDC needs -O2. DMD makes temporaries :)
Re: alias and UDAs
On Thursday, 11 May 2017 at 10:39:03 UTC, Andre Pany wrote: Hi, in this example, both asserts fails. Is my assumption right, that UDA on alias have no effect? If yes, I would like to see a compiler warning. But anyway, I do not understand why the second assertion fails. Are UDAs on arrays not allowed? import std.traits: hasUDA; enum Flattened; struct Foo { int bar; } @Flattened alias FooList = Foo[]; struct Baz { FooList fooList1; @Flattened FooList[] fooList2; } void main() { Baz baz; static assert(hasUDA!(baz.fooList1, "Flattened")); // => false static assert(hasUDA!(baz.fooList2, "Flattened")); // => false } Kind regards André It should've been alias FooList = @Flattened Foo[]; which will generate a compile-time error (UDAs not allowed for alias declarations). And then: static assert(hasUDA!(baz.fooList2, Flattened)); No quotes, since Flattened is an enum, not a string
Re: How to avoid throwing an exceptions for a built-in function?
On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote: Thanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-else That doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
Re: Converting a string[] to char**
On Tuesday, 9 May 2017 at 07:50:33 UTC, David Zhang wrote: If indeed there is no way to avoid allocation, do the allocations have to remain 'alive' for the duration of the instance? Or can I deallocate immediately afterwards? I can't seem to find it in the Vulkan spec. 2.3.1. Object Lifetime: Application-owned memory is immediately consumed by any Vulkan command it is passed into. The application can alter or free this memory as soon as the commands that consume it have returned.
Re: How to avoid throwing an exceptions for a built-in function?
On Saturday, 13 May 2017 at 08:50:20 UTC, k-five wrote: Way arguing when a simple code can clarify the subject? right? If am not clear so consider me as an stupid man, no problem at all. but CAN you please solve it for me? import std.stdio: writeln; import std.conv:to; void main( string[] args ){ string str = "10"; int index; index = to!int( str ); // okay, no exception are thrown str = "some-words"; index = to!int( str ); // problem, an exception is thrown } Please run this code and convert "some-words" to int by using to! function without facing any exception. Thanks Please don't take it the wrong way. It just seems that Mike was as confused by your questions as I was initially. But it's clear that's just the language barrier, nothing more. See, you said: Why I do not want to take care of that? Because I just need the value, if the string is valid, otherwise no matter what the value of string is. ...but it doesn't make sense to have an int "value" for a string like "some-words". *Unless* one defines a "not-a-number" equivalent for an int, i.e. 0 or some other value. That part was hard to infer from what you were saying :) It might've been obvious for you, but hard to understand from what you wrote. This was what made things clear: I just want to silent this exception... Mostly, the source of the confusion was the "I don't want to handle the exception". But in fact what you were asking was was there a way to somehow ignore the exception and just return some predefined value in case of an error. So in fact, you did want to handle the exception (or rather, an exceptional case), you just wanted to do it without inserting control flow instructions (try/catch) into your code. I think the latter part already got covered in others' replies. Nobody was trying to insult you. With this being a multi-lingual and multi-cultural community, remember that understanding goes both ways, and we're sometimes caught right in the middle, in the clash of mentalities.
Re: Do array literals still always allocate?
On Saturday, 13 May 2017 at 18:32:16 UTC, Lewis wrote: import std.random; import std.stdio; int[4] testfunc(int num) @nogc { return [0, 1, num, 3]; } int main() { int[4] arr = testfunc(uniform(0, 15)); writeln(arr); return 0; } I've read a bunch of stuff that seems to indicate that array literals are always heap-allocated, even when being used to populate a static array. On the contrary, when initializing static arrays, allocation is not needed. Note that what's *conceptually* happening in testfunc is this: int[4] testfunc(int num) @nogc { typeof(return) result = [0, 1, num, 3]; return result; } i.e. the type and size of the storage is known beforehand, all there is to do is copy the elements: 0044e528 <@nogc int[4] test.testfunc(int)>: 44e528: 55 push %rbp 44e529: 48 8b ecmov%rsp,%rbp 44e52c: 48 83 ec 10 sub$0x10,%rsp 44e530: 48 89 7d f8 mov%rdi,-0x8(%rbp) 44e534: c7 07 00 00 00 00 movl $0x0,(%rdi) # 0 goes at offset 0 44e53a: c7 47 04 01 00 00 00movl $0x1,0x4(%rdi) # 1 at offset 4 44e541: 89 77 08mov%esi,0x8(%rdi) # parameter at offset 8 44e544: c7 47 0c 03 00 00 00movl $0x3,0xc(%rdi) # 3 at offset 12 44e54b: 48 8b 45 f8 mov-0x8(%rbp),%rax 44e54f: c9 leaveq 44e550: c3 retq Is all the old stuff I was reading just out-of-date now? Where exactly did you read that initialization of a static array requires an allocation? That source should be abolished... errrm... corrected!
Re: How to move append to an array?
On Monday, 15 May 2017 at 21:38:52 UTC, Yuxuan Shui wrote: Suppose I have a struct A { @disable this(this); } x; How do I append it into an array? Do I have to do array.length++; moveEmplace(x, array[$-1]); ? moveEmplace is for moving an initialized object into an uninitialized one. Use the two-argument move() function: move(x, array[$-1]);
Re: How to move append to an array?
On Tuesday, 16 May 2017 at 01:22:49 UTC, Yuxuan Shui wrote: Can I expand an array with uninitialized object? Or can I rely on the compiler to optimize the initialization away? Built-in arrays always default-initialize their elements. If you need something that unsafe, there's std.array.uninitializedArray: http://dlang.org/phobos/std_array.html#uninitializedArray What are you trying to achieve?
Re: Structure of Arrays vs Array of Structures
On Monday, 15 May 2017 at 06:50:04 UTC, Nicholas Wilson wrote: On Monday, 15 May 2017 at 06:44:53 UTC, Nordlöw wrote: Have anybody done this already? Yes, https://maikklein.github.io/post/soa-d/ The code in that article is overly simplified. Concrete use cases would require more than just storing one POD type. Looking back at Jonathan Blow's example, what if you wanted to store this type in a SoA? struct Entity { Vector3 position; Quaternion orientation; } This, obviously, gets more involved, as now the SoA code needs to flatten that whole type recursively, otherwise it'd just store vectors packed together and then quaternions packed together, i.e: [vx0, vy0, vz0, vx1, vy1, vz1...][qx0, qy0, qz0, qw0, qx1, qy1, qz1, qw1...] whereas it should store [vx0, vx1...][vy0, vy1...][vz0, vz1...][qx0, qx1...][qy0, qy1...][qz0, qz1...][qw0, qw1...] Then, if you need to occasionally reassemble PODs from SoA, you need to deal with member alignment. And then there's a matter of providing actual functions dealing with types that are sparsely stored. Also, there is a... debatable assessment of viability there: But sometimes you still want to access all components of your data. An example would be a >vector. [...] Most operations will use all components anyways like add, subtract, dot, length and many >more. And even if you sometimes end up with struct Vec3{ float x; float y; float z; } Array!Vec3 positions; positions[].filter!(v => v.x < 10.0f); and you want to filter all vectors where the x component is less than 10.0f, you will >still only load two additional floats. "You will still *only* load two additional floats": that is incorrect. The CPU (at least, x86/64) won't load "only" two floats. It first needs to fetch the whole cache line only to touch every third float in it. That's ~66% of access time wasted. (Imagine how severe that is if it actually has to fetch from RAM. Scratch that, don't imagine, time it.). And if you not only read, but write data, it gets that much more wasteful. That is precisely the problem SoA is intended to solve: it would always visit 100% of data it needs to fetch. But of course, if you do need to reconstruct tightly packed PODs from SoA, you'll get a pretty severe penalty. So, once you commit to storing data this way, you have to organize the code accordingly, otherwise you're more likely to degrade performance rather than gain it. I do have an ongoing code experiment to see how far D could take us with it, but at this point it's rather immature. Perhaps in a couple of weeks I'd get it to a state that I could publish, if you guys would like to pitch in.
Re: Scope checking on static array struct doesn't kick in
On Tuesday, 9 May 2017 at 12:25:29 UTC, Nordlöw wrote: On Tuesday, 9 May 2017 at 11:52:35 UTC, Nordlöw wrote: I've tagged the ref-returning functions (in this case `opSlice`) with `return scope` for my statically allocated array struct at Here's a simpler example https://github.com/nordlow/phobos-next/blob/cf85f449d24981fbe6269f8096db23282e2fbb65/tests/test_scope.d Looks like a bug, if you change "auto" to "int[]" it starts complaining in f(). I have a question though, why is the syntax like this: auto opSlice() return scope; ? I don't see such in the DIP, proposed there is simply "scope" to the left of the declaration, i.e. scope auto opSlice(); Although with that syntax dmd complains about escaping 'this', as if it was scope { auto opSlice(); }. Is 'return scope' the syntax that is supposed to be used and it's just not reflected in the DIP, or?..
Re: How to avoid throwing an exceptions for a built-in function?
On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote: On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov wrote: On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote: Thanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-else That doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input. -- I know. But I am saying that I do not want to take care of any exceptions. I just wanted to write: int variable = to!int( string-type ); In fact something like using "no throw" is a function: void init( ... ) nothrow { ... int variable = to!int( string-type ); ... } but this is not valid. Thanks anyway and I will test: Function std.exception.assumeWontThrow at this link: https://dlang.org/library/std/exception/assume_wont_throw.html I don't understand. If you don't want to take care of exceptions, then you just don't do anything, simply call to!int(str). If an exception is thrown, it'll propagate further up the stack, until you either handle it or abort the program. "nothrow" does not turn off exceptions, it simply forbids throwing them in the enclosing scope (i.e. calling anything that might throw is not allowed). Or do you mean that you've already made sure that the user input is valid such that to!int() will never throw with it? In that case, yes, assumeWontThrow is a way to express that. But then, the only way you can be sure of that is if you've already parsed the input yourself, so I'm not clear on the intent. Alternatively, if what you're calling still might throw but you don't want to deal with try/catch blocks, there's collectException function in std.exception that'll give you the exception if it was thrown and let you deal with it without using try/catch.
Re: Error writing file a *.obj
On Tuesday, 9 May 2017 at 14:08:48 UTC, bachmeier wrote: On Tuesday, 9 May 2017 at 02:33:06 UTC, dummy wrote: On Monday, 8 May 2017 at 12:29:27 UTC, bachmeier wrote: On Monday, 8 May 2017 at 11:56:10 UTC, dummy wrote: When i build some application with dub, i got this error: I'm not a Dub user, but it has its own forum, so you might want to try there: http://forum.rejectedsoftware.com/ Oh, i solve this problem my self... because, the 'Ransomeware Protection' feature of Bitdefender InternetSecurity 2017. dub and dmd working pretty when i turn off this feature. Very sorry for noob question :/ This is not really a noob question. Since it affects new users trying to run a Hello World program, I wonder if it would be worthwhile to add that information to the error message. Most of the people trying out D will simply give up and blame the language. It's not. It's not the job of the linker to go rummaging through all user's processes to find out which one is locking the file, even if it's possible. What could be improved is the clarity, i.e. "Could not write the file due to it being locked for writing/lack of space on device/etc.".
Re: how to disable inlining of ldc2 when 'dub build --build=release'?
On Saturday, 20 May 2017 at 08:02:26 UTC, lixiaozi wrote: so, what should i do to disable inlining of ldc2 in release build? As Stefan mentioned, a test case would be nice. But have you tried annotating the offending function with pragma(inline, false)? http://dlang.org/spec/pragma.html#inline
Re: Why would an initialised struct pointer field be null in the struct's destructor?
On Saturday, 20 May 2017 at 10:48:54 UTC, Gary Willoughby wrote: In the following code, the `_foo` pointer (of the Foo struct) is null in the first call to the destructor. Why is this? I think it's got something to do with the foreach loop but I'm not sure. Any ideas? Oof. Dangerous stuff. As Moritz pointed out, default opAssign will call the destructor on Foo. I should, however, elaborate further. You're dealing with uninitialized data. calloc() gives you zero-initialized block, which is not necessarily how Foo.init would look (it does in this case, but that's not true in general case). malloc() gives you a potentially garbage-filled block, which is even more dangerous. When filling an array of uninitialized values, use std.algorithm.moveEmplace(src, dst) instead of assignment. And, if you have destructors, you have to call the destructors manually when you free the array. Furthermore, since Bar._data is an array of Foos, and Foo has a pointer in it, you might want to register the Bar._data array with the GC (GC.addRange, GC.removeRange). Unless you're willing to manually make sure that GC *never* sees those pointers.
Re: trait detecting anonymous union?
On Monday, 22 May 2017 at 21:03:42 UTC, Bastiaan Veelo wrote: ` void main() { import std.stdio; struct S { int i; union { int a; double b; } } S s; writeln(s); // S(10, #{overlap a, b}) import std.traits; writeln([FieldNameTuple!S]); // ["i", "a", "b"] } ` Is there a way to detect at CT that S has overlapping data members, when an anonimous union is used as above? Thanks, Bastiaan. There isn't a built-in one. The best I can muster at 1AM is finding all fields that have the same offset: size_t[] memberOffsetsOf(T)() { size_t[] result; foreach(i, _; typeof(T.tupleof)) result ~= T.tupleof[i].offsetof; return result; } string[] overlappingFieldsOf(T)() { import std.traits : FieldNameTuple; import std.range : array, enumerate; import std.algorithm : map, filter, count; enum offsets = memberOffsetsOf!T; auto names = [FieldNameTuple!T]; bool isOverlapping(size_t i) { return offsets.count(offsets[i]) > 1; } return names .enumerate .filter!(a => isOverlapping(a.index)) .map!(a => a.value) .array; } void main() { import std.stdio; struct S { int i; union { int a; double b; } int j; union { struct { short n, m; } float k; } } S s; writeln(overlappingFieldsOf!S); // ["a", "b", "n", "k"] } which is not quite the same as full overlap. This looks like a fun exercise, considering fields can also have arbitrary alignment...
Re: "if" is not evaluated for fields of Class.tupleof
On Tuesday, 23 May 2017 at 06:42:55 UTC, Timoses wrote: The easiest way is probably casting: ``` import std.traits; import std.bitmanip; class Test { byte[4] marray; byte mbyte; } void main() { auto value = [0x12, 0x23, 0x34, 0x45, 0x56]; auto test = cast(Test*) value.ptr; } ``` Don't cast arbitrary types to classes, you're going to stumble upon very nasty surprises :) I guess you meant struct? Classes in D are quite fat, and don't start with data members right away, bookkeeping ClassInfo data comes first.
Re: templatized delegate
On Tuesday, 23 May 2017 at 10:42:54 UTC, Nicholas Wilson wrote: On Tuesday, 23 May 2017 at 10:30:56 UTC, Alex wrote: On Monday, 22 May 2017 at 21:44:17 UTC, ag0aep6g wrote: With that kind of variadics, you're not dealing with a template. A (run-time) variadic delegate is an actual delegate, i.e. a value that can be passed around. But the variadic stuff is a bit weird to use, and probably affects performance. By the way, I'm not even sure, if variadics work in my case. I have a strange struct of a random generator, which cannot be copied, and I have no idea how to pass it to a variadic function: import std.stdio; import mir.random; void main() { Random rndGen = Random(unpredictableSeed); fun(rndGen); } void fun(...) { } Yields "... is not copyable because it is annotated with @disable" :) Random is copy @disabled to prevent incorrect use. You need to pass it by ref or pointer. I dont know if you can pass variables as ref to a variadic, but you should be able to pass it by address. fun(); void variadic(Args...)(auto ref Args args) { /* ... */ } This infers whether you pass lvalues or rvalues. If passing further down the chain of such calls is needed, one can use std.functional : fowrard : void variadic(Args...)(auto ref Args args) { import std.functional : forward; doStuff(forward!args); } void doStuff(Args...)(auto ref Args args) { /* ... */ } 'forward' aliases ref arguments (i.e. passed lvalues) and moves value arguments (i.e. passed rvalues). If a value is not copyable, it may be move-able (check the docs though, it may not be that either). void fun(Args...)(auto ref Args args) { /*...*/ } import std.algorithm : move; auto a = NonCopyable(42); fun(move(a)); // or: func(NonCopyable(42));
Re: Structure of Arrays vs Array of Structures
On Tuesday, 23 May 2017 at 16:48:31 UTC, Nordlöw wrote: On Tuesday, 23 May 2017 at 16:46:18 UTC, Nordlöw wrote: http://forum.dlang.org/post/wvulryummkqtskiwr...@forum.dlang.org Correction; should be: https://github.com/nordlow/phobos-next/blob/a324f16515bd1c3c1185ba0482dae2886d811bb1/src/soa.d What if you instantiate it with a nested struct? What about structs that themselves aggregate other structs? What about custom operators on such structs?.. As I said earlier, generic solution is not easy. The implementation you have is very niche, certainly not "std.".
Re: templatized delegate
On Tuesday, 23 May 2017 at 11:45:13 UTC, Alex wrote: On Tuesday, 23 May 2017 at 11:05:09 UTC, Stanislav Blinov wrote: void variadic(Args...)(auto ref Args args) { /* ... */ } This infers whether you pass lvalues or rvalues. If passing further down the chain of such calls is needed, one can use std.functional : fowrard : yes... void variadic(Args...)(auto ref Args args) { import std.functional : forward; doStuff(forward!args); } void doStuff(Args...)(auto ref Args args) { /* ... */ } 'forward' aliases ref arguments (i.e. passed lvalues) and moves value arguments (i.e. passed rvalues). If a value is not copyable, it may be move-able (check the docs though, it may not be that either). void fun(Args...)(auto ref Args args) { /*...*/ } yes... import std.algorithm : move; auto a = NonCopyable(42); fun(move(a)); // or: func(NonCopyable(42)); the problem, that I have is, that I would like to use the templated approach, but I don't have the function, but only a delegate, so: template(T, U...) { void delegate(ref T neededInput, ref U ignoredInput) dgPtr; } Not sure, if this is possible to handle at all... Ah, now I think I get it. You want to store a single delegate that could be called with different sets of arguments? No, you can't do that: you need an actual delegate instance, and for that, you need to know the signature, at least when instantiating C.
Re: The syntax of sort and templates
On Friday, 26 May 2017 at 11:27:19 UTC, zakk wrote: I have a followup question: my background is C and in Wolfram Mathematica, so my knowledge of templates is limited to trivial examples in C++, like: template const T& min(const T& lhs, const T& rhs) { return lhs < rhs ? lhs : rhs; } where the template argument is a type, and the function does the same job for different types. It seems to me that when programming in D templates are something more powerful, is it correct of thinking of them as some argument which is known at compile time? Is this misleading? It is :) Given your example above, 'template' doesn't mean just 'type'. The whole definition is a template, i.e. that is a template function min. Or, in case of the original question, 'sort' is a template. Not just it's arguments, but it itself. But yes, templates are purely compile-time constructs. When you instantiate them with different arguments, you effectively get different functions in your code. Hence the name: compiler takes an existing definition (a template) and builds a whole new concrete function from it. So if you were to call that C++ min function like this: min(1, 2); the compiler would generate a concrete function min, instantiated with T that is int, and then if you make this call: min(1.5, 2.0); then the compiler would generate *another* min, this time for type double. Note that double is of different size than int (i.e. usually int is 4 bytes, double is 8), and is also a floating-point type, not integral. So the compiler would have to issue different CPU instructions when generating code for it. So now you get two different functions, but code for both of them has only been written once, the compiler takes care of the rest. Had 'min' not been a template, the programmer would have to write a new version by hand for every type needed, to get the most efficient code from the compiler.
Re: The syntax of sort and templates
On Friday, 26 May 2017 at 09:59:26 UTC, zakk wrote: Hello everyone, I just started using D and I am a bit puzzled by the syntax of the sort function is std.algorithm.sorting, which is sort!(comparingFunction)(list) where comparingFunction is often a lambda expression. For instance in the Wolfram Language the equivalent function is Sort[list,comparingFunction] My questions are: 1) Why is D making using of the binary ! operator, which as far as I understand introduces a template? The ! operator is needed to distinguish template arguments, passed and known at compile time, from actual function arguments, passed and known at run time. "!" doesn't "introduce" a template. The definition of 'sort' is a template, sort!(fn)(list) is an instantiation of that template with concrete arguments. In C++, template arguments are denoted with <>, which is more verbose and introduces syntax ambiguity in complex templates. D avoids that by using the !. 2) Why is a template needed here? Templates are a form of polymorphism that works at compile time. It allows the programmer to write, and the compiler to generate, the most efficient an/or the most practical code given the concrete use case. The net effect is that at runtime you get the sorting function that is tailored for the specific types and comparison predicate, as if it was written by hand. 3) It seems to me like the argument passed to the template is a lambda expression. I only know about templates taking types as argument. What's going on? In D, depending on their definition, templates can take types, values or symbols as arguments. In this case, sort takes the comparison function and inserts it directly into the algorithm, which enables the compiler to inline it and/or perform various other optimizations, which would've been harder or impossible to do if the function was only known at runtime. Also, this enables writing concise code: in Phobos, algorithms that take predicates allow to pass them as string literals instead of full-blown functions: sort!"a < b"(list); The "a < b" will be transformed at compile time into (a, b) => a < b.
Re: Out of memory error (even when using destroy())
On Friday, 26 May 2017 at 18:06:42 UTC, Mike B Johnson wrote: On Friday, 26 May 2017 at 14:05:34 UTC, ag0aep6g wrote: On 05/26/2017 10:15 AM, realhet wrote: But hey, the GC knows that is should not search for any pointers in those large blocks. And the buffer is full of 0-s at the start, so there can't be any 'false pointers' in it. And I think the GC will not search in it either. The issue is not that the block contains a false pointer, but that there's a false pointer elsewhere that points into the block. The bigger the block, the more likely it is that something (e.g. an int on the stack) is mistaken for a pointer into it. Wow, if that is the case then the GC has some real issues. The GC should be informed about all pointers and an int is not a pointer. What is a pointer if not an int? :) That is not an issue. The GC holds off releasing memory if there's even a suspicion that someone might be holding on to it. In most problems, ints are small. Pointers are always big, so there's not much overlap there. Accidents do happen occasionally, but it's better to have a system that is too cautious than one that ruins your data. Working with huge memory chunks isn't really a domain for GC though.
Re: Extern C and Symbol Mangling
On Friday, 26 May 2017 at 12:49:27 UTC, Oleksii wrote: Hi, I'm trying to link against a DLL which exports a bunch of C functions. The issue is: C symbols do not have underscore prefix in Windows, but DMD sticks underscore in front of the symbol name. For example: `extern(C) void Foo()` becomes `_Foo`. Is there a way to disable that underscore? Use extern(Windows), or the more general extern(System), which will expand to either extern(C) or extern(Windows), depending on the OS you target.
Re: Why would an initialised struct pointer field be null in the struct's destructor?
On Sunday, 21 May 2017 at 12:48:10 UTC, Adam D. Ruppe wrote: On Saturday, 20 May 2017 at 10:48:54 UTC, Gary Willoughby wrote: // Why is this._foo null here??? The others have answered why and what to do, but note that according to the spec, that any struct should be able to have its destructor called, so you should do a null check in there anyway. Not if you either emplace() or blit Foo.init into all of the array elements.
Re: Multiple template variadic list not working
On Sunday, 21 May 2017 at 15:13:55 UTC, bastien penavayre wrote: I've been trying to translate the following idea expressed here in c++: template void func(Arguments... args) {} so I tried void func(UserArgs..., Arguments...)(Arguments args) {} and then void func(Args...)(Filter!(isType, Args) args) {} but nothing works. This seems like something simple to handle, why is it not then ? In this case, eponymous template should do the trick: template func(UserArgs...) { void func(Arguments...)(Arguments args) {} }
Re: Default class template parameter
On Saturday, 27 May 2017 at 19:23:59 UTC, Igor Shirkalin wrote: Hi, I try to make a class template with single template argument defaulted to some type. Is it possible to use the name of class without specification of template argumet (no '!' operator)? Example: class ClassName(T=double) { this(T value) { /// do some stuff here } /// some other stuff.. } void main() { a = ClassName(1.2); /// error: cannot deduce function from argument types !()(int) a = ClassName!double(1.2); /// OK } It seems the compiler treats 'ClassName' as function, but it is obvious that it should treat it as 'ClassName!double'. No, you'd have to at least write auto a = new ClassName!()(1.2); Or you could define a make function: auto makeClassName(T = double)(T value) { return new ClassName!T(value); } auto a = makeClassName(1.2);
Re: Out of memory error (even when using destroy())
On Saturday, 27 May 2017 at 17:57:03 UTC, Mike B Johnson wrote: And what if one isn't interfacing to C? All pointers should be known. You can't access memory by and int or any other non-pointer type! Hence, when pointers are created or ints are cast to pointers, the GC should be informed and then handle them appropriately Eh? So *every* cast from and to a pointer should become a call into the runtime, poking the GC? Or rather, every variable declaration should somehow be made magically known to the GC without any runtime cost? (then, instead of scanning a 100MB block of memory for "pointers" it should scan the list of possible pointers(which will generally be much much lower). That's precisely what it does, it scans the possible suspects, nothing more. That is, the stack (it has no idea what's there, it's just a block of untyped memory), memory it itself allocated *only if* it needs to (e.g. you allocated a typed array, and the type has pointers), memory you've specifically asked it to scan. It won't scan that block of 500k ints the OP allocated, unless told to do so. It would scan it if it was a void[] block though. Therefor, in a true D program(no outsourcing) with no pointers used, the GC should never have to scan anything. No pointers used? No arrays, no strings, no delegates?.. That's a rather limited program. But thing is, you're right, in such a program the GC will indeed never have to scan anything. If you never allocate, GC collection never occurs either. It seems the GC can be smarter than it is instead of just making blanket assumptions about the entire program(which rarely hold), which is generally always a poor choice when it comes to performance... Unnecessary interaction with the GC, e.g. informing it about every cast, is a poor choice for performance. After all, if we truly want to be safe, why not scan the entire memory of the system? Who knows, some pointer externally might be peeping in on our hello world program. What?
Re: RAII pointers
On Monday, 29 May 2017 at 23:39:17 UTC, Russel Winder wrote: C++ allows one to create types that are pointer types but wrap a primitive pointer to give RAII handling of resources. For example: class Dvb::FrontendParameters_Ptr { private: dvb_v5_fe_parms * ptr; public: FrontendParameters_Ptr(FrontendId const & fei, unsigned int const verbose = 0, unsigned int const legacy = 0); FrontendParameters_Ptr(FrontendParameters_Ptr const &) = delete; FrontendParameters_Ptr & operator=(FrontendParameters_Ptr const &) = delete; ~FrontendParameters_Ptr() {dvb_fe_close(ptr); } dvb_v5_fe_parms * c_ptr() const { return ptr; } dvb_v5_fe_parms * operator->() const { return ptr; } }; Has anyone any experience of doing the analogous thing idiomatically in D. I just re-realised I manually constructed a C++ abstraction layer around some of libdvbv5, so I am going to do the same for D. However whilst I (sort of) understand doing the wrapping with C++, I am not sure I have seen anyone wrapping C pointers with RAII in D. I've found this pattern works rather well: module frontendparametersptr; struct FrontendParametersPtr { // No constructors, initialization with parameters // is done via the frontendParametersPtr function @disable this(this); ~this() { // null check is often useful to detect e.g. // if this object has been `move`d if (_ptr) dvb_fe_close(_ptr); } // with DIP1000, could also return `scope` inout(dvb_v5_fe_parms)* ptr() inout { return _ptr; } alias ptr this; package: void construct(/*your args here*/) { /*...*/ } private: dvb_v5_fe_parms* _ptr; } /// Replaces constructor, i.e. can be called with no arguments for /// replacing "default" construction of C++ auto frontendParametersPtr(Args...)(auto ref Args args) { import std.functional : forward; FrontendParametersPtr result = void; result.construct(forward!args); return result; // moves result, no copy is made } ///- module app; import frontendparametersptr; void main() { auto ptr = frontendParametersPtr(/* your args here */); } The main idea is that construction is handled by the `construct` function (which could be overloaded), instead of `this(...)` constructors: this way client code would either get default-initialized (.init) pointers, or those constructed with appropriate arguments (even with no arguments, if such is needed). Disabling copying is obvious. The rest depends on taste and purpose.
Re: howto count lines - fast
On Tuesday, 30 May 2017 at 23:41:01 UTC, H. S. Teoh wrote: This little challenge piqued my interest. So I decided to take a shot at seeing if I could beat my system's /usr/bin/wc -l. First order of business: whenever it comes to performance, always choose the right compiler for the job... Woohoo!!! Finally, we beat the system's wc -l!! And by a pretty fair margin, too. Eat your heart out, wc!!! (The large user time is because we're using all 6 cores at once. But the actual elapsed time is shorter.) Hm... I cheated a little bit: took your program and compiled with `ldc2 -release -O3 -mcpu=skylake`. For data I took std.datetime concatenated 1000 times (35446000 lines). Results (minimum of 10 runs each): wc -l real 0.50 user 0.40 sys 0.09 lineCount1 real 0.23 user 0.19 sys 0.04 lineCount2 real 0.29 user 0.17 sys 0.12 lineCount3 real 0.23 user 0.18 sys 0.04 lineCount4 real 0.22 user 1.52 sys 0.04 Seems like all of them beat wc, so machine and compiler matter a great deal in this comparison. Thing is, on small files wc is going to win pretty much always, due to D's clunky startup. But with larger ones - wc falls far behind. Interestingly, both lineCount1 and lineCount3 on this machine are nearly even with lineCount4 :)
Re: difference between x = Nullable.init and x.nullify
On Saturday, 3 June 2017 at 08:01:14 UTC, Jonathan M Davis wrote: On Saturday, June 03, 2017 06:41:44 Stanislav Blinov via Digitalmars-d-learn wrote: On Saturday, 3 June 2017 at 06:19:29 UTC, Jonathan M Davis wrote: > looking at what rt_finalize does, I don't see why it > couldn't be nothrow. So, unless I'm missing something, it > seems like that would be a good enhancement. > > - Jonathan M Davis Presently, rt_finalize cannot be made nothrow, or un-made @system, because "reasons": http://forum.dlang.org/thread/aalafajtuhlvfirwf...@forum.dlang.org Fixing that would require significant changes to the runtime, and probably the compiler. I don't think it qualifies as a simple "enhancement" :) Well, as I said, I could be missing something, but all rt_finalize does is call rt_finalize2, and rt_finalize2 _is_ nothrow (it catches any Exceptions that are thrown by the destructor/finalizer). So, I have no idea why it would be the case that rt_finalize couldn't be nothrow, and I saw nothing in that thread which contradicts that, but I could have read it too quickly. Regardless, it's a perfectly valid enhancement request whether it's easy to implement or not. - Jonathan M Davis Whoops, my bad, I forgot it indeed swallows exceptions and does the onFinalizeError instead. So... yep, then it seems that rt_finalize probably should be marked nothrow too. Hmm... if throwing in a destructor is considered a runtime error, perhaps another valid enhancement would be to statically disallow throwing Exceptions in destructors, i.e. *require* them be nothrow?..
Re: difference between x = Nullable.init and x.nullify
On Saturday, 3 June 2017 at 06:19:29 UTC, Jonathan M Davis wrote: looking at what rt_finalize does, I don't see why it couldn't be nothrow. So, unless I'm missing something, it seems like that would be a good enhancement. - Jonathan M Davis Presently, rt_finalize cannot be made nothrow, or un-made @system, because "reasons": http://forum.dlang.org/thread/aalafajtuhlvfirwf...@forum.dlang.org Fixing that would require significant changes to the runtime, and probably the compiler. I don't think it qualifies as a simple "enhancement" :)
Re: string to wchar*?
On Saturday, 3 June 2017 at 23:36:18 UTC, Mike B Johnson wrote: https://dlang.org/phobos/std_utf.html#toUTF16z This didn't work. More errors than the first. Works for me: void main() { import std.conv; import std.stdio; import core.stdc.wchar_; import core.stdc.stdio; auto f = fopen("hello.bin", "w,ccs=UTF16LE"); scope (exit) fclose(f); import std.utf; string hello = "Привет"; wchar bom = '\ufeff'; auto str = hello.toUTF16z; fputwc(bom, f); while (str && *str) { fputwc(*str, f); ++str; } } $ rdmd wchartest.d $ file hello.bin hello.bin: Little-endian UTF-16 Unicode text, with no line terminators $ hexdump hello.bin 000 feff 041f 0440 0438 0432 0435 0442 $ iconv -f UTF-16LE hello.bin Привет In any case, it conv should work. No, it shouldn't. char* et al. are not string types in D. to!(char*)(string) just doesn't make sense.
Re: RAII pointers
On Saturday, 3 June 2017 at 19:55:30 UTC, ag0aep6g wrote: On 06/03/2017 09:37 PM, Moritz Maxeiner wrote: Of course, but AFAIK you'd need to explicitly assign it to an object, so `ptr` won't null by accident, but only by explicit programmer intent (same as overwriting the memory the object lives in via things like `memcpy`); and you can always screw things intentionally (you could also assign some invalid value to the pointer via `memcpy`). I'd say `.init` can easily happen accidentally. Especially when `@disable this(this);` is involved. When you can't copy, you may have to move sometimes. But std.algorithm.move overwrites the old location with `.init`, assuming that `.init` can safely be destroyed. struct S { void* ptr; @disable this(this); ~this() { assert(ptr !is null); /* fails */ } } void f(S s) {} void main() { auto a = S(new int); import std.algorithm: move; f(move(a)); /* overwrites `a` with `S.init` */ } Yep, that's exactly why I added the null check in the example. If the struct has a postblit or a destructor, `move` will be destructive, and will overwrite the source with .init. Sometimes it doesn't matter (i.e. free() is allowed to take a null pointer), but in general, for things like smart pointers where you'd do arbitrary access in destructor, it's a good habit to check for .init values first, in case the object has been moved.
Re: RAII pointers
On Saturday, 3 June 2017 at 21:39:54 UTC, Moritz Maxeiner wrote: On Saturday, 3 June 2017 at 21:16:08 UTC, Stanislav Blinov wrote: On Saturday, 3 June 2017 at 20:53:05 UTC, Moritz Maxeiner wrote: Quite, but if you backtrack to my initial statement, it was about ptr not being/becoming null (implicitly) in the first place, which *might* allow you to skip the check (if you don't set it to null via external means, such as memcpy, move, etc). It's only true as long as you have full control of the source. Once you're using libraries and generic code, it's possible that it's out of your hands: It's always true, because I explicitly wrote *might*, not *will*, to indicate that it depends on your use case. Your example is a common use case where you can't skip the check. Programmers and their tight-binding logic... - Honey, please buy a loaf of bread. If there are eggs, buy a dozen. ... - Hello, do you have eggs? - Yes. - Dozen loaves of bread, please. ;)
Re: string to wchar*?
On Saturday, 3 June 2017 at 22:54:22 UTC, Mike B Johnson wrote: How to convert a string to wchar*? C-style null-terminated wchar*? https://dlang.org/phobos/std_utf.html#toUTF16z
Re: RAII pointers
On Saturday, 3 June 2017 at 20:53:05 UTC, Moritz Maxeiner wrote: On Saturday, 3 June 2017 at 20:25:22 UTC, Stanislav Blinov wrote: On Saturday, 3 June 2017 at 20:13:30 UTC, Moritz Maxeiner wrote: Calling std.algorithm.move is explicit programmer intent, I consider that about as accidental as calling memcpy with a source full of zeroes. In any case, having that check in the destructor is fairly cheap, so better safe than sorry (and include it). Yes, it's explicit. Destructor call is still implicit though, and it better not be performing null dereference or something equally nasty :) Quite, but if you backtrack to my initial statement, it was about ptr not being/becoming null (implicitly) in the first place, which *might* allow you to skip the check (if you don't set it to null via external means, such as memcpy, move, etc). It's only true as long as you have full control of the source. Once you're using libraries and generic code, it's possible that it's out of your hands: import core.stdc.stdio; import std.exception; // external library struct RingBuffer(T,size_t size) { T[size] values = T.init; // the culprit // interface snipped... } // own code struct FileWrapper { FILE* file; @disable this(); @disable this(this); this(FILE* file) { enforce(file); this.file = file; } ~this() { fclose(file); } } void main() { // whoops, segfault RingBuffer!(FileWrapper,8) container; }
Re: How to Compare 2 objects of the same class
On Saturday, 3 June 2017 at 22:38:31 UTC, Mark wrote: In the future I'll include a compilable example. I was having problems with a class I made which is about 45 lines, that might be a lot of code for a post. You can use external resources such as: https://d.godbolt.org/ https://dpaste.dzfl.pl to paste code there and then just post a link to a paste here.
Re: difference between x = Nullable.init and x.nullify
On Sunday, 4 June 2017 at 09:04:14 UTC, Jonathan M Davis wrote: if throwing in a destructor is considered a runtime error, perhaps another valid enhancement would be to statically disallow throwing Exceptions in destructors, i.e. *require* them be nothrow?.. My initial reaction would be that destructors should always be nothrow, though I vaguely recall there being some reason why it was supposed to be nice that destructors in D could cleanly deal with exceptions. And remember that when we're talking about rt_finalize, we're talking about finalizers, not destructors in general. When a destructor is in a GC heap-allocated object, it's treated as a finalizer and may or may not be run (since the object may or may not be collected), It doesn't matter. The only thing that matters is that it may be run, and therefore rt_finalize has to count on that. And it sort of does, at the moment, by assuming the worst possible combination of attributes. Problem is, with current language rules, it cannot be any other way, as the runtime doesn't carry any information about attributes of finalized object, or the context in which finalization takes place (i.e. is it within a @safe function?), which, sadly, makes unsafe code silently executable in a safe context, in direct contradiction to language guarantees. whereas when a destructor is on an object that's on the stack, it's really a destructor. So, while they use the same syntax, It's worse than that. There are two "destructors": __xdtor that calls destructors of RAII members, and, on classes, __dtor that actually calls ~this() for the class. But only that class, not it's ancestors or descendants. Such segregation is, as it turns out, as useful as it is unwieldy. and in the case of a struct, the same function could be either a destructor or a finalizer depending on where the struct is declared, they're not quite the same thing. And destroy muddies the water a bit, because it then explicitly calls the finalizer on a class, whereas it would normally be the GC that does it (and while calling GC-related functions in a finalizer is forbidden when called by the GC, it's fine when called via destroy, since the GC is then not in the middle of a collection). So, I don't know whether it would be reasonable to require that destructors be nothrow. Certainly, it's _more_ likely for it to be reasonable for destructors on classes to be nothrow, since classes always live on the heap (and are thus finalizers) unless you're playing games with something like std.typecons.scoped, but I'd have to study the matter quite a bit more to give a properly informed answer as to whether it would be reasonable to require that all destructors be nothrow. Scoped is not necessary. Classes may not necessarily exist in the GC heap, thanks to custom allocators and emplace(). But because the language does not enforce propagation of destructor attributes, destroy() is @system and not nothrow, which spills out into user code that would otherwise take advantage of static inference. Unfortunately, right now making it any other would impose certain restrictions on classes without real language support, and that is... scary.
Re: .sort vs sort(): std.algorithm not up to the task?
On Thursday, 8 June 2017 at 01:57:47 UTC, Andrew Edwards wrote: Ranges may be finite or infinite but, while the destination may be unreachable, we can definitely tell how far we've traveled. So why doesn't this work? import std.traits; import std.range; void main() { string[string] aa; // what others have referred to as // standard sort works but is deprecated //auto keys = aa.keys.sort; // Error: cannot infer argument types, expected 1 argument, not 2 import std.algorithm: sort; auto keys = aa.keys.sort(); // this works but why should I have to? //import std.array: array; //auto keys = aa.keys.sort().array; foreach (i, v; keys){} } If I hand you a chihuahua for grooming, why am I getting back a pit bull? I simply want a groomed chihuahua. Why do I need to consult a wizard to get back a groomed chihuahua? aa.keys.sort() should just work as is: aa.keys returns a string[], and that's a random access range that can be sorted. What exactly is the error?
Re: .sort vs sort(): std.algorithm not up to the task?
On Thursday, 8 June 2017 at 02:25:17 UTC, Jonathan M Davis wrote: Oh I see, the was error related to iteration, not sorting. Ranges do not support iterating with an index. The workaround if you want to have an index with ranges and foreach, then you should use lockstep: http://dlang.org/phobos/std_range.html#lockstep e.g. foreach(i, v; lockstep(iota!size_t(0), s)) {} or foreach(i, v; lockstep(iota(0), s)) {} There's an enumerate(): https://dlang.org/phobos/std_range.html#enumerate import std.algorithm : sort; import std.range : enumerate; foreach(i, k; aa.keys.sort().enumerate) { /* ... */ }
Re: "Lazy" initialization of structs
On Thursday, 1 June 2017 at 12:04:05 UTC, Daniel Tan Fook Hao wrote: Somehow this code works for me: ```D auto error (int status, string description){ struct Error { int status; string description; } Error err = { status, description }; return err.serializeToJson; } ``` which is supposed to be the same as ```D struct Error { int status; string description; } auto error (int status, string description){ Error err = { status, description }; return err.serializeToJson; } ``` It's not really the same, the structs will have a different type: in the first case, it'd be modulename.error.Error, while in the second case it's just modulename.Error. Furthermore, if Error declared inside the function had methods, it'd become a `nested` struct, which carries a context pointer. If I'm reading this right, in the former, the struct is created when the function is called in run-time, and the type is then inferred after that? I don't really understand the behavior behind this. No, nothing happens at run time, the type is known statically, it is inferred from the `return` statement in that function: https://dlang.org/spec/function.html#auto-functions. If you omit the type or specify 'auto', the compiler will look at your `return`s (if any) and try to infer the type from them. If they clash (i.e. you're trying to return different types from the same function), it's a compile-time error. Otherwise, it's whatever type is being returned.
Re: .sort vs sort(): std.algorithm not up to the task?
On Thursday, 8 June 2017 at 04:07:22 UTC, Andrew Edwards wrote: On Thursday, 8 June 2017 at 03:40:08 UTC, Jonathan M Davis sort() returns a SortedRange so that other algorithms can know... Yes, I understand that. Again, using "std.range: release" earns me nothing more than I already get from "std.array: array" or if you prefer "std.range: array". Earns you nothing? How about not performing an allocation and copy? I can understand if sort returns Range by default but can be instructed to return the original representation. aa.keys.sort!returnOriginalRepresentation; // or something to that effect "Something to that effect" is exactly this: aa.keys.sort().release; No need to import anything but std.algorithm : sort. But it doesn't, it decides what i'm gonna get like it or not. But the fact, a lot of times I just want to work with the underlying data after the operation is performed. And it should be noted that this applies to Ranges in general not just sort. A crucial point of any good design is to *not rob the caller of useful information*. sort() follows that philosophy. If you don't need the extra information, you're free to get rid of it. The other way around that you seem to be proposing would require having a ton of overloads for sort() for any imaginable use case.
Re: RAII pointers
On Saturday, 3 June 2017 at 20:13:30 UTC, Moritz Maxeiner wrote: Calling std.algorithm.move is explicit programmer intent, I consider that about as accidental as calling memcpy with a source full of zeroes. In any case, having that check in the destructor is fairly cheap, so better safe than sorry (and include it). Yes, it's explicit. Destructor call is still implicit though, and it better not be performing null dereference or something equally nasty :)
Re: byLine(n)?
On Sunday, 11 June 2017 at 05:36:08 UTC, helxi wrote: I was writing a program that reads and prints the first nth lines to the stdout: import std.stdio; void main(string[] args) { import std.algorithm, std.range; import std.conv; stdin.byLine.take(args[1].to!ulong).each!writeln; } As far as I understand the stdin.byLine.take(args[1].to!ulong) part reads all the lines written in stdin. What if I want to make byLine read only and only first nth line? stdin.byLine(args[1].to!ulong).each!writeln; Obviously the code above won't work. Is there any efficient workaround? You need only the nth line? Then you'd need to `drop` the preceding ones: void main(string[] args) { import std.algorithm, std.range, std.stdio, std.conv; stdin.byLine.drop(args[1].to!int-1).front.writeln; } Or if you need every nth line, combine `drop` and `stride`: void main(string[] args) { import std.algorithm, std.range, std.stdio, std.conv; auto step = args[1].to!int; stdin.byLine.drop(step-1).stride(step).each!writeln; }
Re: Looking for an equivalent to C++ std::getline in D
On Sunday, 7 May 2017 at 10:33:25 UTC, k-five wrote: On Sunday, 7 May 2017 at 09:46:22 UTC, Patrick Schluter wrote: On Saturday, 6 May 2017 at 10:15:03 UTC, k-five wrote: If you want to learn the basis of the range concept and their link to C++ Iterators, you should definitively read Andrei's article on them in the InformIT magazine. Here is the link http://www.informit.com/articles/printerfriendly/1407357 required read for every aspiring D programmer ;-) --- Thanks for the article. Although I found D for being more better, nicer,and fun than C++ is, but there is a few questions on Stack-Over-Flow, videos on Youtube, and some other forums in my country. So, why D is not popular? Because everyone is asking this question instead of actually doing something about it :) To be fair, D has a good amount of usage even today, it's just not being screamed about ecstatically. I am a big fan of Perl-one-liner and after seeing rdmd --evel='one-line-code' I gasped! Oh, really? a one-liner with D! Or even Unix Command Line, that D has Uniform Function Call Syntax. line.sort.uniq.writeln(); It may you know about the future of D or may introduce some other articles about the future of D to me. Since after learning C++ I am not very comfortable with. Today is the last day of the D Conference 2017, last three days it was livestreaming. There were quite a bit of talks on current developments and future progress. The videos from those streams should appear at https://www.youtube.com/user/sociomantic/videos hopefully early next week. They also have previous conference videos out there.
Re: The .obj file, what is it?
On Wednesday, 3 May 2017 at 10:55:44 UTC, I Lindström wrote: So, a question from a beginner. What is the .obj file that appears after the source is compiled into the executable? I can't find a good explanation on the Net for it. I take it the file has to accompany the executable for the program to function since the online explanations I've found say it contains instructions and is related to memory management? It's been bugging me from the start. The source is not compiled into the executable. The source is compiled into a "object code", output into an "object file" - in this case, the .obj file. Afterwards, object files are linked by a linker (usually also taking other object files and/or libraries) to produce an executable or a library. .obj files are not needed to be redistributed, they've served their purpose when the final target executable or library has been created. But it's useful to keep them in the development environment, as usually the build environment would not spend time recompiling the code when an up-to-date object files are present.
Re: Looking for an equivalent to C++ std::getline in D
On Friday, 5 May 2017 at 09:54:03 UTC, k-five wrote: Hi all. I have a simple command-line program utility in C++ that can rename or remove files, based on regular expression. After finding D that is more fun than C++ is, I want to port the code, but I have problem with this part of it: std::getline( iss, match, delimiter ); std::getline( iss, substitute, delimiter ); I need to read from iss ( = std::istringstream iss( argv[ 1 ] ) and separate them by delimiter. Since the program gets the input from a user, and it can be something like: 's/\d+[a-z]+@(?=\.)//g' or '/[A-Za-z0-9]+//' So for: s/\d+[a-z]+@(?=\.)//g I need: s \d+[a-z]+@(?=\.) g and for: /[A-Za-z0-9]+/ It should be: [A-Za-z0-9]+ --- I tired ( std.string: split or format ) or ( std.regex split ). In fact I need to read from a stream up to a delimiter. Does someone knows a way to do this in D? Thanks So, you need to consume input one element at a time (delimited), dropping empty elements? Try std.algorithm.iteration splitter and filter: auto advance(Range)(ref Range r) { assert(!r.empty); auto result = r.front; r.popFront(); return result; } void main(string[] args) { import std.algorithm.iteration : splitter, filter; import std.range : empty; auto input = args[1].splitter('/').filter!"!a.empty"(); import std.stdio : writeln; while (!input.empty) writeln(input.advance()); } The advance() function reads the next delimited element and pops it from the range.
Re: Looking for an equivalent to C++ std::getline in D
On Saturday, 6 May 2017 at 10:15:03 UTC, k-five wrote: On Saturday, 6 May 2017 at 08:53:12 UTC, Jonathan M Davis wrote: On Saturday, May 6, 2017 8:34:11 AM CEST k-five via Digitalmars-d-learn wrote: On Friday, 5 May 2017 at 17:07:25 UTC, Stanislav Blinov wrote: > On Friday, 5 May 2017 at 09:54:03 UTC, k-five wrote: - Although I am not sure but it may Range in D, has the same concept that C++ has on iterator, like InputIterator or OutputIterator, since I realized that the output of [ filter ] does not have RandomAccessRange so I can not use input[ 0 ]. But I can use input.front(). Also thank you @Stanislav Blinov, I am familiar with lambda but have never seen a lambda in shape of string :) - Solving the problem by using split and empty in std.string or splitter in std.algorithm or splitter in std.regex plus filter in std.algorithm, and accessing the elements by: input.front() input.popFront() - for input: import std.stdio : print = writeln; import std.algorithm: filter; import std.string: split, empty; void main() { immutable (char)[] str = "one//two//three"; auto input = str.split( '/' ).filter!( element => !element.empty )(); print( input.front ); input.popFront(); print( input.front ); input.popFront(); print( input.front ); } the output is: one two three str.split('/') is eager, that is, it will iterate the input and return the array of delimited elements. So in fact you're getting an array of all elements (even empty ones), and then filtering it, ignoring empty elements. If you want to get the output as an array, it's better to use std.array as Jonathan mentioned: import std.array : array; auto inputArray = str.splitter('/').filter!(a => !a.empty)().array; This will eagerly consume the results of filter and put them into an array.
Re: Looking for an equivalent to C++ std::getline in D
On Saturday, 6 May 2017 at 08:34:11 UTC, k-five wrote: Also what is the parameter "a.empty" for template filter Jonathan covered the type part. As for that last bit, the filter template takes a predicate as parameter. This predicate is called for each input element, and if returns false, the element is ignored. The predicate can be a function, or, for example, a lambda: auto input = args[1].splitter('/').filter!((string s) { return !s.empty; })(); or a template lambda: auto input = arga[1].splitter('/').filter!((s) => !s.empty)(); By convention, predicates in Phobos can also be compile-time strings. In that case, std.functional.unaryFun is used to turn that string into a function. By default, unaryFun names the argument 'a', so the "!a.empty" will be expanded by unaryFun into (a) => !a.empty.
Re: How to get field default value at CT
On Saturday, 6 May 2017 at 21:40:24 UTC, Mike B Johnson wrote: I'd like to get the value assign to a field at CT. struct { int x = 3434; } I'd like to get the assigned "value" 3434 for x at CT. Use the .init property: struct S { int x = 3434; } unittest { static assert(S.init.x == 3434); } void main() { enum xAtCT = S.init.x; pragma(msg, xAtCT); }
Re: Equivalent to nullptr
In the meantime, you can get around the issue by redeclaring the function with another name and loading it manually just after calling DerelictSDL2.load(): import derelict.sdl2.sdl; __gshared SDL_bool function (const(SDL_Point)*, int, const(SDL_Rect)*, SDL_Rect*) SDL_EnclosePoints_; void main() { DerelictSDL2.load(); DerelictSDL2.bindFunc(cast(void**)_EnclosePoints_, "SDL_EnclosePoints"); // ... } Now you'd need to call SDL_EnclosePoints_ instead of SDL_EnclosePoints.
Re: site examples
On Thursday, 25 May 2017 at 15:41:47 UTC, crimaniak wrote: It seems to me that examples on the site require additional work and in the current form are counterproductive in terms of attracting new users. https://github.com/dlang/phobos
Re: Searching strings with indexOf vs countUntil
On Thursday, 25 May 2017 at 18:13:15 UTC, Anonymouse wrote: Part of the strings I'm working with can be assumed to be only ASCII, yes. indexOf only wants strings or char[]s, but interestingly if I use the same benchmark but have countUntil work on raw ubyte[]s, it is faster. See https://dpaste.dzfl.pl/2e095f7d18be. There's a less ugly cast in std.string: import std.string : representation; //(cast(ubyte[])line).countUntil(cast(ubyte[])" :"); line.representation.countUntil(" :".representation);
Re: Why would an initialised struct pointer field be null in the struct's destructor?
On Sunday, 21 May 2017 at 23:59:08 UTC, Guillaume Piolat wrote: On Sunday, 21 May 2017 at 12:48:10 UTC, Adam D. Ruppe wrote: Any struct should be able to have its destructor called Does this rule also applies to class objects? Yes. If your destructor does modify the state, you should expect it to be called and have the state ready for it. When you're using the GC, destructors *may* not be called under certain conditions: http://dlang.org/spec/class.html#destructors But there's no stopping you from destructing manually (via destroy() call), or by allocating classes manually via malloc or on the stack.
Re: Why would an initialised struct pointer field be null in the struct's destructor?
On Monday, 22 May 2017 at 00:23:26 UTC, Adam D. Ruppe wrote: On Sunday, 21 May 2017 at 14:13:20 UTC, Stanislav Blinov wrote: Not if you either emplace() or blit Foo.init into all of the array elements. You especially need to be safe calling ~this on Foo.init. How so? .init is supposed to be destructible without question. destroy() calls in the runtime also blit the initializer back over the destructed objects. std.algorithm.move et al. specifically take advantage of .init (blit it over the moved-from object, so it can either be destructed or assigned something else). I can't think of any case where you'd want preconditions on destructor when the object is in .init state.
Re: Why would an initialised struct pointer field be null in the struct's destructor?
On Monday, 22 May 2017 at 00:45:27 UTC, Adam D. Ruppe wrote: On Monday, 22 May 2017 at 00:36:24 UTC, Stanislav Blinov wrote: I can't think of any case where you'd want preconditions on destructor when the object is in .init state. I think we're actually saying the same thing: I mean the destructor must be callable on .init so you might do like struct Foo { int* ptr; ~this() { // might be called with ptr is null cuz of .init // so wanna check if(ptr !is null) free(ptr); } } Ah, yes, exactly. The page is indeed the same one. P.S. Though it's fine to call free with a null pointer :P
Re: Details on how aggregates are constructed with `new` and later destroyed by the GC
On Monday, 8 October 2018 at 11:19:40 UTC, Per Nordlöw wrote: And how this is related to the trait `hasElaborateConstructor` for both `classes` and `structs`. There's no such trait as far as I'm aware. If there were, it'd likely be checking for the presence of a '__ctor' member. Thing is, it can't be generic because ctors may be templates, the best that can be done is checking if `T` is constructible with some arguments `Args`. And how this is related to the trait `hasElaborateDestructor` for both `classes` and `structs`. It isn't. The trait literally just checks if the compiler has generated a '__dtor' member, and it doesn't do so for classes at all.
Re: LDC2 -I option results in unresolved externals
On Friday, 12 October 2018 at 07:32:26 UTC, Mike Parker wrote: DMD has the -i option which tells the compiler to automatically compile all imported modules. I don't know if LDC has anything similar. It does, same option.
Re: ported a sortable list from my old C code
On Saturday, 13 October 2018 at 11:11:41 UTC, Codifies wrote: Does anyone has any ideas on improving this sortable list Yes. Use an array. No, really, use an array. Now, really, use an array. If reallocations while building your paths become a problem, you can write a deque (bucket array) or a dlist. But still, afterwards just convert it to array and use that.
Re: Why is dynamic array length required here?
On Friday, 19 October 2018 at 02:04:37 UTC, Samir wrote: I am working my way through the exercises in the "Programming in D" tutorial (http://ddili.org/ders/d.en/arrays.html). Why is the line assigning the length of the dynamic array required? [...] Without the line: myArray.length = noValues; I get the run-time error... I would have thought that since this is a dynamic array, I don't need to pre-assign its length. Even though the array is dynamic, it doesn't have infinite storage. So you either: - preallocate required storage, like in that example code (note that it's not the same as making a fixed-size ('static') array: in your case you only learn what the required length is at run-time, as opposed to static arrays where you must know it at compile time) - don't preallocate, but instead append new elements like this: myArray ~= newValue; The latter isn't a universally "good" advice: it may cause reallocation every time you do that. That's why it's almost always best to preallocate in advance if you do know the length, or use something like std.array.appender that attempts to reduce memory reallocation. I'm not familiar with Ali's tutorials, maybe he talks about the appender in some future examples.
Re: need help about get all public static function name
On Monday, 22 October 2018 at 11:42:59 UTC, test wrote: some how when I call "is(typeof(__traits(getMember, BaseType, name))) " in the template, my code report others error like: Error: no property fromPointer for type void Error: template instance TypeTemplate!(BaseType) is used as a type Error: template instance `TypeTemplate!(BaseType)` error instantiating That would be hard to diagnose without actually seeing the code, it seems there's something else going on.
Re: need help about get all public static function name
On Monday, 22 October 2018 at 10:16:22 UTC, test wrote: I try use traits get all public static function of a struct pass to template... how to do this ? void allFunctions(T)() { import std.stdio; foreach (name; __traits(allMembers, T)) { static foreach (overload; __traits(getOverloads, T, name)) { static if (__traits(getProtection, overload) == "public" && __traits(isStaticFunction, overload)) { // 'overload' is an alias to a T's public static function writeln(name, ": ", typeof(overload).stringof); } } } }
Re: need help about get all public static function name
On Monday, 22 October 2018 at 10:49:10 UTC, test wrote: test1.d = alias Fn1 = void function(); struct XX { alias Fn= Fn1; // ... } 'Fn' is not a static function, it's a type. I.e. you can declare a function pointer with it: Fn func; test2.d = import test1; void GetPub(BaseType)(){ // ... } My code works fine with your struct XX, with dmd 2.082. std.traits.hasMember expects an aggregate *type*, but you're trying to pass as instance. A revised GetPub: void GetPub(BaseType)(){ static foreach (name; __traits(allMembers, BaseType)) static if( name[0] !is '_' && is(typeof(__traits(getMember, BaseType, name))) && __traits(getProtection, __traits(getMember, BaseType, name)) == "public" ) { //static assert( hasMember!(BaseType.init, name)); static assert(hasMember!(BaseType, name)); static if( __traits(isStaticFunction, __traits(getMember, BaseType, name)) ) { pragma(msg, BaseType.stringof ~ "." ~ name); } } } note the added check that the member is not a type: is(typeof(__traits(getMember, BaseType, name))). You'll still need to iterate overloads if you want to get all static functions.
Re: need help about get all public static function name
On Monday, 22 October 2018 at 12:03:22 UTC, test wrote: On Monday, 22 October 2018 at 11:59:21 UTC, test wrote: On Monday, 22 October 2018 at 11:42:59 UTC, test wrote: I try made a simple example but it has no error: I find the way to show the error: https://run.dlang.io/is/f8cULz import std.traits; struct FiberS { static auto getThis(){ return Fiber.getId(); } } struct Proxy(T){ T* ptr; alias getPayload this; @property ref auto getPayload() inout return { return * ptr ; } static auto getId(){ return 1; } } alias Fiber = Proxy!(FiberS); extern(C) void main(){ auto id = Fiber.getThis(); // work here } struct TcpStream { void read(ubyte[] data){ auto id = Fiber.getThis(); // not work here in my case } } Let's analyze this call: auto id = Fiber.getThis(); You're trying to call a static function 'getThis' on Fiber. The type 'Fiber' is really a Proxy!FiberS. Proxy doesn't have a static getThis() function. So the compiler tries an 'alias this', which forwards to a non-static member function getPayload(). To call that function, you need an instance of 'Proxy', which you don't have. I guess the first error message ("this for getPayload needs to be type Proxy not type TcpStream") just doesn't report that clearly.
Re: custom sorting of lists ?
On Friday, 19 October 2018 at 17:40:59 UTC, Carl Sturtivant wrote: If we imagine an Ordered Range being a finite Range of some kind with the additional property that its values are ordered (--- exact definition needed ---)... There's already a SortedRange: https://dlang.org/phobos/std_range.html#.SortedRange
Re: Can Scope Be Used for Anonymous Objects?
On Wednesday, 17 October 2018 at 20:53:02 UTC, Vijay Nayar wrote: This particular use of "scope" I overheard at the last DConf, and I believe it has been added to the official documentation here: https://dlang.org/spec/expression.html#new_expressions If a NewExpression is used as an initializer for a function local variable with scope storage class, and the ArgumentList to new is empty, then the instance is allocated on the stack rather than the heap or using the class specific allocator. Class-specific allocators (aka overriding 'new') were deprecated a long time ago, and this particular use of 'scope' should follow. Unfortunately, as with many other things in D, allocators, 'scope', DIP1000 etc are somewhere between here and there... I didn't know about the std.typecons scoped, it looks really useful, especially when you want to only create the object when short-circuiting fails, like in the middle of an "||" expression. One drawback of "scoped", however, is that it doesn't appear to warn you if you accidentally let the reference escape out of the function, unlike a scope variable. That's an artifact of it's implementation predating DIP25 and DIP1000, and those DIPs themselves not being realized fully. Why, exactly, is a trivial thing like this even a class? Porting C++ code which unfortunately makes heavy use of inheritance. I originally had this as a struct until I much later stumbled into the other classes that were inheriting from it. Ouch. If there aren't any virtual functions, you could "inherit" via struct inclusion and alias this. Or just take artistic... err... porting license and deviate from the original implementation :)
Re: Access program args outside of main
On Wednesday, 17 October 2018 at 22:30:31 UTC, Jordan Wilson wrote: Ideally, I'd check args before I take the time to load up data. https://dlang.org/phobos/core_runtime.html#.Runtime
Re: Can Scope Be Used for Anonymous Objects?
On Wednesday, 17 October 2018 at 20:24:56 UTC, Vijay Nayar wrote: I have a snippet of code like this: scope chordAngle = new S1ChordAngle(_center, other._center); return _radius + other._radius >= chordAngle; The reason the "scope" temporary variable exists is to avoid a heap allocation and instead prefer a value be created on the stack. Is there a way to do this inline? Why, exactly, is a trivial thing like this even a class?
Re: how to get UDA only for methods
On Wednesday, 17 October 2018 at 02:54:26 UTC, test wrote: I need get the Route UDA only for method without (static methods, property, constructor, destructor), dont know how to do it. 1) Note that __traits(allMembers, T) gets you a tuple of names, not actual member aliases. 2) Remember there may be overloads 3) Filter the unwanted out: import std.traits; import std.meta : Alias, AliasSeq; import std.stdio; import std.string : startsWith; import std.algorithm : among; alias operatorNames = AliasSeq!("opUnary", "opIndexUnary", "opCast", "opBinary", "opBinaryRight", "opIn", "opIn_r", "opEquals", "opCmp", "opCall", "opAssign", "opIndexAssign", "opOpAssign", "opIndexOpAssign", "opSliceOpAssign", "opIndex", "opSlice", "opDollar", "opDispatch"); void main() { writeln(getRoutes!App); } struct Route { string r; } Route[] getRoutes(T)(){ Route[] routes; foreach (name; __traits(allMembers, T)) { alias member = Alias!(__traits(getMember, T, name)); static if (__traits(isStaticFunction, member) || name.startsWith("__") || name.among(operatorNames)) {} else static if (is(typeof(member) == function)) { foreach (overload; __traits(getOverloads, T, name)) { pragma(msg, name); static foreach(route; getUDAs!(overload, Route)) { routes ~= route; } } } } return routes; } struct App { @Route("xxx") int field; @Route("/blah") this(this) {} @Route("ggg") ~this() {} @Route("/index") void home() {} @Route("/index2") void home(bool overloaded) {} @Route("/blog") void blog(){} }
Re: Error: non-shared method core.sync.condition.Condition.notify is not callable using a shared object
On Thursday, 18 October 2018 at 10:50:18 UTC, Paolo Invernizzi wrote: There's a rational behind the fact that there's not a 'shared' version of notify/wait method in Condition? They were implemented before complete `shared` spec existed, which is any time between it's conception and now.
Re: Dealing with ranges where front and popFront do the same logic / eager ranges
On Wednesday, 17 October 2018 at 09:53:22 UTC, Dukc wrote: Whatever iterates through the range could then throw an appopriate exception when it encounters an error token. Exceptions in a parser? Monsieur knows his perversion.
Re: When does GC run?
On Tuesday, 16 October 2018 at 09:38:44 UTC, John Burton wrote: The information I have found indicates that it runs to free memory when the system runs out of memory to allocate. No, that is incorrect. By default, here's what's happening: 1) At startup (or first 'new' or GC.malloc) the GC allocates a pool of memory. 2) Subsequent calls to 'new' or GC.malloc allocate from that pool. 3) If there isn't enough memory in the pool to allocate, it may either: a) Pause all your threads and perform a collection sweep, unless collection is disabled. If there's still not enough contiguous address space in the pool after that, it'll go to b) b) Ask the OS for more memory for the pool. Therefore, implicit automatic collection only occurs when you allocate, and only if needed. Explicit collection can be requested by calling GC.collect(). But will this try to use all the system memory or some other amount before trying to garbage collect? If I have a _lot_ of garbage, will it try to collect that before allocating any more system memory? Is this configurable in any way? If you have a lot of garbage, you should probably allocate in advance, disable/enable collection around hot paths and explicitly ask for collection in between, or just not use the GC, i.e. allocate a block and do your business inside of it.
Re: Who can stop it ? Help me,thank you.
On Wednesday, 17 October 2018 at 13:48:04 UTC, FrankLike wrote: What can I do? Delete the bloatware that you downloaded.
Re: struggling to link against a C global in D (win/vs2017)
On Monday, 29 October 2018 at 00:01:21 UTC, DanielG wrote: In my D app I'm declaring it this way: extern (C) { extern __gshared int myIntValue; int myIntFunc (int a, int b); } The function seems to link OK, but the C global will not. Should it be extern(Windows), perchance?.. (I haven't D on Windows for ages).
Re: how to make '==' safe for classes?
On Sunday, 28 October 2018 at 12:38:12 UTC, ikod wrote: and object.opEquals(a,b) do not inherits safety from class C properties, and also I can't override it. Yep. Since Object is the base class and it defines opEquals as: ``` bool opEquals(Object); ``` the compiler rewrites `a == b` as `(cast(Object)a).opEquals(cast(Object)ob)`, i.e. it inserts a @system call into your code. Is there clean way to use '==' here, or I have to convert this to a.opEquals(b) for classes, leaving '==' for structs? Pretty much, yes. "Implicit" value comparison in general is somewhat alien for classes, since they're reference types.
Re: expanding variadic into format
On Wednesday, 31 October 2018 at 12:13:57 UTC, Codifies wrote: On Wednesday, 31 October 2018 at 12:09:04 UTC, Stanislav Blinov wrote: ``` void printValue(Args...)(Font fnt, float x, float y, string frmt, auto ref Args args) { // ... import std.functional : forward; string message = format(frmt, forward!args); // ... } ``` thats fantastic thanks so much, can you explain a little more about whats going on here ? As rikki already explained, std.format is a variadic template, which gets expanded into argument list at compile time. That's why it can't be used with C-syle variadics: when you passed _arguments, the expansion treated that as a single argument instead of a tuple. Therefore, to forward arguments to std.format, your `printValue` must also be a variadic. There are, broadly speaking, two ways to pass arguments to functions: by value and by reference. When you make a template like this: void foo(T)(T value) { /* ... */ } it will take the argument by value, making copies when necessary: struct S { /* ... */ } S s; foo(S.init); // calls foo without copying, argument is constructed directly foo(s); // copies `s` and passes that copy to `foo` If that template is defined like this: void foo(T)(ref T value) { /* ... */ } then it will *only* take argument by reference: foo(S.init); // error, 'ref' cannot bind to rvalue foo(s); // no copy is made, `foo` takes `s` by reference There are more subtleties, especially when taking `const ref` arguments, but I won't get into those. There's a special syntax for template functions: `auto ref` arguments. Those are deduced to be by-value or by-reference at compile time (see https://dlang.org/spec/template.html#auto-ref-parameters): void foo(T)(auto ref T value) { /* ... */ } foo(S.init); // works, compiles as foo(S); foo(s); // works, compiles as foo(ref S); But, because inside of function definition all arguments are lvalues, you lose this additional information if you pass them to another function directly. To preserve that information, there's a `forward` template in std.functional. D doesn't have rvalue references, so that template will still copy the bits of non-`ref` arguments, but it will not call postblits, etc (it `move`s them using std.algorithm.mutation.move). So, there are two possible ways to implement your print: // Take all Args by value, i.e. copy everything first time void printValue(Args...)(Font fnt, float x, float y, string frmt, Args args) { // make copies of every argument in `args` (again) and pass those to `format` auto message = format(frmt, args); } or // Infer whether each argument is an lvalue or not void printValue(Args...)(Font fnt, float x, float y, string frmt, auto ref Args args) { import std.functional : forward; // preserve lvalue/rvalue string message = format(frmt, forward!args); } Both allow you to accomplish your goal, but the second one only copies the argument bits when necessary. Getting into finer implementation nuances, conceptually this allows a function to even take and pass around non-copyable types as arguments. Sadly, this is not widely adopted by Phobos, which likes to make unnecessary copies. I.e. the `format` function itself takes Args by value, even though it probably should take advantage of this specific language feature. But at least calling it via `forward`, you only make necessary copies once, instead of twice.