Why does foreach allow ref element for non-ref front() of std.range.enumerate()
import std; import std.range; void main() { int[] a = [3, 5, 7]; foreach (i, ref ae; a.enumerate) { writeln(i, " ", ae); ae = 6; } writeln(a); assert(a[].equal([6, 6, 6])); // fails, a is in initial state } Why does the compiler allow such 'ref ae' loop, if the actual value is not a reference? Or it is a reference to hidden stack variable that was copied by enumerate from a during front()?
Re: Bitfields
On Tuesday, 21 May 2019 at 17:16:05 UTC, Russel Winder wrote: Hi, Has anyone used D to work with arbitrary length bitfields with multiple occurences of a sub-bitfield. I am working with DVB Sections and EIT packets are defined as bitfields with loops in them and the header is 112 bits. The loops are handleable with subfields obviously, assuming you can work out how the bigendian works on the byte sequence. As far as I can see std.bitmanip only caters for 8, 16, 32, and 64 bit long bitfields. Never used it myself, but BitArray with careful handling of endianess might fit your task. https://dlang.org/phobos/std_bitmanip.html#.BitArray.this.2 https://dlang.org/phobos/std_bitmanip.html#.peek
Re: Tweakig -lowmem to be more eager
On Sunday, 19 May 2019 at 23:54:27 UTC, Anonymouse wrote: What makes it decide to collect? What triggers it? You can try setting heapSizeFactor option to something lower than 2 to increase collection frequency: https://github.com/dlang/druntime/blob/47b03c14a1097d28afcf22f645628ba4046377bd/src/core/gc/config.d#L26 https://dlang.org/spec/garbage.html#gc_config dmd appears to respect DRT_GCOPT environment variable. The logic behind the decision to collect, I'm afraid, is not described anywhere but the code itself (https://github.com/dlang/druntime/blob/47b03c14a1097d28afcf22f645628ba4046377bd/src/gc/impl/conservative/gc.d#L1690)
Re: Linked List iterating over and inserting an element around (before/after) the current position.
On Sunday, 19 May 2019 at 22:20:48 UTC, Josh wrote: This is just more curiosity, but do you happen to know why I have to use DList.linearRemove() instead of DList.remove()? These two functions are separate because they differ in complexity. remove is O(1), linearRemove on the other hand eagerly walks through the Take range, wich makes it O(take.walklength).
Re: Anonymous mapped regions increases unlimitely on spawn
On Friday, 14 December 2018 at 21:22:05 UTC, unDEFER wrote: So it looks like a bug, and I have reported about it: https://issues.dlang.org/show_bug.cgi?id=19487 Not an expert, but you may wish to try GC.minimize() (https://dlang.org/phobos/core_memory.html#.GC.minimize).
Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?
On Thursday, 13 December 2018 at 09:51:42 UTC, aliak wrote: Ie: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { this.value = value; } } void main() { auto a = Container!S(S(3)); // can't do this. } I can build a custom constructor for Container that makes this work: static auto construct(Args...)(auto ref Args args) { import std.algorithm: move; auto value = T(args); auto opt = Container!T.init; opt.value = move(value); return move(opt); } And then "auto a = Container!T.construct(3);" works. But is there a way to do it without adding a custom constructor type? Cheers, - Ali You can just move in container constructor: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { import std.algorithm: move; this.value = value.move; } } void main() { auto a = Container!S(S(3)); }
Re: Throwing constructors and member destructors
On Tuesday, 20 November 2018 at 13:20:08 UTC, Stanislav Blinov wrote: https://dlang.org/changelog/2.083.0.html#reboot14246 Wording "object" means both classes and structs?
Re: Throwing constructors and member destructors
On Tuesday, 20 November 2018 at 13:20:08 UTC, Stanislav Blinov wrote: https://dlang.org/changelog/2.083.0.html#reboot14246 Nvm, found the info in the issue tracker, thank you for the link.
Throwing constructors and member destructors
https://run.dlang.io/is/LdylJX Notice no "B destructor" line in stdout. Just got bitten by the assumption that my Buffer struct that transactionally aquires multiple external resources in constructor will rollback via member destructors that were successfully completed before the throw. Can I get a clarification about current semantics? Should I essentially never throw in constructors if I want to rely on scope-based RAII? And before we start a 10-page argument about the ideology of constructors, I would mostly just like to hear that this is documented somewhere, because I have certanly missed it.
Re: custom sorting of lists ?
On Sunday, 14 October 2018 at 01:31:26 UTC, Jonathan M Davis wrote: Unless there's something about the implementation that's tied to the list itself, I would think that it would make more sense to make it a generic algorithm, then it will work with any non-random-access range, and it avoids needing to reimplement it for similar circumstances. IMHO, it really only makes sense to tie it to the container if the implementation itself needs to be for some reason. - Jonathan M Davis All operations on collections are tied to implementation. Phobos just intorduced range abstraction that hides iteration code (and is still implemented by collection itself). Iteration is only a small part of functionality that one expects from the data structure. I'm against operation generalization, collections have little in common besides basic semantics of insertion, they should provide their own methods. It is the lack of such methods that is more disheartening. And the lack of cursor\iterator concept, wich maps well to mutation semantics of lists\trees.
Re: Use nested functions as callbacks with Windows API functions?
On Monday, 1 October 2018 at 23:07:29 UTC, spikespaz wrote: The problem with the code you have is that the callback needs to be extern (Windows). I don't know how to do that with a "lambda". Neither do I actually. Apparently it is impossible. Best I could squeeze out was this: https://run.dlang.io/is/CpyfW3
Re: Use nested functions as callbacks with Windows API functions?
On Monday, 1 October 2018 at 20:27:43 UTC, spikespaz wrote: I was hoping I could use something more akin to JavaScript's syntax: (void* hWnd, long) => {}. I tried this but I'm getting errors with the signature, it says the function is a delegate and apparently Windows API can't accept a delegate. You can make it a non-delegate by passing a pointer to hWndList in lParams as it was supposed to by WinApi devs, instead of zero, and not implicitly capturing stack pointer by referencing hWndList directly from the body. https://run.dlang.io/is/t4k4Nc
Re: why use string for this example of appender?
On Monday, 16 April 2018 at 06:46:36 UTC, WhatMeForget wrote: Another thing that had me wondering is the use of put() down below; doesn't the append syntax (~=) give you the same exact functionality; so why bother? Appender also performs unicode-related conversions, so you can append dstring to string and vice-versa, wich may come in handy.
Re: Optional parameters?
On Sunday, 1 April 2018 at 22:44:45 UTC, Jonathan M Davis wrote: Which doesn't work in @safe code and doesn't work when you have an rvalue as you would when passing 42. Ultimately, using pointers ultimately either requires explicitly allocating stuff on the heap to be able to pass rvalues, or it has the same restrictions that ref does in terms of passing rvalues. You can certainly take that approach if you'd like, but overall, I think that it's safe to say that using Nullable generally causes fewer problems. 1). There's nothing wrong with @trusted. 2). Rvalue it trivially converted to lvalue on the stack using local variable. 3). You haven't shown syntax for passing null. Pointer is foo(null). Yours will probably be foo(nullable!int()); 4). I certanly wouldn't like typing nullable(...) for each optional parameter, I see it as a much bigger problem.
Re: Optional parameters?
On Sunday, 1 April 2018 at 22:25:45 UTC, Jonathan M Davis wrote: How would a pointer help? Instead of doing foo(nullable(42)) he'd have to do foo(new int(42)) which is just one character shorter and ends up allocating on the heap, unlike with Nullable. - Jonathan M Davis foo(&x);
Re: Optional parameters?
On Sunday, 1 April 2018 at 15:54:16 UTC, Steven Schveighoffer wrote: I currently have a situation where I want to have a function that accepts a parameter optionally. I would simply use a pointer for this. Fighting D grammar seems too much of a hassle for such simple task.
Re: Fast GC allocation of many small objects
On Friday, 30 March 2018 at 20:31:35 UTC, Per Nordlöw wrote: Is there a faster way of allocating many small class objects such as... maybe something like this: import std.conv: to; import std.stdio; class Node {} class StrNode : Node { string value; } void main() { writeln(StrNode.classinfo.name);// onlineapp.StrNode size_t il = StrNode.classinfo.m_init.length; writeln(il); // 32 void[] backBuf = new void[il * 1000]; StrNode[] nodes = new StrNode[1000]; for (int i = 0; i < 1000; i++) { backBuf[i * il .. (i+1) * il] = StrNode.classinfo.m_init; nodes[i] = cast(StrNode) &backBuf[i * il]; nodes[i].value = i.to!string; } foreach (n; nodes[995..$]) writeln(n.classinfo.name, " ", n.value); // prints onlineapp.StrNode 995-999 }
Re: "in" no longer "scope" since 2.079.0?
On Tuesday, 27 March 2018 at 09:27:07 UTC, Jonathan M Davis wrote: On Tuesday, March 27, 2018 09:15:43 Boris-Barboris via Now that DIP 1000 is being implemented, and scope is actually going to do something for more than just delegates, it was deemed too dangerous to have in suddenly really mean both scope and const, because it would potentially break a lot of code. So, in order to prevent such breakage, in was changed to officially only mean const instead of const scope. https://issues.dlang.org/show_bug.cgi?id=17928 - Jonathan M Davis Well, here I am, writing "in" everywhere in anticipation of DIP1k ) But I guess "do not break" at this point is indeed more important. Thanks.
"in" no longer "scope" since 2.079.0?
Hello! Can someone point me to the changelong entry or maybe a pull request, wich changed the "in" from "scope const" to "const"? I thought the previous matter of things was pretty natural, and current "in" is now redundant. Would be glad to read up on this design decision. https://docarchives.dlang.io/v2.078.0/spec/function.html#parameters https://docarchives.dlang.io/v2.079.0/spec/function.html#parameters
Re: opDispatch with string mixin does not work as I would expect.
On Saturday, 10 February 2018 at 06:32:43 UTC, German Diago wrote: The mixin line does not work. I want to generate the access to the field. How could I achieve that? struct Outer { struct Inner { int a; float b; } Inner i; auto opDispatch(string name)() { return __traits(getMember, i, name); } }
Re: Using Postgres connection functions
On Saturday, 13 January 2018 at 17:58:14 UTC, Joe wrote: ...ddb. The latter perhaps has the distinction that it doesn't use libpq, but rather implements the Postgres FE/BE protocol. That's a bit *too* native for my taste. It means the library maintainer has to keep up with changes to the internal protocol, which although published, the Postgres group doesn't have to maintain compatibility from version to version. Not that it matters, but client-server protocol is actually the most stable one, it hasn't changed since Postgress 7.4 (Release date: 2003-11-17). It's the language-level abstractions like libpq that keep being changed\updated on almost each release.
Re: struct template constructors
On Thursday, 22 June 2017 at 21:16:40 UTC, Ali Çehreli wrote: And yes, there should be one destructor, which may be a no-op if you grab its resource and set it to null. On all compilers... That's a relief, thank you for your help.
Re: struct template constructors
On Thursday, 22 June 2017 at 20:05:46 UTC, Ali Çehreli wrote: To be complete, 'auto ref' passes lvalues by reference and rvalues by value, which you can detect with __traits(isRef): struct S{ } void foo()(auto ref S s) { static if (__traits(isRef, s)) { pragma(msg, "lvalue"); } else { pragma(msg, "rvalue"); } } void main() { auto s = S(); foo(s); foo(S()); } Ali Thank you very much! And the last question: Is it guaranteed an all compilers, that: 1). destructor for said rvalue is called only once. 2). function taking auto ref parameter gets that exact (memory-wise) rvalue, for example: struct S {} S produce() { return S(); } consume(produce()); void consume(auto ref S s) { // s passed by value, but is exactly that struct returned by produce, as if it // was RVO'd inside consume's stack frame. // and S destructor called only once on consume's scope escape? }
Re: struct template constructors
On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote: No time to think about the rest of the design but just to get the code compiled, replace 'ref' with 'auto ref' like so: Ok, looks like this indeed passes rhs by reference, thank you. destcalls - number of times UniquePtr destructor was called deallocs - number of times internal pointer was freed. unittest { deallocs = destcalls = 0; class A {} class B: A {} { UniquePtr!B b = UniquePtr!B.make(); assert(b.owner); { UniquePtr!A a = b; assert(!b.owner); assert(a.owner); assert(destcalls == 0); assert(deallocs == 0); } assert(destcalls == 1); assert(deallocs == 1); } assert(destcalls == 2); assert(deallocs == 1); }
Re: struct template constructors
On Thursday, 22 June 2017 at 19:17:13 UTC, Ali Çehreli wrote: No time to think about the rest of the design but just to get the code compiled, replace 'ref' with 'auto ref' like so: this(DT)(scope auto ref UniquePtr!DT rhs) { // ... } Ali i added this static variable: static int destcalls = 0; changed constructor to: this(DT)(scope auto ref UniquePtr!DT rhs) { // here rhs releases pointer pragma(msg, typeof(rhs)); } wich prints "UniquePtr!(B)" on my machine, and destructor: ~this() { destcalls++; } Following code compiles and runs ok: class A {} class B: A {} UniquePtr!A a = UniquePtr!A.make(); assert(destcalls == 0); UniquePtr!A b = UniquePtr!B.make(); assert(destcalls == 1); Destructor is called for the result of "UniquePtr!B.make();", and if it actually was passed by value (wich is indicated by pragma's output), b's internal pointer would refer to freed heap block.
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 19:11:19 UTC, Cym13 wrote: Here it's the programmer's fault really. You should never use casts in normal code, cast is the ultimate switch to say "Look, I know what I'm doing, so disable all safety, don't try to make sense of it, and let me do my thing. If I'm telling you it's a cat, then it is dammit.". You can't blame the type system not to do something coherent here, you explicitely went out of your way to lie to that very same type system in the most unsafe way possible. We're on the same page, I just think that ability to lie is part of the type system, that's all.
struct template constructors
Hi https://dpaste.dzfl.pl/0def4e286564 Is there a cleaner way to go than the one on the line 26? And why is the constructor /d475/f781.d(37): f781.UniquePtr!(A).UniquePtr.__ctor(DT)(ref scope UniquePtr!DT rhs) unfit for line 51? Is it because the expression " = UniquePtr!B.make()" cannot be interpreted as "scope ref"? It must release ownership of a pointer it holds, and looks like it cannot do it in this form.
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 13:56:29 UTC, ag0aep6g wrote: For example, the type system guarantees that immutable data never changes. But the compiler allows you to cast from immutable to mutable and change the data. It's an invalid operation, but the compiler is not expected to catch that for you. Casts are part of the type system. Yes, D type system allows invalid operations. It's not the compiler's fault, it's type system's fault. unittest { immutable int a = 4; int* b = cast(int*) &a; *b = 5; assert(*(&a) == 5); assert(a == 4); }
Re: Dealing with the interior pointers bug
On Thursday, 22 June 2017 at 09:45:09 UTC, Russel Winder wrote: I think the term "systems programming language" contains no actual data, so needs to be retired. In this situation it provides no reason for conservative garbage collection. It means the intent of language designer to let you write operating system with his language, wich implies certain building blocks available to you. Whether it actually allows it or not is another question. Why should any language allow anything outside the type system. Everything the language allows to compile is allowed by it's type system, or is a bug in the compiler. Strong typing means strong typing Define strong typing then. Pointer is part of the type system, all casts and operations on it are too. If you pass wrongly-typed pointer, it won't compile. Maybe then the fault is having a weak type system, as any language is that allows ints to be pointers and vice versa. What's wrong with pointers in a language? You're not forced to use them, you know? But some tasks force you. If you seek compile-time verifyability, use different coding patterns \ languages, designed around this intent. Maybe type systems should be strong and all FFI be by value with no references to memory allowed? No, they definetly should not. Why can't GC use staticaly available type info (all pointer\reference variables and fields are visible in program text, why not just scan only them)? I don't know, probably it's harder, since it requires more cooperation between compiler and runtime, and increases GC signature (you have to store a huge list of pointers to all pointers on all stacks (and probably heap too), and compiler should generate code to populate this list on every function call). At this point you would be better off with RAII, wich will be more efficient and explicit and do exactly what you tell it to do.
Re: D structs weak identity and RAII
On Monday, 19 June 2017 at 06:34:49 UTC, Ali Çehreli wrote: It's unreliable because structs are value types in D, which means that they can be moved around freely. This is why self-referencing structs are illegal in D. I guess it's more like the spec states, that they can be moved vithout notice. Value type semantics themselves do not mean spontaneous uncontrolled mobility. I can't claim expertise but here is a quick and dirty proof of concept that Vittorio Romeo and I had played with a few weeks ago: ... shared byte b; // to prevent compiler optimizations struct UniquePtr { void * p; this(void * p) { this.p = p; import core.atomic; core.atomic.atomicOp!"+="(b, 1); } Very interesting hack, thank you. Note how post-blit is disabled there. In addition to a moveFrom(), that's exactly what Atila Neves had to do in this automem library as well: https://github.com/atilaneves/automem Nice, thanks.
D structs weak identity and RAII
Hello, I was trying to write some templated unique pointers. Idea was simple: struct UniquePointer that handles underlying pointer in RAII-style and WeakPointer struct that is spawned by UniquePointer. Weak pointer is handled differently in my collections, wich subscribe to the event of UniquePointer destruction, so that there are no dangling references left all over the heap (I use Mallocator). Collection's insertFront\Back methods register callbacks in Weak pointer itself, and all existing weak pointers are registered in Unique pointer. That, unfortunately, failed at the very beginning. Then I wrote a unit test to investigate: https://dpaste.dzfl.pl/d77c72198095 1). line 47 and 76 together mean, that there is basically no reliable way to write uniqueptr method wich returns WeakPointer, registered by the correct pointer in it's constructor. Or is there? Is usage of &this in constructor (or in struct methods in general) fundamentally unreliable in D? 2). postblit was never called when returning struct from function. I noticed it was called once on line 91, if i removed opAssign with ref argument. What are the rules? Why is it always called when passing struct to function and creating local copy of the parameter (lines 113, 127, 139), and why is opAssign not called? 3). Is there a way to reliably encapsulate all assignments? Looks like complete mess will happen should I apply some std.algorithm functions on array of structs with overloaded operators. 4). Any suggested workarounds? I never tried it in C++, but, IIRC, struct life cycle is much more consistent there ang gives the strict control I desire. 5). If all this is a design choice, what is the reason behind it?
Re: DList efficiency
On Thursday, 8 June 2017 at 22:42:14 UTC, Boris-Barboris wrote: 1). Do I understand correctly, that there is currently no way (aside from editing the sources of course) to efficiently (using one underlying iteration) remove all\first element(s) from DList based on a predicate? Oh, sorry, I guess I didn't search thoroughly enough: https://github.com/dlang/phobos/blob/master/std/container/dlist.d#L769
DList efficiency
Good day to you reader! I have a couple questions about Phobos: 1). Do I understand correctly, that there is currently no way (aside from editing the sources of course) to efficiently (using one underlying iteration) remove all\first element(s) from DList based on a predicate? Can such operation be performed for arrays using std.algorithm (though in array case it can at least be done manually)? 2). Was the idea of range types, that allow underlying structure modification ever considered ("remove element from the collection being iterated and shift to next element" is first candidate). 3). Is there a container library featuring alternative concepts, namely, iterators?
Re: protected behaviour on base class member access from another module
Ok, sorry, look's like that was always the case in C++, so it's too late to question it. I'll just elevate it to package, I guess.
protected behaviour on base class member access from another module
Hi! I have a base class in module A: module A; ... class GuiElement: GuiComponent { protected { GuiElement _parent; ... } template isGuiElement(T) { enum isGuiElement = is(T: GuiElement); } ... and derived class in module B: module B; ... class Div(uint dim, uint odim): GuiElement { protected GuiElement[] children; this(Children...)(GuiManager manager, Children kids) if (allSatisfy!(isGuiElement, Children)) { super(manager); children = [kids]; this._parent = null; <- This works foreach (kid; children) kid._parent = this;<- Error: class A.GuiElement member _parent is not accessible A couple of questions: 1). Is this intended? 2). If yes, why? What is the reasoning behind such restriction? Quoting the docs: "...a symbol can only be seen by members of the same module, or by a derived class...". 3). What does the cryptic "If accessing a protected instance member through a derived class member function, that member can only be accessed for the object instance which can be implicitly cast to the same type as ‘this’" mean? Let's say B derives from A, and B instance has a method that accesses A.protected_member inside of it. What does member access have to do with it? Why does this sentence jump from member to method, back to member, and then to some object that was never mentioned before? Objects don't request access, statements do. `this` of who?
Re: strange CFTE issue
On Sunday, 9 April 2017 at 16:44:41 UTC, ag0aep6g wrote: Or you can make it a template value parameter [2] with type `string[]`: string[] sfilter(T, string[] fields)() { string[] result; foreach (f; aliasSeqOf!fields) { /* ... loop body as you have it ... */ } return result; } Thank you, I didn't even expect it was possible, array as a template parameter is quite foreign to me after C++. Function parameters are never usable in static contexts. Good to know, thank you. So, there are no exceptions to this, even when parameter is very simple numeric type value?
Re: strange CFTE issue
On Wednesday, 15 March 2017 at 17:27:35 UTC, ag0aep6g wrote: Phobos has it: std.meta.aliasSeqOf "converts an input range [...] to an alias sequence." [1] Woops, forgot to give the URL for that "[1]". Here it is: http://dlang.org/phobos/std_meta.html#aliasSeqOf Hello, I have a similar problem. For the life of me I can't make CTFE work while manipulating collections. Source: import std.meta; import std.traits; template isFunctionField(OwnerType, string field_name) { enum isFunctionField = isFunction(mixin(OwnerType.stringof ~ "." ~ field_name)); } string[] sfilter(T)(string[] fields) { string[] result; foreach (f; fields) { enum isfunc = isFunctionField!(T, f); // variable f cannot be read at compile time. // Even when I change isFunctionField from template to function that returns // bool and takes "string field_name". if (isfunc) result ~= f; } return result; } string[] TypeFields(T)() pure { enum field_names = [__traits(allMembers, T)]; pragma(msg, typeof(field_names)); // prints string[] pragma(msg, field_names); // prints correct member names enum filtered = sfilter!(T)(field_names); return filtered; } //then I call it by: enum fields = TypeFields!(SomeStruct)(); I can get string array of class members allright. Whenever I try to do any logic with it, I fail. I get that "enum field_names = " is not lvalue. How should I pass it to sfilter? When I change foreach loop into for loop, I can't index "string[] fields" array since "variable fields cannot be read at compile time". Should I pass field_names string array as some other type, AliasSeq or something? The thing is, on some level inside TypeFields, I will need to mutate array, I can't stick to tuples. I tried declaring array parameters immutable, but CTFE forbids casting from mutable into immutable. I'm kinda out of ideas.