Re: How to use destroy and free.
On Monday, 25 April 2022 at 14:25:17 UTC, H. S. Teoh wrote: On Mon, Apr 25, 2022 at 01:28:01PM +, Alain De Vos via Digitalmars-d-learn wrote: Could thc or hboehm provide solutions ? In general, GC (of any kind) does not (and cannot) guarantee the order objects will be collected in. So in the dtor, you cannot assume that any objects you depend on still exist (they may have already been collected). There is also no guarantee that the object will *ever* get collected: in theory, the GC may only collect just enough to make space for further allocations, it's not obligated to collect *everything* that's collectible. Or the collection might not take place before the end of the program -- the GC may skip the final collection because it knows the OS will reclaim everything automatically anyway. Basically, deterministic destruction and GC are antithetical to each other, and trying to have both is the road to trouble. If you wish to have deterministic destruction, don't use the GC; use RAII or reference counting instead. T When you can foresee a "maximum size" , you can create "deterministic" stack objects. ``` class C { @nogc this(){} @nogc this(int dummy){}; @nogc int[3] fixarr=new int[3]; }//C @nogc void myfun(){ int a; scope c = new C(); scope c2 = new C(5); }//myfun void main(){ myfun(); }//main ``` It's just the variable length arrays which are "problematic". Feel free to elaborate.
Re: Assigning to array of structs with custom constructor
On 4/25/22 21:32, Salih Dincer wrote: > So the problem is that the structure is not in the inter-module space Nested structs carry an additional pointer to their containing context. When they don't need the context, we define them with 'static': void foo() { static struct Bar { } } > If ```sruct Foo {}``` is not taken outside of ```main()``` it will fail > for many possibilities! Only if the struct needs the context. Otherwise, nested structs should be defined with 'static' and there is no issue with map... Ali
Re: Assigning to array of structs with custom constructor
😀 So the problem is that the structure is not in the inter-module space On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote: This works: ```d import std; void main() { struct Foo { string s; } Foo[] arr = ["abc", "def", "ghi"].map!Foo.array; arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")] } ``` If ```sruct Foo {}``` is not taken outside of ```main()``` it will fail for many possibilities! **For example:** Error: cannot access frame pointer of `source.main.Foo` SDB@79
Re: Assigning to array of structs with custom constructor
On 4/25/22 19:37, Salih Dincer wrote: > a lot of errors 😀 Hm. I can't reproduce any of that. I did two things: 1) Added necessary import directives 2) Moved all expressions into the main() function I did not change anything else. The program below compiles and works with all these compilers: - dmd 2.098.1 - dmd 2.099.1 - gdc 11.2.0 - ldc 1.28.1 (based on DMD v2.098.1 and LLVM 13.0.1) Are you using a very old compiler? import std.range; import std.algorithm; import std.conv; import std.stdio; struct Bar { string s; this(R)(R result) { import std.conv : to; this.s = result.to!string; } string toString() { return s; } } void main() { auto parts = "abcdefghi".chunks(3); auto compiled = parts.map!(a => Bar(a)); // NOTE: PLEASE IGNORE THE ERROR MESSAGES BELOW. // EVERYTHING COMPILES AND WORKS. auto notCompile1 = parts.map!Bar; /* Error 1: instantiated from here: `map!(Chunks!string)`*/ auto notCompile2 = parts.map!(c => c.to!string) .map!Bar; /* Error 1: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604) : cannot access frame pointer of `source.main.Bar` Error 2: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499) : template instance `std.algorithm.iteration.MapResult!(Bar, MapResult!(__lambda4, Chunks!string))` error instantiating Error 3: instantiated from here: `map!(MapResult!(__lambda4, Chunks!string))` */ auto notCompile3 = parts.array.map!Bar; /* Error 1: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604) : cannot access frame pointer of `source.main.Bar` Error 2: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(616) : cannot access frame pointer of `source.main.Bar` Error 3: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499) : template instance `std.algorithm.iteration.MapResult!(Bar, Take!string[])` error instantiating Error 4: instantiated from here: `map!(Take!string */ auto arr = compiled.array; /* [abc, def, ghi] auto arr2 = str.chunks(3) .map!(a => Bar(a)) .array;//*/ arr.writeln(": ", typeof(arr).stringof); } Ali
Re: Assigning to array of structs with custom constructor
On Tuesday, 26 April 2022 at 00:57:54 UTC, Ali Çehreli wrote: On 4/25/22 16:59, Salih Dincer wrote: > Because it cannot be used with other possibilities such as > ```chunks()``` and ```take()```. There must be something wrong. map is commonly used with chunks(), take(), etc. > Also it cannot be customized with > ```toString()```. Can you show examples of these please? Of course, I have a few friends here: and a lot of errors 😀 ```d struct Bar { string s; this(R)(R result) { import std.conv : to; this.s = result.to!string; } string toString() { return s; } } auto parts = "abcdefghi".chunks(3); auto compiled = parts.map!(a => Bar(a)); auto notCompile1 = parts.map!Bar; /* Error 1: instantiated from here: `map!(Chunks!string)`*/ auto notCompile2 = parts.map!(c => c.to!string) .map!Bar; /* Error 1: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604) : cannot access frame pointer of `source.main.Bar` Error 2: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499) : template instance `std.algorithm.iteration.MapResult!(Bar, MapResult!(__lambda4, Chunks!string))` error instantiating Error 3: instantiated from here: `map!(MapResult!(__lambda4, Chunks!string))` */ auto notCompile3 = parts.array.map!Bar; /* Error 1: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(604) : cannot access frame pointer of `source.main.Bar` Error 2: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(616) : cannot access frame pointer of `source.main.Bar` Error 3: /usr/src/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(499) : template instance `std.algorithm.iteration.MapResult!(Bar, Take!string[])` error instantiating Error 4: instantiated from here: `map!(Take!string */ auto arr = compiled.array; /* [abc, def, ghi] auto arr2 = str.chunks(3) .map!(a => Bar(a)) .array;//*/ arr.writeln(": ", typeof(arr).stringof); ``` SDB@79
Re: Get UDAs of self's declaration as a member?
On 4/25/22 14:32, cc wrote: > Hard to word this question right, but is it possible to get the UDAs > assigned to a class/structure's member variable declaration, within that > variable's definition? e.g. That sounds backwards to me too. :) Policy-based design can work here: import std.stdio; import std.traits; enum SPECIAL { no, yes } struct Foo(SPECIAL special = SPECIAL.no) { void foo() { static if (special == SPECIAL.yes) writeln("special"); else writeln("not special"); } } struct Bar { Foo!(SPECIAL.yes) foo; } alias FooSpecial = Foo!(SPECIAL.yes); alias FooRegular = Foo!(SPECIAL.no); void main() { Foo!() foo;// <-- Without the aliases FooSpecial foo_; // <-- Better syntax with aliases foo.foo; Bar bar; bar.foo.foo; } Ali
Re: How to use destroy and free.
On 4/25/22 16:02, frame wrote: > On Monday, 25 April 2022 at 02:07:50 UTC, Ali Çehreli wrote: >> > import core.memory: GC; >> GC.free(GC.addrOf(cast(void *)(i.ptr))); >> That is wrong because you did not allocate that address yourself. > > Hmm? The GC did allocate here(?) Yes. I still don't understand the need to free GC memory explicitly. I can understand GC.collect() but not the memory of a specific array. >> On 4/24/22 17:26, Salih Dincer wrote: >> >> >MEM.free(i.ptr); >> >// You don't need to addrOf(cast(void*)i) > > Wrong. You are right. I missed the fact that addrOf is a GC function. Ali
Re: Assigning to array of structs with custom constructor
On 4/25/22 16:59, Salih Dincer wrote: > Because it cannot be used with other possibilities such as > ```chunks()``` and ```take()```. There must be something wrong. map is commonly used with chunks(), take(), etc. > Also it cannot be customized with > ```toString()```. Can you show examples of these please? > I guess even when ```this()``` constructor is added, > ```map()``` explodes! Ah! Now I tried *removing* Bar.this and the compilation failed. Perhaps you left the working code in? (?) For others: 1) Remove Bar.this 2) The code will fail below: auto arr2 = "abcdefghi" .chunks(3) .map!(a => Bar(a)) <-- ERROR .array; Error: cannot implicitly convert expression `a` of type `Take!string` to `string` One confusing thing is the fact that we learn that chunks uses take in its implementation. I think it's cool but a newcomer may be confused with where that Take comes from. Let's put that aside. Then the compilation error is easy to understdand because chunks returns a range itself but it is not possible to make a Bar from a range. I don't agree that this is a problem with map's usability. The type system doesn't know what to do. Here is one way of fixing the issue, not surprisingly, with map itself. ;) import std.conv : to; auto arr2 = "abcdefghi" .chunks(3) .map!(c => c.to!string) // <-- ADDED .map!(a => Bar(a)) .array; Or, one can use a single map expression: auto arr2 = "abcdefghi" .chunks(3) .map!(a => Bar(a.to!string)) // <-- COMBINED .array; Or, a function can be called, etc. But to remove a misunderstanding, map can be used with most other range algorithms, in the standard library, provided by the programmer, etc. Ali
Re: std.typecons Typedef initializers?
On Monday, 25 April 2022 at 23:41:47 UTC, Chris Katko wrote: So to use a typedef'd struct... I have to basically add the original type on top of the typedef'd type every time? Surely it's not this clunky? I mean, why even use a typedef then. Why not use just pair, sPair, vPair, etc as separate types with identical members and cast as necessary? I'm not sure what the benefit typedef is adding here. Thanks It could just be an oversight in implementation and worth submitting an enhancement request on bugzilla. Current implementation only defines a constructor that takes rvalue of original type, while what it ought to be doing is defining a variadic template constructor that would forward the arguments to underlying type's constructor. To be fair, as far as your example code goes, it'd almost be easier to indeed simply duplicate the implementations, but have the compiler do it for you, e.g. like this: ```d enum Space { unspecified, screen, viewport, } struct TPair(Space space) { float x, y; } alias Pair = Pair!(Space.unspecified); alias sPair = Pair!(Space.screen); alias vPair = Pair!(Space.viewport); ```
Re: Assigning to array of structs with custom constructor
On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote: ```d import std; void main() { struct Foo { string s; } Foo[] arr = ["abc", "def", "ghi"].map!Foo.array; arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")] } ``` Thank you... Very very nice and simple but not extensible! Because it cannot be used with other possibilities such as ```chunks()``` and ```take()```. Also it cannot be customized with ```toString()```. I guess even when ```this()``` constructor is added, ```map()``` explodes! So it not to explode, it is necessary to move away from simplicity: ```d import std.algorithm; import std.range, std.stdio; void main() { struct Foo { string s; /* string s; string toString() { return s; }//*/ } auto arr1 = ["abc", "def", "ghi"] .map!Foo.array; /* .map!(a => Foo(a)) .array;//*/ typeof(arr1).stringof.writeln(": ", arr1); struct Bar { string s; //* this(R)(R result) { import std.conv : to; this.s = result.to!string; }//*/ string toString() { return s; } } auto arr2 = "abcdefghi" .chunks(3) .map!(a => Bar(a)) .array; typeof(arr2).stringof.writeln(": ", arr2); } /* OUTPUT: Foo[]: [Foo("abc"), Foo("def"), Foo("ghi")] Bar[]: [abc, def, ghi] */ ``` SDB@79
Re: std.typecons Typedef initializers?
On Monday, 25 April 2022 at 12:53:14 UTC, Mike Parker wrote: On Monday, 25 April 2022 at 08:54:52 UTC, Chris Katko wrote: D struct pair { float x,y; } alias sPair = Typedef!pair; // pair of xy in screen space coordinates alias vPair = Typedef!pair; // pair of xy in viewport space coordinates //etc How do you initialize a typedef'd struct? ``d vPair v1 = vPair(pair(1f, 2f)); ``` So to use a typedef'd struct... I have to basically add the original type on top of the typedef'd type every time? Surely it's not this clunky? I mean, why even use a typedef then. Why not use just pair, sPair, vPair, etc as separate types with identical members and cast as necessary? I'm not sure what the benefit typedef is adding here. Thanks
Re: How to use destroy and free.
On Monday, 25 April 2022 at 02:07:50 UTC, Ali Çehreli wrote: > import core.memory: GC; GC.free(GC.addrOf(cast(void *)(i.ptr))); That is wrong because you did not allocate that address yourself. Hmm? The GC did allocate here(?) On 4/24/22 17:26, Salih Dincer wrote: >MEM.free(i.ptr); >// You don't need to addrOf(cast(void*)i) Wrong. Good point about i.ptr but that free() does not or should not do anything because it is "memory not originally allocated by this garbage collector": https://dlang.org/phobos/core_memory.html#.GC.free Well... maybe it was allocated by that garbage collector and may be it points to the beginning of an allocated block but we don't know that. I wouldn't call free() on an array's memory. Ali And if it was, the freeing must be done with `GC.addrOf` or it will fail with larger arrays. You will need the GC address to free the block. That is what `__delete` actually does - which was patched back recently, reported by Adam: https://issues.dlang.org/show_bug.cgi?id=21550
Re: Assigning to array of structs with custom constructor
On Monday, 25 April 2022 at 15:23:12 UTC, Ali Çehreli wrote: auto arr = iota(10).map!(i => Foo(i.text)).array; On Monday, 25 April 2022 at 16:11:47 UTC, rassoc wrote: Foo[] arr = ["abc", "def", "ghi"].map!Foo.array; Ahh that'll do it alright, thanks
Get UDAs of self's declaration as a member?
Hard to word this question right, but is it possible to get the UDAs assigned to a class/structure's member variable declaration, within that variable's definition? e.g. ```d import std.stdio; import std.traits; enum SPECIAL; struct Foo { void foo() { static if (hasUDA!(typeof(this), SPECIAL)) writeln("special"); else writeln("not special"); } } struct Bar { @SPECIAL Foo foo; } void main() { Foo foo; foo.foo; Bar bar; bar.foo.foo; } ``` This doesn't work of course, `@SPECIAL` isn't applied to `struct Foo` itself so no UDA is found by `hasUDA!Foo`. Without iterating Bar directly, is there some way to detect *within* Foo's member functions, that the Foo being called is declared with `@SPECIAL` inside its parent structure?
Re: Assigning to array of structs with custom constructor
On 4/25/22 16:36, cc via Digitalmars-d-learn wrote: ```d struct Foo { string s; this(string s) { this.s = s; } } Foo foo = "a"; Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to `Foo[]` Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type `string` to type `Foo` ``` Was there a way to do this? I thought I recalled seeing something like this before, but I can't seem to find it. This works: ```d import std; void main() { struct Foo { string s; } Foo[] arr = ["abc", "def", "ghi"].map!Foo.array; arr.writeln; // => [Foo("abc"), Foo("def"), Foo("ghi")] } ```
Re: Linked list, printing looks destructive.
Indeed code below works, ``` import std.stdio: write,writeln; class Node { int data; Node next; } class List { Node node=null; this(int[] AR){foreach(i ; AR)pushfront(i);} void pushfront(int data) { Node newnode=new Node(); newnode.data=data; newnode.next=node; node=newnode; }//pushfront int opApply(int delegate(typeof(Node.data)) dg) { Node current = node; while (current) { if (dg(current.data)) return 1; current = current.next; } return 0; }//opApply }//List void main(){ List l=new List([3,2,1]); foreach(element; l) writeln(element); foreach(element; l) writeln(element); }//main ```
Re: Linked list, printing looks destructive.
On Monday, 25 April 2022 at 01:40:01 UTC, Alain De Vod wrote: Following program is a single linked list. We expect as output 1 2 3 1 2 3 But the output is only 1 2 3 ``` If you don't need List to be treated as a true range, but just want to iterate, a simple way to do this is with opApply: https://tour.dlang.org/tour/en/gems/opdispatch-opapply ```d import std.stdio: write,writeln; import std.range: empty,popFront,front; struct Node { int element; Node * next; } class List { Node * root=null; this(int[] AR){foreach(i ; AR)pushfront(i);} bool empty() const {return !root;} /*void popFront() {root=root.next;} float front() const {return root.element;}*/ void pushfront(int element) { Node * newnode=new Node(); newnode.element=element; newnode.next=root; root=newnode; } int opApply(int delegate(typeof(Node.element)) dg) { Node* current = root; while (current) { if (dg(current.element)) return 1; // stop iteration if the foreach body asks to break current = current.next; } return 0; } }//List void main(){ List l=new List([3,2,1]); foreach(element; l) writeln(element); foreach(element; l) writeln(element); } // 1 2 3 1 2 3 ```
Re: Assigning to array of structs with custom constructor
On 4/25/22 07:36, cc wrote: > ```d > struct Foo { > string s; > this(string s) { this.s = s; } > } > Foo foo = "a"; I don't understand why that syntax exists. I always write it like this: auto foo = Foo("a"); > Foo[] foos = ["a"]; // Error: cannot implicitly convert expression > `["a"]` of type `string[]` to `Foo[]` This is a way: Foo[] foos = [Foo("a")]; Or: import std.stdio; import std.algorithm; import std.range; import std.conv; auto arr = iota(10).map!(i => Foo(i.text)).array; writeln(arr); Ali
Re: Assigning to array of structs with custom constructor
On Monday, 25 April 2022 at 15:13:51 UTC, Stanislav Blinov wrote: Make it explicit: ```d Foo[] foos = [Foo("a")]; ``` There's that too, but I still have to iterate manually. e.g.: ```d string[] ss = loadABunchOfStringsFromSomewhere(); //Foo[] foos = ss; //error Foo[] foos; foos.reserve(ss.length); foreach (s; ss) foos ~= Foo(s); ``` Was just hoping there was a way to streamline it within the struct definition.
Re: Linked list, printing looks destructive.
On 4/25/22 03:48, Salih Dincer wrote: > It is also possible with the copy constructor of a struct. I don't know > how to do with class... Classes don't have language provided construction because nobody needs it and in fact they have to protect themselves when a language provides it. (See, e.g. C++'s slicing problem: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-copy-virtual ) [1] In case you want to copy a class object, you must provide a function yourself, which may be called anything you want or 'dup' to match with a name used by D. Ali Off-topic rant: It frustrates me when C++ programmers shun D because it is "a language with reference types" as told to me by a well-known C++ speaker. I guess they should attempt to read C++'s core guidelines to understand how a polymorphic class makes it an accident to pass its objects by value.
Re: Assigning to array of structs with custom constructor
On Monday, 25 April 2022 at 14:36:25 UTC, cc wrote: ```d struct Foo { string s; this(string s) { this.s = s; } } Foo foo = "a"; Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to `Foo[]` Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type `string` to type `Foo` ``` Was there a way to do this? I thought I recalled seeing something like this before, but I can't seem to find it. Make it explicit: ```d Foo[] foos = [Foo("a")]; ```
Re: Assigning to array of structs with custom constructor
On Monday, 25 April 2022 at 15:00:13 UTC, Alain De Vos wrote: Not really an answer but this works, ``` void main(){ Foo foo = "a"; Foo[] foos; foos ~=foo; }% ``` Right, I can append individual elements, but can't assign or append a slice of a type that can be individually cast to the struct.
Re: Assigning to array of structs with custom constructor
Not really an answer but this works, ``` struct Foo { string s; this(string s) { this.s = s; } } void main(){ Foo foo = "a"; Foo[] foos; foos ~=foo; }% ```
Assigning to array of structs with custom constructor
```d struct Foo { string s; this(string s) { this.s = s; } } Foo foo = "a"; Foo[] foos = ["a"]; // Error: cannot implicitly convert expression `["a"]` of type `string[]` to `Foo[]` Foo[] foos = cast(Foo[]) ["a"]; // Error: e2ir: cannot cast `"a"` of type `string` to type `Foo` ``` Was there a way to do this? I thought I recalled seeing something like this before, but I can't seem to find it.
Re: How to use destroy and free.
On Mon, Apr 25, 2022 at 01:28:01PM +, Alain De Vos via Digitalmars-d-learn wrote: > Could thc or hboehm provide solutions ? In general, GC (of any kind) does not (and cannot) guarantee the order objects will be collected in. So in the dtor, you cannot assume that any objects you depend on still exist (they may have already been collected). There is also no guarantee that the object will *ever* get collected: in theory, the GC may only collect just enough to make space for further allocations, it's not obligated to collect *everything* that's collectible. Or the collection might not take place before the end of the program -- the GC may skip the final collection because it knows the OS will reclaim everything automatically anyway. Basically, deterministic destruction and GC are antithetical to each other, and trying to have both is the road to trouble. If you wish to have deterministic destruction, don't use the GC; use RAII or reference counting instead. T -- What do you mean the Internet isn't filled with subliminal messages? What about all those buttons marked "submit"??
Re: How to use destroy and free.
Could thc or hboehm provide solutions ?
Re: How to use destroy and free.
GC-allocated objects are run (when they are run). If you need deterministic destruction e.g. for resource management, do not use GC. Descend destroy and free functions should return something. "destroy" should return if the destructor was called successfully. "free" should return the exact number of bytes freed on the heap. Probably this is not implemented in the library because it is probably "buggy".
Re: How to implement private constructor
On Monday, 25 April 2022 at 07:19:31 UTC, bauss wrote: Yes and in addition to Ali's message then remember it's private for the module only. Oops typo. What I meant is that private is module level, so it's __not__ private in the module, but it is for other modules. Thanks for the reply. Got it. All I wanted to implement more than ctor with different parameters and avoid code duplication.
Re: How to implement private constructor
On Monday, 25 April 2022 at 02:22:42 UTC, Ali Çehreli wrote: Looks good to me. There are other ways as well: Thanks a lot. All I wanted to implement more than ctor with different parameters and avoid code duplication.
Re: std.typecons Typedef initializers?
On Monday, 25 April 2022 at 08:54:52 UTC, Chris Katko wrote: D alias sPair = Typedef!pair; // pair of xy in screen space coordinates alias vPair = Typedef!pair; // pair of xy in viewport space coordinates //etc This doesn't do what you think it does. Both `sPair` and `vPair` are the same type. If you want to create two distinct `Typedef`s from the same base type, you must use the optional `cookie` argument, as shown in [the examples in the documentation:][1] ```d alias MoneyEuros = Typedef!(float, float.init, "euros"); alias MoneyDollars = Typedef!(float, float.init, "dollars"); // The two Typedefs are _not_ the same type. static assert(!is(MoneyEuros == MoneyDollars)); ``` [1]: https://phobos.dpldocs.info/std.typecons.Typedef.html#examples
Re: std.typecons Typedef initializers?
On Monday, 25 April 2022 at 08:54:52 UTC, Chris Katko wrote: D struct pair { float x,y; } alias sPair = Typedef!pair; // pair of xy in screen space coordinates alias vPair = Typedef!pair; // pair of xy in viewport space coordinates //etc How do you initialize a typedef'd struct? ``d vPair v1 = vPair(pair(1f, 2f)); ```
Re: How to use destroy and free.
On Monday, 25 April 2022 at 10:13:43 UTC, Alain De Vos wrote: Ali, thanks for the answer but i rephrase my question. How to destroy,free , for garbage-collection-cycle in the destructor of this code : // But How to force destroy and free , GC-cycle for heap object i ? Short answer: use `destroy`. Long answer: don't do that. https://dlang.org/spec/class.html#destructors GC is not guaranteed to call destructors, and in fact it may run into situations when it can't (i.e. objects pointing to one another). Neither does it specify in what order destructors of GC-allocated objects are run (when they are run). If you need deterministic destruction e.g. for resource management, do not use GC.
Re: How to use destroy and free.
Note, heap object i is not an instance of the class C
Re: Linked list, printing looks destructive.
On Monday, 25 April 2022 at 09:38:05 UTC, Alain De Vos wrote: This program works ok, (but List is no Range) It is also possible with the copy constructor of a struct. I don't know how to do with class... ```d struct Node { int element; Node * next; } struct List { Node * root, walker; this(int[] AR) { foreach(i; AR) { pushfront(i); } } bool empty() const { return !walker; } void popFront() { walker = walker.next; } float front() const { return walker.element; } void pushfront(int element) { Node * newnode = new Node(); newnode.element = element; newnode.next = root; root = newnode; } // shallow copy this(ref return scope List that) { this.walker = that.root; } }//List import std.stdio; void main() { List list = List([3,2,1]); //Node backupnode=l.node; foreach(l; list) l.writeln(); //l.node=backupnode;//Restore state destroyed by writeln foreach(l; list) l.writeln(); } ``` SDB@79
Re: How to use destroy and free.
On Monday, 25 April 2022 at 10:13:43 UTC, Alain De Vos wrote: destructor of this code : ```d ~this(){ writeln("Free heap"); import object: destroy; import core.memory: GC; i=null; // But How to force destroy and free , GC-cycle for heap object i ? }; ``` If you use destroy in destructor (~this), it will call destructor two times but thats not error. SDB@79
Re: How to use destroy and free.
Ali, thanks for the answer but i rephrase my question. How to destroy,free , for garbage-collection-cycle in the destructor of this code : ``` import std.stdio: writeln; class C{ int[] i=null; this(){ writeln("Allocate heap"); i=new int[1]; writeln(typeid(typeof(i))); writeln(typeid(typeof(i.ptr))); i[9000]=5; } ~this(){ writeln("Free heap"); import object: destroy; import core.memory: GC; i=null; // But How to force destroy and free , GC-cycle for heap object i ? }; } struct S{ C c; @disable this(); this(int dummy){c=new C;} } void main(){ enum _=0; writeln(S(_).c.i[9000]); } ```
Re: Linked list, printing looks destructive.
This program works ok, (but List is no Range) ``` class Node { int data; Node next; } class List { Node node=null; this(int[] AR){foreach(i ; AR)pushfront(i);} bool empty() const {return !node;} void popFront() {node=node.next;} float front() const {return node.data;} void pushfront(int data) { Node newnode=new Node(); newnode.data=data; newnode.next=node; node=newnode; } }//List void main(){ List l=new List([3,2,1]); Node backupnode=l.node; l.writeln(); l.node=backupnode;//Restore state destroyed by writeln l.writeln(); } ```
std.typecons Typedef initializers?
D struct pair { float x,y; } alias sPair = Typedef!pair; // pair of xy in screen space coordinates alias vPair = Typedef!pair; // pair of xy in viewport space coordinates //etc void test() { pair v0 = pair(1f, 2f); // works fine, but what about the typedefs? vPair v1 = vPair(1f, 2f); //nope vPair v2 = Typedef!vPair(1f, 2f); //nope } How do you initialize a typedef'd struct?
Re: Linked list, printing looks destructive.
On Monday, 25 April 2022 at 05:17:28 UTC, Salih Dincer wrote: On Monday, 25 April 2022 at 02:19:46 UTC, Ali Çehreli wrote: This type violates a fundamental rule: Containers and ranges are separate concepts. Your List is a container, not a range. I changed your code by moving the range functions to a Range [...] Dear Ali, I implemented a linkedlist over classical logic (*_leaf and const *_root). Now seeing the ranges approach I tried it but without success. The following implementation can work with foreach() though; as long as you call goRoot() :) ```d class List(dType) { struct Node { dType item; Node* next; } bool FIFO; private Node * _leaf; this(bool FIFO = true, dType item = dType.init) { this.FIFO = FIFO; if(FIFO) _leaf= new Node(item, null); _root = cast(const)_leaf; } /* auto opSlice() { return Range(_leaf); } static struct Range {//*/ const Node * _root; auto empty() { return !_leaf; } auto popFront() { return _leaf = _leaf.next; } dType front(Node * node = null) { dType result; if(node) { result = (*node).item; } else result = (*_leaf).item; return result; } //} alias Next = popFront; alias pop = front; alias push = InsertBack; void InsertBack(dType item) { _leaf = new Node(item, _leaf); } void InsertFront(dType item) { (*_leaf).next = new Node(item, null); Next; } auto goRoot() { return _leaf = cast(Node*)_root.next; } } import std.stdio; enum FIFO { False, True } enum end = 20; void main() { int firstNumber = 10; auto FIFO_Stack = new List!int; with(FIFO_Stack) { do { InsertFront(firstNumber); } while(++firstNumber <= end); goRoot(); do pop.writef!" %s"; while(Next); writeln; } FIFO_Stack.goRoot(); foreach(stack; FIFO_Stack) { stack.writeln; } } /* OUTPUT: 10 11 12 13 14 15 16 17 18 19 20 10 11 12 13 14 15 16 17 18 19 20 */ ``` SDB@79 I implemented an alternative goroot it's called re_init and next program works. Still I don't understand what is really going on. Some state is lost using a class and you have restore it. And the state is not lost using a struct. ``` cat test.d import std.stdio: write,writeln; import std.range: empty,popFront,front; struct Node { int element; Node * next; } class List { Node * root=null; Node * walker=null; this(int[] AR){foreach(i ; AR)pushfront(i);} bool empty() const {return !walker;} void popFront() {walker=walker.next;} float front() const {return walker.element;} void pushfront(int element) { Node * newnode=new Node(); newnode.element=element; newnode.next=root; root=newnode; re_init(); } void re_init(){walker=root;} }//List void main(){ List l=new List([3,2,1]); l.writeln(); l.re_init(); l.writeln(); } ```
Re: How to implement private constructor
On Monday, 25 April 2022 at 07:18:44 UTC, bauss wrote: On Monday, 25 April 2022 at 00:18:03 UTC, Vinod K Chandran wrote: Hi all, Please take a look at this code. Is this the right way to use private constructors ? ```d class Foo { int p1 ; string p2 ; bool p3 ; private this(int a, string b, bool c) { this.p1 = a this.p2 = b this.p3 = c } this(int a) { this(a, "some string", true); } this(int a, string b) { this(a, b, true); } } ``` Yes and in addition to Ali's message then remember it's private for the module only. Oops typo. What I meant is that private is module level, so it's __not__ private in the module, but it is for other modules.
Re: How to implement private constructor
On Monday, 25 April 2022 at 00:18:03 UTC, Vinod K Chandran wrote: Hi all, Please take a look at this code. Is this the right way to use private constructors ? ```d class Foo { int p1 ; string p2 ; bool p3 ; private this(int a, string b, bool c) { this.p1 = a this.p2 = b this.p3 = c } this(int a) { this(a, "some string", true); } this(int a, string b) { this(a, b, true); } } ``` Yes and in addition to Ali's message then remember it's private for the module only.