Re: SegFault with HibernateD
On Friday, 12 January 2018 at 05:24:52 UTC, Venkat wrote: I get a SegFault with the main method below which uses HibernateD . The second main method which uses ddbc just works fine. What is wrong with the first main method ? I have attached the error at the bottom although I don't think it says much. This is the error. object.Exception@source/dub/generators/build.d(530): Program It says enough to know that the exception is being thrown from dub and not your program. You program is never executed because dub throws the exception before it gets that far. You should report this at the dub repository: https://github.com/dlang/dub/issues
Re: Voldemort type for mixin template.
On Thursday, 11 January 2018 at 21:30:43 UTC, aliak wrote: On Thursday, 11 January 2018 at 08:56:11 UTC, ChangLong wrote: When I try add some sub type for struct with mixin template, seems there is no way to hidden the private type. Is there a way to hidden type from mix template like Voldemort type ? fake code: mix template TypeX () { alias This = typeof(this); static struct Unique { This* _ptr ; } static struct Helper { private Unique data; } alias TypeX = { alias PublicName = Helper ; } } struct Node { mixin TypeX!(); PublicName helper; } Hi, can you explain a bit more? The question is not entirely clear to me. Can you mixin a struct of type PublicName and just hide everything in there? mixin template TypeX() { struct PublicName { private alias This = typeof(this); private struct Unique { This* _ptr; } private Unique _data; alias _data this; } } void main(string[] args) { mixin TypeX; PublicName helper; helper._ptr.writeln; } Cheers If PublicName is complex type, require has some private type information. there is noway to hidden the private type from the scope of mixin. the purpose is hidden helper._ptr from main function to avoid name conflict. I try use mixin fo modify struct to allow it has some kind zero cost abstract, or memory manage function.since the system is complex it will import a lot symbol into the class. I has to put the mix template into struct, since I has to add member with type from mix template. and I also want to avoid access ref_count from the struct body(and a lot other name conflict)
SegFault with HibernateD
I get a SegFault with the main method below which uses HibernateD . The second main method which uses ddbc just works fine. What is wrong with the first main method ? I have attached the error at the bottom although I don't think it says much. This method uses HibernateD int main() { // setup DB connection string url = MySQLDriver.generateUrl("localhost", 3306, "test"); string[string] params = MySQLDriver.setUserAndPassword("test", "test"); DataSource ds = new ConnectionPoolDataSourceImpl(new MySQLDriver(), url, params); // create metadata from annotations EntityMetaData schema = new SchemaInfoImpl!(Preferences); // create session factory Dialect dialect = new MySQLDialect(); SessionFactory factory = new SessionFactoryImpl(schema, dialect, ds); scope(exit) factory.close(); auto conn = ds.getConnection(); scope(exit) conn.close(); // create session Session sess = factory.openSession(); scope(exit) sess.close(); Query q = sess.createQuery("select p from Preferences p"); Preferences[] list = q.list!Preferences(); return 0; } The method below uses ddbc. int main(string[] args) { string url = "mysql://localhost:3306/test?user=test,password=test"; // creating Connection auto conn = createConnection(url); scope(exit) conn.close(); // creating Statement auto stmt = conn.createStatement(); scope(exit) stmt.close(); // reading DB auto rs = stmt.executeQuery("SELECT * FROM preferences_wm ORDER BY id"); writeln(rs.getFetchSize()); return 0; } This is the error. Running ./bin/hibernated-test Program exited with code -11 Full exception: object.Exception@source/dub/generators/build.d(530): Program exited with code -11 /home/vagrant/old-dmd/dmd2/linux/bin64/../../src/phobos/std/exception.d:420 pure @safe void std.exception.bailOut!(Exception).bailOut(immutable(char)[], ulong, const(char[])) [0x8d036c] /home/vagrant/old-dmd/dmd2/linux/bin64/../../src/phobos/std/exception.d:388 pure @safe bool std.exception.enforce!(Exception, bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong) [0x8defcd] source/dub/generators/build.d:530 void dub.generators.build.BuildGenerator.runTarget(dub.internal.vibecompat.inet.path.Path, const(dub.compilers.buildsettings.BuildSettings), immutable(char)[][], dub.generators.generator.GeneratorSettings) [0x97b1c9] source/dub/generators/build.d:110 void dub.generators.build.BuildGenerator.performPostGenerateActions(dub.generators.generator.GeneratorSettings, const(dub.generators.generator.ProjectGenerator.TargetInfo[immutable(char)[]])) [0x977541] source/dub/generators/generator.d:118 void dub.generators.generator.ProjectGenerator.generate(dub.generators.generator.GeneratorSettings) [0x9805a0] source/dub/dub.d:494 void dub.dub.Dub.generateProject(immutable(char)[], dub.generators.generator.GeneratorSettings) [0x8918e0] source/dub/commandline.d:789 int dub.commandline.GenerateCommand.execute(dub.dub.Dub, immutable(char)[][], immutable(char)[][]) [0x857579] source/dub/commandline.d:821 int dub.commandline.BuildCommand.execute(dub.dub.Dub, immutable(char)[][], immutable(char)[][]) [0x857913] source/dub/commandline.d:849 int dub.commandline.RunCommand.execute(dub.dub.Dub, immutable(char)[][], immutable(char)[][]) [0x857b23] source/dub/commandline.d:239 int dub.commandline.runDubCommandLine(immutable(char)[][]) [0x853647] source/app.d:14 _Dmain [0x84fc27]
Re: Why is this valued zeroed?
On Thursday, January 11, 2018 14:07:18 Ali Çehreli via Digitalmars-d-learn wrote: > On 01/11/2018 12:21 PM, Marc wrote: > > I stuck at this and can't figure out the reason why the value of the > > variable ds is 0 when I do this: startTime = MonoTime.currTime; > > It's not clear which of the two statements you're talking about. > > >> http.onProgress = (size_t dltotal, size_t dlnow, > >> > >>size_t ultotal, size_t ulnow) { > >> > >> if(dlNow > 0) { > >> > >>MonoTime endTime = MonoTime.currTime; > >>Duration duration = endTime - startTime; > >> > >> long ds = duration.total!"seconds"; > >> writeln("duration!seconds = ", ds); > >> startTime = MonoTime.currTime; > > I would remove the one above and keep the one below. > > >> startTime = MonoTime.currTime; > >> http.perform(); > > If you're trying to measure time between two onProgress() calls, as > Steve noted, seconds is probably too large a unit. And if all what you're doing is printing the value out, you might as well just print the Duration directly rather than calling total. Duration.toString returns the units in a human-readable format such as "2 secs, 300 msecs, and 24 μs" or "29 msecs". https://dlang.org/phobos/core_time.html#.Duration.toString And if you're doing something like adding up the time spent, then you'd be better off keeping it in a Duration than converting it to long holding seconds or milliseconds or whatever. - Jonathan M Davis
__gshared as part of alias
Is there a way to make __gshared part of an alias? as in enum AddrSpace : uint { Private = 0, Global = 1, Shared = 2, Constant = 3, Generic = 4, } struct Variable(AddrSpace as, T) { T val; alias val this; } alias Global(T) = __gshared Variable!(AddrSpace.Global, T); Global!float bar1; // <- still thread local
Problem with function taking variable number of arguments with -m64
// // rdmd -m64 foo.d // module va_arg_x64_windows; void foo(void* a, void* b, void *c, void* d, ...) { import core.vararg : va_arg; import std.stdio : writeln; foreach (arg; _arguments) { if (arg == typeid(int)) { int x = va_arg!(int)(_argptr); writeln("x: ", x); } //else { //writeln("unknown arg type: ", arg.toString()); //} } } void main() { foo(null, null, null, null, 1234, 5678); // expected: // x: 1234 // x: 5678 // output: // x: 0 // x: 1234 }
Re: Interfacing with webcam
On Thursday, 11 January 2018 at 17:02:58 UTC, Amorphorious wrote: Looking for something similar. I simply need to show the video of a camera and be able to do to basics like rotation, crop, etc. On which platform? On Windows I've successfully used DirectShow, I can show an example of working with a camera.
Re: Druntime: Changing the underlying C Standard Library
On Friday, 12 January 2018 at 03:21:15 UTC, Sebastian Trent wrote: I'm writing an operating system in D for some exotic hardware. I understand the D runtime environment depends on a C stdlib being available (at compile time or run time?) both As a consequence of the hardware, I need to use our own C std lib for the operating system. How can I set about directing the compiler (or run-time) to non-default implementation? Same way you would in C itself: instruct the linker to use your runtime instead. On Linux, something like `-L-nostdlib -L-lmy_c_library` should do it. The -L option to dmd passes the rest of the option down to the linker (gcc, which then passes it to ld), so that `-nostdlib` flag is actually one of gcc's. Alternatively, I infer there's nothing breaking about replacing all of core.stdc with an implementation written in -betterC? core.stdc has no code per se, it is just function prototypes to access the C library. The C library itself is provided externally by the linker.
Druntime: Changing the underlying C Standard Library
Hello, I'm writing an operating system in D for some exotic hardware. I understand the D runtime environment depends on a C stdlib being available (at compile time or run time?) As a consequence of the hardware, I need to use our own C std lib for the operating system. How can I set about directing the compiler (or run-time) to non-default implementation? Alternatively, I infer there's nothing breaking about replacing all of core.stdc with an implementation written in -betterC? Thanks, ST.
Re: union/toString: crash/segfault: What's happening here?
On Friday, 12 January 2018 at 00:54:03 UTC, kdevel wrote: $ dmd crash.d $ ./crash Nicholas Wilson is right that you can use = "" to work around it, but with strings, null is supposed to behave the same way. And this gives different (each wrong) behavior on -m32 vs -m64, which leads me to believe you actually found a compiler bug. Calling u.toString directly also leads to random spam, which means it isn't even the library. I'd file this as a compiler codegen bug.
Re: union/toString: crash/segfault: What's happening here?
On 01/12/2018 02:45 AM, Nicholas Wilson wrote: because you don't initialise `s` in string toString () { string s; return s; } so it defaults to `string s = null;` thus giving a segfault. try `string s = "";` instead. A null string is a perfectly fine empty string. Printing it does not lead to a segfault. And the thrown error is not a segfault. Actually, the problem seems to be that s is not default initialized. It's garbage. And garbage usually isn't a proper string, so writeln fails. Looks like a compiler bug.
Re: union/toString: crash/segfault: What's happening here?
On Friday, 12 January 2018 at 01:45:37 UTC, Nicholas Wilson wrote: so it defaults to `string s = null;` thus giving a segfault. null and "" are basically the same for strings. that's not the problem.
Re: Rvalue references
On Monday, 8 January 2018 at 23:31:27 UTC, Jonathan M Davis wrote: auto foo(T)(auto ref T t) { return t; } foo(42); will result in foo being instantiated as int foo(int t) { return t; } whereas int i; foo(i); will result in foo being instantiated as int foo(ref int t) { return t; } So, by using auto ref, a function can accept both lvalues and rvalues. And in D, rvalues get moved, not copied. What does it mean to "move" a variable/value instead of copying it? Was "auto ref" created for anything besides structs?
Re: union/toString: crash/segfault: What's happening here?
On Friday, 12 January 2018 at 00:54:03 UTC, kdevel wrote: crash.d ``` import std.stdio; union U { float f; int i; string toString () { string s; return s; } } void main () { U u; writeln (u); } ``` $ dmd crash.d $ ./crash because you don't initialise `s` in string toString () { string s; return s; } so it defaults to `string s = null;` thus giving a segfault. try `string s = "";` instead.
union/toString: crash/segfault: What's happening here?
crash.d ``` import std.stdio; union U { float f; int i; string toString () { string s; return s; } } void main () { U u; writeln (u); } ``` $ dmd crash.d $ ./crash std.exception.ErrnoException@/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(2776): (Bad address) ??:? @safe int std.exception.errnoEnforce!(int, "/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d", 2776uL).errnoEnforce(int, lazy immutable(char)[]) [0x43f20a] ??:? @safe void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[]) [0x4422a7] ??:? @safe void std.range.primitives.doPut!(std.stdio.File.LockingTextWriter, immutable(char)[]).doPut(ref std.stdio.File.LockingTextWriter, ref immutable(char)[]) [0x44224b] ??:? @safe void std.range.primitives.put!(std.stdio.File.LockingTextWriter, immutable(char)[]).put(ref std.stdio.File.LockingTextWriter, immutable(char)[]) [0x44222b] ??:? void std.format.formatObject!(std.stdio.File.LockingTextWriter, crash.U, char).formatObject(ref std.stdio.File.LockingTextWriter, ref crash.U, ref const(std.format.FormatSpec!(char).FormatSpec)) [0x44220a] ??:? void std.format.formatValue!(std.stdio.File.LockingTextWriter, crash.U, char).formatValue(ref std.stdio.File.LockingTextWriter, ref crash.U, ref const(std.format.FormatSpec!(char).FormatSpec)) [0x44219d] ??:? uint std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, crash.U).formattedWrite(ref std.stdio.File.LockingTextWriter, const(char[]), crash.U) [0x43e703] ??:? void std.stdio.File.write!(crash.U, char).write(crash.U, char) [0x43e3f5] ??:? void std.stdio.writeln!(crash.U).writeln(crash.U) [0x43e389] ??:? _Dmain [0x43e344]
Can you introspect predicate arity and if it's an equality predicate?
Hi, so basically is there a way to: void func(alias pred = null, Range)(Range range) { // 1) check if pred(ElementType!Range.init, ElementType!Range.init) is equality // 2) check if isUnary!pred // 3) check if isBinary!pred } I think maybe the isUnary or isBinary may not work unless it takes an extra parameter that gives it some context, i.e. isBinary!(pred, T, U) where T and U are the parameter types. Currently I have this for an isUnary template isUnary(alias pred) { static if (is(typeof(pred) : string)) { enum isUnary = is(typeof(unaryFun!pred(0))); } else static if (is(Parameters!pred F) && F.length == 1) { enum isUnary = true; } else { enum isUnary = false; } } But that does not seem to work in this situation: isUnary!(a => a) // returns false It won't work if I do isUnary!"a(2)" for e.g, in the case that T is callable or isUnary!"a.x" in the case that "a" is a struct with a member x ... just to name a couple of cases. If I give context then all's good: enum isUnaryOver = is(typeof(unaryFun!pred(T.init))); // works isEqualityFunction Im not sure how to go about. So open to any ideas, or if there're already some traits or something I can use. I was thinking I could do: alias E = // some element type static if (isBinary!(pred, E) && binaryFun!pred(E.init, E.init) == true) { // is equality ... but the for double.init is NaN == NaN ? // and probably some other things I'm not thinking about. } Advice and/or suggestions? Cheers PS: the purpose of the isEqualityFunction is to determine whether I should use the predicate for sorting or for just for searching, so: f!"a < b"(range) // range is sorted and then operated on f!"a == b"(range) // range is not sorted and is operated on by leveraging pred
Re: How to move an associative array between modules?
On Thursday, 11 January 2018 at 23:20:44 UTC, WhatMeWorry wrote: When I simply move the array out of main() but still in app.d, the compiler returns Error: expression ["SCRATCH":Track("scratch.wav", cast(Sound)1, 0, null),... is not a constant. Can I use "static if" or "static this()", or "mixin" or some other technique? Yeah, just declare the array outside, then initialize it inside a static this() constructor. int[int] foo; static this() { foo = [1:1]; }
How to move an associative array between modules?
I've built a sound.d module with lots data types, free functions (initAndOpenSound() loadSound()), and enums etc. In my main/app.d module, I've created the the following associative array: void main(string[] argv) { initAndOpenSound(); Track[string] tracks = [ "SCRATCH" : Track("scratch.wav", Sound.SFX, ONCE,null ), "BACKGROUND_SOUND" : Track("beat.wav",Sound.MUSIC, FOREVER, null ), "HIGH" : Track("high.wav",Sound.SFX, ONCE,null ) ]; foreach(string s, Track t; tracks) { loadSound(t); // sets ptr to a file with audio data tracks[s] = t; // update associative array } Everything works. But I know in the future, that the tracks is going to get very large. So I want to get it out of main() and move it to the sound.d module. I've tried this but all hell breaks loose and I can't make just of the compiler errors When I simply move the array out of main() but still in app.d, the compiler returns Error: expression ["SCRATCH":Track("scratch.wav", cast(Sound)1, 0, null),... is not a constant. Can I use "static if" or "static this()", or "mixin" or some other technique? Or do I need to refactor my code completely?
Re: Why is this valued zeroed?
On 01/11/2018 12:21 PM, Marc wrote: > I stuck at this and can't figure out the reason why the value of the > variable ds is 0 when I do this: startTime = MonoTime.currTime; It's not clear which of the two statements you're talking about. >> http.onProgress = (size_t dltotal, size_t dlnow, >>size_t ultotal, size_t ulnow) { >> if(dlNow > 0) { >>MonoTime endTime = MonoTime.currTime; >>Duration duration = endTime - startTime; >> long ds = duration.total!"seconds"; >> writeln("duration!seconds = ", ds); >> startTime = MonoTime.currTime; I would remove the one above and keep the one below. >> startTime = MonoTime.currTime; >> http.perform(); If you're trying to measure time between two onProgress() calls, as Steve noted, seconds is probably too large a unit. Ali
Re: calloc for std.experimental.allocator
On Thursday, 11 January 2018 at 21:09:01 UTC, Nordlöw wrote: Is there no equivalent of `calloc()` for `std.experimental.allocator`, something like Allocator.zeroAllocate(size_t numberOfElements) ? http://dpldocs.info/experimental-docs/std.experimental.allocator.makeArray.4.html
Re: Voldemort type for mixin template.
On Thursday, 11 January 2018 at 08:56:11 UTC, ChangLong wrote: When I try add some sub type for struct with mixin template, seems there is no way to hidden the private type. Is there a way to hidden type from mix template like Voldemort type ? fake code: mix template TypeX () { alias This = typeof(this); static struct Unique { This* _ptr ; } static struct Helper { private Unique data; } alias TypeX = { alias PublicName = Helper ; } } struct Node { mixin TypeX!(); PublicName helper; } Hi, can you explain a bit more? The question is not entirely clear to me. Can you mixin a struct of type PublicName and just hide everything in there? mixin template TypeX() { struct PublicName { private alias This = typeof(this); private struct Unique { This* _ptr; } private Unique _data; alias _data this; } } void main(string[] args) { mixin TypeX; PublicName helper; helper._ptr.writeln; } Cheers
calloc for std.experimental.allocator
Is there no equivalent of `calloc()` for `std.experimental.allocator`, something like Allocator.zeroAllocate(size_t numberOfElements) ?
Re: Why is this valued zeroed?
On 1/11/18 3:21 PM, Marc wrote: I stuck at this and can't figure out the reason why the value of the variable ds is 0 when I do this: startTime = MonoTime.currTime; if I remove that statement, the value of ds isn't zeroed, it has the actual number of seconds. But I can't figure out, ds is of integer type and such, it is copied, right? or is this related to the fact I'm setting it withi a callback function? here's the piece of code: import std.net.curl; auto http = HTTP(url); http.method = HTTP.Method.get; the relevant part: http.onProgress = (size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { if(dlNow > 0) { MonoTime endTime = MonoTime.currTime; Duration duration = endTime - startTime; long ds = duration.total!"seconds"; writeln("duration!seconds = ", ds); startTime = MonoTime.currTime; if I put startTime = MonoTime.currTime, ds is zero, otherwise, if I remove it, ds has the actual value. startTime is first set right before http.perform() call: startTime = MonoTime.currTime; http.perform(); (My goal is define the download transfer rate, different approachs for this are welcome) `total` truncates. So your time is less than 1 second. -Steve
Why is this valued zeroed?
I stuck at this and can't figure out the reason why the value of the variable ds is 0 when I do this: startTime = MonoTime.currTime; if I remove that statement, the value of ds isn't zeroed, it has the actual number of seconds. But I can't figure out, ds is of integer type and such, it is copied, right? or is this related to the fact I'm setting it withi a callback function? here's the piece of code: import std.net.curl; auto http = HTTP(url); http.method = HTTP.Method.get; ... the relevant part: http.onProgress = (size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { if(dlNow > 0) { MonoTime endTime = MonoTime.currTime; Duration duration = endTime - startTime; long ds = duration.total!"seconds"; writeln("duration!seconds = ", ds); startTime = MonoTime.currTime; if I put startTime = MonoTime.currTime, ds is zero, otherwise, if I remove it, ds has the actual value. startTime is first set right before http.perform() call: startTime = MonoTime.currTime; http.perform(); (My goal is define the download transfer rate, different approachs for this are welcome)
Re: Is it possible to append to a local buffer without reallocating?
On 1/11/18 12:41 PM, tipdbmp wrote: Appender is able to do this: It seems that Appender allocates its own private data: private struct Data { size_t capacity; Unqual!T[] arr; bool canExtend = false; } private Data* _data; _data = new Data; But hopefully its bug free unlike what I posted (missing `T.sizeof *` in the memcpy call). Hm... I thought it was using C malloc, or at least there was a version where it wasn't allocating an impl struct (I thought that had gone in a while ago?) But you can see how to accomplish what you seek by reading the code. -Steve
Re: Is it possible to append to a local buffer without reallocating?
Appender is able to do this: It seems that Appender allocates its own private data: private struct Data { size_t capacity; Unqual!T[] arr; bool canExtend = false; } ... private Data* _data; ... _data = new Data; But hopefully its bug free unlike what I posted (missing `T.sizeof *` in the memcpy call).
Re: How to test a DUB-based library during development?
On Thursday, 11 January 2018 at 14:59:18 UTC, DanielG wrote: Ah, thank you! I replaced: "libs-windows-x86-dmd" with: "sourceFiles-windows-x86-dmd" (and added a .lib suffix) and now everything works as expected. I see now that I was using "libs" improperly. It seems more for system-wide libraries / things in the library search path, not to be used for individual .lib files. Thanks again, you saved me many hours this morning :) I get mixed up with that too.
Re: Is it possible to append to a local buffer without reallocating?
On 1/11/18 6:21 AM, tipdbmp wrote: string push_stuff(char[] buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; return cast(string) buf[0 .. 3]; } else { buf ~= 'A'; buf ~= 'B'; return cast(string) buf[0 .. 2]; } } void foo() { { char[2] buf; string result = push_stuff(buf, 1); assert(buf.ptr != result.ptr); } { char[2] buf; string result = push_stuff(buf, 0); assert(buf.ptr == result.ptr); // <-- this assert fails } } Appender is able to do this: import std.array; void main() { char[2] buf; auto app = appender(buf[]); app.clear; // resets the buffer so it can be used again. app ~= 'A'; app ~= 'B'; assert(buf[] == "AB"); assert(app.data.ptr == buf.ptr); app ~= 'C'; assert(app.data.ptr != buf.ptr); } -Steve
Re: new int[]
On Wednesday, 10 January 2018 at 23:08:28 UTC, Luís Marques wrote: void main() { int[]* x = &[[1, 2, 3]][0]; int[]* x2 = [[1, 2, 3]].ptr; /* same */ } That's an interesting solution. I'm not sure which one I prefer, the wrapper or this one. Still... I feel like the language should just allow allocating an array itself on the GC heap :( I believe this does allocate from the automanaged heap already. At least it won't work with @nogc. If one wants to reserve the memory from the program space, he needs to use module-level static arrays. With immutable stuff I don't know, perhaps it's implementation dependant.
Re: Interfacing with webcam
On Tuesday, 30 September 2014 at 03:41:20 UTC, Kyle wrote: Hi, Has anyone successfully used D to capture images from a webcam? Something like what you can do with OpenCV or pygame's camera API? Any idea how I can do this without having to know a lot of complex stuff? Thanks! Looking for something similar. I simply need to show the video of a camera and be able to do to basics like rotation, crop, etc.
Re: Checking @nogc-ness of an Allocator.allocate()
On Thursday, 11 January 2018 at 13:18:47 UTC, Simen Kjærås wrote: On Thursday, 11 January 2018 at 12:32:54 UTC, Per Nordlöw wrote: Is this an ok implementation: enum bool isNogc(alias fun) = (isCallable!fun && (functionAttributes!fun & FunctionAttribute.nogc)); @safe pure nothrow @nogc unittest { static int foo(int x) @nogc pure nothrow; static int goo(int x) pure nothrow; static assert(isNogc!foo); static assert(!isNogc!goo); } Seems to be working fine. I'd go with this version for perhaps a bit more brevity and clarity: enum bool isNogc(alias fun) = hasFunctionAttributes!(fun, "@nogc"); Both functionAttributes and hasFunctionAttributes already check that the argument is a callable (which function attributes should "foo" have?), so that's unnecessary. -- Simen Author of hasFunctionAttributes here. FYI: `hasFunctionAttributes` is exactly intended to be used how you do it. functionAttributes is only there for legacy reasons. And it works nicely with inference too: https://run.dlang.io/is/9OXZct
Re: How to test a DUB-based library during development?
Ah, thank you! I replaced: "libs-windows-x86-dmd" with: "sourceFiles-windows-x86-dmd" (and added a .lib suffix) and now everything works as expected. I see now that I was using "libs" improperly. It seems more for system-wide libraries / things in the library search path, not to be used for individual .lib files. Thanks again, you saved me many hours this morning :)
Re: How to test a DUB-based library during development?
On Thursday, 11 January 2018 at 14:22:50 UTC, DanielG wrote: If I manually override "libs-windows-x86-dmd" in the example's dub.json, it links despite the error, but if possible I would like users of my library to not have to concern themselves with linkage issues. vibe.d seems to do it successfully: https://github.com/vibe-d/vibe.d/blob/master/tls/dub.sdl#L18
Re: How to test a DUB-based library during development?
Thank you very much, very helpful! I'm currently attempting the (A) suggestion, but find that dub isn't fixing up the relative path to one of the parent's prerequisite libraries. In the parent: "libs-windows-x86-dmd": ["./lib/32/dmd/SomeLibrary"] This causes a warning when building the nested example, because it's not adjusting the path: "Warning 2: File Not Found .\lib\32\dmd\SomeLibrary.lib" If I manually override "libs-windows-x86-dmd" in the example's dub.json, it links despite the error, but if possible I would like users of my library to not have to concern themselves with linkage issues.
Re: Is it possible to append to a local buffer without reallocating?
Have you checked what push_stuff actually returns with those inputs? Right, we get [0xFF, 0xFF, 'A'] and [0xFF, 0xFF]. I think the following is a pretty easy workaround though: alias usize = size_t; struct Push_Buf(T, usize stack_size) { T[stack_size] stack_buf; T[] heap_buf; usize p = 0; void opOpAssign(string op)(T e) if (op == "~") { if (p < stack_size) { stack_buf[p] = e; p += 1; } else { if (p == stack_size) { heap_buf = stack_buf.dup(); p += 1; } heap_buf ~= e; } } void opOpAssign(string op)(immutable(T)[] es) if (op == "~") { if (p + es.length <= stack_size) { import core.stdc.string : memcpy; memcpy(_buf[p], es.ptr, es.length); p += es.length; } else { if (p < stack_size) { heap_buf = stack_buf[0 .. p].dup(); p += es.length; } heap_buf ~= es; } } U opCast(U: T[])() { return as_slice(); } U opCast(U: immutable(T)[])() { return cast(immutable(T)[]) as_slice(); } @property T[] as_slice() { if (p <= stack_size) { return stack_buf[0 .. p]; } else return heap_buf; } alias as_slice this; } string push_stuff(usize buf_size)(ref Push_Buf!(char, buf_size) buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; } else { buf ~= 'A'; buf ~= 'B'; } return cast(string) buf; } void foo() { { Push_Buf!(char, 2) buf; string result = push_stuff(buf, 1); assert(buf.heap_buf.ptr == result.ptr); } { Push_Buf!(char, 2) buf; string result = push_stuff(buf, 0); assert(buf.stack_buf.ptr == result.ptr); } }
Re: Checking @nogc-ness of an Allocator.allocate()
On Thursday, 11 January 2018 at 12:32:54 UTC, Per Nordlöw wrote: Is this an ok implementation: enum bool isNogc(alias fun) = (isCallable!fun && (functionAttributes!fun & FunctionAttribute.nogc)); @safe pure nothrow @nogc unittest { static int foo(int x) @nogc pure nothrow; static int goo(int x) pure nothrow; static assert(isNogc!foo); static assert(!isNogc!goo); } Seems to be working fine. I'd go with this version for perhaps a bit more brevity and clarity: enum bool isNogc(alias fun) = hasFunctionAttributes!(fun, "@nogc"); Both functionAttributes and hasFunctionAttributes already check that the argument is a callable (which function attributes should "foo" have?), so that's unnecessary. -- Simen
Re: How to test a DUB-based library during development?
On Thursday, 11 January 2018 at 12:27:27 UTC, DanielG wrote: Is there a simple example that shows how to test the library during development, before publishing (ie, before being able to add it as a dependency to another project)? I guess I'm just asking, what's the convention here? Do I create a separate project and then add my not-yet-published library via 'dub add-local'? Put everything in a unittest in the library itself? etc etc. You may have some unittest blocks in your source files, and then type: $ dub test If you want to add examples, some do it either A. with a separate dub.json/dub.sdl To keep your example up-to-date with master you should use path-based dependencies. See https://github.com/vibe-d/vibe.d/tree/master/examples for examples examples. This is the closest to "standard" you'll get. But if the examples are too large and numerous some libraries also keep them in another repositery, in such case you will need to use tags. B. with a DUB configuration C. with a DUB sub-package IMHO you should rather do A rather than C rather than B.
Re: Is it possible to append to a local buffer without reallocating?
On Thursday, January 11, 2018 11:21:08 tipdbmp via Digitalmars-d-learn wrote: > string push_stuff(char[] buf, int x) { > if (x == 1) { > buf ~= 'A'; > buf ~= 'B'; > buf ~= 'C'; > return cast(string) buf[0 .. 3]; > } > else { > buf ~= 'A'; > buf ~= 'B'; > return cast(string) buf[0 .. 2]; > } > } > > void foo() { > { > char[2] buf; > string result = push_stuff(buf, 1); > assert(buf.ptr != result.ptr); > } > > { > char[2] buf; > string result = push_stuff(buf, 0); > assert(buf.ptr == result.ptr); // <-- this assert fails > } > } A dynamic array can only expand in place without reallocating if its memory was allocated by the GC for a dynamic array, and it's the farthest slice into that block of memory (so that appending to it wouldn't overlap with another array). A dynamic array which is a slice of a static array is not allocated by the GC to be a dynamic array; it was allocated on the stack to be a stack array. So, appending to it even once would cause it to be reallocated. But if you want to know whether reallocation is going to occur, then check the array's capacity. If the capacity is the length of the dynamic array or less, then appending will cause it to reallocate. For a dynamic array backed by a static array or malloc-ed memory or anything other than memory allocated by the GC to be a dynamic array, the capacity will be 0. - Jonathan M Davis
Re: Checking @nogc-ness of an Allocator.allocate()
On Thursday, 11 January 2018 at 12:24:36 UTC, Nordlöw wrote: How do I check whether an aggregate member function (call for a specific argument) is @nogc or not? I want to check whether Allocator.allocate(1) (for a any Allocator) is @nogc or not? Is https://dlang.org/phobos/std_traits.html#hasFunctionAttributes the way to do it? Is this an ok implementation: enum bool isNogc(alias fun) = (isCallable!fun && (functionAttributes!fun & FunctionAttribute.nogc)); @safe pure nothrow @nogc unittest { static int foo(int x) @nogc pure nothrow; static int goo(int x) pure nothrow; static assert(isNogc!foo); static assert(!isNogc!goo); }
How to test a DUB-based library during development?
I want to create a library and eventually publish it via the DUB registry. Is there a simple example that shows how to test the library during development, before publishing (ie, before being able to add it as a dependency to another project)? I guess I'm just asking, what's the convention here? Do I create a separate project and then add my not-yet-published library via 'dub add-local'? Put everything in a unittest in the library itself? etc etc.
Checking @nogc-ness of an Allocator.allocate()
How do I check whether an aggregate member function (call for a specific argument) is @nogc or not? I want to check whether Allocator.allocate(1) (for a any Allocator) is @nogc or not? Is https://dlang.org/phobos/std_traits.html#hasFunctionAttributes the way to do it?
Re: Is it possible to append to a local buffer without reallocating?
On Thursday, 11 January 2018 at 11:21:08 UTC, tipdbmp wrote: string push_stuff(char[] buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; return cast(string) buf[0 .. 3]; } else { buf ~= 'A'; buf ~= 'B'; return cast(string) buf[0 .. 2]; } } void foo() { { char[2] buf; string result = push_stuff(buf, 1); assert(buf.ptr != result.ptr); } { char[2] buf; string result = push_stuff(buf, 0); assert(buf.ptr == result.ptr); // <-- this assert fails } } Have you checked what push_stuff actually returns with those inputs? When you pass buf to push_stuff, it contains [255,255], and already has a length of 2. It's not possible to append to that without reallocating. Now, that's not the whole problem. When you append to an array, the GC checks if there's any free space in the block that's been allocated. Since this is on the stack, the GC doesn't have a blockinfo for it, and even if it did, the layout would change so often that the overhead would be immense. So, the answer is no, it's not possible. -- Simen
Is it possible to append to a local buffer without reallocating?
string push_stuff(char[] buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; return cast(string) buf[0 .. 3]; } else { buf ~= 'A'; buf ~= 'B'; return cast(string) buf[0 .. 2]; } } void foo() { { char[2] buf; string result = push_stuff(buf, 1); assert(buf.ptr != result.ptr); } { char[2] buf; string result = push_stuff(buf, 0); assert(buf.ptr == result.ptr); // <-- this assert fails } }
Is it possible to append to a local buffer without reallocating?
string push_stuff(char[] buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; return cast(string) buf[0 .. 3]; } else { buf ~= 'A'; buf ~= 'B'; return cast(string) buf[0 .. 2]; } } void foo() { { char[2] buf; string result = push_stuff(buf, 1); assert(buf.ptr != result.ptr); } { char[2] buf; string result = push_stuff(buf, 0); assert(buf.ptr == result.ptr); // <-- this assert fails } }
Re: Getting a Type from TypeInfo / Getting Variant Type
On Thursday, 11 January 2018 at 08:59:01 UTC, Chirs Forest wrote: I'm using std.variant.Variant to hold a value of unknown type (not a string, could be a numeric type or a container holding multiple numeric types). I'm trying to retrieve this value with .get!T but I need the type to do that... .type gives me TypeInfo, but that's not a type so I'm not sure how to get the type without checking the TypeInfo against all possible types (which would be a massive pain). Since types are compile-time features, you can't just turn a TypeInfo into a type, sadly. However, provided you use Algebraic and not Variant, you have a limited type universe, and can iterate over the possibilities: import std.variant; import std.stdio; template dispatch(alias Fn) { auto dispatch(A)(A arg) if (A.AllowedTypes.length > 0) { static foreach (T; A.AllowedTypes) { if (typeid(T) == arg.type) { return Fn(arg.get!T); } } } } void test(int n) { writeln("It's an int!"); } void test(string s) { writeln("It's a string!"); } unittest { Algebraic!(int, string) a = 4; a.dispatch!test(); // It's an int! a = "Test"; a.dispatch!test(); // It's a string! Algebraic!(float, int[]) b = 2.3f; a.dispatch!test(); // Will not compile, since test has no overloads for float or int[]. Variant v = 3; v.dispatch!test; // Will not compile, since we don't know which types it can take } -- Simen
Re: Getting a Type from TypeInfo / Getting Variant Type
On Thursday, January 11, 2018 08:59:01 Chirs Forest via Digitalmars-d-learn wrote: > I'm using std.variant.Variant to hold a value of unknown type > (not a string, could be a numeric type or a container holding > multiple numeric types). I'm trying to retrieve this value with > .get!T but I need the type to do that... .type gives me TypeInfo, > but that's not a type so I'm not sure how to get the type without > checking the TypeInfo against all possible types (which would be > a massive pain). If you have a variable of the type you put in, then you can use the typeof operator on it to get the type. e.g. int i = 42; static assert(is(typeof(i) == int)); It's even possible to declare variables of voldemort types that way - e.g. if you want to save the result in a member variable. But from what I can tell, you're either going to need to know the type you'r dealing with, or you're going to need a variable of the type so that you can then use typeof on it to get its type. - Jonathan M Davis
Getting a Type from TypeInfo / Getting Variant Type
I'm using std.variant.Variant to hold a value of unknown type (not a string, could be a numeric type or a container holding multiple numeric types). I'm trying to retrieve this value with .get!T but I need the type to do that... .type gives me TypeInfo, but that's not a type so I'm not sure how to get the type without checking the TypeInfo against all possible types (which would be a massive pain).
Voldemort type for mixin template.
When I try add some sub type for struct with mixin template, seems there is no way to hidden the private type. Is there a way to hidden type from mix template like Voldemort type ? fake code: mix template TypeX () { alias This = typeof(this); static struct Unique { This* _ptr ; } static struct Helper { private Unique data; } alias TypeX = { alias PublicName = Helper ; } } struct Node { mixin TypeX!(); PublicName helper; }