Re: Problem overloading operator for a struct with an immutable member

2015-03-26 Thread Nicolas Sicard via Digitalmars-d-learn

On Thursday, 26 March 2015 at 04:57:55 UTC, ketmar wrote:


by the way. do you know that you still CAN overload 
postincrement
operation? yes, the code is still here, and it works... 
somethimes. ;-)


Thnaks. Indeed, this works:
---
struct S
{
int i;
immutable(Object) o;

void opAddAssign(int j) { i += j; }
S opPostInc() { ++i; return this; }
void opAssign(S other) {}
}

unittest
{
S s;
++s;
assert(s.i == 1);
s++;
assert(s.i == 2);
}
---

Old operator overloading to the rescue !


Re: Problem overloading operator for a struct with an immutable member

2015-03-26 Thread ketmar via Digitalmars-d-learn
On Thu, 26 Mar 2015 09:02:53 +, Nicolas Sicard wrote:

> On Thursday, 26 March 2015 at 04:57:55 UTC, ketmar wrote:
>>
>> by the way. do you know that you still CAN overload postincrement
>> operation? yes, the code is still here, and it works...
>> somethimes. ;-)
> 
> Thnaks. Indeed, this works:
> ---
> struct S {
>  int i;
>  immutable(Object) o;
> 
>  void opAddAssign(int j) { i += j; }
>  S opPostInc() { ++i; return this; }
>  void opAssign(S other) {}
> }
> 
> unittest {
>  S s;
>  ++s;
>  assert(s.i == 1);
>  s++;
>  assert(s.i == 2);
> }
> ---
> 
> Old operator overloading to the rescue !

just make sure you didn't add `opUnary` there, as it will kill 
`opPostInc`.

it worth nothing that `opPostInc` is not deprecated yet. ;-)

signature.asc
Description: PGP signature


Re: Problem overloading operator for a struct with an immutable member

2015-03-26 Thread ketmar via Digitalmars-d-learn
On Thu, 26 Mar 2015 09:17:21 +, ketmar wrote:

> worth nothing
heh. my pet misspelling.



signature.asc
Description: PGP signature


Re: problems with std.bitmanip.append (bug?)

2015-03-26 Thread Hugo via Digitalmars-d-learn
On Thursday, 26 March 2015 at 02:39:56 UTC, Steven Schveighoffer 
wrote:


An array as an output range writes to the front. You can use 
std.array.Appender to get appending behavior. I know, it's 
weird.


Alternatively, you can add more bytes to the array, and append 
to the slice, but that may be ugly/hard to do.


-Steve


Hmm... isnt that't what the std.bitmanip.write function is for? 
It even provides an index.


I could make an 8 byte buffer and then make a slice with the last 
4 bytes and use append there, but it would be rather a hack 
around something that should have worked.


Perhaps I have found a bug. Actually I am not sure because I am 
not yet familiar with the way to use templates, so there is the 
possibility that I am using incorrect arguments.


If only the documentation and/or test units were more clear...





Re: problems with std.bitmanip.append (bug?)

2015-03-26 Thread Hugo via Digitalmars-d-learn

On Thursday, 26 March 2015 at 10:07:07 UTC, Hugo wrote:


If only the documentation and/or test units were more clear...


OK, I made a simpler test, using an example from the 
documentation:



void main() {
   import std.stdio, std.array, std.bitmanip;
   auto buffer = appender!(const ubyte[])();
   buffer.append!ushort(261);
   assert(buffer.data == [1, 5]);
   writefln("%s", buffer.data);
}

It seems to work, so apparently one has to explicitly create a 
buffer with the appender template. Not terribly useful IMHO.


Wouldn't it be possible for the append function to automaticaly 
change the mode of an already existing buffer?


Also, can anyone provide a similar example but using little 
endian order? If only to contrast differences between modes of 
invocation...


Re: problems with std.bitmanip.append (bug?)

2015-03-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/26/15 6:07 AM, Hugo wrote:

On Thursday, 26 March 2015 at 02:39:56 UTC, Steven Schveighoffer wrote:


An array as an output range writes to the front. You can use
std.array.Appender to get appending behavior. I know, it's weird.

Alternatively, you can add more bytes to the array, and append to the
slice, but that may be ugly/hard to do.



Hmm... isnt that't what the std.bitmanip.write function is for? It even
provides an index.


Quite possibly write and append do the same thing for arrays because of 
the way slices support the output range idiom.



Perhaps I have found a bug. Actually I am not sure because I am not yet
familiar with the way to use templates, so there is the possibility that
I am using incorrect arguments.


No, it's not a bug. A slice does not support appending in the way you 
expect as an output range.


Think of a slice/array as a buffer in which to put information, maybe 
it's a stack buffer. If you output to this buffer, you wouldn't expect 
it to allocate more memory and append to the end would you? Instead, 
you'd expect to write data starting at the beginning.


If you want append behavior, use std.array.Appender, as is described in 
the example of std.bitmanip.append.


I do, however, think that the term "append" is very misleading. If it 
were named "putInto", that might have been a less confusing term.


-Steve


Re: problems with std.bitmanip.append (bug?)

2015-03-26 Thread John Colvin via Digitalmars-d-learn

On Thursday, 26 March 2015 at 12:21:23 UTC, Hugo wrote:

On Thursday, 26 March 2015 at 10:07:07 UTC, Hugo wrote:


If only the documentation and/or test units were more clear...


OK, I made a simpler test, using an example from the 
documentation:



void main() {
   import std.stdio, std.array, std.bitmanip;
   auto buffer = appender!(const ubyte[])();
   buffer.append!ushort(261);
   assert(buffer.data == [1, 5]);
   writefln("%s", buffer.data);
}

It seems to work, so apparently one has to explicitly create a 
buffer with the appender template. Not terribly useful IMHO.


Wouldn't it be possible for the append function to automaticaly 
change the mode of an already existing buffer?


Also, can anyone provide a similar example but using little 
endian order? If only to contrast differences between modes of 
invocation...


void main() {
   import std.stdio, std.array, std.bitmanip, std.system;
   auto buffer = appender!(const ubyte[])();
   buffer.append!(ushort, Endian.littleEndian)(261);
   assert(buffer.data == [5, 1]);
   writefln("%s", buffer.data);
}


Re: std.typecons.Flag -- public import for API users?

2015-03-26 Thread rcorre via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 16:41:28 UTC, Rene Zwanenburg wrote:
Should not be necessary. privately import Flag and make a 
public alias:


module a;
import std.typecons : Flag;

alias SomeFlag = Flag!"SomeFlag";

SomeFlag.Yes and SomeFlag.No should be usable in other modules 
without additional imports.


Nice idea Rene, thanks!


Re: Looking for a little help with the win32 headers

2015-03-26 Thread Belly via Digitalmars-d-learn

Thank you guys, I tried the second reply and it works great!


need help with CTFE

2015-03-26 Thread Dmitri Makarov via Digitalmars-d-learn

I'm compiling the following application (2 d modules)

// file c/tool.d
module c.tool;

struct Tool
{
  string name;

  auto generate()
  {
version (DOES_NOT_WORK)
{
  import std.traits : hasMember;
  if (hasMember!(Tool, name))
return `writeln("this is a ` ~ mixin ("this." ~ name ~ 
"()") ~ `.");`;

}
else
{
  if (name == "hammer")
return `writeln("this is a ` ~ this.hammer() ~ `.");`;
}
return `writeln("unknown tool ` ~ name ~ `.");`;
  }

  auto hammer()
  {
return "screwdriver";
  }
}

string code(string input)
{
  auto tool = Tool(input);
  return tool.generate();
}
-
// file x/app.d
class Application
{
  void run()
  {
import c.tool;
import std.stdio;
mixin (code("hammer"));
mixin (code("transmogrifier"));
  }
}

int main(string[] args)
{
  auto app = new Application();
  app.run();
  return 0;
}

When I compile version DOES_NOT_WORK, I get the following error:
c/tool.d(13): Error: variable name cannot be read at compile time
c/tool.d(13):while looking for match for hasMember!(Tool, 
name)


However, the other version ('else' case) compiles, runs, and 
outputs (as expected):

this is a screwdriver.
unknown tool transmogrifier.

What's the fundamental difference that makes the variable 'name' 
readable in one version and unreadable in another?  Should the 
version DOES_NOT_WORK not be compilable in principle or is it 
only a limitation of the current CTFE implementation in the 
front-end?


Thanks.


Re: Looking for a little help with the win32 headers

2015-03-26 Thread Belly via Digitalmars-d-learn
No, wait, the first code is even better because it uses the 
headers so I don't need to declare the API myself and it uses the 
MAX_COMPUTERNAME_LENGTH define, too, nice!


Re: need help with CTFE

2015-03-26 Thread anonymous via Digitalmars-d-learn

On Thursday, 26 March 2015 at 16:19:17 UTC, Dmitri Makarov wrote:

When I compile version DOES_NOT_WORK, I get the following error:
c/tool.d(13): Error: variable name cannot be read at compile 
time
c/tool.d(13):while looking for match for 
hasMember!(Tool, name)


However, the other version ('else' case) compiles, runs, and 
outputs (as expected):

this is a screwdriver.
unknown tool transmogrifier.

What's the fundamental difference that makes the variable 
'name' readable in one version and unreadable in another?


Should the version DOES_NOT_WORK not be compilable in principle 
or is it only a limitation of the current CTFE implementation 
in the front-end?


In DOES_NOT_WORK you're trying to pass `name` in a template value 
parameter. You cannot do that, because `name` is a "dynamic 
value" but you can only pass a "static value" there. (There may 
be better terms than dynamic/static value.)


You may think: But it all happens in CTFE, so all values are 
"compile time values" or "static values", aren't they?


They aren't. The semantics during CTFE are the same as for run 
time. `name` is still a dynamic value. If it doesn't fly for run 
time execution, it doesn't fly in CTFE.


To solve the problem at hand, here's one solution that's similar 
to what you tried:


string generate()
{
import std.traits : isCallable;
foreach(memberName; __traits(allMembers, Tool))
{
if(memberName == name)
{
alias M = typeof(mixin("this." ~ memberName));
static if(isCallable!M)
{
return `writeln("this is a ` ~
mixin("this." ~ memberName ~ "()") ~ 
`.");`;

}
}
}
return `writeln("unknown tool ` ~ name ~ `.");`;
}

The foreach is (implicitly) a 'static' one, because 
__traits(allMembers, ...) results in a static/type/expression 
tuple (I don't know what's the best name to set it apart from 
other kinds of tuples).


That means, `memberName` is a static value. And so it can be used 
in mixin, whereas `name` cannot be used there.


Re: Looking for a little help with the win32 headers

2015-03-26 Thread rumbu via Digitalmars-d-learn

On Thursday, 26 March 2015 at 16:46:06 UTC, Belly wrote:
No, wait, the first code is even better because it uses the 
headers so I don't need to declare the API myself and it uses 
the MAX_COMPUTERNAME_LENGTH define, too, nice!


Using this will return only the first 15 characters of the 
computer name, if longer.


Please use the unicode version of the function GetComputerNameW 
instead of the ANSI one (GetComputerNameA), because the second 
one has a known bug, returning always 0 as required buffer size.


import std.stdio;
import std.c.windows.windows;

wstring getComputerName()
{
enum ERROR_BUFFER_OVERFLOW = 111;
uint size;
	if (GetComputerNameW(null, &size) == 0 && GetLastError() == 
ERROR_BUFFER_OVERFLOW)

{
wchar[] buf = new wchar[size];
if (GetComputerNameW(buf.ptr, &size))
return buf[0 .. size].idup;
}
return "Unknown";
}

int main(string[] argv)
{
writeln(getComputerName());
getchar();
return 0;
}











Re: need help with CTFE

2015-03-26 Thread Dmitri Makarov via Digitalmars-d-learn

On Thursday, 26 March 2015 at 17:30:40 UTC, anonymous wrote:
value parameter. You cannot do that, because `name` is a 
"dynamic value" but you can only pass a "static value" there. 
(There may be better terms than dynamic/static value.)


Thank you, anonymous. It makes sense. I guess rather than 
"static/dynamic", I would think of "known/unknown at 
compile-time". In this case, 'if (name == "hammer")' seems no 
more static or less dynamic than 'hasMember!(Tool, name)'. 
Nevertheless, I appreciate your help and will use the solution 
that you offered.


feature request for dlang.org library preview

2015-03-26 Thread Steven Schveighoffer via Digitalmars-d-learn
So I just noticed, when I click on "source code" button for a function 
in dlang.org library preview, it brings me to the source code as of that 
release, but to the file itself (on github).


I'd like it to go to the specific line where that function is defined 
instead. I'm not sure if we need updated output from dmd, or if this is 
all ddox, so I don't know where to file this feature request. Does one 
file ddox requests on issues.dlang.org?


-Steve


HTTP() from std.net.curl hidden state

2015-03-26 Thread Ilya Korobitsyn via Digitalmars-d-learn

Hello!

I am using HTTP structure to perform calls to a simple REST API.
Like this:

class API
{
 HTTP http;
 this() { http = HTTP(); }
 void call() {
  http.url = "some url";
  http.method = POST;
  http.setPostData("data", "type");
  http.perform();
 }
}

My issue is that I have to reinitialize http with HTTP() every 
call(), otherwise some state keeps on adding. For example, 
headers Content-Type keep on multiplying, and after setting 
method to DELETE it can not be changed to POST again (request 
still sends as delete).


Reinitializing http seems fine, however I suspect that something 
is lost (DNS cache, from example). Is there any workaround?


Thank you.

Example (without reinitialization):
3 subsequent requests with verbose curl, >> lines are what is 
desired, << received, rest is curl debug output.



POST http://localhost:9515/session
{"desiredCapabilities":{},"requiredCapabilities":{}}

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9515 (#0)

POST /session HTTP/1.1

User-Agent: Phobos-std.net.curl/2.067 (libcurl/7.35.0)
Host: localhost:9515
Accept: */*
Content-Type: application/json;charset=UTF-8
Content-Length: 52
* upload completely sent off: 52 out of 52 bytes
< HTTP/1.1 200 OK
< Content-Length:550
< Content-Type:application/json; charset=utf-8
< Connection:close
<
* Closing connection 0
<< 200 
{"sessionId":"d833e91674e2d14d2a81133821ab76fd","status":0,"value":{"acceptSslCerts":true,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{"userDataDir":"/tmp/.com.google.Chrome.AlM0Ze"},"cssSelectorsEnabled":true,"databaseEnabled":false,"handlesAlerts":true,"javascriptEnabled":true,"locationContextEnabled":true,"mobileEmulationEnabled":false,"nativeEvents":true,"platform":"Linux","rotatable":false,"takesHeapSnapshot":true,"takesScreenshot":true,"version":"41.0.2272.76","webStorageEnabled":true}}



DELETE 
http://localhost:9515/session/d833e91674e2d14d2a81133821ab76fd

* Hostname was found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9515 (#1)

DELETE /session/d833e91674e2d14d2a81133821ab76fd HTTP/1.1

User-Agent: Phobos-std.net.curl/2.067 (libcurl/7.35.0)
Host: localhost:9515
Accept: */*
Content-Type: application/json;charset=UTF-8
Content-Type: text/plain
Content-Length: 0
< HTTP/1.1 200 OK
< Content-Length:72
< Content-Type:application/json; charset=utf-8
< Connection:close
<
* Closing connection 1
<< 200 
{"sessionId":"d833e91674e2d14d2a81133821ab76fd","status":0,"value":null}




POST http://localhost:9515/session
{"desiredCapabilities":{},"requiredCapabilities":{}}

* Hostname was found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9515 (#2)

DELETE /session HTTP/1.1

User-Agent: Phobos-std.net.curl/2.067 (libcurl/7.35.0)
Host: localhost:9515
Accept: */*
Content-Type: application/json;charset=UTF-8
Content-Type: text/plain
Content-Type: application/json;charset=UTF-8
Content-Length: 52
* upload completely sent off: 52 out of 52 bytes
< HTTP/1.1 404 Not Found
< Content-Length:24
< Content-Type:text/plain
< Connection:close
<
* Closing connection 2
<< 404 unknown command: session


Re: problems with std.bitmanip.append (bug?)

2015-03-26 Thread Hugo via Digitalmars-d-learn

On Thursday, 26 March 2015 at 12:29:03 UTC, John Colvin wrote:


On Thursday, 26 March 2015 at 12:21:23 UTC, Hugo wrote:


Also, can anyone provide a similar example but using little 
endian order? If only to contrast differences between modes of 
invocation...


void main() {
   import std.stdio, std.array, std.bitmanip, std.system;
   auto buffer = appender!(const ubyte[])();
   buffer.append!(ushort, Endian.littleEndian)(261);
   assert(buffer.data == [5, 1]);
   writefln("%s", buffer.data);
}



Thanks, although it puzzles me that one has to move the type 
inside the parenthesis and the value after them, otherwise it 
doesn't compile.


It looks quite irregular, at least to someone like me, more used 
to function than templates. :(


I wish one could simply append a buffer using the concatenation 
operator, which would be the obvious choice, but it doesn't seem 
to work for ubytes...


Re: Looking for a little help with the win32 headers

2015-03-26 Thread Belly via Digitalmars-d-learn

On Thursday, 26 March 2015 at 17:41:37 UTC, rumbu wrote:

On Thursday, 26 March 2015 at 16:46:06 UTC, Belly wrote:
No, wait, the first code is even better because it uses the 
headers so I don't need to declare the API myself and it uses 
the MAX_COMPUTERNAME_LENGTH define, too, nice!


Using this will return only the first 15 characters of the 
computer name, if longer.


Please use the unicode version of the function GetComputerNameW 
instead of the ANSI one (GetComputerNameA), because the second 
one has a known bug, returning always 0 as required buffer size.


import std.stdio;
import std.c.windows.windows;

wstring getComputerName()
{
enum ERROR_BUFFER_OVERFLOW = 111;
uint size;
	if (GetComputerNameW(null, &size) == 0 && GetLastError() == 
ERROR_BUFFER_OVERFLOW)

{
wchar[] buf = new wchar[size];
if (GetComputerNameW(buf.ptr, &size))
return buf[0 .. size].idup;
}
return "Unknown";
}

int main(string[] argv)
{
writeln(getComputerName());
getchar();
return 0;
}


I changed the code to use GetComputerName, so I guess 
GetComputerNameA is actually used, right? Anyway it's not really 
important, I'm just playing around with winAPIs to get a feel of 
things. I'm making a simple health cheat for a game I've written 
in FreeBasic!


I'm going through a nice D2 tutorial here:
http://ddili.org/ders/d.en

If anyone reading this can save me some time and help me with 
this: How to declare a byte pattern, for example to pass to 
WriteProcessMemory?


I guess it's uint[] bytes;
How do I set it to 0x12345678 ?


Re: Looking for a little help with the win32 headers

2015-03-26 Thread rumbu via Digitalmars-d-learn

On Friday, 27 March 2015 at 01:27:25 UTC, Belly wrote:



If anyone reading this can save me some time and help me with 
this: How to declare a byte pattern, for example to pass to 
WriteProcessMemory?


I guess it's uint[] bytes;
How do I set it to 0x12345678 ?



Since WriteProcessMemory accepts a LPCVOID (that is const void*), 
you can use any type of array (provided that you will take care 
of endianess):


uint[] ints = [0x12345678];
ushort[] shorts = [0x1234, 0x5678];
ubyte[] bytes = [0x12, 0x34, 0x56, 0x78];

WriteProcessMemory(processHandle, address, ints.ptr, ints.length 
* 4 null);
WriteProcessMemory(processHandle, address, shorts.ptr, 
shorts.length * 2, null);
WriteProcessMemory(processHandle, address, bytes.ptr, 
bytes.length, null);






OT; Donald Knuth on beauty, efficiency, and the programmer as artist

2015-03-26 Thread Laeeth Isharc via Digitalmars-d-learn
An old essay that may yet be relevant today at a time when 
intellectual fashion has continued in the direction he was moved 
to address in his speech.


"there is a way to make a big improvement: it is still a pleasure 
to do routine jobs if we have beautiful things to work with. For 
example, a person will really enjoy wiping off the dining room 
table, day after day, if it is a beautifully designed table made 
from some fine quality hardwood."


"Language designers also have an obligation to provide languages 
that encourage good style, since we all know that style is 
strongly influenced by the language in which it is expressed. The 
present surge of interest in structured programming has revealed 
that none of our existing languages is really ideal for dealing 
with program and data structure"


http://www.paulgraham.com/knuth.html

CACM, December 1974

When Communications of the ACM began publication in 1959, the 
members of ACM'S Editorial Board made the following remark as 
they described the purposes of ACM'S periodicals [2]:
"If computer programming is to become an important part of 
computer research and development, a transition of programming 
from an art to a disciplined science must be effected."
Such a goal has been a continually recurring theme during the 
ensuing years; for example, we read in 1970 of the "first steps 
toward transforming the art of programming into a science" [26]. 
Meanwhile we have actually succeeded in making our discipline a 
science, and in a remarkably simple way: merely by deciding to 
call it "computer science."


Implicit in these remarks is the notion that there is something 
undesirable about an area of human activity that is classified as 
an "art"; it has to be a Science before it has any real stature. 
On the other hand, I have been working for more than 12 years on 
a series of books called "The Art of Computer Programming." 
People frequently ask me why I picked such a title; and in fact 
some people apparently don't believe that I really did so, since 
I've seen at least one bibliographic reference to some books 
called "The Act of Computer Programming."


In this talk I shall try to explain why I think "Art" is the 
appropriate word. I will discuss what it means for something to 
be an art, in contrast to being a science; I will try to examine 
whether arts are good things or bad things; and I will try to 
show that a proper viewpoint of the subject will help us all to 
improve the quality of what we are now doing.

...
As I was looking up these things about the meanings of "art," I 
found that authors have been calling for a transition from art to 
science for at least two centuries. For example, the preface to a 
textbook on mineralogy, written in 1784, said the following [17]: 
"Previous to the year 1780, mineralogy, though tolerably 
understood by many as an Art, could scarce be deemed a Science."


According to most dictionaries "science" means knowledge that has 
been logically arranged and systematized in the form of general 
"laws." The advantage of science is that it saves us from the 
need to think things through in each individual case; we can turn 
our thoughts to higher-level concepts. As John Ruskin wrote in 
1853 [32]: "The work of science is to substitute facts for 
appearances, and demonstrations for impressions."


It seems to me that if the authors I studied were writing today, 
they would agree with the following characterization: Science is 
knowledge which we understand so well that we can teach it to a 
computer; and if we don't fully understand something, it is an 
art to deal with it. Since the notion of an algorithm or a 
computer program provides us with an extremely useful test for 
the depth of our knowledge about any given subject, the process 
of going from an art to a science means that we learn how to 
automate something.

...
From this standpoint it is certainly desirable to make computer 
programming a science, and we have indeed come a long way in the 
15 years since the publication ot the remarks I quoted at the 
beginning of this talk. Fifteen years ago computer programming 
was so badly understood that hardly anyone even thought about 
proving programs correct; we just fiddled with a program until we 
"knew" it worked. At that time we didn't even know how to express 
the concept that a program was correct, in any rigorous way. It 
is only in recent years that we have been learning about the 
processes of abstraction by which programs are written and 
understood; and this new knowledge about programming is currently 
producing great payoffs in practice, even though few programs are 
actually proved correct with complete rigor, since we are 
beginning to understand the principles of program structure.

...
A scientific approach is generally characterized by the words 
logical, systematic, impersonal, calm, rational, while an 
artistic approach is characterized by the words aesthetic, 
creative, humanitarian, anxious,