Re: dub: how to reference a compiled package
On Friday, 26 February 2016 at 04:03:15 UTC, BBasile wrote: e.g the DMD equivalent for the two previous example is DMD "sourceThis.d" "folder/interface.di" "folder/binary.a" -ofbin/thesoft You can mix unlinked binaries and text-editor source files on commandline? Didn't know that when I tried this. http://imgur.com/AIgZGmW I ought to try these interface *.di files. Just tried `ldc2 -H ` but it wouldn't do a C file also.
Re: dub: how to reference a compiled package
On Friday, 26 February 2016 at 04:03:15 UTC, BBasile wrote: The D interface file must be specified to DUB using "sourceFiles" : ["folder/interface.di"], either in a config or in the globals. The binary, so either a .lib | .a or .obj | .o must be specified to DUB using "DFlags" : ["folder/binary.a"], Here again also accepted in a config or the globals. This is because DUB doesn't consider such binary as source file but DMD or LDMD2 will accept them as source in the command line. e.g the DMD equivalent for the two previous example is DMD "sourceThis.d" "folder/interface.di" "folder/binary.a" -ofbin/thesoft Why? As long as the interface file is on the import path, it shouldn't need to be passed along to DMD. When you import foo.bar, the compiler will look for both foo/bar.di and foo/bar.d.
Re: dub: how to reference a compiled package
On Friday, 26 February 2016 at 03:19:26 UTC, mahdi wrote: Great! Thanks. I was looking for a feature like `jar` files in Java or `assemblies` in C# where all compiled code and metadata/symbols are stored together inside a single binary file. I think same can be implemented for D language and it won't break any code because it is not touching the language itself, but the compiler. The magic in Java isn't from Jar files, but from the fact that class binaries are distributed as byte code. All of the information from the source is still there. The compiler can learn everything it needs to know about imported classes simply by reading the byte code instead of the source. In the model that D uses, I don't know enough about object file formats to know how much information would still be available if they were used at compile time, but I'm fairly certain it wouldn't allow the use of templates. There was a project several years ago that allowed loading D classes dynamically from object files, but I suspect if it were practical to use object files at compile time in the same way Java class files are used, someone would have implemented such a thing already (in C and C++ as well). That said, it might be an interesting enhancement for the compiler to support reading source or interface files from zip archives (which is I know is what you're getting at), allowing the required imports and the binary to be located in one place so that only a single path need be passed on the command line to find everything.
Minimise and collect by GC when OutOfMemory
Would it be a good idea to call "collect" and "minimize" methods of core.memory.GC when OutOfMemory error is received FOR A LONG RUNNING PROGRAM? or there won't be any benefit of that? Example program: A web server that allocates and releases memory from heap continuously.
Re: all functions that have a first arg of type T
On Friday, 26 February 2016 at 04:21:15 UTC, BBasile wrote: On Friday, 26 February 2016 at 04:19:29 UTC, BBasile wrote: static if (__traits(isStaticFunction,typeof(m2))) static if (__traits(isStaticFunction, __traits(getMember, vulkan_input, m2 Sorry don't copy paste like this there's a superfluous right paren. static if (__traits(isStaticFunction, __traits(getMember, vulkan_input, m2))) thanks Nic
Re: all functions that have a first arg of type T
On Friday, 26 February 2016 at 04:19:29 UTC, BBasile wrote: static if (__traits(isStaticFunction,typeof(m2))) static if (__traits(isStaticFunction, __traits(getMember, vulkan_input, m2 Sorry don't copy paste like this there's a superfluous right paren. static if (__traits(isStaticFunction, __traits(getMember, vulkan_input, m2)))
Re: all functions that have a first arg of type T
On Friday, 26 February 2016 at 03:57:25 UTC, Nicholas Wilson wrote: foreach(m; __traits(allMembers, vulkan_input)) { static if (m.endsWith("_T")) { foreach(m2; __traits(allMembers, vulkan_input)) { static if (__traits(isStaticFunction,typeof(m2)))// <- what here? { enum fn = __traits(getMember,vulkan_input, m2); enum parameters = Parameters!(fn); static if (parameters[0] == m) writeln( m, ":",m2); } } } } static if (__traits(isStaticFunction,typeof(m2))) static if (__traits(isStaticFunction, __traits(getMember, vulkan_input, m2
Re: dub: how to reference a compiled package
On Thursday, 25 February 2016 at 12:15:42 UTC, mahdi wrote: Hi, Suppose I have a package `mypack` in `~/mypack`. I run `dub` command on this package and have the compiled `mypack` file (OS is Linux). Now I am working on my project. I know how to use the source-code of `mypack` package in the project but what if I only have the compiled binary? How can I reference and use the modules of the compiled `mypack`? (I looked into the DUB homepage and it's Getting Started page but could not find anything). As you've been told previous you need a D interface file. But additionally: The D interface file must be specified to DUB using "sourceFiles" : ["folder/interface.di"], either in a config or in the globals. The binary, so either a .lib | .a or .obj | .o must be specified to DUB using "DFlags" : ["folder/binary.a"], Here again also accepted in a config or the globals. This is because DUB doesn't consider such binary as source file but DMD or LDMD2 will accept them as source in the command line. e.g the DMD equivalent for the two previous example is DMD "sourceThis.d" "folder/interface.di" "folder/binary.a" -ofbin/thesoft
all functions that have a first arg of type T
foreach(m; __traits(allMembers, vulkan_input)) { static if (m.endsWith("_T")) { foreach(m2; __traits(allMembers, vulkan_input)) { static if (__traits(isStaticFunction,typeof(m2)))// <- what here? { enum fn = __traits(getMember,vulkan_input, m2); enum parameters = Parameters!(fn); static if (parameters[0] == m) writeln( m, ":",m2); } } } } m2 is a string I've tried mixin: gives me Error: function vulkan_input.VK_MAKE_VERSION (int major, int minor, int patch) is not callable using argument types () and various combos of typeof and mixin typeof(m2) is an __error typeof(mixin(m2)) " T is not an expression". fails for m2 == uint etc and m2 == module gives module had no type Nic
Re: how to initialise const variables
On Friday, 26 February 2016 at 02:32:44 UTC, Nicholas Wilson wrote: struct A { const (void *) p; } struct B { Aa; this(void * _p) { a.p = _p; } } I cannot change the definition of A how do I initialise b.a.p? Use a constructor for A instead of trying to write to one specific member: a = A(_p); const variable must be initialized in constructors. Structs have automatically defined constructors that take all the member variables so even if it isn't explicitly written, you can still do this.
Re: dub: how to reference a compiled package
On Friday, 26 February 2016 at 02:49:20 UTC, Mike Parker wrote: On Thursday, 25 February 2016 at 21:06:59 UTC, mahdi wrote: On Thursday, 25 February 2016 at 16:45:46 UTC, Chris Wright Thanks. Is there a way to use a D library without having access to it's source code? I tried `dmd -lib abcd.d` which creates a static library. But still I need to specify path to library's source files using -I option when compiling the code that uses that library. So if we have just access to the library file, is it possible to use it in the code? The compiler needs to know what symbols are available from any imports you use in your source. .di files exist to allow closed source projects to be distributed as binary. They are analagous to C or C++ header files. You could create them by hand like so: // foo.d struct S { int x, y; } void addTwo(S s) { s.x += 2; s.y += 2; } // foo.di struct S { int x, y; } void addTwo(S s); The compiler needs to know about S and its types, and it needs to know the signature of addTwo. The .di file allows you to provide that while keeping the implementation of addTwo closed. When foo is imported in client code, the compiler will find foo.di and use that instead of foo.d. However, the compiler must have the source for templates, as they are instantiated when they are used, not when the library is compiled. The same is true for any functions you want inlined. In the example above, addTwo can only be inlined when foo.d is used, since the compiler will not have the implementation with foo.di. Great! Thanks. I was looking for a feature like `jar` files in Java or `assemblies` in C# where all compiled code and metadata/symbols are stored together inside a single binary file. I think same can be implemented for D language and it won't break any code because it is not touching the language itself, but the compiler. Anyway, thanks.
Re: how to initialise const variables
On Friday, 26 February 2016 at 02:48:35 UTC, cym13 wrote: On Friday, 26 February 2016 at 02:32:44 UTC, Nicholas Wilson wrote: struct A { const (void *) p; } struct B { Aa; this(void * _p) { a.p = _p; } } I cannot change the definition of A how do I initialise b.a.p? As you did: void main() { int i = 42; B b = B(); int* p = cast(int*)b.a.p; assert(*p == 42); } a.p = _p; fails to compile fixed by a = typeof(a)(_p);
Re: dub: how to reference a compiled package
On Friday, 26 February 2016 at 02:49:20 UTC, Mike Parker wrote: The compiler needs to know about S and its types, and it needs S and its *members*
Re: dub: how to reference a compiled package
On Thursday, 25 February 2016 at 21:06:59 UTC, mahdi wrote: On Thursday, 25 February 2016 at 16:45:46 UTC, Chris Wright Thanks. Is there a way to use a D library without having access to it's source code? I tried `dmd -lib abcd.d` which creates a static library. But still I need to specify path to library's source files using -I option when compiling the code that uses that library. So if we have just access to the library file, is it possible to use it in the code? The compiler needs to know what symbols are available from any imports you use in your source. .di files exist to allow closed source projects to be distributed as binary. They are analagous to C or C++ header files. You could create them by hand like so: // foo.d struct S { int x, y; } void addTwo(S s) { s.x += 2; s.y += 2; } // foo.di struct S { int x, y; } void addTwo(S s); The compiler needs to know about S and its types, and it needs to know the signature of addTwo. The .di file allows you to provide that while keeping the implementation of addTwo closed. When foo is imported in client code, the compiler will find foo.di and use that instead of foo.d. However, the compiler must have the source for templates, as they are instantiated when they are used, not when the library is compiled. The same is true for any functions you want inlined. In the example above, addTwo can only be inlined when foo.d is used, since the compiler will not have the implementation with foo.di.
Re: how to initialise const variables
On Friday, 26 February 2016 at 02:32:44 UTC, Nicholas Wilson wrote: struct A { const (void *) p; } struct B { Aa; this(void * _p) { a.p = _p; } } I cannot change the definition of A how do I initialise b.a.p? As you did: void main() { int i = 42; B b = B(); int* p = cast(int*)b.a.p; assert(*p == 42); }
how to initialise const variables
struct A { const (void *) p; } struct B { Aa; this(void * _p) { a.p = _p; } } I cannot change the definition of A how do I initialise b.a.p?
Re: how do you append arrays?
On 2/25/16 4:39 PM, asdf wrote: if(line != "" && line != history[0]) { string[] x = [line]; foreach(string i; history[0..99]) x ~= i; history = x; } ugh! history = line ~ history[0 .. $ - 1]; What you may want to consider is making history backwards referenced. That is, history[0] is the oldest line. Then you could do: history = history[1 .. $]; history ~= line; Is there a good way to pick out matching prefixes of a string? Picking out the first word without disrupting whitespace after the second word would be nice =) How do you read chars without waiting for a newline? That would be needed to respond to the ANSI esapes for arrow keys... If you are only getting characters after a newline, then you aren't interacting directly with the terminal (which requires some terminal access library). The terminal is letting the user edit the line, then when he hits return, it sends the whole line to your program. You won't get arrow key codes. -Steve
Re: Accessing all data in TypeTupple (AliasSeq) and stringify them
On 02/25/2016 12:53 PM, Voitech wrote: template TupleToString(TList...){ string a; foreach(T;TList){ // Error: declaration expected, not 'foreach' a~=T.stringof; } enum string TupleToString=a; } Of course i can use template function, but wanted to know if can omit this. Cheers Voitech You have to wrap the logic in a function and call that function: template TupleToString(TList...){ string make_a() { string a; foreach(T;TList){ a~=T.stringof; } return a; } enum string TupleToString=make_a(); } Ali
Re: Accessing all data in TypeTupple (AliasSeq) and stringify them
On Thursday, 25 February 2016 at 20:53:12 UTC, Voitech wrote: On Thursday, 25 February 2016 at 14:29:30 UTC, Nicholas Wilson wrote: On Thursday, 25 February 2016 at 13:16:43 UTC, Voitech wrote: [...] You can (see std.meta/(std.traits?) , with recursive templates), but there is nothing stopping from using for/foreach in a template this should do what you want string[] functionSig; string[] params; foreach(s; Parameters!T)) // returns AliasSeq of types { params ~=s.stringof; } string[] pits; foreach(p; ParameterIdentifierTuple!(T)); // returns AliasSeq of strings { pits ~=p; } and the either join(er) or do as you see fit. or use plain old for for(auto i=0;i< pits.length; i++) { functionSig ~= params[i]; functionSig ~= pits[i]; } writeln(functionSig); // should print ["int" , "param0" , "string" , "param1"] Nic Thank You for answering, well i wanted to make all of this in template block, not using template functions (testing if it is possible), but i'm getting error when i try to create something like template TupleToString(TList...){ string a; foreach(T;TList){ // Error: declaration expected, not 'foreach' a~=T.stringof; } enum string TupleToString=a; } Of course i can use template function, but wanted to know if can omit this. Cheers Voitech See the recursive templates in std.meta; this would be something like template TupleToString(TList...) { static if(Tlist.length == 0) enum string TupleToString = ""; else enum string TupleToString=TList[0].stringof ~ TupleToString(TList[1 . $]; } Nic
Re: Calling python code from D
On Thursday, 25 February 2016 at 21:46:40 UTC, asdf wrote: Hi, me again. I'm having trouble making a demonstration and not sure if is obsolete or not anyways. :/ Anyways take a look here. http://www.tutorialspoint.com/python/python_further_extensions.htm http://dlang.org/spec/interfaceToC.html
Re: Calling python code from D
On Thursday, 25 February 2016 at 21:46:40 UTC, asdf wrote: I haven't tried this myself but D is supposed to have excellent interface to C code. Perhaps you can go that route. http://stackoverflow.com/questions/145270/calling-c-c-from-python That question is the reverse, calling C from python, rather than calling python from C. I think PyD is really your best option. The problem with PyD's docs is that it's not obvious how to get to them from the github page. You actually have to go to the wiki page and then there's a link to older docs from Bitbucket or ReadTheDocs, but those links are broken. Here's the readthedocs page: http://pyd.readthedocs.org/en/latest/ You would actually be interested in something like: http://pyd.readthedocs.org/en/latest/embed.html
Re: Installing DUB on OSX
On Thursday, 25 February 2016 at 11:06:09 UTC, Jacob Carlborg wrote: On 2016-02-24 23:11, Joel wrote: Error: Error writing file '../../../.dub/packages/dsfml-2.1.0/libdsfml_system.a' Joels-MacBook-Pro:DGuy joelcnz$ Is the full path of ../../../.dub/packages/dsfml-2.1.0 writable? It is path: Macky -> Users/joelcnz and is writable. But .dub etc on the path isn't writable. (joelcnz/.dub)
Re: Calling python code from D
On Thursday, 25 February 2016 at 21:40:45 UTC, Wyatt wrote: I have a project I started in Python before I realised I really don't enjoy Python. It's been on the back-burner for a few years and I'd like to start again in D, but there's a particular python module (Mutagen) that I outright refuse to reimplement. What's the state of the art in calling Python code from D? I have a hunch PyD fits somewhere in this equation, but the documentation is pretty sparse, and what little I can find about this area makes it seem like a fairly tedious manual process. Is there a less-painful and intensive way to truss things up? Something to generate a simple D wrapper from a python module? -Wyatt I haven't tried this myself but D is supposed to have excellent interface to C code. Perhaps you can go that route. http://stackoverflow.com/questions/145270/calling-c-c-from-python
Calling python code from D
I have a project I started in Python before I realised I really don't enjoy Python. It's been on the back-burner for a few years and I'd like to start again in D, but there's a particular python module (Mutagen) that I outright refuse to reimplement. What's the state of the art in calling Python code from D? I have a hunch PyD fits somewhere in this equation, but the documentation is pretty sparse, and what little I can find about this area makes it seem like a fairly tedious manual process. Is there a less-painful and intensive way to truss things up? Something to generate a simple D wrapper from a python module? -Wyatt
Re: how do you append arrays?
On Thursday, 25 February 2016 at 19:21:31 UTC, Steven Schveighoffer wrote: On 2/25/16 2:12 PM, Steven Schveighoffer wrote: I believe you could use std.algorithm.copy, but probably need to do it with retro as well. Heh, or of course use memmove :) -Steve I got the history list working this morning but probably not very efficient. You can see: cut debug = 0; import std.stdio; import std.string; void main() { string line; string[] history; char cmd = '/', sep = ';', dot = '.', bak = '\\'; line = readln().chomp; foreach(int i; 0..100) history ~= ""; debug(1) { stderr.writeln(history); } while(!stdin.eof) { string[] emit = line.split(sep); foreach(string e; emit) { /* how to do proper prefix and/or leading word? */ if(e[0] == cmd) { /* ... */ } else if(e[0] == dot) { /* ... */ } else if(e[0] == bak) { /* ... */ } else writeln(e); } if(line != "" && line != history[0]) { string[] x = [line]; foreach(string i; history[0..99]) x ~= i; history = x; } debug(1) { stderr.writeln(history); } line = readln().chomp; } } cut Is there a good way to pick out matching prefixes of a string? Picking out the first word without disrupting whitespace after the second word would be nice =) How do you read chars without waiting for a newline? That would be needed to respond to the ANSI esapes for arrow keys...
Re: Installing DUB on OSX
On Thursday, 25 February 2016 at 11:06:09 UTC, Jacob Carlborg wrote: On 2016-02-24 23:11, Joel wrote: Error: Error writing file '../../../.dub/packages/dsfml-2.1.0/libdsfml_system.a' Joels-MacBook-Pro:DGuy joelcnz$ Is the full path of ../../../.dub/packages/dsfml-2.1.0 writable? .dub is grayed out on Finder, and isn't writable.
Re: How to better organize dub project to get 3 exe from same codebase?
On Thursday, 25 February 2016 at 20:55:33 UTC, Suliman wrote: On Thursday, 25 February 2016 at 19:09:59 UTC, Suliman wrote: Where to store shared classes? { "name": "123", "authors": [ "Suliman" ], "description": "A minimal D application.", "copyright": "Copyright © 2016, Suliman", "license": "proprietary", "subPackages": [ { "name": "App1", "description": "App1", "targetType": "executable", "sourcePaths": ["source/App1"] }, { "name": "App2", "description": "App2", "targetType": "executable", "sourcePaths": ["source/App2"] }, { "name": "App3", "description": "App3", "targetType": "executable", "sourcePaths": ["source/App3"] } } Should I link from subPackages to general source/ folder ? I don't link nothing. I have some shared D source code files between the 3 files (on src/dcpu). So each subpackage generates a executable file, excluding the not common files of the other subpackages. It isn't the best way of doing this, but just works for my case. Eventually i would change this. I think that alphaPhobos does what you are asking : https://github.com/rikkimax/alphaPhobos/blob/master/dub.sdl
Re: dub: how to reference a compiled package
On Thursday, 25 February 2016 at 16:45:46 UTC, Chris Wright wrote: On Thu, 25 Feb 2016 12:15:42 +, mahdi wrote: Hi, Suppose I have a package `mypack` in `~/mypack`. I run `dub` command on this package and have the compiled `mypack` file (OS is Linux). Now I am working on my project. I know how to use the source-code of `mypack` package in the project but what if I only have the compiled binary? How can I reference and use the modules of the compiled `mypack`? (I looked into the DUB homepage and it's Getting Started page but could not find anything). First thing, you need D interface files. See: https://dlang.org/dmd-linux.html#interface-files Note that D interface files still require you to include the full body of anything in a template, so you might have to modify your code somewhat for improved secrecy. Copy the *.di files and binaries into another dub project and add a postBuildCommand to copy that binary to the output location. I think that will work. dub might complain that it doesn't have any source files, in which case you'll have to provide at least one D file for it to compile, but that can be empty. Thanks. Is there a way to use a D library without having access to it's source code? I tried `dmd -lib abcd.d` which creates a static library. But still I need to specify path to library's source files using -I option when compiling the code that uses that library. So if we have just access to the library file, is it possible to use it in the code?
Re: How to better organize dub project to get 3 exe from same codebase?
On Thursday, 25 February 2016 at 19:09:59 UTC, Suliman wrote: Where to store shared classes? { "name": "123", "authors": [ "Suliman" ], "description": "A minimal D application.", "copyright": "Copyright © 2016, Suliman", "license": "proprietary", "subPackages": [ { "name": "App1", "description": "App1", "targetType": "executable", "sourcePaths": ["source/App1"] }, { "name": "App2", "description": "App2", "targetType": "executable", "sourcePaths": ["source/App2"] }, { "name": "App3", "description": "App3", "targetType": "executable", "sourcePaths": ["source/App3"] } } Should I link from subPackages to general source/ folder ?
Re: Accessing all data in TypeTupple (AliasSeq) and stringify them
On Thursday, 25 February 2016 at 14:29:30 UTC, Nicholas Wilson wrote: On Thursday, 25 February 2016 at 13:16:43 UTC, Voitech wrote: Hi, I have some code processing functions definition in compile time, I want to override them in some other class but not explicitly so created this code: template MixinFunction(alias attributes,alias returnType,alias name,alias parameters,alias bodyy){ enum string MixinFunction = format(q{ %s %s %s(%s){ %s } },attributes,returnType,name,parameters,bodyy); } unittest{ alias func=MixinFunction!("static","void","testFunc","int a,int b",q{ import std.stdio; writeln("im void body"); }); pragma(msg,func); mixin(func); } Now i acquired all data like return type, parameters but need to turn them into string for example function parameters must have form of: for function func: void func(int a,string b){} alias parameters=Parameters!func; returns me AliasSeq!(int,string) I want to to turn them into string: like "int param0, string param1", but in template template AliasSeqToString(TList...){ enum AliasSeqToString= ... //each ? } How to operate on TypeTuple/AliasSeq elemens withouth foreach ? You can (see std.meta/(std.traits?) , with recursive templates), but there is nothing stopping from using for/foreach in a template this should do what you want string[] functionSig; string[] params; foreach(s; Parameters!T)) // returns AliasSeq of types { params ~=s.stringof; } string[] pits; foreach(p; ParameterIdentifierTuple!(T)); // returns AliasSeq of strings { pits ~=p; } and the either join(er) or do as you see fit. or use plain old for for(auto i=0;i< pits.length; i++) { functionSig ~= params[i]; functionSig ~= pits[i]; } writeln(functionSig); // should print ["int" , "param0" , "string" , "param1"] Nic Thank You for answering, well i wanted to make all of this in template block, not using template functions (testing if it is possible), but i'm getting error when i try to create something like template TupleToString(TList...){ string a; foreach(T;TList){ // Error: declaration expected, not 'foreach' a~=T.stringof; } enum string TupleToString=a; } Of course i can use template function, but wanted to know if can omit this. Cheers Voitech
Re: How to detect if an array if dynamic or static
On 02/25/2016 04:47 AM, sigod wrote: > void bar(ref int[] arr) > > Code wouldn't compile if you try to pass static array as `ref` argument. To qualify further, static arrays cannot be passed as slice references because although there is an automatic slicing of static arrays, such slices are rvalues and rvalues cannot be bound to 'ref' parameters: > Error: function f436.bar (ref int[] arr) is not callable using > argument types (int[3]) Ali
Re: how do you append arrays?
On 2/25/16 2:12 PM, Steven Schveighoffer wrote: I believe you could use std.algorithm.copy, but probably need to do it with retro as well. Heh, or of course use memmove :) -Steve
Re: How to detect if an array if dynamic or static
On 2/24/16 9:08 PM, Adam D. Ruppe wrote: On Thursday, 25 February 2016 at 01:31:17 UTC, Chris Wright wrote: When you get to GC-allocated stuff, there's no way to tell. The GC is easy, you can simply ask it: http://dpldocs.info/experimental-docs/core.memory.GC.addrOf.1.html "If p references memory not originally allocated by this garbage collector, if p is null, or if the garbage collector does not support this operation, null will be returned." The append operator uses this kind of logic to determine if it is safe to append. The `capacity` property on slices can query, though it is zero in some cases where the GC owns it, but it still needs reallocation to be appended to (e.g. when the array is already at the max length of the allocated block, or when the stomping protection kicks in. See: http://dlang.org/d-array-article.html ) Just a slight nit -- it will only return 0 if the array slice doesn't end at the end of valid data as defined by the metadata. If it ends exactly at the max length of the block, then arr.capacity == arr.length. It will also return 0 if the memory block in question wasn't allocated via the array allocation routine (and therefore has no metadata). The correct answer is what you said, to use the GC to look up whether it's part of the GC. -Steve
Re: how do you append arrays?
On 2/25/16 8:24 AM, asdf wrote: On Thursday, 25 February 2016 at 13:06:10 UTC, cym13 wrote: In D the binary operator "~" is used to concatenate both strings (arrays of characters) and arrays. (also the ~= operator is equivalent to lhs = lhs ~ rhs Nic Just a precision: "lhs ~= rhs" isn't exactly equivalent to "lhs = lhs ~ rhs", those are two distinct operators that may deal with memory etc in different ways. For arrays doing "lhs = lhs ~ rhs" will first create (and allocate) the array corresponding to "lhs ~ rhs" and then assign this new array to lhs. On the other hand "lhs ~= rhs" realises in-place append. I tried both, the error this time is: object.Exception@/data/data/com.termux/files/home/ldc/runtime/druntime/src/ldc/arrayinit.d(151): overlapping array copy overlapping copies are not supported. In this case especially, the copying has to be done backwards. I believe you could use std.algorithm.copy, but probably need to do it with retro as well. -Steve
Re: How to better organize dub project to get 3 exe from same codebase?
Where to store shared classes?
Re: How to better organize dub project to get 3 exe from same codebase?
On Thursday, 25 February 2016 at 18:57:08 UTC, Suliman wrote: I have got 3 small projects that have shared code base. At compile time they use few same classes. On runtime they use same config file. How to better to organize work with dub? Try with subpacjages like I did : name "dedcpu" authors "Luis Panadero Guardeño" targetType "none" license "BSD 3-clause" description "DCPU-16 tools" subPackage { name "lem1802" description "Visual LEM1802 font editor" excludedSourceFiles "src/bconv.d" excludedSourceFiles "src/ddis.d" targetType "executable" targetName "lem1802" libs "gtkd" platform="windows" configuration "nogtk" { platforms "windows" } configuration "gtk" { platforms "posix" dependency "gtk-d:gtkd" version="~>3.2.0" } } subPackage { name "bconv" description "Binary file conversor. Converts between different data files for DCPU-16 emulators" targetType "executable" targetName "bconv" excludedSourceFiles "src/lem1802_fontview.d" excludedSourceFiles "src/ddis.d" excludedSourceFiles "src/ui/*" } subPackage { name "ddis" description "Dis-assembler for DCPU-16. Generates a DCPU-16 assembly dump from a binary file." targetType "executable" targetName "ddis" excludedSourceFiles "src/lem1802_fontview.d" excludedSourceFiles "src/bconv.d" excludedSourceFiles "src/ui/*" } https://github.com/Zardoz89/DEDCPU-16/blob/master/dub.sdl
How to better organize dub project to get 3 exe from same codebase?
I have got 3 small projects that have shared code base. At compile time they use few same classes. On runtime they use same config file. How to better to organize work with dub?
Re: Shared static constructors from C# EXE
On Thursday, 25 February 2016 at 16:05:37 UTC, Benjamin Thaut wrote: On Thursday, 25 February 2016 at 14:42:14 UTC, Thalamus wrote: your entry point. Hi Guillaume, Thanks for responding so quickly! I had found that wiki page before and I'd been following the "DLLs with a C Interface" section closely. I had forgotten to add -shared when building the DLL, but the behavior didn't change when I added it. So, I added a call to Runtime.initialize() as the first line of the endpoint I'm exposing. (I also made sure that this was the only endpoint invoked and that it was only invoked once just to be cautious.) I can see Runtime.initialize() being called, but the Class A shared static constructor still is not called when run from the C# EXE. Do you have any other ideas? In the meantime, I'm working on putting together a minimal repro source, but the scenario is a bit complicated so there's a lot of details to whittle away. thanks! Gene You shouldn't be calling Runtime.initialize() manually. Just do the following in one of your source files: import core.sys.windows.dll; mixin SimpleDllMain; This will generate a DllMain that will correctly initialize and deinitialize druntime. Kind Regards Benjamin Thaut Thanks Benjamin. When I went to whittle this down to its barest essentials, though, the repro is pretty simple. It involves LIBs, but not Dlls, and it doesn't require anything but a single D EXE. NOTE: if attempting to repro any of this, you must do a clean build after changing build.cmd or main.d before you'll see a change in behavior. I have the shared static ctors output files to make it really easy to see. If you have Class A: module ClassA; import std.file; import std.stdio; export class ClassA { shared static this() { File file = File(r"c:\A.txt", "w"); file.writeln("Called A's shared static constructor."); file.flush(); file.close(); } } and you have Class B: module ClassB; import std.file; import std.stdio; export class ClassB { shared static this() { File file = File(r"c:\B.txt", "w"); file.writeln("Called B's shared static constructor."); file.flush(); file.close(); } } and you have main.d: void main() { } And you build it in one step into an EXE: dmd -m64 -debug ClassA.d ClassB.d main.d -ofDriver.exe Then you run Driver.exe, both A.txt and B.txt are created. But, if you build it as a LIB and then link the LIB to the EXE: dmd -c -lib -m64 -debug ClassA.d ClassB.d -ofInit.lib dmd -m64 -debug Init.lib main.d -ofDriver.exe When you run Driver.exe, neither are created. If you then add "import ClassA" to main.d and clean build, only A.txt will be created, or instead if you add "import ClassB", then only B.txt is created. Also, if either of these is included, Driver.exp and Driver.lib are emitted by the build, whereas otherwise they aren't. It looks from this like a class in a linked LIB that is not directly imported will not have its shared static constructor called. Am I missing something obvious? :) Long term I will need all this not only in separate LIBs but in separate DLLs. My scenario is roughly like this (-> indicate dependencies): ClassA : IClass -> ClassManagement ClassB : IClass -> ClassManagement EntryPoint -> ClassManagement, ClassB, IClass Then EntryPoint asks ClassManagement to give it an instance of ClassB's complement (ClassA). ClassManagement only knows anything about any of these classes via TypeInfo_Class object mappings, and it uses Object.factory to instantiate them. EntryPoint and its dependencies then work with that object via the IClass interface. I've gotten this to work in C# easily and C++ with some effort. (Class map population was, of course, very different for each, though.) I can probably figure out a way to make this work for now, but if there's a way to ensure shared static ctors are run in this scenario without importing modules across separation boundaries, it would be a very good thing. thanks! Gene
Re: How to detect if an array if dynamic or static
On Wednesday, 24 February 2016 at 21:48:14 UTC, mahdi wrote: Suppose we have a function like this: void diss(int[] array) ... How can we detect is `array` is static (fixed size) or dynamic, inside the function body? I don't see that anyone has mentioned it but: https://dlang.org/phobos/std_traits.html#isStaticArray https://dlang.org/phobos/std_traits.html#isDynamicArray
Re: dub: how to reference a compiled package
On Thu, 25 Feb 2016 12:15:42 +, mahdi wrote: > Hi, > > Suppose I have a package `mypack` in `~/mypack`. I run `dub` command on > this package and have the compiled `mypack` file (OS is Linux). > > Now I am working on my project. I know how to use the source-code of > `mypack` package in the project but what if I only have the compiled > binary? How can I reference and use the modules of the compiled > `mypack`? > > (I looked into the DUB homepage and it's Getting Started page but could > not find anything). First thing, you need D interface files. See: https://dlang.org/dmd-linux.html#interface-files Note that D interface files still require you to include the full body of anything in a template, so you might have to modify your code somewhat for improved secrecy. Copy the *.di files and binaries into another dub project and add a postBuildCommand to copy that binary to the output location. I think that will work. dub might complain that it doesn't have any source files, in which case you'll have to provide at least one D file for it to compile, but that can be empty.
Re: How to detect if an array if dynamic or static
On Thu, 25 Feb 2016 02:08:18 +, Adam D. Ruppe wrote: > On Thursday, 25 February 2016 at 01:31:17 UTC, Chris Wright wrote: >> When you get to GC-allocated stuff, there's no way to tell. > > The GC is easy, you can simply ask it: > > http://dpldocs.info/experimental-docs/core.memory.GC.addrOf.1.html I saw that method, and I saw that it returned the base address of a Pool. >From the name, fields, and Gcx invocation, I guessed that Pool represented a bundle of multiple values. It's got about ten or twelve words of overhead, which would be a bit heavy to have one for each allocated object. (And that's on top of the bookkeeping malloc has to do, since the GC uses malloc under the hood.) Or maybe it's just got that much overhead.
Re: Shared static constructors from C# EXE
On Thursday, 25 February 2016 at 14:42:14 UTC, Thalamus wrote: your entry point. Hi Guillaume, Thanks for responding so quickly! I had found that wiki page before and I'd been following the "DLLs with a C Interface" section closely. I had forgotten to add -shared when building the DLL, but the behavior didn't change when I added it. So, I added a call to Runtime.initialize() as the first line of the endpoint I'm exposing. (I also made sure that this was the only endpoint invoked and that it was only invoked once just to be cautious.) I can see Runtime.initialize() being called, but the Class A shared static constructor still is not called when run from the C# EXE. Do you have any other ideas? In the meantime, I'm working on putting together a minimal repro source, but the scenario is a bit complicated so there's a lot of details to whittle away. thanks! Gene You shouldn't be calling Runtime.initialize() manually. Just do the following in one of your source files: import core.sys.windows.dll; mixin SimpleDllMain; This will generate a DllMain that will correctly initialize and deinitialize druntime. Kind Regards Benjamin Thaut
Re: Dynamic pitch shift
On Wednesday, 24 February 2016 at 11:17:27 UTC, Tanel Tagaväli wrote: Sorry for the confusing state of the codebase. Only the saw wave generator is currently functional, the `saw` and `sine` functions are not used and should be left out of analysis. Also, audio output is only to ALSA. Be careful with naive wave generators. You could get very funny artefacts from aliasing. You should try one of this approximations : - Correct naive wave generator : Use furrier composition to build the wave (ie, sum i=1->n An*sin(Wn*t + phase)), On this case, should drop of the sumatory the sin that generate armonics >= (Niquist freq)/2 This way, at least should be enough for sound testing, but isn't very efficient. See for example (C++) this Square wave generator against OpenAL (It needed some tweaks about just what you asked on the first post. The phase wasn't correct, but was enough for me on these moment) : https://github.com/Zardoz89/trillek-vcomputer-module/blob/78c9dd7bf0ead23cb9a8ccf29fd30c9d0ed7e2e5/tools/src/AlEngine.cpp#L210 - Wavetables - band-limited resampling algorithm aka BLIP or BLEP algorithms (See http://www.cs.cmu.edu/~eli/L/icmc01/hardsync.html and http://slack.net/~ant/libs/audio.html#Blip_Buffer )
Re: Shared static constructors from C# EXE
On Thursday, 25 February 2016 at 14:07:21 UTC, Guillaume Piolat wrote: On Thursday, 25 February 2016 at 14:01:30 UTC, Thalamus wrote: I don't control the EXE itself and the code I write to interface with it must be either C# or JavaScript, but this repros with a test C# driver EXE as well. The interfacing C# code can only be aware of the exposed D DLL functions defined in .def and shouldn't be aware directly of Class A, B, or ClassMapper, the factory specifically, etc.. Make sure your DLL must initialize the D runtime, which is where shared static constructors should get called. http://wiki.dlang.org/Win32_DLLs_in_D Alternatively you can call Runtime.initialize() yourself in your entry point. Hi Guillaume, Thanks for responding so quickly! I had found that wiki page before and I'd been following the "DLLs with a C Interface" section closely. I had forgotten to add -shared when building the DLL, but the behavior didn't change when I added it. So, I added a call to Runtime.initialize() as the first line of the endpoint I'm exposing. (I also made sure that this was the only endpoint invoked and that it was only invoked once just to be cautious.) I can see Runtime.initialize() being called, but the Class A shared static constructor still is not called when run from the C# EXE. Do you have any other ideas? In the meantime, I'm working on putting together a minimal repro source, but the scenario is a bit complicated so there's a lot of details to whittle away. thanks! Gene
Re: Accessing all data in TypeTupple (AliasSeq) and stringify them
On Thursday, 25 February 2016 at 13:16:43 UTC, Voitech wrote: Hi, I have some code processing functions definition in compile time, I want to override them in some other class but not explicitly so created this code: template MixinFunction(alias attributes,alias returnType,alias name,alias parameters,alias bodyy){ enum string MixinFunction = format(q{ %s %s %s(%s){ %s } },attributes,returnType,name,parameters,bodyy); } unittest{ alias func=MixinFunction!("static","void","testFunc","int a,int b",q{ import std.stdio; writeln("im void body"); }); pragma(msg,func); mixin(func); } Now i acquired all data like return type, parameters but need to turn them into string for example function parameters must have form of: for function func: void func(int a,string b){} alias parameters=Parameters!func; returns me AliasSeq!(int,string) I want to to turn them into string: like "int param0, string param1", but in template template AliasSeqToString(TList...){ enum AliasSeqToString= ... //each ? } How to operate on TypeTuple/AliasSeq elemens withouth foreach ? You can (see std.meta/(std.traits?) , with recursive templates), but there is nothing stopping from using for/foreach in a template this should do what you want string[] functionSig; string[] params; foreach(s; Parameters!T)) // returns AliasSeq of types { params ~=s.stringof; } string[] pits; foreach(p; ParameterIdentifierTuple!(T)); // returns AliasSeq of strings { pits ~=p; } and the either join(er) or do as you see fit. or use plain old for for(auto i=0;i< pits.length; i++) { functionSig ~= params[i]; functionSig ~= pits[i]; } writeln(functionSig); // should print ["int" , "param0" , "string" , "param1"] Nic
Re: Shared static constructors from C# EXE
On Thursday, 25 February 2016 at 14:01:30 UTC, Thalamus wrote: I don't control the EXE itself and the code I write to interface with it must be either C# or JavaScript, but this repros with a test C# driver EXE as well. The interfacing C# code can only be aware of the exposed D DLL functions defined in .def and shouldn't be aware directly of Class A, B, or ClassMapper, the factory specifically, etc.. Make sure your DLL must initialize the D runtime, which is where shared static constructors should get called. http://wiki.dlang.org/Win32_DLLs_in_D Alternatively you can call Runtime.initialize() yourself in your entry point.
Shared static constructors from C# EXE
Hi everyone, I looked in the forums and Google in general but I didn't find a similar question, and I'm stumped. I have a scenario where a set of classes must be registered with a class mapper and then instantiated via a factory. The classes themselves are agnostic of one another, and all interaction with these classes after instantiation is via interfaces. I've succeeded in having the classes register themselves at runtime by using shared static constructors, which is really seamless! This works just fine when the EXE is written in D, but only a subset of shared static constructors get called when the EXE is written in C#. A few more details: ClassMapper class includes a shared static constructor that initializes a class map associative array, and it exposes a public Map() function an Instantiate(TypeInfo_Class classType, etc.) function. Class A and Class B both have shared static constructors that call Map() to register themselves. The above is built into a D EXE, and ClassMapper.map is fully populated before main() starts. -OR- The above is built into a D DLL with a CreateClassB() function exposed via .def, etc. A C# EXE invokes CreateClassB() via p/invoke. The call works just fine, and ClassB and anything class B calls, recursively, are all registered with ClassMapper.map just fine, because their shared static constructors are invoked. But, Class A is not in the map because its shared static constructor is never called. I don't control the EXE itself and the code I write to interface with it must be either C# or JavaScript, but this repros with a test C# driver EXE as well. The interfacing C# code can only be aware of the exposed D DLL functions defined in .def and shouldn't be aware directly of Class A, B, or ClassMapper, the factory specifically, etc.. Has anyone seen this before, or have an idea for a workaround? The best workaround I've come up with so far is to use a registry config file instead of calls to Map() so the ClassMapper can populate itself. It's not a very elegant solution, but it was the best I was able to come up with for C++ too. (In C# I've used class attributes, which I had thought was elegant. D's shared static constructors are even more so, though.) thanks much! Thalamus
Re: How to detect if an array if dynamic or static
On Wednesday, 24 February 2016 at 21:48:14 UTC, mahdi wrote: Suppose we have a function like this: void diss(int[] array) ... How can we detect is `array` is static (fixed size) or dynamic, inside the function body? I don't understand what I'm doing but got a proof of concept for you. This https://dlang.org/phobos/std_traits.html page helped. import std.stdio; void main() { int[] a; int[1] b; writeln(is(typeof(a) == int[])); // true writeln(is(typeof(b) == int[])); // false }
Re: how do you append arrays?
On Thursday, 25 February 2016 at 13:38:56 UTC, ag0aep6g wrote: On 25.02.2016 14:33, Nicholas Wilson wrote: Note that D has zero based array indexing so assuming your array has 100 elements history[1..100] is going one past the end of the array. No, that's fine. `history[1..100]` gives you 99 elements starting at index 1, i.e. all except the first one. Derp. You are correct, I was thinking about the first index.
Re: how do you append arrays?
On 25.02.2016 14:33, Nicholas Wilson wrote: Note that D has zero based array indexing so assuming your array has 100 elements history[1..100] is going one past the end of the array. No, that's fine. `history[1..100]` gives you 99 elements starting at index 1, i.e. all except the first one.
Re: how do you append arrays?
On Thursday, 25 February 2016 at 13:24:09 UTC, asdf wrote: On Thursday, 25 February 2016 at 13:06:10 UTC, cym13 wrote: In D the binary operator "~" is used to concatenate both strings (arrays of characters) and arrays. (also the ~= operator is equivalent to lhs = lhs ~ rhs Nic Just a precision: "lhs ~= rhs" isn't exactly equivalent to "lhs = lhs ~ rhs", those are two distinct operators that may deal with memory etc in different ways. For arrays doing "lhs = lhs ~ rhs" will first create (and allocate) the array corresponding to "lhs ~ rhs" and then assign this new array to lhs. On the other hand "lhs ~= rhs" realises in-place append. I tried both, the error this time is: object.Exception@/data/data/com.termux/files/home/ldc/runtime/druntime/src/ldc/arrayinit.d(151): overlapping array copy so you will have to make a copy and then move it Im assuming history[1..100] = history[0..99]; this is the line causing your problem. Note that D has zero based array indexing so assuming your array has 100 elements history[1..100] is going one past the end of the array. also using a circular buffer here will solve this problem. Nic
Re: how do you append arrays?
On Thursday, 25 February 2016 at 13:06:10 UTC, cym13 wrote: In D the binary operator "~" is used to concatenate both strings (arrays of characters) and arrays. (also the ~= operator is equivalent to lhs = lhs ~ rhs Nic Just a precision: "lhs ~= rhs" isn't exactly equivalent to "lhs = lhs ~ rhs", those are two distinct operators that may deal with memory etc in different ways. For arrays doing "lhs = lhs ~ rhs" will first create (and allocate) the array corresponding to "lhs ~ rhs" and then assign this new array to lhs. On the other hand "lhs ~= rhs" realises in-place append. I tried both, the error this time is: object.Exception@/data/data/com.termux/files/home/ldc/runtime/druntime/src/ldc/arrayinit.d(151): overlapping array copy
Accessing all data in TypeTupple (AliasSeq) and stringify them
Hi, I have some code processing functions definition in compile time, I want to override them in some other class but not explicitly so created this code: template MixinFunction(alias attributes,alias returnType,alias name,alias parameters,alias bodyy){ enum string MixinFunction = format(q{ %s %s %s(%s){ %s } },attributes,returnType,name,parameters,bodyy); } unittest{ alias func=MixinFunction!("static","void","testFunc","int a,int b",q{ import std.stdio; writeln("im void body"); }); pragma(msg,func); mixin(func); } Now i acquired all data like return type, parameters but need to turn them into string for example function parameters must have form of: for function func: void func(int a,string b){} alias parameters=Parameters!func; returns me AliasSeq!(int,string) I want to to turn them into string: like "int param0, string param1", but in template template AliasSeqToString(TList...){ enum AliasSeqToString= ... //each ? } How to operate on TypeTuple/AliasSeq elemens withouth foreach ?
Re: how do you append arrays?
On Thursday, 25 February 2016 at 12:58:54 UTC, Nicholas Wilson wrote: On Thursday, 25 February 2016 at 12:53:37 UTC, asdf wrote: I'm trying to make a terminal input preprocessor with alias/shortcuts and history. import std.stdio; void main() { string line; string[] history; line = readln(); foreach(int i; 0..100) history = history + [""]; // XXX while(!stdin.eof) { writeln(line); if(line != history[0]) { history[1..100] = history[0..99]; history[0] = line; } line = readln(); } } In D the binary operator "~" is used to concatenate both strings (arrays of characters) and arrays. (also the ~= operator is equivalent to lhs = lhs ~ rhs Nic Just a precision: "lhs ~= rhs" isn't exactly equivalent to "lhs = lhs ~ rhs", those are two distinct operators that may deal with memory etc in different ways. For arrays doing "lhs = lhs ~ rhs" will first create (and allocate) the array corresponding to "lhs ~ rhs" and then assign this new array to lhs. On the other hand "lhs ~= rhs" realises in-place append.
Re: how do you append arrays?
On Thursday, 25 February 2016 at 12:58:54 UTC, Nicholas Wilson wrote: In D the binary operator "~" is used to concatenate both strings (arrays of characters) and arrays. (also the ~= operator is equivalent to lhs = lhs ~ rhs Nic It worked! A link from someone else's question suggested `new string[101]` also. Now on to other problems, it never ends...
Re: how do you append arrays?
On Thursday, 25 February 2016 at 12:53:37 UTC, asdf wrote: I'm trying to make a terminal input preprocessor with alias/shortcuts and history. import std.stdio; void main() { string line; string[] history; line = readln(); foreach(int i; 0..100) history = history + [""]; // XXX while(!stdin.eof) { writeln(line); if(line != history[0]) { history[1..100] = history[0..99]; history[0] = line; } line = readln(); } } Also for this kind of thing you probably want to use a circular buffer. I'm sure there is an implementation of one somewhere. see std.range.cycle
Re: how do you append arrays?
On Thursday, 25 February 2016 at 12:53:37 UTC, asdf wrote: I'm trying to make a terminal input preprocessor with alias/shortcuts and history. import std.stdio; void main() { string line; string[] history; line = readln(); foreach(int i; 0..100) history = history + [""]; // XXX while(!stdin.eof) { writeln(line); if(line != history[0]) { history[1..100] = history[0..99]; history[0] = line; } line = readln(); } } In D the binary operator "~" is used to concatenate both strings (arrays of characters) and arrays. (also the ~= operator is equivalent to lhs = lhs ~ rhs Nic
how do you append arrays?
I'm trying to make a terminal input preprocessor with alias/shortcuts and history. import std.stdio; void main() { string line; string[] history; line = readln(); foreach(int i; 0..100) history = history + [""]; // XXX while(!stdin.eof) { writeln(line); if(line != history[0]) { history[1..100] = history[0..99]; history[0] = line; } line = readln(); } }
Re: How to detect if an array if dynamic or static
On Thursday, 25 February 2016 at 12:18:07 UTC, mahdi wrote: On Thursday, 25 February 2016 at 11:50:02 UTC, sigod wrote: On Thursday, 25 February 2016 at 10:03:08 UTC, mahdi wrote: Thanks. So when we define the function, we MUST specify the array size to be able to accept a static array? Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)? Static array can be accepted in place of dynamic: void foo() { int[3] arr = [1, 2, 3]; bar(arr); } void bar(scope int[] arr) { import std.stdio : writeln; writeln(arr); // [1, 2, 3] } But be careful not to escape such variables. Demonstration: http://dpaste.dzfl.pl/613e04d4fe3f My question: If in your `bar` function, the code tries to add a new element to the dynamic array, it will be completely ok because array is dynamic. BUT if we pass a static array to this function, can this error be detected at compile time (and prevent a runtime error)? If so, how? Also, if you need to append elements to an array inside of a function, then you need to mark function arguments as `ref`: void bar(ref int[] arr) Code wouldn't compile if you try to pass static array as `ref` argument. Error: function f436.bar (ref int[] arr) is not callable using argument types (int[3])
Re: How to detect if an array if dynamic or static
On Thursday, 25 February 2016 at 12:18:07 UTC, mahdi wrote: On Thursday, 25 February 2016 at 11:50:02 UTC, sigod wrote: On Thursday, 25 February 2016 at 10:03:08 UTC, mahdi wrote: Thanks. So when we define the function, we MUST specify the array size to be able to accept a static array? Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)? Static array can be accepted in place of dynamic: void foo() { int[3] arr = [1, 2, 3]; bar(arr); } void bar(scope int[] arr) { import std.stdio : writeln; writeln(arr); // [1, 2, 3] } But be careful not to escape such variables. Demonstration: http://dpaste.dzfl.pl/613e04d4fe3f My question: If in your `bar` function, the code tries to add a new element to the dynamic array, it will be completely ok because array is dynamic. BUT if we pass a static array to this function, can this error be detected at compile time (and prevent a runtime error)? If so, how? I'm not sure if this is an error at all. Append sees that array doesn't have any available space and allocates new array. writeln(arr.ptr); // 7FBFC45AA0 arr ~= 1; writeln(arr.ptr); // 4002E000 I would say that you have poor code design if your function must be able to accept static arrays and append elements to it. You might find this useful: http://dlang.org/phobos/std_array.html#.Appender
Re: How to detect if an array if dynamic or static
On Thursday, 25 February 2016 at 11:50:02 UTC, sigod wrote: On Thursday, 25 February 2016 at 10:03:08 UTC, mahdi wrote: Thanks. So when we define the function, we MUST specify the array size to be able to accept a static array? Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)? Static array can be accepted in place of dynamic: void foo() { int[3] arr = [1, 2, 3]; bar(arr); } void bar(scope int[] arr) { import std.stdio : writeln; writeln(arr); // [1, 2, 3] } But be careful not to escape such variables. Demonstration: http://dpaste.dzfl.pl/613e04d4fe3f My question: If in your `bar` function, the code tries to add a new element to the dynamic array, it will be completely ok because array is dynamic. BUT if we pass a static array to this function, can this error be detected at compile time (and prevent a runtime error)? If so, how?
dub: how to reference a compiled package
Hi, Suppose I have a package `mypack` in `~/mypack`. I run `dub` command on this package and have the compiled `mypack` file (OS is Linux). Now I am working on my project. I know how to use the source-code of `mypack` package in the project but what if I only have the compiled binary? How can I reference and use the modules of the compiled `mypack`? (I looked into the DUB homepage and it's Getting Started page but could not find anything).
Re: How to detect if an array if dynamic or static
On Thursday, 25 February 2016 at 10:03:08 UTC, mahdi wrote: Thanks. So when we define the function, we MUST specify the array size to be able to accept a static array? Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)? Static array can be accepted in place of dynamic: void foo() { int[3] arr = [1, 2, 3]; bar(arr); } void bar(scope int[] arr) { import std.stdio : writeln; writeln(arr); // [1, 2, 3] } But be careful not to escape such variables. Demonstration: http://dpaste.dzfl.pl/613e04d4fe3f
Re: tell if __traits(allMembers, ... ) is an enum (not manifest constant)
On Thursday, 25 February 2016 at 08:40:00 UTC, nkgu wrote: On Thursday, 25 February 2016 at 04:55:09 UTC, Nicholas Wilson wrote: oops should be writeln(typeof(__traits(getMember, vulkan_input, m)).stringof); that compiles but still prints nothing try pragma(msg, typeof(__traits(getMember, vulkan_input, m)).stringof); because at compile time the code generated for writeln() is not executed. Also take care with the getMember trait, it will only work if the member is public. (or not public but located in the module where the __traits() code resides). Heh. Thanks for the Idea anyway. source/app.d(308): Error: module object has no type source/app.d(308):while evaluating pragma(msg, (_error_).stringof) source/app.d(308): Error: type uint is not an expression source/app.d(308):while evaluating pragma(msg, (_error_).stringof) pure nothrow @nogc @safe int(int major, int minor, int patch) int int pure nothrow @nogc @safe uint(uint ver) pure nothrow @nogc @safe uint(uint ver) pure nothrow @nogc @safe uint(uint ver) ... void void ... source/app.d(308): Error: type VkInstance_T is not an expression source/app.d(308):while evaluating pragma(msg, (_error_).stringof) ... Cheating somewhat static if(m.startsWith("Vk") && __traits(compiles, mixin(m~"."~m.camelToUpper_ ~ "_MAX_ENUM"))) does some of what I want but (unsurprisingly) fails to pick up the bitfield enums (that don't have a "_MAX_ENUM" member).
Re: Installing DUB on OSX
On 2016-02-24 23:11, Joel wrote: Error: Error writing file '../../../.dub/packages/dsfml-2.1.0/libdsfml_system.a' Joels-MacBook-Pro:DGuy joelcnz$ Is the full path of ../../../.dub/packages/dsfml-2.1.0 writable? -- /Jacob Carlborg
Re: Const vs Non const method
On Thursday, 25 February 2016 at 10:44:49 UTC, Andrea Fontana wrote: Check this simple code: http://dpaste.dzfl.pl/2772c9144f1c I can't understand how to minimize code duplication for function like get(). Of course on real case body is much bigger and complex than that. The only way I found is to move the body of function inside a mixin template: mixin template getterImpl() { auto getterImpl() { /* very long body */ return inner; } } and then: auto get() const { mixin getterImpl; return getterImpl; } auto get() { mixin getterImpl; return getterImpl; } Am I missing something? I don't think it's the right way. You can do this using inout: http://dpaste.dzfl.pl/678cac023051 That getter can be written even shorter due to a quirk in the D syntax, like: inout get() { return inner; } But I prefer to explicitly state inout for every parameter and return type. inout is kind of a wildcard for mutable, const, and immutable. You can also add it to your function parameters, for example: inout(int[]) doSomething(inout(SomeClass) c); So the constness of doSomething's return type depends on the constness of the passed argument.
Re: Const vs Non const method
On Thursday, 25 February 2016 at 10:48:34 UTC, Namespace wrote: Try inout: import std.stdio; struct Inner { int field = 3; } struct Test { auto get() inout { return inner; } private Inner inner; } void main() { { Test test; test.get.field = 4; } { immutable Test test; writeln(test.get.field); } } Uh, I didn't know inout can be used with function. I think it was used only with params/return. Thank you :)
Re: Const vs Non const method
Try inout: import std.stdio; struct Inner { int field = 3; } struct Test { auto get() inout { return inner; } private Inner inner; } void main() { { Test test; test.get.field = 4; } { immutable Test test; writeln(test.get.field); } }
Const vs Non const method
Check this simple code: http://dpaste.dzfl.pl/2772c9144f1c I can't understand how to minimize code duplication for function like get(). Of course on real case body is much bigger and complex than that. The only way I found is to move the body of function inside a mixin template: mixin template getterImpl() { auto getterImpl() { /* very long body */ return inner; } } and then: auto get() const { mixin getterImpl; return getterImpl; } auto get() { mixin getterImpl; return getterImpl; } Am I missing something? I don't think it's the right way.
Re: How to detect if an array if dynamic or static
void diss(int n)(ref int[n] array) { } But to consume array of any size, just take dynamic array as parameter.
How to detect if an array if dynamic or static
Thanks. So when we define the function, we MUST specify the array size to be able to accept a static array? Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)?
Re: tell if __traits(allMembers, ... ) is an enum (not manifest constant)
On Thursday, 25 February 2016 at 04:55:09 UTC, Nicholas Wilson wrote: oops should be writeln(typeof(__traits(getMember, vulkan_input, m)).stringof); that compiles but still prints nothing try pragma(msg, typeof(__traits(getMember, vulkan_input, m)).stringof); because at compile time the code generated for writeln() is not executed. Also take care with the getMember trait, it will only work if the member is public. (or not public but located in the module where the __traits() code resides).