Re: Is there a more elegant way to do this?
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?
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?
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?
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?
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?
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?
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?
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?
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
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?
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
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?
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?
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?
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?
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
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
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
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
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
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?
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?
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?
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?
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?
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?
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 { /* ... */ }