Re: Interfacing with C - calling member function of D struct from C?

2017-06-24 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 25 June 2017 at 02:05:35 UTC, unleashy wrote:

How would I call `addToBar` from C code?


You don't. Instead write it like:

struct Foo
{
int bar;
}

extern(C) void addToBar(Foo* foo, int what) {
   foo.bar += what;
}


Then define it in C the same way and you call it the normal way 
from C.


But from D, you can UFCS call it:

Foo* foo = new Foo();
foo.addToBar(5); // cool


though I'd prolly just call it from D the same way you do from C 
too.


Interfacing with C - calling member function of D struct from C?

2017-06-24 Thread unleashy via Digitalmars-d-learn

Hello! If I have a D struct like:

struct Foo
{
int bar;

void addToBar(int what) {
bar += what;
}
}

How would I call `addToBar` from C code? Would I need to put the 
`addToBar` function outside of the struct and mark it as `extern 
(C)` and in normal D code take advantage of UFCS or is there some 
magic C incantation?


I've scoured the forums and other places for anything about this 
but couldn't find any information whatsoever... so yeah. (or my 
Google-fu is terrible)


Thanks!


Re: casting to structure

2017-06-24 Thread Igor Shirkalin via Digitalmars-d-learn

On Saturday, 24 June 2017 at 21:41:22 UTC, Moritz Maxeiner wrote:

Hi, unfortunately not:
- Operator overloading is supported via member functions only 
[1].
- Corollary: You cannot overload operators for builtin types 
(i.e. where the cast gets rewritten to `e.opOverloaded` where 
`e` is a builtin type)
- opCast needs to be defined for the type that you are casting 
from [2], not the one you are casting to

=> You cannot overload opCast for casting from builtin types
[...]
You cannot. As any such cast operation would have to create a 
new A object, anyway (and would as such be a wrapper around a 
(possibly default) constructor), I suggest using elaborate 
constructors:


Thank you for your detailed explanation!


Word of warning, though: What you're doing is highly unsafe.


I guess it is unsafe, but core.sys.windows module works this way.


That *is* how the Windows C API works AFAIK.


I have no choice except for using it as it is.

Define a struct for HWND as shown above for A and use 
constructors. Add an `alias this` to the wrapped pointer value.


That was the first thing I did. And it is led me to my question.

Thank you!






Re: casting to structure

2017-06-24 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 24 June 2017 at 21:11:13 UTC, Igor Shirkalin wrote:

Is it possible without such a constructor?


No. Also, the above works because of the following [1]:

Casting a value v to a struct S, when value is not a struct of 
the same type, is equivalent to: `S(v)`


[1] https://dlang.org/spec/expression.html#CastExpression


Re: casting to structure

2017-06-24 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 24 June 2017 at 20:43:48 UTC, Igor Shirkalin wrote:

I'm in trouble with opCast function.
Is it possible to cast some (integral) type to user defined 
structure?


Hi, unfortunately not:
- Operator overloading is supported via member functions only [1].
- Corollary: You cannot overload operators for builtin types 
(i.e. where the cast gets rewritten to `e.opOverloaded` where `e` 
is a builtin type)
- opCast needs to be defined for the type that you are casting 
from [2], not the one you are casting to

=> You cannot overload opCast for casting from builtin types


[...]

How can we define opCast operator to make the following 
expression working properly?


auto a = cast(A) 12;


You cannot. As any such cast operation would have to create a new 
A object, anyway (and would as such be a wrapper around a 
(possibly default) constructor), I suggest using elaborate 
constructors:


---
struct A
{
void* data;

this(int data) { this.data = cast(void*) data; }
}

...

auto a = A(12);
---



The task arised from core.sys.windows module. This module 
defines a lot of windows specific types based on HANDLE: these 
are HWND, HDC, HBITMAP, etc. The problem is that all these 
types are identical, and it is too bad.


Why is this a problem? That *is* how the Windows C API works 
AFAIK.
Typesafety would require a higher abstraction level than the 
Windows C API functions provide, anyway.



When I redefine these types like:
   alias Typedef!(void*) HDC;

I have another problem:

  HWND_MESSAGE = cast(HWND) -3;  // Error: cannot cast 
expression -3 of type int to Typedef!(void*, null, null)


You have explicitly asked for those two types to be different 
from each other [3]; that means they are also *not* implicitly 
convertible to each other and thus you also cannot cast from one 
to the other without defining an opCast (which you can't in this 
case, since the source type is a builtin type).



So, is there any solution to this?


Define a struct for HWND as shown above for A and use 
constructors. Add an `alias this` to the wrapped pointer value.

Word of warning, though: What you're doing is highly unsafe.

[1] https://dlang.org/spec/operatoroverloading.html
[2] https://dlang.org/spec/operatoroverloading.html#cast
[3] https://dlang.org/phobos/std_typecons.html#.Typedef


Re: casting to structure

2017-06-24 Thread Igor Shirkalin via Digitalmars-d-learn

On Saturday, 24 June 2017 at 20:43:48 UTC, Igor Shirkalin wrote:

struct A
{
  void * data; // void * type is just for example
  // no matter what is here
}


I know that if I add constructor  this(int)

struct A {
void * p;
this(int k) { p = cast(void*)k; }
}

auto a = cast(A) 23; // it works

Is it possible without such a constructor?



casting to structure

2017-06-24 Thread Igor Shirkalin via Digitalmars-d-learn

Hello!

I'm in trouble with opCast function.
Is it possible to cast some (integral) type to user defined 
structure?


We have a structure:

struct A
{
  void * data; // void * type is just for example
  // no matter what is here
}

How can we define opCast operator to make the following 
expression working properly?


auto a = cast(A) 12;

The task arised from core.sys.windows module. This module defines 
a lot of windows specific types based on HANDLE: these are HWND, 
HDC, HBITMAP, etc. The problem is that all these types are 
identical, and it is too bad. When I redefine these types like:

   alias Typedef!(void*) HDC;

I have another problem:

  HWND_MESSAGE = cast(HWND) -3;  // Error: cannot cast expression 
-3 of type int to Typedef!(void*, null, null)


So, is there any solution to this?





Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread via Digitalmars-d-learn

On Saturday, 24 June 2017 at 18:46:06 UTC, ketmar wrote:

Petar Kirov [ZombineDev] wrote:

Oh, I should have mentioned that I don't expect anything but 
ugly platform-specific hacks possibly involving the object 
file format ;)
Just enough of them to claim that the solution is somewhat 
cross-platform :D


i guess you can loot at how TSL scanning is done in druntime 
(at least on GNU/Linux). it does some parsing of internal 
structures of loaded ELF. i guess you can parse section part of 
the loaded ELF too, to find out r/o sections and their address 
ranges.


that's the stuff :P


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread ketmar via Digitalmars-d-learn

Petar Kirov [ZombineDev] wrote:

Oh, I should have mentioned that I don't expect anything but ugly 
platform-specific hacks possibly involving the object file format ;)
Just enough of them to claim that the solution is somewhat cross-platform 
:D


i guess you can loot at how TSL scanning is done in druntime (at least on 
GNU/Linux). it does some parsing of internal structures of loaded ELF. i 
guess you can parse section part of the loaded ELF too, to find out r/o 
sections and their address ranges.


Re: Targetting the 8051

2017-06-24 Thread Russel Winder via Digitalmars-d-learn
On Sat, 2017-06-24 at 18:04 +, FoxyBrown via Digitalmars-d-learn
wrote:
> Is it possible? Using LDC or GCC? I do not need any libraries, 
> druntime, etc. Just bare bones with the nice D meta 
> features(templates, etc).

Sorry but this is an ill-defined wish list. 8051 processors about in
the world just as they did 15 years ago. They are however very low
level things. Most people use assembler or specially extended C – to
deal with the 8-bit structure and the bit-addressable values some 8051
variants have. Trying to work with a 32-bit or 64-bit focused language
on an 8-bit target is never going to work particularly well.

-- 
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: What's the fastest way to check if a slice points to static data

2017-06-24 Thread via Digitalmars-d-learn

On Saturday, 24 June 2017 at 18:05:55 UTC, ketmar wrote:

Petar Kirov [ZombineDev] wrote:


***
But in any case, the null-terminated string was just an 
example application.
I'm interested in a fast way to determine the "storage class" 
of the memory
a slice or a pointer point to. I'm expecting some magic along 
the lines of
checking the range of addresses that the rodata section 
resides in memory.
Similar to how some allocators or the GC know if they own a 
range of memory.

Any ideas on that?
***


the only query you can do is GC query (see `core.memory.CG` 
namespace, `addrOf()` API, for example). it will tell you if 
something was allocated with D GC or not.


yet it is not guaranteed to be fast (althru it is usually "fast 
enough").


I'm not interested in asking the GC specifically,
but I have looked at its implementation and I know
that it keeps such information around:
https://github.com/dlang/druntime/blob/v2.074.1/src/gc/impl/conservative/gc.d#L843

i think this is all what you can get without resorting to ugly 
platform-specific hacks (that will inevitably break ;-).


Oh, I should have mentioned that I don't expect anything but ugly 
platform-specific hacks possibly involving the object file format 
;)
Just enough of them to claim that the solution is somewhat 
cross-platform :D


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread ketmar via Digitalmars-d-learn

Petar Kirov [ZombineDev] wrote:


***
But in any case, the null-terminated string was just an example 
application.
I'm interested in a fast way to determine the "storage class" of the 
memory

a slice or a pointer point to. I'm expecting some magic along the lines of
checking the range of addresses that the rodata section resides in memory.
Similar to how some allocators or the GC know if they own a range of 
memory.

Any ideas on that?
***


the only query you can do is GC query (see `core.memory.CG` namespace, 
`addrOf()` API, for example). it will tell you if something was allocated with D 
GC or not.


yet it is not guaranteed to be fast (althru it is usually "fast enough").

i think this is all what you can get without resorting to ugly 
platform-specific hacks (that will inevitably break ;-).


Targetting the 8051

2017-06-24 Thread FoxyBrown via Digitalmars-d-learn
Is it possible? Using LDC or GCC? I do not need any libraries, 
druntime, etc. Just bare bones with the nice D meta 
features(templates, etc).


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread via Digitalmars-d-learn

On Saturday, 24 June 2017 at 14:18:33 UTC, ketmar wrote:


with the edge case when something like the code i posted below 
managed to make `a` perfectly aligned with r/o area, and you 
got segfault by accising out-of-bounds byte.


BTW, are you sure? AFAIU, it doesn't matter if the CTFE engine 
returns a
non-null-terminated string expression, since the backend or 
the glue layer
would write it to the object file as if it was a 
null-terminated string.


immutable ubyte[2] a = [65,66];
enum string s = cast(string)a;
	immutable ubyte[2] b = [67,68]; // just to show you that there 
is no zero


void main () {
  assert(s[$-1] == 0);
}


Thanks, I haven't considered immutable statically allocated 
fixed-size arrays of chars.
Specifically, while mutable fixed-size arrays of both character 
and non-character type
are common, I don't think immutable fixed-size char arrays are 
much used compared to string literals and ctfe-derived strings. 
I'm tempted to write in the documentation of my hypothetical 
fastStringZ function that passing anything, but something 
originating from a slice is UB, though I'm aware how 
under-specified and hand-wavy this sounds.


On Saturday, 24 June 2017 at 14:21:23 UTC, ketmar wrote:

ketmar wrote:

p.s.: btw, druntime tries to avoid that edge case by not 
checking for trailing out-of-bounds zero if string ends 
exactly on dword boundary. it will miss some strings this way, 
but otherwise it is perfectly safe.


oops. not druntime, phobos, in `std.string.toStringz()`.


Thanks, for some reason I assumed that toStringz always 
conservatively copies the string, without even checking the code.
It looks like the more aggressive optimization was at some point 
removed which is visible in this revision:

http://www.dsource.org/projects/phobos/changeset/101#file15
and later Andrei reintroduced it with the more conservative 
heuristic: 
https://github.com/dlang/phobos/commit/460c844b4fb9b96833871c111dd529d22129ab7c,

but I didn't manage to find any discussion about it.

***
But in any case, the null-terminated string was just an example 
application.
I'm interested in a fast way to determine the "storage class" of 
the memory
a slice or a pointer point to. I'm expecting some magic along the 
lines of
checking the range of addresses that the rodata section resides 
in memory.
Similar to how some allocators or the GC know if they own a range 
of memory.

Any ideas on that?
***


Re: Help me escape optional parens hell

2017-06-24 Thread Meta via Digitalmars-d-learn

On Saturday, 24 June 2017 at 08:08:33 UTC, ketmar wrote:

Meta wrote:

So I have no clue what I'm doing wrong. This is driving me 
insane.


h. known $#^#$@^@%.

	enum SymName = ().stringof[2..$]; // this, instead of 
symbol.stringof


dirty hack, let's hope that DMD devs won't change `.toString()` 
output (i.e. first two chars will always be "& ").


besides this, i know no other way to stop compiler from calling 
the function there.


It's dirty but I guess I'll have to go with this hack for the 
time being.


Also, I filed a bug:

https://issues.dlang.org/show_bug.cgi?id=17546


Re: Are padding bits always zero?

2017-06-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/24/17 10:32 AM, Honey wrote:

On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer wrote:
Any padding bits between fields should be 0 as long as the struct is 
initialized (i.e. as long as you don't do Struct s = void).


Padding bits after the fields I assume would be 0, but I don't know if 
this is defined. It's possible the compiler doesn't consider those 
bits to be part of the struct, and just there for alignment.


There is no spec for this, but I know that when the compiler has to 
fill gaps with something it chooses 0.


Thanks. Your answer has generated more questions. ;-)

Let's say, I have a struct S of size n with m bits of padding at the 
end. How can I find m?


Is it possible to provide a facility Pad such that for any struct T, 
Pad!T is a struct that mimics T but contains explicit instead of 
implicit padding? E.g.


struct Foo
{
ubyte b;
double d;
int i;
}

struct Pad!Foo
{
ubyte b;
ubyte[7] __padding_0;
double d;
int i;
ubyte[4] __padding_1;
}


Of course it's possible. Best thing I can think of is using offsetof and 
sizeof:


string generatePad(T)()
{
   string result = "";
   size_t lastIndex = 0;
   foreach(x; T.tupleof)
   {
   // not sure about offsetof working like this, you may need to do
   // tupleof with index
   auto padSpace = x.offsetof - lastIndex;
   if(padSpace > 0) result ~= "ubyte[" ~ padSpace ~ "] __padding__" 
~ padIndex ~ ";";

   result ~= typeof(x).stringof ~ " " ~ x.stringof ~ ";";
   lastIndex = x.offsetof + x.sizeof;
   }
   return result;
}

This needs a bit of work, but you get the idea. I'm not sure all the 
properties work correctly there. Then you mixin the result of that 
function to get your members. Adding the ending padding would involve 
comparing lastIndex to the sizeof T.


-Steve


Re: Are padding bits always zero?

2017-06-24 Thread Honey via Digitalmars-d-learn

On Saturday, 24 June 2017 at 14:03:16 UTC, Adam D. Ruppe wrote:
On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer 
wrote:
There is no spec for this, but I know that when the compiler 
has to fill gaps with something it chooses 0.


I'm almost certain there at least used to be a spec for this, 
because I remember citing a link to someone who then complained 
that this zero requirement hurt optimization of void members. 
On the other hand though, the zero padding requirement does 
simplify equality to being memcmp.


The only hint I could find is this statement from Walter:

   http://forum.dlang.org/post/hn11oh$1usk$1...@digitalmars.com




Re: Are padding bits always zero?

2017-06-24 Thread Honey via Digitalmars-d-learn

On Saturday, 24 June 2017 at 14:03:16 UTC, Adam D. Ruppe wrote:
On the other hand though, the zero padding requirement does 
simplify equality to being memcmp.


That's the reason for my question.


Re: Are padding bits always zero?

2017-06-24 Thread Honey via Digitalmars-d-learn
On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer 
wrote:
Any padding bits between fields should be 0 as long as the 
struct is initialized (i.e. as long as you don't do Struct s = 
void).


Padding bits after the fields I assume would be 0, but I don't 
know if this is defined. It's possible the compiler doesn't 
consider those bits to be part of the struct, and just there 
for alignment.


There is no spec for this, but I know that when the compiler 
has to fill gaps with something it chooses 0.


Thanks. Your answer has generated more questions. ;-)

Let's say, I have a struct S of size n with m bits of padding at 
the end. How can I find m?


Is it possible to provide a facility Pad such that for any struct 
T, Pad!T is a struct that mimics T but contains explicit instead 
of implicit padding? E.g.


struct Foo
{
   ubyte b;
   double d;
   int i;
}

struct Pad!Foo
{
   ubyte b;
   ubyte[7] __padding_0;
   double d;
   int i;
   ubyte[4] __padding_1;
}


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread ketmar via Digitalmars-d-learn

ketmar wrote:

p.s.: btw, druntime tries to avoid that edge case by not checking for 
trailing out-of-bounds zero if string ends exactly on dword boundary. it 
will miss some strings this way, but otherwise it is perfectly safe.


oops. not druntime, phobos, in `std.string.toStringz()`.


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread ketmar via Digitalmars-d-learn
p.s.: btw, druntime tries to avoid that edge case by not checking for 
trailing out-of-bounds zero if string ends exactly on dword boundary. it 
will miss some strings this way, but otherwise it is perfectly safe.


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread ketmar via Digitalmars-d-learn

Petar Kirov [ZombineDev] wrote:

Please note that not all static immutable strings have to be null 
terminated.
It is possible to generate a string at ctfe which may appear the same as 
string literal, but does not have the \0 at the end.


But in that case, the check `s.ptr[s.length] == 0` in fastStringZ
would do the trick, right?


with the edge case when something like the code i posted below managed to 
make `a` perfectly aligned with r/o area, and you got segfault by accising 
out-of-bounds byte.



BTW, are you sure? AFAIU, it doesn't matter if the CTFE engine returns a
non-null-terminated string expression, since the backend or the glue layer
would write it to the object file as if it was a null-terminated string.


immutable ubyte[2] a = [65,66];
enum string s = cast(string)a;
immutable ubyte[2] b = [67,68]; // just to show you that there is no 
zero

void main () {
  assert(s[$-1] == 0);
}



Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread via Digitalmars-d-learn

On Saturday, 24 June 2017 at 13:11:02 UTC, Stefan Koch wrote:
On Saturday, 24 June 2017 at 12:22:54 UTC, Petar Kirov 
[ZombineDev] wrote:

[ ... ]

/**
 * Returns:
 * A pointer to a null-terminated string in O(1) time,
 * (with regards to the length of the string and the required
 * memory, if any) or `null` if  * the time constraint
 * can't be met.
 */
immutable(T)* fastStringZ(T)(return immutable(T)[] s) @trusted
if (isSomeChar!T)
{
if (isStaticallyAllocated(s) && s.ptr[s.length] == 0)
return s.ptr;
else
return null;
}
---

(Without `isStaticallyAllocated`, `fastStringZ` may *appear* to
work but if you pass the pointer to e.g. a C library and that
library keeps it after the call has completed, good luck 
tracking
memory corruption if the slice was pointing to 
automatic/dynamic
memory - e.g. static array buffer on the stack or GC / RC * 
heap

allocation.
* malloc or custom allocator + smart pointer wrapper)


Please note that not all static immutable strings have to be 
null terminated.
It is possible to generate a string at ctfe which may appear 
the same as string literal, but does not have the \0 at the end.


But in that case, the check `s.ptr[s.length] == 0` in fastStringZ
would do the trick, right?

BTW, are you sure? AFAIU, it doesn't matter if the CTFE engine 
returns a
non-null-terminated string expression, since the backend or the 
glue layer
would write it to the object file as if it was a null-terminated 
string.
But you're right if you mean that this trick won't work in CTFE, 
since

the `s.ptr[s.length] == 0` trick rightfully is disallowed.

---
void main()
{
static immutable str = generateString();
pragma (msg, str, " is null-terminated at CT: ", 
str.isNullTerminated());


import std.stdio;
writeln(str, " is null-terminated at RT: ", 
str.isNullTerminated());

}

string generateString()
{
string res;
foreach (i; 0 .. 26) res ~= 'a' + i;
return res;
}

import std.traits : isSomeChar;

bool isNullTerminated(T)(scope const T[] str)
if (isSomeChar!T)
{
if (!__ctfe)
return str.ptr[str.length] == 0;
else
return false;
}
---

Compilation output:
abcdefghijklmnopqrstuvwxyz is null-terminated at CT: false

Application output:
abcdefghijklmnopqrstuvwxyz is null-terminated at RT: true




Re: Converting a ubyte[] to a struct with respect to endianness?

2017-06-24 Thread Stefan Koch via Digitalmars-d-learn

On Saturday, 24 June 2017 at 02:52:23 UTC, Felix wrote:
I'm trying to read in just the first part of a .png file to 
peek at it's width and height without loading in the whole 
file. I'm using FreeImage for reading the whole file but since 
it doesn't have a function to let me peek at the image size 
before loading it all in I'm rolling my own.


I've gotten as a far as reading in the first 16 bytes which 
includes an 8 byte signature, then the length and type of the 
first chunk:


struct Header {
ubyte[8] signature;
uint length;
char[4] type;
}
union Un {
Header h;
ubyte[16] u;
}

auto f = File(path, "r");
foreach (ubyte[] buffer; f.byChunk(16)){
Un fff;
fff.u = buffer[0..16];
writeln(fff.h);
break;
}

It prints out:
Header([137, 80, 78, 71, 13, 10, 26, 10], 218103808, "IHDR")

The signature is correct, the type is correct, but the value I 
get for length should be 13, not 218103808. So I'm guessing my 
ubytes are in the wrong order in the uint... how should I put 
them around the correct way so that my code won't break on 
another machine with different endianness?


I would advise a look at sqlite.d 
https://github.com/UplinkCoder/sqlite-d
which solves the same problem albeit for sqlite database files 
and for png.
But it provides the means of simply putting a BigEndian!uint into 
your struct and have conversion on stuff be automatically handled.


Re: Are padding bits always zero?

2017-06-24 Thread Adam D. Ruppe via Digitalmars-d-learn
On Saturday, 24 June 2017 at 12:41:47 UTC, Steven Schveighoffer 
wrote:
There is no spec for this, but I know that when the compiler 
has to fill gaps with something it chooses 0.


I'm almost certain there at least used to be a spec for this, 
because I remember citing a link to someone who then complained 
that this zero requirement hurt optimization of void members. On 
the other hand though, the zero padding requirement does simplify 
equality to being memcmp.


I can't find the reference now. Perhaps I'm looking in the wrong 
place... or perhaps that optimization complaint actually got the 
requirement removed from the spec.


I don't know. (I find search of most D stuff to be fruitless and 
heavily rely on my old brain memory to index these things, but 
while my memory is pretty good, it isn't flawless.)


Re: What's the fastest way to check if a slice points to static data

2017-06-24 Thread Stefan Koch via Digitalmars-d-learn
On Saturday, 24 June 2017 at 12:22:54 UTC, Petar Kirov 
[ZombineDev] wrote:

[ ... ]

/**
 * Returns:
 * A pointer to a null-terminated string in O(1) time,
 * (with regards to the length of the string and the required
 * memory, if any) or `null` if  * the time constraint
 * can't be met.
 */
immutable(T)* fastStringZ(T)(return immutable(T)[] s) @trusted
if (isSomeChar!T)
{
if (isStaticallyAllocated(s) && s.ptr[s.length] == 0)
return s.ptr;
else
return null;
}
---

(Without `isStaticallyAllocated`, `fastStringZ` may *appear* to
work but if you pass the pointer to e.g. a C library and that
library keeps it after the call has completed, good luck 
tracking

memory corruption if the slice was pointing to automatic/dynamic
memory - e.g. static array buffer on the stack or GC / RC * heap
allocation.
* malloc or custom allocator + smart pointer wrapper)


Please note that not all static immutable strings have to be null 
terminated.
It is possible to generate a string at ctfe which may appear the 
same as string literal, but does not have the \0 at the end.


Re: Are padding bits always zero?

2017-06-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/24/17 4:44 AM, Honey wrote:

Hi everyone!

Are there any guarantees about the values of padding bits in structs?

Thanks,
Honey


Any padding bits between fields should be 0 as long as the struct is 
initialized (i.e. as long as you don't do Struct s = void).


Padding bits after the fields I assume would be 0, but I don't know if 
this is defined. It's possible the compiler doesn't consider those bits 
to be part of the struct, and just there for alignment.


There is no spec for this, but I know that when the compiler has to fill 
gaps with something it chooses 0.


-Steve


Re: Converting a ubyte[] to a struct with respect to endianness?

2017-06-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/24/17 1:18 AM, H. S. Teoh via Digitalmars-d-learn wrote:

On Fri, Jun 23, 2017 at 10:10:22PM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:

On 06/23/2017 09:26 PM, Felix wrote:

That works, thanks!


I've just tried this, which seems cleaner:

import std.stdio;
import std.system;
import std.bitmanip;

void ensureBigEndian(T)(ref T value) {
 if (endian == Endian.littleEndian) {
 value = *cast(T*)nativeToBigEndian(value).ptr;
 }


This is wrong, you should be detecting the endianness of the input and
use {big,little}EndianToNative instead.  For example, if the input is
big endian, you should use bigEndianToNative.  Internally, if native is
already big endian, it will do nothing; otherwise it will swap the
endianness. This way you don't have to check the current machine's
endianness yourself; you can just recompile on a machine of different
endianness and it will Just Work.


I would also point out that there are pre-defined versions for 
endianness: version(BigEndian) and version(LittleEndian). This makes 
static checking a lot easier when you are writing your own code that 
deals with endiannness.


For byte-swapping one field, I would use the standard tools as H.S. has 
advised.


-Steve


What's the fastest way to check if a slice points to static data

2017-06-24 Thread via Digitalmars-d-learn
I need a fast and hopefully relatively cross-platform (ELF, OMF, 
COFF and MachO) way of checking if a slice points to data in the 
read-only section of the binary, i.e. it's pointing to a 
statically-allocated piece of memory.




Of course a simple solution using meta programming would be:

---
enum isStaticallyAllocated(alias var) = __traits(compiles,
{
// ensures that the value is known at compile-time
enum value = var;

// ensures that it's not a manifest constant and that it's
// actually going to be part of the binary (modulo linker
// optimizations like gc-sections).
static immutable addr = 
});

enum x = 3;
static immutable y = 4;
immutable z = 5;
int w = 6;

void main()
{
enum localX = 3;
static immutable localY = 4;
immutable localZ = 5;
int localW = 6;

pragma (msg, isStaticallyAllocated!x); // false
pragma (msg, isStaticallyAllocated!y); // true
pragma (msg, isStaticallyAllocated!z); // true
pragma (msg, isStaticallyAllocated!w); // false
pragma (msg, isStaticallyAllocated!localX); // false
pragma (msg, isStaticallyAllocated!localY); // true
pragma (msg, isStaticallyAllocated!localZ); // false
pragma (msg, isStaticallyAllocated!localW); // false
}
---

However, that doesn't work when all you have is a slice as a 
run-time

argument to a function.



Additionally, if the the slice was constructed from a string 
literal,
it should possible to recover a pointer to the zero-terminated 
string.


Or in pseudo-code:

---
void main()
{
import core.stdc.stdio : printf;
auto p = "test".fastStringZ;
p || assert(0, "Something is terribly wrong!");
printf("%s\n", p);
}

import std.traits : isSomeChar;

// Does the magic
bool isStaticallyAllocated(in scope void[] slice)
{
// XXX_XXX Fix me
return true;
}

/**
 * Returns:
 * A pointer to a null-terminated string in O(1) time,
 * (with regards to the length of the string and the required
 * memory, if any) or `null` if  * the time constraint
 * can't be met.
 */
immutable(T)* fastStringZ(T)(return immutable(T)[] s) @trusted
if (isSomeChar!T)
{
if (isStaticallyAllocated(s) && s.ptr[s.length] == 0)
return s.ptr;
else
return null;
}
---

(Without `isStaticallyAllocated`, `fastStringZ` may *appear* to
work but if you pass the pointer to e.g. a C library and that
library keeps it after the call has completed, good luck tracking
memory corruption if the slice was pointing to automatic/dynamic
memory - e.g. static array buffer on the stack or GC / RC * heap
allocation.
* malloc or custom allocator + smart pointer wrapper)


Re: Help me escape optional parens hell

2017-06-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/24/17 3:53 AM, Meta wrote:

The code:

alias Response = Nullable!(string, "empty response (error)");

Response processMessage(string commandModule)(string message, bool 
isCommand)

{
 import std.meta;
 import std.string;
 import std.traits;

 import command_uda;

 mixin("import " ~ commandModule ~ ';');
 bool foundCommandMatch = false;
 foreach(symbol; getSymbolsByUDA!(mixin(commandModule), Command))
 {
 enum commandUDA = getUDAs!(symbol, Command)[0];
 auto commandPhrase = commandUDA.phrase == "" ? symbol.stringof 
: commandUDA.phrase; //Error: function  is not 
callable using argument types ()

 auto commandPhrasePattern = regex(`^%s\s`.format(commandPhrase));
 if (message.matchFirst(commandPhrasePattern) && 
!foundCommandMatch)

 {
 version(responseDebug) writeln("Matched command ", 
symbol.stringof, " with phrase '", commandPhrase, "'\n"); //Same issue

 return Response(symbol(message.strip()));
 }
 }

 return Response.init;
}

I've been banging my head against this and cannot figure out why 
`symbol.stringof` is being called instead of getting a string of the 
symbol. I tried to create a reduced test case but it works fine:


import std.stdio;
import std.traits;

enum Attr;

@Attr string test1() { return __FUNCTION__; }
@Attr string test2() { return __FUNCTION__; }

void process()
{
 foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr))
 {
 writeln("The result of calling ", symbol.stringof, " is ", 
symbol());

 }
}

void main()
{
 process();
}

So I have no clue what I'm doing wrong. This is driving me insane.


I know what you are doing wrong in your reduced case. Try this instead:

@Attr string test1(int) { return __FUNCTION__; }
@Attr string test2(int) { return __FUNCTION__; }

void process()
{
foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr))
{
writeln("The result of calling ", symbol.stringof, " is ", 
symbol(1));

}
}

The reason your version "works" is because your functions actually are 
callable with no args!


I tried many things including:

enum symbolname = symbol.stringof;
enum symbolname = (symbol).stringof;
pragma(msg, symbol.stringof);

Nothing works. If this isn't already a bug, you should file it. Aside 
from ketmar's workaround, I can't think of one.


It's interesting that the ability to call without parentheses is what 
causes the error, yet when you *can* call without parentheses, it 
doesn't actually do so (symbol.stringof prints the name of the symbol). 
This seems very obviously to be a bug.


-Steve


Re: More optional parens concerns

2017-06-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, June 24, 2017 9:56:55 AM MDT Russel Winder via Digitalmars-d-
learn wrote:
> I note that:
>
>   x.map!(…).array.sort
>
> is not valid, you have to have the parentheses on sort:
>
>   x.map!(…).array.sort()
>
> Why?

Because the built-in sort for arrays has been deprecated but not yet
removed. So, for now, calling sort on an array without parens calls the
built-in sort. Once the built-in sort has been removed, then this problem
will go away.

- Jonathan M Davis




Re: More optional parens concerns

2017-06-24 Thread ketmar via Digitalmars-d-learn

Russel Winder wrote:


On Sat, 2017-06-24 at 11:58 +0300, ketmar via Digitalmars-d-learn
wrote:

Russel Winder wrote:


I note that:
x.map!(…).array.sort
is not valid, you have to have the parentheses on sort:
x.map!(…).array.sort()
Why?

built-in property .sort kicks in and ruins the day. luckily, it will
be completely removed in the upcoming major release.


Ah, thanks. We like stuff being removed as well as added.


sort and .reverse builtins was deprecated for a long time, and scheduled 
to be removed anyway. finally, this happens! (the patch is in git already)


Re: More optional parens concerns

2017-06-24 Thread Russel Winder via Digitalmars-d-learn
On Sat, 2017-06-24 at 11:58 +0300, ketmar via Digitalmars-d-learn
wrote:
> Russel Winder wrote:
> 
> > I note that:
> > 
> > x.map!(…).array.sort
> > 
> > is not valid, you have to have the parentheses on sort:
> > 
> > x.map!(…).array.sort()
> > 
> > Why?
> 
> built-in property .sort kicks in and ruins the day. luckily, it will
> be 
> completely removed in the upcoming major release.

Ah, thanks. We like stuff being removed as well as added.

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


Alias template parameter to a private function

2017-06-24 Thread Sebastien Alaiwan via Digitalmars-d-learn

Hi,

I'm trying to call std.algorithm.iteration.filter with a private 
function as a predicate.

Here's a reduced example code:

// yo.d
import std.algorithm;

void moduleEntryPoint()
{
  privateFunction1();
  privateFunction2();
}

private:

void privateFunction1()
{
  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is 
private

}

void privateFunction2()
{
  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is 
private

}

bool isValid(int i)
{
  return i % 2 == 0;
}

Here's the compiler output:

/usr/include/dmd/phobos/std/algorithm/iteration.d(1132): Error: 
function yo.isValid is not accessible from module iteration
yo.d(14): Error: template instance 
std.algorithm.iteration.filter!(isValid).filter!(int[]) error 
instantiating


This seems like the compiler, when instanciating the calls to 
'filter', is resolving 'isValid' from std.algorithm.iteration 
scope (however, this isn't actually the case, see below).
I was expecting this identifier to be resolved from yo.d, where 
we have access to the private functions.


Surprisingly, the following works:

void privateFunction2()
{
  static bool isValid(int i)
  {
return i % 2 == 0;
  }

  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is 
private

}

This makes the instanciation of 'filter' "see" 'isValid', 
however, now, the other privateFunctions can't use it.


Am I missing something here?
Thanks!



Re: More optional parens concerns

2017-06-24 Thread ketmar via Digitalmars-d-learn

Russel Winder wrote:


I note that:

x.map!(…).array.sort

is not valid, you have to have the parentheses on sort:

x.map!(…).array.sort()

Why?


built-in property .sort kicks in and ruins the day. luckily, it will be 
completely removed in the upcoming major release.


More optional parens concerns

2017-06-24 Thread Russel Winder via Digitalmars-d-learn
I note that:

x.map!(…).array.sort

is not valid, you have to have the parentheses on sort:

x.map!(…).array.sort()

Why?

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


Are padding bits always zero?

2017-06-24 Thread Honey via Digitalmars-d-learn

Hi everyone!

Are there any guarantees about the values of padding bits in 
structs?


Thanks,
Honey


Re: Help me escape optional parens hell

2017-06-24 Thread ketmar via Digitalmars-d-learn

ketmar wrote:


Meta wrote:


So I have no clue what I'm doing wrong. This is driving me insane.


h. known $#^#$@^@%.

	enum SymName = ().stringof[2..$]; // this, instead of 
symbol.stringof


dirty hack, let's hope that DMD devs won't change `.toString()` output 
(i.e. first two chars will always be "& ").


besides this, i know no other way to stop compiler from calling the 
function there.


i hope devs won't break string representation: i bet that there is ALOT of 
code that is using this trick. i myself borrowed it from some other module 
several years ago. and it looks that the module where i found it borrowed 
the trick from some another module. a really long history. ;-)


Re: Help me escape optional parens hell

2017-06-24 Thread ketmar via Digitalmars-d-learn

Meta wrote:


So I have no clue what I'm doing wrong. This is driving me insane.


h. known $#^#$@^@%.

enum SymName = ().stringof[2..$]; // this, instead of 
symbol.stringof

dirty hack, let's hope that DMD devs won't change `.toString()` output 
(i.e. first two chars will always be "& ").


besides this, i know no other way to stop compiler from calling the function 
there.


Re: Help me escape optional parens hell

2017-06-24 Thread ketmar via Digitalmars-d-learn

ketmar wrote:


`.toString()`


toChars().

;-)


Help me escape optional parens hell

2017-06-24 Thread Meta via Digitalmars-d-learn

The code:

alias Response = Nullable!(string, "empty response (error)");

Response processMessage(string commandModule)(string message, 
bool isCommand)

{
import std.meta;
import std.string;
import std.traits;

import command_uda;

mixin("import " ~ commandModule ~ ';');
bool foundCommandMatch = false;
foreach(symbol; getSymbolsByUDA!(mixin(commandModule), 
Command))

{
enum commandUDA = getUDAs!(symbol, Command)[0];
auto commandPhrase = commandUDA.phrase == "" ? 
symbol.stringof : commandUDA.phrase; //Error: function signature> is not callable using argument types ()
auto commandPhrasePattern = 
regex(`^%s\s`.format(commandPhrase));
if (message.matchFirst(commandPhrasePattern) && 
!foundCommandMatch)

{
version(responseDebug) writeln("Matched command ", 
symbol.stringof, " with phrase '", commandPhrase, "'\n"); //Same 
issue

return Response(symbol(message.strip()));
}
}

return Response.init;
}

I've been banging my head against this and cannot figure out why 
`symbol.stringof` is being called instead of getting a string of 
the symbol. I tried to create a reduced test case but it works 
fine:


import std.stdio;
import std.traits;

enum Attr;

@Attr string test1() { return __FUNCTION__; }
@Attr string test2() { return __FUNCTION__; }

void process()
{
foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr))
{
		writeln("The result of calling ", symbol.stringof, " is ", 
symbol());

}
}

void main()
{
process();
}

So I have no clue what I'm doing wrong. This is driving me insane.


Re: Converting a ubyte[] to a struct with respect to endianness?

2017-06-24 Thread Ali Çehreli via Digitalmars-d-learn

On 06/23/2017 10:18 PM, H. S. Teoh via Digitalmars-d-learn wrote:

On Fri, Jun 23, 2017 at 10:10:22PM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:

On 06/23/2017 09:26 PM, Felix wrote:

That works, thanks!


I've just tried this, which seems cleaner:

import std.stdio;
import std.system;
import std.bitmanip;

void ensureBigEndian(T)(ref T value) {
if (endian == Endian.littleEndian) {
value = *cast(T*)nativeToBigEndian(value).ptr;
}


This is wrong, you should be detecting the endianness of the input and
use {big,little}EndianToNative instead.  For example, if the input is
big endian, you should use bigEndianToNative.  Internally, if native is
already big endian, it will do nothing; otherwise it will swap the
endianness. This way you don't have to check the current machine's
endianness yourself; you can just recompile on a machine of different
endianness and it will Just Work.


T



Thanks. Something like this:

import std.stdio;
import std.system;
import std.bitmanip;

void ensureCorrectFromBigEndian(T)(ref T value) {
value = bigEndianToNative!(T, T.sizeof)(*cast(ubyte[T.sizeof]*));
}

struct S {
uint u;
}

void main() {
// Bytes on the wire
ubyte[] bytes = [ 0, 0, 0, 13 ];

// Overlaying an object on those bytes
S s = *cast(S*)bytes.ptr;

void checkValue(uint expectedOnLE, uint expectedOnBE) {
if (endian == Endian.littleEndian) {
assert(s.u == expectedOnLE);
} else if (endian == Endian.bigEndian) {
assert(s.u == expectedOnBE);
} else {
assert(false, "What is this?");
}
}

// The value should be wrong no a little-endian system
checkValue(218103808, 13);

s.u.ensureCorrectFromBigEndian;

// No matter what, now the result will be correct on any system
checkValue(13, 13);
}

Ali