Re: scope(~this)
On Sunday, 12 March 2017 at 21:38:44 UTC, Inquie wrote: Is there any easy way to create a scope for termination of the object? I have a template method that takes a type and allocates and deallocates based on that type. class bar { void foo(T)() { T x; alloc(x); scope(~this) dealloc(x); // hypothetical that wraps the statement in a lambda and deallocates in the destructor ... x must stay allocated until class instance termination(has to do with COM, can't release it in foo) } } Now, x cannot be a field because T is unknown(i suppose I could use object, void*, etc, but...). If it is COM then you should use IUnknown (the COM root interface),or if you are expecting multiple calls to foo, an array of IUnknown. I think the GC will clean up completely for you in either case and call release(?) on the member(s). Also as it is COM you probably don't need to template it, just choose T to be the most recent ancestor of all (old) T's you would be expecting foo to be instantiated with (e.g. IUnknown if you expect any COM object.
Declaring interfaces with a constructor
What it says on the tin. Is there a way to create interfaces with a constructor or must I use an abstract class. Additionally, is there a way to force the linker to link a function in a class without an implementation with another that does have an implementation? i.e. --- //module a; class Foo { void fun(); } import b: Foo; //module b; class Foo { void fun() { import std.stdio; writeln("!"); } } --- Or something like this? Thanks.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 21:12:13 UTC, data pulverizer wrote: On Sunday, 12 March 2017 at 20:15:43 UTC, Meta wrote: auto max(T: const U, U)(T* x, T* y) <- Changed `ConstOf!U` to `const U` { writeln("Const template"); return *x > *y ? x : y; } How detailed can I be about the template specialisation? From example in the book "C++ the complete guide" we can have: /* pointer const reference */ template inline T* const& max(T* const& a, T* const) { return a* < b* ? b : a; } /* const reference const pointer */ template inline T const* const& max(T* const* const& a, T* const* const& b) { ...; } What would be the equivalent in D? Unfortunately this is impossible in D as const is transitive. The best you can do is try to emulate it using wrapper types. I'd start by taking a look at std.experimental.typecons.Final, which implements C++-style head (logical) constness.
Re: how to assign tuple named Tuple easily
On Monday, 13 March 2017 at 00:02:12 UTC, Inquie wrote: I just figured it didn't work in general, but seems to be an issue with appending. Oh, it is because of the implicit construction thing, see my answer here to learn more: http://stackoverflow.com/a/42285015/1457000 You can construct the named tuple from a tuple() but you can't convert one to another since the names change the type. I don't think the language has a solution with this since you can't implicit construct nor overload operators on built in arrays (if it is a custom array, you can do an opOpAssign). What you could do is alias ShortName = Tuple!(int, "A"); ShortName[] a; a ~= ShortName(3); ... of course, at that point, you can also just use a regular struct too...
Re: how to assign tuple named Tuple easily
On 03/13/2017 01:02 AM, Inquie wrote: Ok, it doesn't work for appending though ;) [...] Tuple!(int, "A", double, "B")[] y; y ~= tuple(3, 2.5); Interestingly, this works: Tuple!(int, "A", double, "B")[] y; y.length += 1; y[$ - 1] = tuple(3, 2.5);
Re: how to assign tuple named Tuple easily
On Sunday, 12 March 2017 at 23:55:44 UTC, Adam D. Ruppe wrote: On Sunday, 12 March 2017 at 23:16:48 UTC, Inquie wrote: Tuple!(int, "A") x; x = tuple(3); fails of course umm it works for me... Ok, it doesn't work for appending though ;) Tuple!(int, "A", double, "B")[] y; y ~= tuple!("A", "B")(3, 2.5); vs Tuple!(int, "A", double, "B")[] y; y ~= tuple(3, 2.5); I just figured it didn't work in general, but seems to be an issue with appending.
Re: how to assign tuple named Tuple easily
On Sunday, 12 March 2017 at 23:16:48 UTC, Inquie wrote: Tuple!(int, "A") x; x = tuple(3); fails of course umm it works for me...
Re: scope(~this)
On Sunday, 12 March 2017 at 22:13:21 UTC, Stefan Koch wrote: On Sunday, 12 March 2017 at 21:38:44 UTC, Inquie wrote: Is there any easy way to create a scope for termination of the object? [...] scope(exit) That is for the function, correct? If I release the resource at the end of the function, the COM interface will no longer be valid. It must be done when the class terminates, not the function.
Re: scope(~this)
On Sunday, 12 March 2017 at 21:38:44 UTC, Inquie wrote: Is there any easy way to create a scope for termination of the object? [...] scope(exit)
scope(~this)
Is there any easy way to create a scope for termination of the object? I have a template method that takes a type and allocates and deallocates based on that type. class bar { void foo(T)() { T x; alloc(x); scope(~this) dealloc(x); // hypothetical that wraps the statement in a lambda and deallocates in the destructor ... x must stay allocated until class instance termination(has to do with COM, can't release it in foo) } } Now, x cannot be a field because T is unknown(i suppose I could use object, void*, etc, but...). I realize there are ways to work around this. I will create lambdas that release them since that is easiest. I could return x but that creates a mess. Hoping that either something like this exists or could be a feature enhancement.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 20:15:43 UTC, Meta wrote: auto max(T: const U, U)(T* x, T* y) <- Changed `ConstOf!U` to `const U` { writeln("Const template"); return *x > *y ? x : y; } How detailed can I be about the template specialisation? From example in the book "C++ the complete guide" we can have: /* pointer const reference */ template inline T* const& max(T* const& a, T* const) { return a* < b* ? b : a; } /* const reference const pointer */ template inline T const* const& max(T* const* const& a, T* const* const& b) { ...; } What would be the equivalent in D?
Re: Template specialisation for range of types
Meta wrote: On Sunday, 12 March 2017 at 20:22:33 UTC, ketmar wrote: Meta wrote: The reason this doesn't work is when you use ConstOf!U, it's not looking for a `const U`, it's looking for the type `ConstOf!U`. I'm not sure if this is a bug or not... no, not a bug. this is the way type deconstruction works: it checks if your type was constructed with a given template. Yeah, it seems to be checking the pattern rather than the type. However, ConstOf!T is just an alias for const(T), but the alias does not seem to be "unwrapped", even though they are supposed to be transparent. yeah. "eponymous template" trick.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 20:22:33 UTC, ketmar wrote: Meta wrote: The reason this doesn't work is when you use ConstOf!U, it's not looking for a `const U`, it's looking for the type `ConstOf!U`. I'm not sure if this is a bug or not... no, not a bug. this is the way type deconstruction works: it checks if your type was constructed with a given template. Yeah, it seems to be checking the pattern rather than the type. However, ConstOf!T is just an alias for const(T), but the alias does not seem to be "unwrapped", even though they are supposed to be transparent.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 20:15:43 UTC, Meta wrote: import std.stdio : writeln; import std.traits : ConstOf; auto max(T)(T x, T y) { writeln("General template"); return x > y ? x : y; } auto max(T: const U, U)(T* x, T* y) <- Changed `ConstOf!U` to `const U` { writeln("Const template"); return *x > *y ? x : y; } void main(){ const double p = 2.4, q = 3; writeln(max(, )); //Prints "Const template" } This is great Meta, thanks very much! I was trying to avoid using template constraints because the more cases you add, the more complicated the constraints get.
Re: Template specialisation for range of types
Meta wrote: The reason this doesn't work is when you use ConstOf!U, it's not looking for a `const U`, it's looking for the type `ConstOf!U`. I'm not sure if this is a bug or not... no, not a bug. this is the way type deconstruction works: it checks if your type was constructed with a given template.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 18:49:22 UTC, data pulverizer wrote: Hello all, I am attempting to write templates for differently qualified types using specialisations. Below is an example for const and non-const outlining my approach: `` import std.stdio : writeln; import std.traits : ConstOf; auto max(T)(T x, T y) { writeln("General template"); return x > y ? x : y; } auto max(T: ConstOf!U, U)(T* x, T* y) { writeln("Const template"); return *x > *y ? x : y; } void main(){ const double p = 2.4, q = 3; writeln(max(, )); } `` I get this output: General template 7FFE5B3759A8 In this case would like to use the ConstOf specialisation instead of the default implementation for the inputs which are const. Thanks for you answers in advance You need to make one little change for this to work: import std.stdio : writeln; import std.traits : ConstOf; auto max(T)(T x, T y) { writeln("General template"); return x > y ? x : y; } auto max(T: const U, U)(T* x, T* y) <- Changed `ConstOf!U` to `const U` { writeln("Const template"); return *x > *y ? x : y; } void main(){ const double p = 2.4, q = 3; writeln(max(, )); //Prints "Const template" } The reason this doesn't work is when you use ConstOf!U, it's not looking for a `const U`, it's looking for the type `ConstOf!U`. I'm not sure if this is a bug or not... Anyway, this will also work if we change the following: void main(){ ConstOf!double p = 2.4, q = 3; <- Changed `const double` to `ConstOf!double` writeln(max(, )); //Prints "Const template" }
Re: Code style for property
On Sunday, 12 March 2017 at 17:50:41 UTC, Stefan wrote: On Sunday, 12 March 2017 at 10:47:35 UTC, Andrey wrote: Hello, how better to declare properties, for example I have class: class Foo { this(in int x, in int y, Bar bar) { this.x = x; this.y = y; this.bar = bar; } private: int x; int y; Bar bar; } Andrey, you could try https://github.com/funkwerk/accessors We use it to avoid clutter. Stefan Wow! that's great! thank you so much!
Re: Template specialisation for range of types
data pulverizer wrote: I need at least those two implementation for the different cases, a general "default", and for specified types and type qualifications. p.s.: if you want that to work with both pointers and non-pointers, you have to add more constraints, to remove further conflicts.
Re: Template specialisation for range of types
data pulverizer wrote: If I change the implementation of the second template to your above declaration, I get the error: max.max called with argument types (const(double)*, const(double)*) matches both: max.d(34): max.max!(const(double)*).max(const(double)* x, const(double)* y) and: max.d(42): max.max!double.max(const(double)* x, const(double)* y) I need at least those two implementation for the different cases, a general "default", and for specified types and type qualifications. 'cause your templates are for different types, so they both matches. i wrote only about type deconstruction. the following will work: import std.stdio : writeln; import std.traits : Unqual; auto max(T)(T* x, T* y) if (is(T == Unqual!T)) { writeln("General template"); return *x > *y ? x : y; } auto max(T)(T* x, T* y) if (is(T == const)) { writeln("Const template"); return *x > *y ? x : y; } void main () { const double p = 2.4, q = 3; writeln(max(, )); } note the change in the first template.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 19:32:37 UTC, ketmar wrote: data pulverizer wrote: In this case would like to use the ConstOf specialisation instead of the default implementation for the inputs which are const. actually, second template is uninstantiable at all. you want to do type deconstruction at instantiation, and that doesn't work. i.e. what your code wants to do (as it is written) is to have `T` in second template to be equal to `double`. you cannot deconstruct the type like that in template. what you *can* do, though, is this: auto max(T)(const(T)* x, const(T)* y) this way it will select your second template. If I change the implementation of the second template to your above declaration, I get the error: max.max called with argument types (const(double)*, const(double)*) matches both: max.d(34): max.max!(const(double)*).max(const(double)* x, const(double)* y) and: max.d(42): max.max!double.max(const(double)* x, const(double)* y) I need at least those two implementation for the different cases, a general "default", and for specified types and type qualifications.
Re: Template specialisation for range of types
data pulverizer wrote: In this case would like to use the ConstOf specialisation instead of the default implementation for the inputs which are const. actually, second template is uninstantiable at all. you want to do type deconstruction at instantiation, and that doesn't work. i.e. what your code wants to do (as it is written) is to have `T` in second template to be equal to `double`. you cannot deconstruct the type like that in template. what you *can* do, though, is this: auto max(T)(const(T)* x, const(T)* y) this way it will select your second template.
Re: Template specialisation for range of types
On Sunday, 12 March 2017 at 18:49:22 UTC, data pulverizer wrote: Hello all, I am attempting to write templates for differently qualified types using specialisations. Below is an example for const and non-const outlining my approach: `` import std.stdio : writeln; import std.traits : ConstOf; auto max(T)(T x, T y) { writeln("General template"); return x > y ? x : y; } auto max(T: ConstOf!U, U)(T* x, T* y) { writeln("Const template"); return *x > *y ? x : y; } void main(){ const double p = 2.4, q = 3; writeln(max(, )); } `` I get this output: General template 7FFE5B3759A8 In this case would like to use the ConstOf specialisation instead of the default implementation for the inputs which are const. Thanks for you answers in advance Wouldn't just putting const infront work?
Template specialisation for range of types
Hello all, I am attempting to write templates for differently qualified types using specialisations. Below is an example for const and non-const outlining my approach: `` import std.stdio : writeln; import std.traits : ConstOf; auto max(T)(T x, T y) { writeln("General template"); return x > y ? x : y; } auto max(T: ConstOf!U, U)(T* x, T* y) { writeln("Const template"); return *x > *y ? x : y; } void main(){ const double p = 2.4, q = 3; writeln(max(, )); } `` I get this output: General template 7FFE5B3759A8 In this case would like to use the ConstOf specialisation instead of the default implementation for the inputs which are const. Thanks for you answers in advance
Re: Code style for property
On Sunday, 12 March 2017 at 10:47:35 UTC, Andrey wrote: Hello, how better to declare properties, for example I have class: class Foo { this(in int x, in int y, Bar bar) { this.x = x; this.y = y; this.bar = bar; } private: int x; int y; Bar bar; } Andrey, you could try https://github.com/funkwerk/accessors We use it to avoid clutter. Stefan
Re: GDC options
Am Sun, 12 Mar 2017 12:09:01 + schrieb Russel Winder via Digitalmars-d-learn: > Hi, > > ldc2 has the -unittest --main options to compile a file that has > unittests and no main so as to create a test executable. What causes > the same behaviour with gdc? > https://github.com/D-Programming-GDC/GDMD/tree/dport gdmd -unittest --main The unittest flag for GDC is -funittest but there's no flag to generate a main function. gdmd generates a temporary file with a main function to implement this. -- Johannes
Re: Code style for property
On Sunday, 12 March 2017 at 11:15:04 UTC, Nicholas Wilson wrote: You should only declare getters/setters if you need to (or think you may need to later) intercept the assignment or acquisition of a variable (logging, computing on demand) have a field as externally read only (setter only) otherwise you should have the variables as normally assignable. What about it? @property FrameRect margin() { return p_margin; } @property void margin(in vec4 val) { p_margin = FrameRect(val); } @property void margin(in FrameRect val) { p_margin = val; } or I started to use public members and after I wanted make some optimizations, I need rewrite my public member to property like this: @property vec2 position() { return p_position; } @property void position(vec2 val) { p_position = val; needUpdateMatrices = true; } @property float rotation() { return p_rotation; } @property void rotation(float val) { p_rotation = val; needUpdateMatrices = true; } @property vec2 scaling() { return p_scaling; } @property void scaling(vec2 val) { p_scaling = val; needUpdateMatrices = true; } @property vec2 pivot() { return p_pivot; } @property void pivot(vec2 val) { p_pivot = val; needUpdateMatrices = true; } But code with this public members has spread throughout the project, e.g.: obj.position += vec2(2, 3); obj.rotation -= pi/2; In that case I need to spend a lot more time than if I made members initially as property.
Re: Code style for property
On Sunday, 12 March 2017 at 11:15:04 UTC, Nicholas Wilson wrote: On Sunday, 12 March 2017 at 10:47:35 UTC, Andrey wrote: And I want make access to read x, y and bar. Probably I should add prefix for private members, that is a question: what prefix should I use? Now I use prefix p_ (from the word property), but maybe prefix m_ is better and you need to use it for all private members? A single leading underscore is usually used to denote a private variable ( names prefixed with two leading underscores are reserved for use by the compiler). If you need any prefix at all, a single underscore is enough, and it's also the tradition in other languages such as Python, C#... Whether a private member is exposed as property or in some other way, can be seen in the getter/setter, no need to classify it into the member declaration. C++ kind or requires a letter on top such as m_ simply because any identifiers starting with an underscore are (mostly and certainly at the global scope) reserved (namespace pollution anyone?). It's really up to you, we won't call the police ;)
Re: Best ways to declare associative arrays
On Sunday, 12 March 2017 at 07:58:40 UTC, helxi wrote: string[string] change(ref string[string] arg_array){ //.. arg_array["first"] = strip(readln()); //.. arg_array["second"] = strip(readln()); //.. return def; } Nicholas clarified why your declaration was wrong, but there are several strange things in your code that you may want to re-think. Also it looks to me that an associative array is not the most appropriate type for what you want to do. To call a function you just pass the names of the arguments, not their types. So simply change(test), NOT change(string[string] test) arg_array is an in-out (ref) parameter, but change() returns another value of the same type, def, not defined in your code, and which you do not use in main(). I think you may be interested only in changing arg_array, so the signature could be instead: void change(ref ...) What you seem to want from your associative array is to associate two strings, "first" and "second" with two values (strings from the user), and only two. An associate array is more flexible than that, which is bad, you want your code to restrict you away from errors. For example if you keep using an associative array you could at the end of change(): assert(arg_array.length == 2); I wonder if it's not enough and better for you to use a plain array. Keys "first" and "second" are not more informative than numeric indices. You may also use the advantage that an array can be hard-typed as fixed-length if this is known at compile time (and if you don't declare it with new), so it restricts your code in the perfect way: void change(ref string[2] arg_array) { arg_array[0] = strip(readln()); arg_array[1] = strip(readln()); } void main() { string[2] test; change(test); } Also another disadvantage of associative arrays is that they are not ordered, so if for example in main() you read through the values in test with a foreach loop, you may get the result in any order (second first, and first second is possible). A simple array will keep order 0, 1. If you were so bummed about using 0-1 instead of "first"-"second" you could define: enum lineKey :size_t { first = 0, second } void change(ref string[2] arg_array) { arg_array[lineKey.first ] = strip(readln()); arg_array[lineKey.second] = strip(readln()); } But at least to me it looks worse. As a programmer you already know that the first index is 0 and 1 comes next.
GDC options
Hi, ldc2 has the -unittest --main options to compile a file that has unittests and no main so as to create a test executable. What causes the same behaviour with gdc? -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Code style for property
On Sunday, 12 March 2017 at 10:47:35 UTC, Andrey wrote: Hello, how better to declare properties, for example I have class: class Foo { this(in int x, in int y, Bar bar) { this.x = x; this.y = y; this.bar = bar; } private: int x; int y; Bar bar; } And I want make access to read x, y and bar. Probably I should add prefix for private members, that is a question: what prefix should I use? Now I use prefix p_ (from the word property), but maybe prefix m_ is better and you need to use it for all private members? Another question: what style is better for declare getters? this: class Foo { @property int x() { return p_x; // or m_x; } @property int y() { return p_y; // or m_y; } @property int bar() { return p_bar; // or m_bar; } } or this: class Foo { @property { int x() { return p_x; } int y() { return p_y; } int bar() { return p_bar; } } } And one more question: should I add ref for property, to be able do this (if setter is declared): foo.x += 5 You should only declare getters/setters if you need to (or think you may need to later) intercept the assignment or acquisition of a variable (logging, computing on demand) have a field as externally read only (setter only) otherwise you should have the variables as normally assignable. A single leading underscore is usually used to denote a private variable ( names prefixed with two leading underscores are reserved for use by the compiler). If you must use @property and you have a whole lot of them in a row the second form is preferred (consider also using `@property:` if you have no more non-@property function to declare). Note that you still need to declare the variables you are going to return in the property if the variable you are going to return is ref then unless you are choosing which variable to return at runtime (see first paragraph) then just have the variable be public.
Code style for property
Hello, how better to declare properties, for example I have class: class Foo { this(in int x, in int y, Bar bar) { this.x = x; this.y = y; this.bar = bar; } private: int x; int y; Bar bar; } And I want make access to read x, y and bar. Probably I should add prefix for private members, that is a question: what prefix should I use? Now I use prefix p_ (from the word property), but maybe prefix m_ is better and you need to use it for all private members? Another question: what style is better for declare getters? this: class Foo { @property int x() { return p_x; // or m_x; } @property int y() { return p_y; // or m_y; } @property int bar() { return p_bar; // or m_bar; } } or this: class Foo { @property { int x() { return p_x; } int y() { return p_y; } int bar() { return p_bar; } } } And one more question: should I add ref for property, to be able do this (if setter is declared): foo.x += 5
Re: Best ways to declare associative arrays
On Sunday, 12 March 2017 at 07:58:40 UTC, helxi wrote: How would an experienced programmer declare an associative array of strings that has 2 keys? My initial impression was string[string][2] my_array; which does not seem to work. Here is a snippet of the code I am working on: import std.string; import std.stdio; string[string] change(ref string[string] arg_array){ //.. arg_array["first"] = strip(readln()); //.. arg_array["second"] = strip(readln()); //.. return def; } You appear to be confused about the way arrays work. string[string] foo; //declares an assoc array of strings, index by string string[string][2] bar; // declares a static array of two string[string] foo = { "key1" : "some data", "key2" : "some other data" }; // initialise foo with some data foo["blarg"] = "fxgsdzfcxf"; // insert some more data associative array of strings that has 2 keys? is a regular associative array that has two entries. much like the difference between int[] baz = [1 ,2]; // has two elements int[][2] quux; // a static array of length 2 whose elements are of type int[] void main(){ string[string][2] test; // remove the `[2]` change(string[string] test); just do change(test); it is invalid syntax to have a type before the variable in a function call, unless you were trying to cast it, in which use `cast(type)(expression)` } If you wish to reserve capacity for the array, use `arr.reserve(N)` to allocate memory enough to hold N elements.
Re: Best ways to declare associative arrays
On Sunday, 12 March 2017 at 07:58:40 UTC, helxi wrote: return def; I meant return arg_array;
Best ways to declare associative arrays
How would an experienced programmer declare an associative array of strings that has 2 keys? My initial impression was string[string][2] my_array; which does not seem to work. Here is a snippet of the code I am working on: import std.string; import std.stdio; string[string] change(ref string[string] arg_array){ //.. arg_array["first"] = strip(readln()); //.. arg_array["second"] = strip(readln()); //.. return def; } void main(){ string[string][2] test; change(string[string] test); }