Re: Convert duration to years?

2017-01-14 Thread rikki cattermole via Digitalmars-d-learn

On 15/01/2017 4:43 PM, Nestor wrote:

Hi,

I would simply like to get someone's age, but I am a little lost with
time and date functions. I can already get the duration, but after
reading the documentation it's unclear to me how to convert that into
years. See following code:

import std.stdio;

void getAge(int , int mm, int dd) {
  import std.datetime;
  SysTime t1 = SysTime(Date(, mm, dd));
  SysTime t2 = Clock.currTime();
  writeln(t2 - t1);
}

int main() {
  try
getAge(1980, 1, 1);
  catch(Exception e) {
writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line);
  }
}

Notice getAge should return ubyte instead of void, only I haven't been
able to find how to do it. Any suggestion would be welcome.

Thanks in advance.


So I had a go at this and found I struggled looking at "magic" functions 
and methods.

Turns out there is a much simpler answer.

int getAge(int , int mm, int dd) {
  import std.datetime;
  auto t1 = cast(DateTime)SysTime(Date(, mm, dd));
  auto t2 = cast(DateTime)Clock.currTime();

  int numYears;
  while(t2 > t1) {
 t1.add!"years"(1);
 numYears++;
  }

  return numYears;
}



Re: Convert duration to years?

2017-01-14 Thread Nestor via Digitalmars-d-learn

On Sunday, 15 January 2017 at 06:23:56 UTC, Dave Chapman wrote:

Does this do what you want?
import std.stdio;

uint getAge(int , int mm, int dd) {
  import std.datetime;
  SysTime t1 = SysTime(Date(, mm, dd));
  SysTime t2 = Clock.currTime();
  return( (t2.year - t1.year));
}

void main() {
  auto age = getAge(1980, 1, 1);
  writefln("age is %s", age);
}


It seems to work, but not very accurately, see variation:

import std.stdio;

uint getAge() {
  import std.datetime;
  SysTime t1 = SysTime(Date(2000, 12, 31));
  SysTime t2 = SysTime(Date(2001, 1, 1));
  return((t2.year - t1.year));
}

void main() {
  auto age = getAge();
  writefln("age is %s", age);
}


I eventually came up with this, but it seems an ugly hack:

import std.stdio;

uint getAge(int , ubyte mm, ubyte dd) {
  ubyte correction;
  import std.datetime;
  SysTime t = Clock.currTime();
  if (t.month < mm) correction = 1;
  else if (t.month == mm) correction = (t.day < dd) ? 1 : 0;
  else correction = 0;
  return (t.year -  - correction);
}

void main() {
  try
writefln("Edad: %s años.", getAge(1958, 1, 21));
  catch(Exception e) {
writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line);
  }
}

Isn't there a built-in function to do this?


Re: Convert duration to years?

2017-01-14 Thread Dave Chapman via Digitalmars-d-learn

On Sunday, 15 January 2017 at 03:43:32 UTC, Nestor wrote:

Hi,

I would simply like to get someone's age, but I am a little 
lost with time and date functions. I can already get the 
duration, but after reading the documentation it's unclear to 
me how to convert that into years. See following code:


import std.stdio;

void getAge(int , int mm, int dd) {
  import std.datetime;
  SysTime t1 = SysTime(Date(, mm, dd));
  SysTime t2 = Clock.currTime();
  writeln(t2 - t1);
}

int main() {
  try
getAge(1980, 1, 1);
  catch(Exception e) {
writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line);
  }
}

Notice getAge should return ubyte instead of void, only I 
haven't been able to find how to do it. Any suggestion would be 
welcome.


Thanks in advance.


Does this do what you want?
import std.stdio;

uint getAge(int , int mm, int dd) {
  import std.datetime;
  SysTime t1 = SysTime(Date(, mm, dd));
  SysTime t2 = Clock.currTime();
  return( (t2.year - t1.year));
}

void main() {
  auto age = getAge(1980, 1, 1);
  writefln("age is %s", age);
}



Re: Gtkd how to add double value to liststore

2017-01-14 Thread Erdem via Digitalmars-d-learn

On Sunday, 15 January 2017 at 01:36:44 UTC, Ali Çehreli wrote:

It looks like ListStore is a collection of 'Value's. Does the 
following work?


setValue(iterator, 1, new Value(price));


Yes it works.

Ali bey teşekkürler! :)



Convert duration to years?

2017-01-14 Thread Nestor via Digitalmars-d-learn

Hi,

I would simply like to get someone's age, but I am a little lost 
with time and date functions. I can already get the duration, but 
after reading the documentation it's unclear to me how to convert 
that into years. See following code:


import std.stdio;

void getAge(int , int mm, int dd) {
  import std.datetime;
  SysTime t1 = SysTime(Date(, mm, dd));
  SysTime t2 = Clock.currTime();
  writeln(t2 - t1);
}

int main() {
  try
getAge(1980, 1, 1);
  catch(Exception e) {
writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line);
  }
}

Notice getAge should return ubyte instead of void, only I haven't 
been able to find how to do it. Any suggestion would be welcome.


Thanks in advance.


Re: Accessing a function within an object's superclass from the outside

2017-01-14 Thread Meta via Digitalmars-d-learn

On Saturday, 14 January 2017 at 23:31:53 UTC, Adam D. Ruppe wrote:
On Saturday, 14 January 2017 at 21:55:27 UTC, David  Zhang 
wrote:
I seem to remember something about using aliases to fix this, 
but I can't find anything about it either way.


So you can alias the names together to merge the overload sets, 
or at the call site, you can also specify which class's version 
you want with a dot:


cb.ClassA.fun(a, b); // compiles, specifically calls the ClassA 
method


Is this documented anywhere? I had no idea this was a feature.


Re: Gtkd how to add double value to liststore

2017-01-14 Thread Ali Çehreli via Digitalmars-d-learn

On 01/14/2017 11:47 AM, Erdem wrote:

> void addGoods(string name, double price)
> {
> TreeIter iterator = createIter();
> setValue(iterator, 0, name);
> setValue(iterator, 1, price);
> }
> }

> Error: none of the overloads of 'setValue' are callable using argument
> types (TreeIter, int, double), candidates are:
>
> import/gtk/ListStore.d(273):
> gtk.ListStore.ListStore.setValue(TreeIter iter, int column, string value)
> import/gtk/ListStore.d(281):
> gtk.ListStore.ListStore.setValue(TreeIter iter, int column, int value)
> import/gtk/ListStore.d(569):
> gtk.ListStore.ListStore.setValue(TreeIter iter, int column, Value value)

It looks like ListStore is a collection of 'Value's. Does the following 
work?


setValue(iterator, 1, new Value(price));

https://github.com/gtkd-developers/GtkD/blob/3e18afcc5f0b970db1ed042c3818cafebccb35bb/src/gobject/Value.d#L48

Ali



Re: Accessing a function within an object's superclass from the outside

2017-01-14 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 14 January 2017 at 21:55:27 UTC, David  Zhang wrote:
I seem to remember something about using aliases to fix this, 
but I can't find anything about it either way.


So you can alias the names together to merge the overload sets, 
or at the call site, you can also specify which class's version 
you want with a dot:


cb.ClassA.fun(a, b); // compiles, specifically calls the ClassA 
method


Re: Accessing a function within an object's superclass from the outside

2017-01-14 Thread Ali Çehreli via Digitalmars-d-learn
Templates are not virtual. Depending the interface, a different function 
is called:


import std.stdio;

class ClassA {
void fun(T)(T a) { writeln("ClassA"); }
}

class ClassB: ClassA {
void fun(uint a) { writeln("ClassB"); }
}

void main() {
auto cb = new ClassB();
ClassA ca = cb;

uint a = 42;
ca.fun(a);// calls ClassA.fun
cb.fun(a);// calls ClassB.fun
}

Ali



Re: Accessing a function within an object's superclass from the outside

2017-01-14 Thread ketmar via Digitalmars-d-learn

On Saturday, 14 January 2017 at 22:38:15 UTC, David  Zhang wrote:

On Saturday, 14 January 2017 at 22:17:23 UTC, ketmar wrote:

class ClassB: ClassA {
  alias fun = super.fun;
  override void fun(uint a) {}
}


I tried that, but it seems to think I mean to override 
super.fun(uint) instead of super.fun(uint, float).


ahem?
`void fun(uint a)` == `void fun(uint a)`
`void fun(uint a)` != `void fun(uint, float)`
of course, you mean to override `void fun(uint a)` with this code.


Re: Accessing a function within an object's superclass from the outside

2017-01-14 Thread David Zhang via Digitalmars-d-learn

On Saturday, 14 January 2017 at 22:17:23 UTC, ketmar wrote:

class ClassB: ClassA {
  alias fun = super.fun;
  override void fun(uint a) {}
}


I tried that, but it seems to think I mean to override 
super.fun(uint) instead of super.fun(uint, float).


Looking at my code again, one of them is templated with a range 
interface. I think that might be the problem, though I can't 
figure out how to fix it. Wrapping the alias in a template block 
doesn't seem to do it.


Re: Accessing a function within an object's superclass from the outside

2017-01-14 Thread ketmar via Digitalmars-d-learn

On Saturday, 14 January 2017 at 21:55:27 UTC, David  Zhang wrote:

Hello,

Say I have a class, and it overrides a function from its 
superclass. However, the superclass has two overloaded versions 
of the same function. My intent is to override only one of the 
functions, but the second is rendered inaccessible from outside 
of the class. How can I make the overloaded function visible?


ie:

class ClassA {
void fun(uint a) {}
void fun(uint a, float b) {}
}

class ClassB: ClassA {
void fun(uint a) {}
}

ca.fun(a);   //ok
ca.fun(a, b);//ok
cb.fun(a);   //ok
cb.fun(a, b);//function fun not callable with uint and float

I seem to remember something about using aliases to fix this, 
but I can't find anything about it either way.


class ClassB: ClassA {
  alias fun = super.fun;
  override void fun(uint a) {}
}


Accessing a function within an object's superclass from the outside

2017-01-14 Thread David Zhang via Digitalmars-d-learn

Hello,

Say I have a class, and it overrides a function from its 
superclass. However, the superclass has two overloaded versions 
of the same function. My intent is to override only one of the 
functions, but the second is rendered inaccessible from outside 
of the class. How can I make the overloaded function visible?


ie:

class ClassA {
void fun(uint a) {}
void fun(uint a, float b) {}
}

class ClassB: ClassA {
void fun(uint a) {}
}

ca.fun(a);   //ok
ca.fun(a, b);//ok
cb.fun(a);   //ok
cb.fun(a, b);//function fun not callable with uint and float

I seem to remember something about using aliases to fix this, but 
I can't find anything about it either way.


Re: switch to member

2017-01-14 Thread Meta via Digitalmars-d-learn

On Saturday, 14 January 2017 at 16:05:33 UTC, Ignacious wrote:

Go join the Nazi Youth group, you OSS Sympathizer!


What?



Re: Converting from DirIterator to string[] without a loop

2017-01-14 Thread Dave Chapman via Digitalmars-d-learn

On Saturday, 14 January 2017 at 01:02:38 UTC, Ali Çehreli wrote:

On 01/13/2017 04:29 PM, Dave Chapman wrote:

> When I use auto and print out the type of b it is  something
like
> args.main.FilterResult!(__lambda2, DirIterator).FilterResult
and for the
> "if" version of
> b and args.main.FilterResult!(__lambda3,
DirIterator).FilterResult for
> the "else" version
> so they are really different types.

The solution for that case is to use std.range.choose:

auto b = choose(some_condition,
all.filter!(f => baseName(f.name) == 
"file_name.txt"),

all.filter!(f => (f.name.endsWith(".d") )));

but I get the following error with DMD64 D Compiler v2.072.1:

  Error: no property '__postblit' for type 
'FilterResult!(__lambda2, DirIterator)', did you mean 
'__xpostblit'?


So, I put .array after both expressions below.

The idiomatic way for what you're looking for is 
std.array.array (which is also exposed through std.range):


import std.stdio;
import std.file;
import std.algorithm;
import std.range;
import std.path;

void main(string[] args) {
bool some_condition = (args.length > 1) && (args[1] == 
"foo");


auto all = dirEntries("directory", SpanMode.shallow);

auto b = choose(some_condition,
all.filter!(f => baseName(f.name) == 
"file_name.txt").array,
all.filter!(f => (f.name.endsWith(".d") 
)).array);


writeln(b);
}

However, in most cases keeping 'b' as a lazy algorithm is 
sufficient. Unless you really need an array e.g. for sorting, 
you can use std.algorithm.each (or map, etc.). (Not applicable 
in this case because of the error I mentioned above.)


Ali


Thank you very much.

I had a little trouble getting it working. It was acting as if 
both halves of the "choose" expression were always getting 
executed and the first half was making the contents of "all" 
empty and so the array b was always empty if I used the second 
half of the choose statement. I made a second copy of "all" and 
used it in the second half of the choose statement and then it 
worked.  Like this:


  auto all   = dirEntries("directory", SpanMode.shallow);
  auto all_2 = dirEntries("directory", SpanMode.shallow);

  auto b = choose(some_condition,
  all.filter!(f => (baseName(f.name) == requested_file)).array,
  all_2.filter!(f => (f.name.endsWith(".html") )).array);


Note that I am really using requested_file instead of 
"file_name.txt" and ".html" instead of ".d" which is different 
than what I told you before just in case that matters.


I am using  Mac  OS X 10.11.5 and dmd version 2.072.2

Thanks again for the help,
Dave




Gtkd how to add double value to liststore

2017-01-14 Thread Erdem via Digitalmars-d-learn
I would like to pass some double value to ListStore's constructor 
but it doesn't allows me to do.


import gtk.Main;
import gtk.MainWindow;
import gtk.Box;
import gtk.ListStore;
import gtk.TreeView;
import gtk.TreeViewColumn;
import gtk.TreeIter;
import gtk.CellRendererText;


class MyWindow: MainWindow
{
Box mainBox;

this()
{
super("Tree view exercise");
setBorderWidth(10);
mainBox = new Box(Orientation.HORIZONTAL, 0);
add(mainBox);


showAll();
}
}

class InfoModel: ListStore /* model */
{
this()
{
super([GType.STRING, GType.DOUBLE]);

}

void addGoods(string name, double price)
{
TreeIter iterator = createIter();
setValue(iterator, 0, name);
setValue(iterator, 1, price);
}
}

class DisplayModel: TreeView /* view */
{
TreeViewColumn articleColumn;
TreeViewColumn priceColumn;

this (ListStore model)
{
articleColumn = new TreeViewColumn("Article", new 
CellRendererText(), "text", 0);


}

}

void main(string[] args)
{
Main.init(args);
new MyWindow();
Main.run();
}

When I try to compile this program it gives this error message:

Error: none of the overloads of 'setValue' are callable using 
argument types (TreeIter, int, double), candidates are:


import/gtk/ListStore.d(273):
gtk.ListStore.ListStore.setValue(TreeIter iter, int column, 
string value)
import/gtk/ListStore.d(281):
gtk.ListStore.ListStore.setValue(TreeIter iter, int column, int 
value)
import/gtk/ListStore.d(569):
gtk.ListStore.ListStore.setValue(TreeIter iter, int column, Value 
value)


Also is it possible to round this double to 2 decimal places when 
presenting data with GtkTreeView.




Re: Android Status

2017-01-14 Thread Andre Pany via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 21:13:07 UTC, Ignacious wrote:

On Wednesday, 11 January 2017 at 03:49:42 UTC, Joakim wrote:

On Tuesday, 10 January 2017 at 18:48:17 UTC, Ignacious wrote:

[...]


It's probably not easier, and in any case, android-x86 won't 
be supported, largely because I don't have any working x86 
devices.


[...]


Ok, well the x86 thing wasn't my idea! It seems I was using the 
wrong build command for trying to compile the examples.


In any case, I'll just wait until things get working a bit 
better. I'd suggest you put, in the title of the page, a bit 
more information. I didn't realize I was looking at an old 
version(which looks too similar to the new one).


I am currently preparing a repository on dockerhub which contains 
the newest ldc with android support and the Android NDK. While 
these two applications run in a container you only have to 
install the Android SDK on your host machine. The dockerfile is 
in an early state, I will create an anouncememt when it is 
finished. You can already have a look 
https://hub.docker.com/r/andre2007/ldc-android/


Kind regards
Andre


Re: Referring to array element by descriptive name

2017-01-14 Thread Ali Çehreli via Digitalmars-d-learn

On 01/14/2017 07:11 AM, albert-j wrote:
> Is it possible to refer to an array element by a descriptive name, just
> for code clarity, without performance overhead? E.g.
>
> void aFunction(double[] arr) {
> double importantElement = arr[3];
> ... use importantElement ...
> }
>
> But the above, I suppose, introduces an extra copy operation?
>

I've used nested functions before. Compiled with

  -O -inline -boundscheck=off

even dmd produces exact code for the following three access methods:

import std.stdio;

void aFunction(double[] arr) {
ref importantElement() {
return arr[3];
}
writeln("Indexed element : ", arr[3]);
writeln("importantElement: ", importantElement);

double originalIdea = arr[3];
writeln("Original idea   : ", originalIdea);
}

void main() {
}

Here are the three calls; comments added by me. The only difference is 
RCX vs. RAX for one of the calls:


.text._D6deneme9aFunctionFAdZv  segment
assume  CS:.text._D6deneme9aFunctionFAdZv
_D6deneme9aFunctionFAdZv:
pushRBP
mov RBP,RSP
sub RSP,010h
mov -010h[RBP],RDI
mov -8[RBP],RSI

; arr[3]
mov EDX,offset FLAT:_TMP0@32
mov EDI,012h
mov RSI,RDX
mov RAX,-8[RBP]
movsd   XMM0,018h[RAX]
call  _D3std5stdio18__T7writelnTAyaTdZ7writelnFNfAyadZv@PC32

; importantElement:
mov EDX,offset FLAT:_TMP0@32
mov EDI,012h
mov RSI,RDX
mov RCX,-8[RBP]
movsd   XMM0,018h[RCX]
call  _D3std5stdio18__T7writelnTAyaTdZ7writelnFNfAyadZv@PC32

; originalIdea:
mov EDX,offset FLAT:_TMP0@32
mov EDI,012h
mov RSI,RDX
mov RAX,-8[RBP]
movsd   XMM0,018h[RAX]
call  _D3std5stdio18__T7writelnTAyaTdZ7writelnFNfAyadZv@PC32


mov RSP,RBP
pop RBP
ret
0f1f
add byte ptr [RAX],0
add [RAX],AL
.text._D6deneme9aFunctionFAdZv  ends

Ali



Re: writeln and ~

2017-01-14 Thread Era Scarecrow via Digitalmars-d-learn

On Saturday, 14 January 2017 at 17:42:05 UTC, Ignacious wrote:
Why can't string concatenation automatically try to convert the 
arguments? Is there any reason this is bad behavior?


 Somehow I think that everything implicitly converting to a 
string seems like a bad idea.


 Although writefln and writeln using ,'s seems like better ideas 
than some minor JavaScript convenience.


Re: Referring to array element by descriptive name

2017-01-14 Thread Era Scarecrow via Digitalmars-d-learn

On Saturday, 14 January 2017 at 15:11:40 UTC, albert-j wrote:
Is it possible to refer to an array element by a descriptive 
name, just for code clarity, without performance overhead? E.g.


void aFunction(double[] arr) {
double importantElement = arr[3];
... use importantElement ...
}

But the above, I suppose, introduces an extra copy operation?


 Is the array always a fixed size? Or what?

 I wonder since you might get away with a union, or a struct that 
simply redirects the information appropriately. However it's a 
lot of writing for very little benefit at all.


 But honestly for as little loss you'll get of copying the one 
element and then copying it back (maybe if you change it) I doubt 
it will mean much if you just ignore trying to do a 0-cost 
aliasing as you are trying to do. You'd have to be doing it 
millions of times for such a copy to be noticeable.


Re: writeln and ~

2017-01-14 Thread thedeemon via Digitalmars-d-learn

On Saturday, 14 January 2017 at 17:42:05 UTC, Ignacious wrote:

writeln(x ~ " ok");


Just write writeln(x, " ok");
Any number of arguments, no unnecessary allocations.
Do you really need ~?



Re: writeln and ~

2017-01-14 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 14 January 2017 at 17:42:05 UTC, Ignacious wrote:
Why can't string concatenation automatically try to convert the 
arguments? Is there any reason this is bad behavior?


You'd be liable to write buggy stuff like appending the wrong 
kind of array since the auto conversion was wrong.


How bout then having writeln parse the arguments as a 
string(take an alias or something first) and then automatically 
convert them?


writeln already knows how to convert. There's also a 
std.conv.text function that returns the string instead of 
printing it.


http://dpldocs.info/experimental-docs/std.conv.text.html


writeln and ~

2017-01-14 Thread Ignacious via Digitalmars-d-learn

string concatenation is weird.

We can do stuff like

writeln(x);

where x is, say a struct and it prints fine

but when we do

writeln(x ~ " ok");

it fails and requires us to convert x!

Why can't string concatenation automatically try to convert the 
arguments? Is there any reason this is bad behavior?


How bout then having writeln parse the arguments as a string(take 
an alias or something first) and then automatically convert them?


Seems like there is no real excuse to add such obfuscation...

Obviously I can roll my own but that is not an acceptable answer.





Re: switch to member

2017-01-14 Thread Ignacious via Digitalmars-d-learn

On Saturday, 14 January 2017 at 11:32:10 UTC, Marc Schütz wrote:
You can utilize a little-known `switch` syntax trick in 
combination with `foreach`. Because a `foreach` over tuples is 
unrolled at compile time, it works even if your fields don't 
have exactly the same types:


--

struct Foo {
int x, y;
long a, b, c;
short i, j, k;
}

enum Which {
x, y, a, b, c, i, j, k,
}

void assignValue(ref Foo q, Which member, short e) {
import std.traits : EnumMembers;
import std.conv : to;

final switch(member) {
// foreach over a tuple is unrolled at compile time
foreach(w; EnumMembers!Which) {
case w:
// expands to: q.x, q.y, ...
mixin("q." ~ w.to!string) = e;
break;
}
}
}

void main() {
import std.stdio : writeln;
Foo q;
writeln("before: ", q);
assignValue(q, Which.a, 42);
assignValue(q, Which.x, 1);
writeln("after: ", q);
}


Cool, pretty straightforward and somewhat easy to use. I suppose 
it might be easier to mark the enum members with an attribute 
though and use that rather than having two enums? I didn't know 
about the foreach in the switch, cool idea!


Thanks.



Re: switch to member

2017-01-14 Thread Ignacious via Digitalmars-d-learn

On Saturday, 14 January 2017 at 08:30:04 UTC, Meta wrote:
On Saturday, 14 January 2017 at 05:29:49 UTC, Nicholas Wilson 
wrote:

enum XX
{
X = Q.X.offsetof,
Y = Q.Y.offsetof
//ect.
}

and then

*(cast(void*)(this) + x) = e; //if inside struct/class

or
*(cast(void*)(q) + x) = e; // if outside

Unfortunately this loses you `@safe`ty, but as long as you 
trust

the value of x then it should be safe to `@trusted` that code.

If you are trying to avoid code duplication the enum 
declaration of X

could also be done with a string mixin.


IMO this is massive overkill to save some typing. To the OP, 
it's not really worth it to go to so much trouble. Just write 
some slightly duplicated code and move on.


Go join the Nazi Youth group, you OSS Sympathizer!


Re: Referring to array element by descriptive name

2017-01-14 Thread tcak via Digitalmars-d-learn

On Saturday, 14 January 2017 at 15:11:40 UTC, albert-j wrote:
Is it possible to refer to an array element by a descriptive 
name, just for code clarity, without performance overhead? E.g.


void aFunction(double[] arr) {
double importantElement = arr[3];
... use importantElement ...
}

But the above, I suppose, introduces an extra copy operation?


Unless the item type of that array is a complex like a big 
struct, copying basic types won't have much effect at all. You 
wouldn't notice it.


You could point to that element with a pointer:

double* importantElement = &arr[3];

But then you are going to define that pointer variable anyway. On 
top of that, for every access, instead of using the available 
data, CPU would look at the pointed memory address to get the 
value again and again (ignoring the cache).


Referring to array element by descriptive name

2017-01-14 Thread albert-j via Digitalmars-d-learn
Is it possible to refer to an array element by a descriptive 
name, just for code clarity, without performance overhead? E.g.


void aFunction(double[] arr) {
double importantElement = arr[3];
... use importantElement ...
}

But the above, I suppose, introduces an extra copy operation?



Re: switch to member

2017-01-14 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 14 January 2017 at 11:32:10 UTC, Marc Schütz wrote:
You can utilize a little-known `switch` syntax trick in 
combination with `foreach`. Because a `foreach` over tuples is 
unrolled at compile time, it works even if your fields don't 
have exactly the same types:





That looks concise.  Perhaps enum Which can also be automatically 
filled by __traits (allMembers) or std.traits.Fields if needed.




Re: switch to member

2017-01-14 Thread Ivan Kazmenko via Digitalmars-d-learn

On Saturday, 14 January 2017 at 03:20:24 UTC, Ignacious wrote:

switch(x)
{
case X:
 q.X = e;
 break;
case Y:
 q.Y = e;
 break
etc...
}


Do you mean that verbatim?  Or are the case values strings, like:

switch(x)
{
case "foo":
 q.foo = e;
 break;
case "bar":
 q.bar = e;
 break
}

I imagine one could write a string mixin that generates the 
cases and assignments but I'm hoping for a more elegant 
solution.


In any case, I also can imagine a mixin answer, but not much 
better.  Unless you want to actually look at the broader picture 
and maybe redesign the surrounding code to somehow cleverly get 
rid of the switch altogether.  The question as it is however 
doesn't give the context to make it possible.


Ivan Kazmenko.



Re: switch to member

2017-01-14 Thread Marc Schütz via Digitalmars-d-learn
You can utilize a little-known `switch` syntax trick in 
combination with `foreach`. Because a `foreach` over tuples is 
unrolled at compile time, it works even if your fields don't have 
exactly the same types:


--

struct Foo {
int x, y;
long a, b, c;
short i, j, k;
}

enum Which {
x, y, a, b, c, i, j, k,
}

void assignValue(ref Foo q, Which member, short e) {
import std.traits : EnumMembers;
import std.conv : to;

final switch(member) {
// foreach over a tuple is unrolled at compile time
foreach(w; EnumMembers!Which) {
case w:
// expands to: q.x, q.y, ...
mixin("q." ~ w.to!string) = e;
break;
}
}
}

void main() {
import std.stdio : writeln;
Foo q;
writeln("before: ", q);
assignValue(q, Which.a, 42);
assignValue(q, Which.x, 1);
writeln("after: ", q);
}


Re: switch to member

2017-01-14 Thread Meta via Digitalmars-d-learn
On Saturday, 14 January 2017 at 05:29:49 UTC, Nicholas Wilson 
wrote:

enum XX
{
X = Q.X.offsetof,
Y = Q.Y.offsetof
//ect.
}

and then

*(cast(void*)(this) + x) = e; //if inside struct/class

or
*(cast(void*)(q) + x) = e; // if outside

Unfortunately this loses you `@safe`ty, but as long as you trust
the value of x then it should be safe to `@trusted` that code.

If you are trying to avoid code duplication the enum 
declaration of X

could also be done with a string mixin.


IMO this is massive overkill to save some typing. To the OP, it's 
not really worth it to go to so much trouble. Just write some 
slightly duplicated code and move on.