RAII trouble
I have the following code in attempt to create an RAII object wrapper, but it seems that it might be impossible. The problem here is that FT_Init_FreeType is a static which is set at some previous time to a function entry point in the FreeType library. I could use a scope block, but would rather have a self contained thing to do the work. Perhaps some sort of mixin is the other solution? The ideal would be to have a struct that can be placed inside a function scope, or perhaps as a module global variable. Why does Ft_Init_FreeType have to be read at compile time? text.d(143,15): Error: static variable FT_Init_FreeType cannot be read at compile time text.d(174,43):called from here: initialise() struct FreeType { @disable this(); static FreeType initialise() { return FreeType(0); } this(int) { int error = FT_Init_FreeType(); /// ERROR enforce(!error); } alias library this; ~this() { FT_Done_FreeType(library); } FT_Library library; } FreeType freeType = FreeType.initialise();
Re: RAII trouble
On Friday, 20 November 2015 at 23:21:03 UTC, anonymous wrote: [...] FT_Init_FreeType must be read at compile time, because freeType is a module level variable, and initializers for module variables must be static values. The initializer is run through CTFE (Compile Time Function Evaluation). Put the initialization/assignment in a function and it should work. That function can be a static constructor or the main function: [...] Yes, I see. I made a mistake. I need to initialize it elsewhere. It was quite confusing. Thanks.
Re: RAII trouble
On Friday, 20 November 2015 at 23:35:50 UTC, Spacen Jasset wrote: On Friday, 20 November 2015 at 23:21:03 UTC, anonymous wrote: [...] FT_Init_FreeType must be read at compile time, because freeType is a module level variable, and initializers for module variables must be static values. The initializer is run through CTFE (Compile Time Function Evaluation). Put the initialization/assignment in a function and it should work. That function can be a static constructor or the main function: [...] Yes, I see. I made a mistake. I need to initialize it elsewhere. It was quite confusing. Thanks. I Just noticed this trick you posted, that's interesting. Of course I couldn't get it working without the void to discard the initialization; FreeType freeType = void; /* 'void' prevents default initialization */ static this() {freeType = FreeType.initialise();} /* should work */
Re: char[] == null
On Thursday, 19 November 2015 at 08:30:54 UTC, Jonathan M Davis wrote: On Wednesday, November 18, 2015 22:15:19 anonymous via Digitalmars-d-learn wrote: [...] Exactly. T[] _is_ a dynamic array. Steven's otherwise wonderful article on arrays in D ( http://dlang.org/d-array-article.html ) made the mistake of calling the buffer that T[] points to on the GC heap (assuming that even does point to the GC heap) the dynamic array. And per the language spec, that's not true at all. [...] I mentioned this because it's bit of an error trap, that I fell into. char[] == null vs char[] is null Is there any good use for char[] == null ? If not, a warning might be helpful.
scope keyword
I thought scope was deprecated, but I see that this is still here: http://dlang.org/attribute.html#scope Is it just the uses on classes and local variables that are discouraged, but the use in a function signature will continue? in == const scope?
char[] == null
Should this be allowed? What is it's purpose? It could compare two arrays, but surely not that each element of type char is null? char[] buffer; if (buffer == null) {}
Re: Deprecation: module std.stream is deprecated
On Tuesday, 10 November 2015 at 11:57:03 UTC, Jonathan M Davis wrote: ... building blocks rather than kitchen sinks. And most range-based ... I still can't really see why byChunk and byLine are part of the File API? Especially byLine, I'll get byChunk go for now. I think what I am trying to say is that there doesn't need to be a byLine, if lineSplitter could work with some range that comes out of the File. The problem with your example using joiner is that: (a) it is external to the calling function, and therefore messy, since it will have to be used everywhere. // not ideal printFile(f.byChunk(1000).joiner()); (b) still can't use the range to split by lines afterwards, lineSplitter etc don't work. void printFile(Range)(Range i) { foreach (l; lineSplitter(i)) { writefln("%d\n", l); } } void main() { File f = File("/etc/passwd"); printFile(f.byChunk(1000).joiner()); // Not work, linesplitter needs slicing and length? }
Split range that has no length or slice?
I can't seem to find a way of splitting a range of characters into lines unless the range has a length or can be sliced? This presumably is because i is a range of chunks, which cannot have a length or a slice. I do not see how to get anything else from the File object at the moment. import std.stdio; import std.string; void printFile(Range)(Range i) { foreach (l; lineSplitter(i)) { writefln("%d\n", l); } } auto range(File f) { const size_t someArbitrary = 4096; return f.byChunk(someArbitrary); } void main() { File f = File("/etc/passwd"); printFile(f.range()); // std.string.lineSplitter(Flag keepTerm = KeepTerminator.no, Range)(Range r) if (hasSlicing!Range && hasLength!Range || isSomeString!Range) // test.d(21): Error: template instance test.printFile!(ByChunk) error instantiating }
Re: Split range that has no length or slice?
On Monday, 9 November 2015 at 18:04:23 UTC, Alex Parrill wrote: On Monday, 9 November 2015 at 17:56:14 UTC, Alex Parrill wrote: On Monday, 9 November 2015 at 15:23:21 UTC, Spacen Jasset wrote: On Monday, 9 November 2015 at 14:58:19 UTC, Adam D. Ruppe wrote: File has a .byLine and .byLineCopy method you could use to just get lines from it. Ah yes. but unfortunately I don't want to do that. I want to pass a range into my print function. i.e. Sometimes it may not be a File, it might be from a string. Looks like it's not possible without adaptor code. I would suggest File should have a range function on it to return a range, for that matter byLine and byChunk probably shouldn't even be associated with file at all IMHO. The `.byLine` and `.byLineCopy` functions return ranges. Use those. Scratch that, just read your post. Ideally, something like `file.byChunk(4096).joiner.splitter('\n')` would work. The issue is that the byChunk ranges aren't forward or sliceable ranges (which makes sense). Theoretically, it should be possible to implement `splitter` with a plain input range, but it would require that the sub-range that `splitter.front` returns be invalidated when calling `splitter.popFront`. I don't yet understand the D ranges unfortunately. I can raise a bug about this if people generally agree its currently not a good situation. I don't see that The `.byLine` and `.byLineCopy` functions should be on the File object either. They are surely part of range algorithms, or string functions like std.string.lineSplitter
Re: Split range that has no length or slice?
On Monday, 9 November 2015 at 14:58:19 UTC, Adam D. Ruppe wrote: File has a .byLine and .byLineCopy method you could use to just get lines from it. Ah yes. but unfortunately I don't want to do that. I want to pass a range into my print function. i.e. Sometimes it may not be a File, it might be from a string. Looks like it's not possible without adaptor code. I would suggest File should have a range function on it to return a range, for that matter byLine and byChunk probably shouldn't even be associated with file at all IMHO.
Re: Deprecation: module std.stream is deprecated
On Sunday, 8 November 2015 at 08:29:30 UTC, BBaz wrote: On Sunday, 8 November 2015 at 08:21:38 UTC, BBaz wrote: On Saturday, 7 November 2015 at 13:52:29 UTC, Spacen Jasset wrote: [...] I have a used a template, because I cannot directly use the InputRange(char) interface as a type, and auto won't work either, so is there another parameter type I can use, such that I can have the concept of an abstract stream of bytes. With the help of a template constraint you can abstract this. It looks like your problem is more getting the whole range since .byLine or .byChunk don't return the full stuff. Maybe use std.alsorithm.joiner. As you noted you can carry the iterator without knowing the type with auto, example: --- import std.stdio; import std.range, std.algorithm; void main(string[] args) { auto inputRange = File(__FILE__).byChunk(1024).joiner; Foo foo = Foo(inputRange); } struct Foo { this(T)(T t) if (isInputRange!T && is(ElementType!T == ubyte)) { foreach(byte b; t) { writef("0x%.2X ", b); if (b == 0xA) writeln; } } } --- or even using an auto function: --- import std.stdio; import std.range, std.algorithm; void main(string[] args) { auto inputRange0 = inputByteRange(File(__FILE__)); Foo foo0 = Foo(inputRange0); ubyte[] arr = [1,2,3,4,5]; auto inputRange1 = inputByteRange(arr); Foo foo1 = Foo(inputRange1); } auto inputByteRange(T)(auto ref T t) { static if (is(T == File)) return t.byChunk(1024).joiner; else static if (is(T == ubyte[])) return t; else assert(0, "unsupported inputByteRange arg"); } struct Foo { this(T)(T t) if (isInputRange!T && is(ElementType!T == ubyte)){} } --- Thank you for your detailed replies, I shall try them out when I get a moment. I would like to *winge* and say that it doesn't appear to be straight forward, or at least not obvious and clean to get the concept of an abstract steam working, which is to my mind a basic thing. This looks the simplest solution at the moment: auto inputRange = File(__FILE__).byChunk(1024).joiner; Foo foo = Foo(inputRange); But it doesn't seem efficient and strays off the conceptual path. In other words, why chunk things up, join them back, to get a stream? Perhaps the problem is that File is missing a .range() function?
Re: Deprecation: module std.stream is deprecated
On Saturday, 7 November 2015 at 13:30:44 UTC, Jonathan M Davis wrote: On Saturday, November 07, 2015 12:10:05 Spacen Jasset via Digitalmars-d-learn wrote: Deprecation: module std.stream is deprecated - It will be removed from Phobos in October 2016. The std.stream module documentation doesn't give any clues as to what an alternative might be. I have this sort of code: this(InputStream input) { int line_no = 1; foreach (char[] line; input) { Am I right in thinking to use std.stdio with an InputRange? At this point, you pretty much have three options: 1. Use std.stdio.File and read it in in pieces (e.g. with byLine or byChunk). 2. Read the whole file in at once with std.file.read or std.file.readText. 3. Use std.mmfile.MmFile to mmap the file so that the parts that you access get read into memory, and the rest don't get loaded from disk, but you get to operate on the whole file as if you had read it all from disk. - Jonathan M Davis Thanks Jonathan. I don't quite see what I want to do though. In order to abstract the file aspect of things away, and deal with a stream of chars that could be from a file, or some some other source would I use a range? what I am after is a replacement for InputStream, I don't really want to directly use File in most places. So far I have this, and it seems to work, but it doesn't seem right: this(InputRange)(InputRange input) { int line_no = 1; foreach (char[] line; input.byLine()) { ... I have a used a template, because I cannot directly use the InputRange(char) interface as a type, and auto won't work either, so is there another parameter type I can use, such that I can have the concept of an abstract stream of bytes.
Deprecation: module std.stream is deprecated
Deprecation: module std.stream is deprecated - It will be removed from Phobos in October 2016. The std.stream module documentation doesn't give any clues as to what an alternative might be. I have this sort of code: this(InputStream input) { int line_no = 1; foreach (char[] line; input) { Am I right in thinking to use std.stdio with an InputRange? - Jason
Re: struct constructor co nfusion
On Friday, 6 November 2015 at 17:50:17 UTC, Atila Neves wrote: On Friday, 6 November 2015 at 17:34:29 UTC, Spacen Jasset wrote: Hello, I have read various things about struct constructors, specifically 0 argument constructors, and using opCall and @disable this(); which no longer seems to work. What I am after I think is the behavior of C++'s structs on the stack, namely for some or all of these uses at a given time: 1. Allocation on the stack 2. Value type semantics 3. RAII (combined with (1) often) This is common in D as well. The difference to C++ is 0-argument struct constructors to do extra work to satisfy invariants. Is it the case that a struct should now be used with a factory method? Does this also mean that the struct destructor must be It's the easiest way to emulate C++'s 0-argument struct constructors. made to work when .init is called instead of the factory method? If the factory method isn't called, then yes, the destructor shouldn't blow up just because all the struct members are T.init. This idiom is inconsistent with struct constructors that do have one or more arguments, and I think that this question is likely to arise time immemorial from others who are not expecting this particular inconstancy. How is it inconsistent? Nobody stops me from doing this: struct Struct { void* ptr = cast(void*)5; this(int size) { ptr = malloc(size); } ~this() { free(ptr); } } void main() { auto ok = Struct(10); //auto oops = Struct.init; } Atila What I mean is that: this(int a, int b) {} is allowed Whereas: this() {} isn't allowed. I see why that is the case now, but it seems inconsistent to me, and I think each new person that comes to D is going to wonder about this. Also, I had to add a dummy private constructor to make my structs 'createable', or is there another way? e.g. struct Texture { @disable this(); static Texture create() { return Texture(0); } ... private: this(int) { glGenTextures(1, _); enforce(0 != textureId_); } GLuint textureId_; }
Re: Working Windows GUI library - no console Window
On Friday, 6 November 2015 at 15:52:10 UTC, johann wrote: hi, i like to use a window gui library and i think i found a working one. https://github.com/FrankLIKE/dfl2 - works with x64 the problem is, that with DMD 2.069.0, VS2015 and visualD the trick of using "-L/SUBSYSTEM:windows,6.00 -L/ENTRY:mainCRTStartup" does not suppress the console window anymore. does anybody have a solution for that problem? is anybody still working on that library? johann Have a look at the resultant executable header with a tool like objdump / pebrowse. In the header somewhere there is a field that specifies the subsystem type. It should be set to gui, rather than console. IMAGE_SUBSYSTEM_WINDOWS_GUI 2 https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339%28v=vs.85%29.aspx
struct constructor co nfusion
Hello, I have read various things about struct constructors, specifically 0 argument constructors, and using opCall and @disable this(); which no longer seems to work. What I am after I think is the behavior of C++'s structs on the stack, namely for some or all of these uses at a given time: 1. Allocation on the stack 2. Value type semantics 3. RAII (combined with (1) often) The scope keyword on classes has been deprecated, it seems because it was hard to detect returning destroyed scope references, otherwise that might have done the job. Is it the case that a struct should now be used with a factory method? Does this also mean that the struct destructor must be made to work when .init is called instead of the factory method? This idiom is inconsistent with struct constructors that do have one or more arguments, and I think that this question is likely to arise time immemorial from others who are not expecting this particular inconstancy. Would it not make sense to ban constructors on structs entirely -- or find another solution that clears this up?
Re: std.utf.decode behaves unexpectedly - Bug?
On Friday, 6 November 2015 at 19:26:50 UTC, HeiHon wrote: Consider this: [code] import std.stdio, std.utf, std.exception; void do_decode(string txt) { try { size_t idx; writeln("decode ", txt); for (size_t i = 0; i < txt.length; i++) { dchar dc = std.utf.decode(txt[i..i+1], idx); writeln(" i=", i, " length=", txt[i..i+1].length, " char=", txt[i], " idx=", idx, " dchar=", dc); } } catch(Exception e) { writeln(e.msg, " file=", e.file, " line=", e.line); } writeln(); } void main() { do_decode("abc"); /+ result: decode abc i=0 length=1 char=a idx=1 dchar=a i=1 length=1 char=b idx=2 dchar=c i=2 length=1 char=c idx=3 dchar= +/ do_decode("åbc"); /+ result: decode åbc Attempted to decode past the end of a string (at index 1) file=D:\dmd2\windows\bin\..\..\src\phobos\std\utf.d line=1268 +/ do_decode("aåb"); /+ result: decode aåb i=0 length=1 char=a idx=1 dchar=a core.exception.RangeError@std\utf.d(1265): Range violation 0x004054D4 0x0040214F 0x004045A7 0x004044BB 0x00403008 0x755D339A in BaseThreadInitThunk 0x76EE9EF2 in RtlInitializeExceptionChain 0x76EE9EC5 in RtlInitializeExceptionChain +/ } [/code] I would expect: decode abc -> dchar a, dchar b, dchar c decode åbc -> dchar å, dchar b, dchar c decode aåb -> dchar a, dchar å, dchar b Am I using std.utf.decode wrongly or is it buggy? I wouldn't have thought you would want to do this: dchar dc = std.utf.decode(txt[i..i+1], idx); since txt is utf8, and this is a multiple byte, and variable length encoding, so txt[i..i+1] won't work, you will end up with invalid chops of utf8. It would seem that you might want to just say decode(txt, i) instead if you look at the documentation it should decode one code point and advance i the right amount of characters forward. In other words, perhaps that paired with a while ( i < txt.length) might do the trick.
version and configuration
If I say this in one module: version = current version (Current) { version = featurea; version = featureb; version = featurec; } It appears that I can't put this in a module and import it elsewhere to test the version specifications as they are all in their own namespaces. Is this then a dead end for having a feature configuration file? Is the way to do this to define some constants in a module, and test these instead. Something like: features.d featureA = true; featureB = false; -- main.d import features; static if (featureA == true) { }
Re: stuck on opDiv / opBinary
On Sunday, 30 August 2015 at 18:12:40 UTC, BBasile wrote: On Sunday, 30 August 2015 at 17:02:58 UTC, Spacen Jasset wrote: [...] try --- Vector3 opBinary(string op)(Vector3 rhs) { static if (op ==/){} else static assert(0, op ~ not implemented); } --- you used the char litteral delims ('') instead of the strings ones (). Ah yes, it's didnt' complain. But anyway that was the wrong funciton I implemented. I found the problem. I failed to implement a opDivAssign
Re: observation: D getting a bit complex
On Sunday, 30 August 2015 at 07:36:55 UTC, BBasile wrote: On Sunday, 30 August 2015 at 02:42:30 UTC, Spacen Jasset wrote: immutable(ElementEncodingType!(ElementType!Range))[] buildPath(Range)(Range segments) if (isInputRange!Range isSomeString!(ElementType!Range)); pure nothrow @safe immutable(C)[] buildPath(C)(const(C)[][] paths...) if (isSomeChar!C); this is stodgy, particularly in a console with line wrapping at 80 chars. To be fair is was the docs page I was reading not a compiler diagnostic, but I did get something a bit shorter from the compiler once. It's slighty hard to see that you can give that function a string, and that it can return a string like thing -- although on that score too I've found I have to use char[] in some places instead of string which is to do with immutability, that I've not quite worked that out yet either -- It's just a feeling I have when looking at this now that it is quite complex. I only mention this as it was something that I think other people may notice too, when starting out, or coming back to D. Maybe I've just been doing too much python recently.
stuck on opDiv / opBinary
I have just added an opDiv to this class, but it doesn't seem to pick it up. math/vector.d(30): Error: 'this /= mag' is not a scalar, it is a Vector3 I can't see why that is, becuase my opMul works in the same place. Can anyone point out what I have done wrong? Class Matrix { void normalise() { const float mag = magnitude(); if (mag) { //this.scalarDivide(mag); this /= mag; // Not work this *= 1/mag; // Does work. } } //Vector3 opBinary(string op)(Vector3 rhs) if (op=='/') Vector3 opDiv(float scalar) { Vector3 v = this; v.scalarDivide(scalar); return v; } }
Re: stuck on opDiv / opBinary
On Sunday, 30 August 2015 at 20:09:25 UTC, Timon Gehr wrote: On 08/30/2015 07:02 PM, Spacen Jasset wrote: [...] import std.math: sqrt; import std.algorithm: map,sum,canFind; struct Vector3{ float[3] xyz; void normalise(){ this/=magnitude(); } float magnitude(){ return sqrt(xyz[].map!(a=a*a).sum); } enum scalarOps=[*,/]; enum isScalarOp(string op)=scalarOps.canFind(op); void scalar(string op)(float scalar)if(isScalarOp!op){ foreach(ref a;xyz) mixin(`a `~op~`=scalar;`); } Vector3 opBinary(string op)(float scalar)if(isScalarOp!op){ Vector3 v=this; v.scalar!op(scalar); return v; } auto opOpAssign(string op)(float rhs)if(isScalarOp!op){ return mixin(`this=this `~op~` rhs`); } } Thanks, that is interesting. I am curently porting, rather than trying to rewrite anything at the moment, but I will try this out later.
observation: D getting a bit complex
The following reminds me of the good old C++ template errors the C++ compiler spits out. Whilst D has fixed that problem, some things have gotten more complex. I just wanted to find a replacement for D1 path join, and found this, but it doesn't seem very easy to wade though this stuff. immutable(ElementEncodingType!(ElementType!Range))[] buildPath(Range)(Range segments) if (isInputRange!Range isSomeString!(ElementType!Range)); pure nothrow @safe immutable(C)[] buildPath(C)(const(C)[][] paths...) if (isSomeChar!C); http://dlang.org/phobos/std_path.html It would take me a lot of time to appeciate what that all means, although I can imagine what it is for. ...just and observation. The complexity is building.
Re: GLU in DerelictOrg
On Wednesday, 22 July 2015 at 00:49:29 UTC, Mike Parker wrote: On Tuesday, 21 July 2015 at 16:34:35 UTC, Spacen Jasset wrote: On Tuesday, 21 July 2015 at 15:17:13 UTC, Alex Parrill wrote: On Tuesday, 21 July 2015 at 14:51:47 UTC, John Colvin wrote: Isn't glu considered legacy these days? I think it's entirely OpenGL 2.x. For the maths stuff see http://code.dlang.org/packages/gl3n Yep. It still uses immediate mode, GL matrix functions, and all sorts of other stuff removed in OpenGL 3.1+ core. Yes, thanks John. I will be using the legacy mode though :-) Not got around to the wizz bang stuff yet. I intentionally did not port the Derelict3 GLU binding to DerelictOrg because it uses parts of the deprecated OGL API and is considered legacy these days. Initially, I didn't include support for the deprecated OGL API either, but there were enough requests for it that I finally added it. I have no intention of adding GLU, though. It's easily replaceable. Thanks Mike, that's fair enough. I shall just implement the functions I need I think until such time as I end up using the newer OpenGL 3 stuff.
Re: GLU in DerelictOrg
On Tuesday, 21 July 2015 at 15:17:13 UTC, Alex Parrill wrote: On Tuesday, 21 July 2015 at 14:51:47 UTC, John Colvin wrote: Isn't glu considered legacy these days? I think it's entirely OpenGL 2.x. For the maths stuff see http://code.dlang.org/packages/gl3n Yep. It still uses immediate mode, GL matrix functions, and all sorts of other stuff removed in OpenGL 3.1+ core. Yes, thanks John. I will be using the legacy mode though :-) Not got around to the wizz bang stuff yet.
GLU in DerelictOrg
Hello, Can anyone tell me if the GLU functions, gluSpehere etc are availble in DerelictOrg or have they been removed. I can replace these with my own versions, but was hoping to do a quick port to DerelictOrg
Re: GLU in DerelictOrg
On Tuesday, 21 July 2015 at 11:23:23 UTC, John Colvin wrote: On Tuesday, 21 July 2015 at 11:08:13 UTC, Spacen Jasset wrote: Hello, Can anyone tell me if the GLU functions, gluSpehere etc are availble in DerelictOrg or have they been removed. I can replace these with my own versions, but was hoping to do a quick port to DerelictOrg They are not available. See http://dblog.aldacron.net/2014/10/derelict-3-removed-from-dub-repository/ I'm not sure why they aren't part of the DerelictOrg. I'm sure it wouldn't be hard to take https://github.com/aldacron/Derelict3/tree/master/import/derelict/freeglut and make a dub package out of it yourself, maybe even add it to code.dlang.org as derelict_extras-freeglut Thanks John, it looks really simple. I'll see if I can get round to making a proper package from it.
Re: GLU in DerelictOrg
It seems that Derelict3 contains GLUT whereas derelict2 containss GLU. It appears I need GLU but I am somewhat confused as to what the diffrence is.
have function must pass delegate.
A method call in the GTK API takes a delegate as an argument(addOnActivate) I would like to be able to pass a function instead (address of). What is the solution, at present I have a wrapper class around the function.