Re: scope(~this)

2017-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

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

2017-03-12 Thread David Zhang via Digitalmars-d-learn
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

2017-03-12 Thread Meta via Digitalmars-d-learn

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

2017-03-12 Thread Adam D. Ruppe via Digitalmars-d-learn

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

2017-03-12 Thread ag0aep6g via Digitalmars-d-learn

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

2017-03-12 Thread Inquie via Digitalmars-d-learn

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

2017-03-12 Thread Adam D. Ruppe via Digitalmars-d-learn

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)

2017-03-12 Thread Inquie via Digitalmars-d-learn

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)

2017-03-12 Thread Stefan Koch via Digitalmars-d-learn

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)

2017-03-12 Thread Inquie via Digitalmars-d-learn
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

2017-03-12 Thread data pulverizer via Digitalmars-d-learn

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

2017-03-12 Thread ketmar via Digitalmars-d-learn

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

2017-03-12 Thread Meta via Digitalmars-d-learn

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

2017-03-12 Thread data pulverizer via Digitalmars-d-learn

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

2017-03-12 Thread ketmar via Digitalmars-d-learn

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

2017-03-12 Thread Meta via Digitalmars-d-learn

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

2017-03-12 Thread Andrey via Digitalmars-d-learn

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

2017-03-12 Thread ketmar via Digitalmars-d-learn

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

2017-03-12 Thread ketmar via Digitalmars-d-learn

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

2017-03-12 Thread data pulverizer via Digitalmars-d-learn

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

2017-03-12 Thread ketmar via Digitalmars-d-learn

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

2017-03-12 Thread Jerry via Digitalmars-d-learn

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

2017-03-12 Thread data pulverizer via Digitalmars-d-learn

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

2017-03-12 Thread Stefan via Digitalmars-d-learn

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

2017-03-12 Thread Johannes Pfau via Digitalmars-d-learn
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

2017-03-12 Thread Andrey via Digitalmars-d-learn

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

2017-03-12 Thread XavierAP via Digitalmars-d-learn

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

2017-03-12 Thread XavierAP via Digitalmars-d-learn

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

2017-03-12 Thread 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?

-- 
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

2017-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

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

2017-03-12 Thread Andrey via Digitalmars-d-learn

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

2017-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

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

2017-03-12 Thread helxi via Digitalmars-d-learn

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

2017-03-12 Thread helxi via Digitalmars-d-learn
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);
}