Re: Is there a more elegant way to do this?

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

On Sunday, 12 March 2017 at 05:13:41 UTC, bauss wrote:
I was wondering if there's a more elegant way to do something 
like this?


template BitSize(T) {
enum BitSize = T.sizeof * 8;
}

struct Data(ParentType,ChildType) {
@property {
ChildType low() { return cast(ChildType)value; }
void low(ChildType lowValue) {
value = ((high << (BitSize!ParentType / 2)) | lowValue);
}

		ChildType high() { return cast(ChildType)(value >> 
(BitSize!ParentType / 2)); }

void high(ChildType highValue) {
value = ((highValue << 16 | low));
}
}

ParentType value;

alias value this;
}

Example usage:
void main() {
Data!(uint,ushort) data;
data = 14065735;

writefln("low: %s high: %s", data.low, data.high);

data.low = 41031 ;
data.high = 214;

writefln("value: %s", data.value);
}

Basically to explain what it is: You give it a parent-type and 
a corresponding child-type.


Ex. if the parent-type is uint, the child-type would be ushort.
if the parent-type is long, the child-type would be int.
etc.

What it allows you to is to either manipulate the data as the 
parent-type or as two values of the child type.


I was just wondering if there's a more elegant or performant 
way to do this, perhaps something in Phobos exist already?


template HalfSize(T)
{
static if (T==long)
alias HalfSize == int;
// repeat for all combos
}

struct Data(T)
{
union
{
 T value;
 struct
 {
  version(LittleEndian)
  {
  HalfSize!T low;
  HalfSize!T high;
  }
  version(BigEndian)
  {
  HalfSize!T low;
  HalfSize!T high;
  }
 }
}
alias value this;
}



Re: Is there a more elegant way to do this?

2017-03-11 Thread bauss via Digitalmars-d-learn

On Sunday, 12 March 2017 at 05:13:41 UTC, bauss wrote:
I was wondering if there's a more elegant way to do something 
like this?


[...]


I saw one improvement to it which would be BitSize!ChildType 
instead of taking parent type's bit size divided by two.


Also

value = ((highValue << 16 | low));

Is supposed to be

value = ((highValue << BitSize!ChildType | low));


Is there a more elegant way to do this?

2017-03-11 Thread bauss via Digitalmars-d-learn
I was wondering if there's a more elegant way to do something 
like this?


template BitSize(T) {
enum BitSize = T.sizeof * 8;
}

struct Data(ParentType,ChildType) {
@property {
ChildType low() { return cast(ChildType)value; }
void low(ChildType lowValue) {
value = ((high << (BitSize!ParentType / 2)) | lowValue);
}

		ChildType high() { return cast(ChildType)(value >> 
(BitSize!ParentType / 2)); }

void high(ChildType highValue) {
value = ((highValue << 16 | low));
}
}

ParentType value;

alias value this;
}

Example usage:
void main() {
Data!(uint,ushort) data;
data = 14065735;

writefln("low: %s high: %s", data.low, data.high);

data.low = 41031 ;
data.high = 214;

writefln("value: %s", data.value);
}

Basically to explain what it is: You give it a parent-type and a 
corresponding child-type.


Ex. if the parent-type is uint, the child-type would be ushort.
if the parent-type is long, the child-type would be int.
etc.

What it allows you to is to either manipulate the data as the 
parent-type or as two values of the child type.


I was just wondering if there's a more elegant or performant way 
to do this, perhaps something in Phobos exist already?


Re: C interface provides a pointer and a length... wrap without copying?

2017-03-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, March 12, 2017 02:47:19 cy via Digitalmars-d-learn wrote:
> On Saturday, 11 March 2017 at 23:43:54 UTC, Nicholas Wilson wrote:
> > A string *is* a pointer length pair, an immutable(char)[].
>
> Yes, but surely there's some silly requirement, like that the
> pointer must only ever point to garbage collected memory, or
> something?

No. A dynamic array is just a struct with a pointer and a length. Aside from
avoiding accessing memory that is no longer valid or avoiding allocations,
it doesn't matter one whit what memory it points to.

char[5] a;
char[] b = a;

is perfectly valid as is slicing memory that comes from malloc or some other
crazy place. Most dynamic array operations don't even need to care about
what memory they refer to. If you access an element, it does the math and
dereferences it like you'd get with naked pointer arithmetic. The difference
is that it also does bounds checking for you, because it knows the length.
If you slice the array, then you just get an array with an adjusted pointer
and/or length.

The only times that the GC gets involved are when doing anything involving
appending. If you call capacity, reserve, or ~=, then the GC gets involved.
In those cases, the GC looks at the pointer to determine whether it can
append. If it finds that it's GC-allocated memory, then it will look to see
what room there is in the GC-allocated block after the array. If you're
calling capacity, it will just return how large the array can grow to
without being reallocated. If you're calling reserve or ~= it checks to see
whether the capacity is great enough to grow into that space. If not, it
will allocate a new block of memory, copy the array's elements into that,
and set the array to point to it. In the case of ~=, it will also grow the
array into that memory and put the new elements in it, whereas in the case
of reserve, it just does the reallocation. If there was enough space, then
~= will just expand the array into that space without reallocating, and
reserve will do nothing.

If you have a dynamic array that was not allocated by the GC (be it a slice
of a static array or malloc-ed memory or whatever), then its capacity will
be 0. So, capacity will tell you 0, and ~= and reserve will always result in
the array being reallocated.

I would suggest that you read this excellent article:

http://dlang.org/d-array-article.html

though I would point out that it uses the wrong terminology in that it
refers to the GC-allocated buffer as the dynamic array rather than T[], and
it refers to T[] as a slice, whereas the official terminology is that T[] is
the dynamic array and that buffer doesn't have an official name, and while
T[] _is_ a slice of memory (assuming that it's not null), slice refers to a
lot of other stuff in D (e.g. slicing a container gives you range over that
container, so it's a slice of the container, but it's not T[]). And your use
case here is a perfect example of why T[] is the dynamic array and not the
GC-allocated buffer.

Dynamic arrays simply don't care about the memory that they refer to,
because they don't manage their own memory. ~=, reserve, and capacity do
care about what memory a dynamic array refers to, but they work exactly the
same way regardless of what the dynamic array refers to. It's just a
question of when reallocations do or do not occur.

The big concern with slicing static arrays or malloc-ed memory to get a
dynamic array is that it's then up to you to ensure that that dynamic array
does not outlive the memory that it refers to. So, there is some danger
there, but that's no different from operating on raw pointers, and operating
on dynamic arrays gives better safety thanks to bounds-checking, and it also
works with appending, though that will cause the dynamic array to then refer
to GC-allocated memory instead of the original memory.

- Jonathan M Davis



Re: C interface provides a pointer and a length... wrap without copying?

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

cy wrote:


On Saturday, 11 March 2017 at 23:43:54 UTC, Nicholas Wilson wrote:

A string *is* a pointer length pair, an immutable(char)[].


Yes, but surely there's some silly requirement, like that the pointer 
must only ever point to garbage collected memory, or something?


why should it? a slice can point anywhere, and GC is smart enough to know 
what memory it owns and what it isn't. if you'll try to append something to 
non-GC-owned slice, GC will make a copy first. so the only requirement is: 
"don't use `~=` on it if you don't want to have a memory leak".


Re: C interface provides a pointer and a length... wrap without copying?

2017-03-11 Thread cy via Digitalmars-d-learn

On Saturday, 11 March 2017 at 23:43:54 UTC, Nicholas Wilson wrote:

A string *is* a pointer length pair, an immutable(char)[].


Yes, but surely there's some silly requirement, like that the 
pointer must only ever point to garbage collected memory, or 
something?


ubyte[] arr; // or byte/char whatever is the pointed to type 
returned by giveMeTheMemory

arr = giveMeTheMemory()[0 .. getMeTheLength()];


...guess not! :D



Re: I think is a bug?

2017-03-11 Thread Random D user via Digitalmars-d-learn

On Sunday, 12 March 2017 at 01:55:20 UTC, ketmar wrote:

Random D user wrote:


How come string* suddenly has a .length property?


due to automatic pointer dereferencing that `.` does. no, not a 
bug.


Ah... right. Silly me. Of course, since string is actually 
immutable(char)[].
That's bit of a nasty corner case where -> == . isn't that nice. 
Fortunately, it's rare.


Thanks.

This happened to me, when I was packing stuff into SoA layout and 
didn't want to duplicate the length in the struct (implicitly by 
using []). Of course, I forgot to update one place to use the 
shared length.

That is:

length
ptr
ptr
ptr

instead of

ptr
length
ptr
length
ptr
length

Perhaps I should do a SoA layout template that somehow disables 
.length on individual arrays.


Re: I think is a bug?

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

Random D user wrote:


How come string* suddenly has a .length property?


due to automatic pointer dereferencing that `.` does. no, not a bug.


I think is a bug?

2017-03-11 Thread Random D user via Digitalmars-d-learn

int*[] foo;
foo.length = 5;

import std.c.string;
int* baz = cast(string*)malloc(50);

import std.c.stdio;
printf("%d %d", foo.length, baz.length );

prints:
Error: no property 'length' for type 'int*'

BUT:

string*[] foo;
foo.length = 5;

import std.c.string;
string* baz = cast(string*)malloc(50);

import std.c.stdio;
printf("%d %d", foo.length, baz.length );

compiles and prints:
5 -842150451

How come string* suddenly has a .length property?
Anyway the result is garbage, so I think this must be a bug.

DMD32 D Compiler v2.073.2


Re: DMD win32.mak error

2017-03-11 Thread Paul D Anderson via Digitalmars-d-learn

On Saturday, 11 March 2017 at 18:02:00 UTC, Stefan Koch wrote:
On Saturday, 11 March 2017 at 02:25:15 UTC, Paul D Anderson 
wrote:
On Saturday, 11 March 2017 at 00:34:03 UTC, Paul D Anderson 
wrote:
On Friday, 10 March 2017 at 22:04:23 UTC, Paul D Anderson 
wrote:

[...]


I see John Colvin has already filed a bug report (issue 
17165) addressing this. Apparently the missing file is 
available on GitHub.


I copied the missing file John referenced to my src/dmd file 
but this did not have any effect.


I've created a bug report (17253) addressing this problem.

Paul


verstring is created automatically


I think the problem is a failure in the process of creating 
verstring.


The missing file is "dmd/res/default_ddoc_theme/ddoc"



Re: C interface provides a pointer and a length... wrap without copying?

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

On Saturday, 11 March 2017 at 22:39:02 UTC, cy wrote:
So a lovely C library does its own opaque allocation, and 
provides access to the malloc'd memory, and that memory's 
length. Instead of copying the results into garbage collected 
memory (which would probably be smart) I was thinking about 
creating a structure like:


struct WrappedString {
  byte* ptr;
  size_t length;
}

And then implementing opIndex for it, and opEquals for all the 
different string types, and conversions to those types, and 
then it occurred to me that this sounds like a lot of work. Has 
anybody done this already? Made a pointer/length pair, that 
acts like a string?


A string *is* a pointer length pair, an immutable(char)[]. Your 
`WrappedString` is effectively a byte[].


All you need to do is:

ubyte[] arr; // or byte/char whatever is the pointed to type 
returned by giveMeTheMemory

arr = giveMeTheMemory()[0 .. getMeTheLength()];

No need to reimplement anything.


Dub and bindings

2017-03-11 Thread qznc via Digitalmars-d-learn
Are there any general tips or best practices for bindings in dub 
packages?


For example, I love the d2sqlite3 package. It just works out of 
the box. No linker configuration or anything. However, that is 
probably a testament to sqlite's lack of dependencies. That 
cannot work for libraries, which rely on other libraries.


Should the C code be included in the Github repo? Are submodules 
fine? Should the C build be invoked by dub via 
"preBuildCommands"? What about system libraries? Can that be made 
cross-platform? Should lflags be specified in the dub config or 
should they be passed via environment variable?


There should be a general guide for this. Maybe there already is 
one?


Re: C interface provides a pointer and a length... wrap without copying?

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

cy wrote:

So a lovely C library does its own opaque allocation, and provides access 
to the malloc'd memory, and that memory's length. Instead of copying the 
results into garbage collected memory (which would probably be smart) I 
was thinking about creating a structure like:


struct WrappedString {
   byte* ptr;
   size_t length;
}

And then implementing opIndex for it, and opEquals for all the different 
string types, and conversions to those types, and then it occurred to me 
that this sounds like a lot of work. Has anybody done this already? Made 
a pointer/length pair, that acts like a string?


yep, it was done before.

 int* a = cast(int*)malloc(1024);
 auto b = a[0..1024];
 // yay, b is just an ordinary slice now!


C interface provides a pointer and a length... wrap without copying?

2017-03-11 Thread cy via Digitalmars-d-learn
So a lovely C library does its own opaque allocation, and 
provides access to the malloc'd memory, and that memory's length. 
Instead of copying the results into garbage collected memory 
(which would probably be smart) I was thinking about creating a 
structure like:


struct WrappedString {
  byte* ptr;
  size_t length;
}

And then implementing opIndex for it, and opEquals for all the 
different string types, and conversions to those types, and then 
it occurred to me that this sounds like a lot of work. Has 
anybody done this already? Made a pointer/length pair, that acts 
like a string?


Re: Can you fix this code to avoid using pointers?

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

On Saturday, 11 March 2017 at 19:15:59 UTC, H. S. Teoh wrote:


What about just:

foreach (const ref p; [in1, in2, in3, in4])


I would think there will be already one copy from the local 
parameter variables to the in situ array. Then from that one into 
the for each element it's ref'd all right. But I'm afk and can't 
test.


Like the other copy I missed and Adam spotted when passing the 
arguments with missing ref qualifiers..


I realized that the code that sparked the question made no sense 
and should be done in a different way... As is always the case 
when these questions come up.

But I still like the version with pointers ;)


Re: Can you fix this code to avoid using pointers?

2017-03-11 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Mar 11, 2017 at 12:45:10PM +, XavierAP via Digitalmars-d-learn 
wrote:
> On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote:
> > I do not really think it's a bad solution, to check several scalar
> > arguments that must obey the same condition; just wondering if you
> > have better ideas. Try to avoid modifying the function's signature
> > and defining custom types, unless you have a really terrific idea.
> > 
> > void calc(double in1, double in2, double in3, double in4)
> > in {
> >foreach(const p; [, , , ])
> >   enforce(*p > 0);
> > }
> > body { /* ... */ }
> 
> Please imagine double is a type that I wanted to avoid copying, just
> check by ref. Same question :p

What about just:

foreach (const ref p; [in1, in2, in3, in4])
...

?


T

-- 
Stop staring at me like that! It's offens... no, you'll hurt your eyes!


Re: Problem building DMD

2017-03-11 Thread Eric via Digitalmars-d-learn

On Saturday, 11 March 2017 at 17:54:55 UTC, ag0aep6g wrote:

On 03/11/2017 06:41 PM, Eric wrote:

I'm trying to build the master branch of DMD on redhat 7.
I get the following errors:

ddmd/root/newdelete.c:26:8: error: expected identifier or ‘(’ 
before

string constant
 extern "C"
^
ddmd/root/newdelete.c:31:17: error: expected ‘=’, ‘,’, ‘;’, 
‘asm’ or

‘__attribute__’ before ‘new’
 void * operator new(size_t m_size)
 ^
ddmd/root/newdelete.c:36:15: error: expected ‘=’, ‘,’, ‘;’, 
‘asm’ or

‘__attribute__’ before ‘delete’
 void operator delete(void *p)

Does anyone know what I am doing wrong?


Looks like a C compiler is used instead of a C++ compiler. 
Despite the extension, dmd's *.c files are C++ code.


Yes - I needed to install gcc-c++, not g++.  That fixed 
everything.


Re: Problem building DMD

2017-03-11 Thread Eric via Digitalmars-d-learn

On Saturday, 11 March 2017 at 17:54:55 UTC, ag0aep6g wrote:


Looks like a C compiler is used instead of a C++ compiler. 
Despite the extension, dmd's *.c files are C++ code.


Yes, that's what I thought - redhat has gcc, but not g++.  There 
must

be a needed compile option...


Re: DMD win32.mak error

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

On Saturday, 11 March 2017 at 02:25:15 UTC, Paul D Anderson wrote:
On Saturday, 11 March 2017 at 00:34:03 UTC, Paul D Anderson 
wrote:
On Friday, 10 March 2017 at 22:04:23 UTC, Paul D Anderson 
wrote:
While building DMD -- "make -fwin32.mak release" -- I 
received the following error message:


echo "2.073.2" > verstr.h
Error: don't know how to make '../res/default_ddoc_theme/ddoc'
--- error level 1

I'm guessing it might be a build configuration problem on my 
end, but what is the problem?


Paul


I see John Colvin has already filed a bug report (issue 17165) 
addressing this. Apparently the missing file is available on 
GitHub.


I copied the missing file John referenced to my src/dmd file 
but this did not have any effect.


I've created a bug report (17253) addressing this problem.

Paul


verstring is created automatically


Re: Problem building DMD

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

On 03/11/2017 06:41 PM, Eric wrote:

I'm trying to build the master branch of DMD on redhat 7.
I get the following errors:

ddmd/root/newdelete.c:26:8: error: expected identifier or ‘(’ before
string constant
 extern "C"
^
ddmd/root/newdelete.c:31:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or
‘__attribute__’ before ‘new’
 void * operator new(size_t m_size)
 ^
ddmd/root/newdelete.c:36:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or
‘__attribute__’ before ‘delete’
 void operator delete(void *p)

Does anyone know what I am doing wrong?


Looks like a C compiler is used instead of a C++ compiler. Despite the 
extension, dmd's *.c files are C++ code.


Problem building DMD

2017-03-11 Thread Eric via Digitalmars-d-learn

I'm trying to build the master branch of DMD on redhat 7.
I get the following errors:

ddmd/root/newdelete.c:26:8: error: expected identifier or ‘(’ 
before string constant

 extern "C"
^
ddmd/root/newdelete.c:31:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ 
or ‘__attribute__’ before ‘new’

 void * operator new(size_t m_size)
 ^
ddmd/root/newdelete.c:36:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ 
or ‘__attribute__’ before ‘delete’

 void operator delete(void *p)

Does anyone know what I am doing wrong?




Re: Can you fix this code to avoid using pointers?

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

On Saturday, 11 March 2017 at 14:49:42 UTC, XavierAP wrote:
But also I don't want to modify the function signature, 
certainly in this way.


It is already copied by the time you get in to the function 
though because of the signature (unless they are constructed 
in-place at the call site).


But you can also do an unrolled loop with AliasSeq 
http://dpldocs.info/experimental-docs/std.meta.AliasSeq.html


import std.meta;
import std.exception;
void calc(double in1, double in2, double in3, double in4)
in {
   foreach(ref item; AliasSeq!(in1, in2, in3, in4))
  enforce(item > 0);
}
body { /* ... */ }

Note that if the loop body is large, this could bloat the code 
slightly since a foreach over AliasSeq is always an unrolled 
loop. But that's probably irrelevant to you.


Re: Can you fix this code to avoid using pointers?

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

On Saturday, 11 March 2017 at 13:44:30 UTC, Satoshi wrote:


void calc(in double[] array...) {
foreach (x; array) { }
}


To do what I want it should be foreach(ref x; array) -- or const 
ref. But also I don't want to modify the function signature, 
certainly in this way. In another situation yes, but the 
arguments are very different magnitudes, for example 
temperatures, conductivity, heat power, etc. They should be 
separate arguments with self-documenting names. And it's not 
worth the bother to define a struct type for them as a set. 
Specially since this is an internal implementation "problem" that 
shouldn't affect the outer interface.


I know there's something in std.algorithm for this, but afaik it 
would be relatively bloated compared to this pointer solution. In 
C++ I would use a  instead of a *pointer, but I 
actually think C++ references are redundant with pointers, not 
much safer, and plain confusing.


I guess it's a not a common case because if a type is non trivial 
to copy it should probably be a class, which is already assigned 
by reference so I wouldn't need the pointer/ref.


Re: Can you fix this code to avoid using pointers?

2017-03-11 Thread Satoshi via Digitalmars-d-learn

On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote:
I do not really think it's a bad solution, to check several 
scalar arguments that must obey the same condition; just 
wondering if you have better ideas. Try to avoid modifying the 
function's signature and defining custom types, unless you have 
a really terrific idea.


void calc(double in1, double in2, double in3, double in4)
in {
   foreach(const p; [, , , ])
  enforce(*p > 0);
}
body { /* ... */ }



void calc(in double[] array...) {
foreach (x; array) { }
}


Re: Can you fix this code to avoid using pointers?

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

On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote:
I do not really think it's a bad solution, to check several 
scalar arguments that must obey the same condition; just 
wondering if you have better ideas. Try to avoid modifying the 
function's signature and defining custom types, unless you have 
a really terrific idea.


void calc(double in1, double in2, double in3, double in4)
in {
   foreach(const p; [, , , ])
  enforce(*p > 0);
}
body { /* ... */ }


Please imagine double is a type that I wanted to avoid copying, 
just check by ref. Same question :p


Re: Can you fix this code to avoid using pointers?

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

Oh... please forget it
What a terrible example :p I forgot why I was using pointers at 
all... I must have had a reason to write this in the past ???


Can you fix this code to avoid using pointers?

2017-03-11 Thread XavierAP via Digitalmars-d-learn
I do not really think it's a bad solution, to check several 
scalar arguments that must obey the same condition; just 
wondering if you have better ideas. Try to avoid modifying the 
function's signature and defining custom types, unless you have a 
really terrific idea.


void calc(double in1, double in2, double in3, double in4)
in {
   foreach(const p; [, , , ])
  enforce(*p > 0);
}
body { /* ... */ }