Re: How to create an overwriteable struct that is always const?
On Saturday, June 1, 2019 8:23:58 PM MDT David Zhang via Digitalmars-d-learn wrote: > On Saturday, 1 June 2019 at 16:30:12 UTC, Jonathan M Davis wrote: > > If any member variable of a struct is const, then you can't > > modify that member ever, and assignment isn't possible unless > > you override opAssign so that it overwrites only the mutable > > members. It's very rare that it makes sense to make any member > > variables of a struct const or immutable, because then you > > basically can't use assignment anymore. > > > > You could make all of the member variables private and provide > > no functions that set any of them, then the only way to change > > any of their values would be to construct a new value of that > > type and assign it to the variable. > > > > - Jonathan M Davis > > Ideally, I'd like for member functions to be checked against > modifying s also, not just externally. If the member functions are const or inout, then they won't be able to modify any members. - Jonathan M Davis
Re: hasElaborateCopyConstructor bug?
On Sunday, 2 June 2019 at 04:02:08 UTC, Paul Backus wrote: On Saturday, 1 June 2019 at 23:29:08 UTC, SrMordred wrote: On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote: On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote: Haven't tested it extensively, so use at your own risk, but it should work. Nice, thanks! Atm i'm using __traits(compiles, instance.__ctor(other) ) but your solution may be the right way of doing it :)
Re: hasElaborateCopyConstructor bug?
On Saturday, 1 June 2019 at 23:29:08 UTC, SrMordred wrote: On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote: On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote: hasElaborateCopyConstructor checks if the type defines a postblit[0]. Yes, I know this. But since dmd 2.086 we have copy ctors: https://dlang.org/changelog/2.086.0.html#copy_constructor And its seem logical that if I want a trait that check if copy ctors exists I will use this name 'hasElaborateCopyConstructor' So it looks like a naming issue for me. Unless postblits will be eventually replaced by copy ctors. Here's something I came up with to check for new-style copy constructors: import std.traits; import std.meta; template hasNewCopyConstructor(T) { static if (hasMember!(T, "__ctor")) { enum hasCopyConstructor = anySatisfy!( isNewCopyConstructor, __traits(getOverloads, T, "__ctor") ); } else { enum hasNewCopyConstructor = false; } } enum isNewCopyConstructor(alias ctor) = is(Unqual!(Parameters!ctor[0]) == __traits(parent, ctor)) && (ParameterStorageClassTuple!ctor[0] & ParameterStorageClass.ref_); Haven't tested it extensively, so use at your own risk, but it should work.
Re: How to create an overwriteable struct that is always const?
On Saturday, 1 June 2019 at 13:00:50 UTC, ag0aep6g wrote: How is setting/replacing different from modifying? e.g.: S s; this() { s = ...; } update(S s) { this.s = s; } mod(int i) { s.i = i; } // illegal Kinda like how strings can be copied and assigned to, but not modified.
Re: How to create an overwriteable struct that is always const?
On Saturday, 1 June 2019 at 16:30:12 UTC, Jonathan M Davis wrote: If any member variable of a struct is const, then you can't modify that member ever, and assignment isn't possible unless you override opAssign so that it overwrites only the mutable members. It's very rare that it makes sense to make any member variables of a struct const or immutable, because then you basically can't use assignment anymore. You could make all of the member variables private and provide no functions that set any of them, then the only way to change any of their values would be to construct a new value of that type and assign it to the variable. - Jonathan M Davis Ideally, I'd like for member functions to be checked against modifying s also, not just externally.
Re: hasElaborateCopyConstructor bug?
On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote: On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote: hasElaborateCopyConstructor checks if the type defines a postblit[0]. Yes, I know this. But since dmd 2.086 we have copy ctors: https://dlang.org/changelog/2.086.0.html#copy_constructor And its seem logical that if I want a trait that check if copy ctors exists I will use this name 'hasElaborateCopyConstructor' So it looks like a naming issue for me. Unless postblits will be eventually replaced by copy ctors.
Re: hasElaborateCopyConstructor bug?
On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote: import std.traits; struct T { this(ref return scope T other){} } pragma(msg, hasElaborateCopyConstructor!T); //false hasElaborateCopyConstructor checks if the type defines a postblit[0]. That is, a function called this(this). this(T) is just a regular constructor, and as such does not qualify. From the documentation[1]: Elaborate copy constructors are introduced by defining this(this) for a struct. Postblits are called after assignment, on the instance being assigned to, and has no access to the source of the assignment. If you need access to the source, a ref constructor like yours will work. -- Simen [0]: https://dlang.org/spec/struct.html#struct-postblit [1]: https://dlang.org/library/std/traits/has_elaborate_copy_constructor.html
hasElaborateCopyConstructor bug?
import std.traits; struct T { this(ref return scope T other){} } pragma(msg, hasElaborateCopyConstructor!T); //false
Re: Calling copyctor manually
On Saturday, 1 June 2019 at 19:10:36 UTC, Paul Backus wrote: On Saturday, 1 June 2019 at 02:27:36 UTC, SrMordred wrote: void main() { T a; T b; a.__ctor(b); } https://run.dlang.io/is/NeioBs Thanks! The most obvious way i didn´t think :P
Re: Calling copyctor manually
On Saturday, 1 June 2019 at 02:27:36 UTC, SrMordred wrote: Its possible to call copyctor manually without calling dtor? ex, what i did before: struct T{ ~this(){ writeln("DTOR"); } this(this){ writeln("POSTBLIT"); } } T a; T b; memcpy(&a,&b,T.sizeof); a.__postblit; /* output: POSTBLIT DTOR DTOR */ With copy ctors, not sure what to do. struct T{ ~this(){ writeln("DTOR"); } this(ref return scope T self){ writeln("COPYCTOR"); } } T a; T b; memcpy(&a,&b,T.sizeof); a.opAssign(b); //??? //same as a = b; /* output: COPYCTOR DTOR DTOR DTOR */ I want something like '.__xcopyctor' The copy constructor is implemented as an overload of `__ctor`: import std.stdio; struct T { ~this() { writeln("DTOR"); } this(ref return scope T self) { writeln("COPYCTOR"); } } void main() { T a; T b; a.__ctor(b); } /* Output: COPYCTOR DTOR DTOR */ https://run.dlang.io/is/NeioBs
Re: How to create a template class using foreach delegate to filter objects in a member function call?
On Saturday, 1 June 2019 at 14:24:11 UTC, Robert M. Münch wrote: The myFilter struct is the implementation which myClass.put() should use to iterate over all objects. Which ones? The E-objects, or the objects contained in myClass, which you don't want to know about? All things being only examples. Sure. So, please, provide a minimal example, as I'm only guessing what use case you want to solve. Even if it is not compilable. So, the idea is, that I can provide a delegate which foreach(...; myFilter(objects)) uses. Like a run-time plug-in. Maybe you can. But "put" has to remain a function, not a template. Do you have control about the contained classes? If so, it is a hint to implement the testing inside them. Like: /* probably inside a templated mixin */ bool testfunction(inputs){...} class myOtherClass(/*probably templated*/){... mixin testfunction ... & provide a put function} I thought about a mixin too. But this requires an understanding of how myClass works. Which I what I want to avoid. Over which objects your filter will be iterating then? * So, you are not totally against the idea of modifying the foreign library, but you want to keep modifications small? Yes, because myClass is some external lib, which can be changed to support this approach here. But not more.
Why is this pure function taking a string literal not CTFE-executable?
Hi Guys! In my programm, I have a custom String-type that I want to initialize some variables of at compile time by casting a string literal to said custom String type. I thought I could achieve this straight forwardly, but after trying a bit, I could not find a (simple) working solution. I made this minimal example to show where the easy solution all fall flat: struct My_String{ long size; char* data; } My_String make_my_string(string s){ My_String my_string; my_string.data = cast(char*) s.ptr; my_string.size = s.length; return my_string; } struct Dummy{ My_String s = make_my_string("hello!"); } void main(){ Dummy dummy; } Which produces the compilation error "cannot use non-constant CTFE pointer in an initializer My_String(6L, &"hello!"[0])". I do not understand this error message. What is the non-constant CTFE pointer here. The "data"-member? If so, why does this compile: struct My_String{ long size; char* data; } struct Dummy{ My_String s = My_String("hello!".length, cast(char*) "hello!".ptr); } void main(){ Dummy dummy; } Why does the error message show an opcall to My_String with filled out members ("6L, &"hello!"[0]"), although the code only ever default-constructs a My_string variable? I am confused. And why on earth does this work: struct My_String{ long size; char* data; } My_String make_my_string(string s){ My_String my_string; my_string.data = cast(char*) s.ptr; my_string.size = s.length; return my_string; } void main(){ My_String s = make_my_string("hello!"); } Please help, I have no idea whats going on here.
Re: How to create an overwriteable struct that is always const?
On Saturday, June 1, 2019 6:51:08 AM MDT David Zhang via Digitalmars-d-learn wrote: > Say I have a struct `S`: > > struct S { > /*const*/ char* pointer; > ... other members ... > > this(/*const*/ char* p, ... others ...) { > pointer = p; > ... > } > } > > What I want, is to be able to use `S` in other data structures > with the following properties checked by the compiler: > > - The variable can be set > - The variable can be read > - The variable cannot be modified, only replaced > > Is there a type-safe way to do this? If this were a class, I'd > try std.typecons.Rebindable. > > Thanks If any member variable of a struct is const, then you can't modify that member ever, and assignment isn't possible unless you override opAssign so that it overwrites only the mutable members. It's very rare that it makes sense to make any member variables of a struct const or immutable, because then you basically can't use assignment anymore. You could make all of the member variables private and provide no functions that set any of them, then the only way to change any of their values would be to construct a new value of that type and assign it to the variable. If what you really want is const(S)* though, then it would be simplest to just use const(S)*, though that requires allocating. Rebindable only exists, because the language basically conflates a reference to the class object with the class object itself, meaning that you can't make the class object const without making the reference const. - Jonathan M Davis
Re: How to create a template class using foreach delegate to filter objects in a member function call?
On 2019-06-01 04:43:13 +, Alex said: That's ok, but could you provide an example anyway? Is it like this? ´´´ void main(){ auto target = new myClass!int(); target.objects.length = 4; auto val = 42; put(target, val, testfunction); // does the test function enters here? put(target, val); auto f = myFilter!int; // where do you want to use this entity? } ´´´ myClass shouldn't be subclassed, only just used. The myFilter struct is the implementation which myClass.put() should use to iterate over all objects. All things being only examples. So, the idea is, that I can provide a delegate which foreach(...; myFilter(objects)) uses. Like a run-time plug-in. Do you have control about the contained classes? If so, it is a hint to implement the testing inside them. Like: /* probably inside a templated mixin */ bool testfunction(inputs){...} class myOtherClass(/*probably templated*/){... mixin testfunction ... & provide a put function} I thought about a mixin too. But this requires an understanding of how myClass works. Which I what I want to avoid. * So, you are not totally against the idea of modifying the foreign library, but you want to keep modifications small? Yes, because myClass is some external lib, which can be changed to support this approach here. But not more. With the approach now, you could, for example, handle compile time blocks inside the put function in the myClass and dynamical ones inside the myOtherClasses. class myClass(E){/* inserted put function */ void put(...){static if put action is at all possible --> put. }} As said, KISS and really just want to provide a plug-in which is used to iterate of a sequence I provide from the outside. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: How to create an overwriteable struct that is always const?
On 01.06.19 14:51, David Zhang wrote: struct S { /*const*/ char* pointer; ... other members ... this(/*const*/ char* p, ... others ...) { pointer = p; ... } } What I want, is to be able to use `S` in other data structures with the following properties checked by the compiler: - The variable can be set - The variable can be read - The variable cannot be modified, only replaced How is setting/replacing different from modifying? Is there a type-safe way to do this? If this were a class, I'd try std.typecons.Rebindable. struct S { const(char)* pointer; /* ... */ }
Re: How to create an overwriteable struct that is always const?
01.06.2019 15:55, drug пишет: Is there a type-safe way to do this? If this were a class, I'd try std.typecons.Rebindable. Ah, sorry))
Re: How to create an overwriteable struct that is always const?
01.06.2019 15:51, David Zhang пишет: Say I have a struct `S`: struct S { /*const*/ char* pointer; ... other members ... this(/*const*/ char* p, ... others ...) { pointer = p; ... } } What I want, is to be able to use `S` in other data structures with the following properties checked by the compiler: - The variable can be set - The variable can be read - The variable cannot be modified, only replaced Is there a type-safe way to do this? If this were a class, I'd try std.typecons.Rebindable. Thanks https://dlang.org/phobos/std_typecons.html#Rebindable ?
How to create an overwriteable struct that is always const?
Say I have a struct `S`: struct S { /*const*/ char* pointer; ... other members ... this(/*const*/ char* p, ... others ...) { pointer = p; ... } } What I want, is to be able to use `S` in other data structures with the following properties checked by the compiler: - The variable can be set - The variable can be read - The variable cannot be modified, only replaced Is there a type-safe way to do this? If this were a class, I'd try std.typecons.Rebindable. Thanks
Re: Dub dependencies / How to use own Github fork?
On 2019-05-30 18:29:44 +, Steven Schveighoffer said: You can dub add-local your local fork, and it will use that instead of going out to code.dlang.org. Ok, any chance to switch back and forth between local/remote versions? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: emulate with
On Friday, 31 May 2019 at 08:35:23 UTC, Simen Kjærås wrote: With 1), 2) and 3) fixed, the code would look like this (only changed code included): unittest { with (Dispatcher.X) { A(1); A("a"); B(2); C_Q(3); } } struct Dispatcher { struct opDispatch(string prefix, alias context = __CONTEXT__) { static auto opDispatch(string name, Args...)(Args args) { return getMethod!(context, prefix~"_"~name)(args); } } } Actually, Dispatcher could look like this: struct Dispatcher { struct opDispatch(string prefix, alias context = __CONTEXT__) { alias opDispatch(string name) = getMethod!(context, prefix~"_"~name); } } -- Simen
Re: How to create GTK+ apps with Glade and D on windows
On Fri, 2019-05-31 at 18:47 +, Obsidian Jackal via Digitalmars-d- learn wrote: > I'm new to D and want to create GTK+ apps. I have Visual Studio, > Glade, the Gtk+ runtime, DMD, and DUB installed. What steps, > guides, or advice should I follow to be able to be able to use > these tools together to make a sane app?. Many people ignore Glade and hand code the widget structure of their applications. For small and simple applications this is fine. I have done this for Me TV – though I have now switched from D to Rust for this application so no public D repository, long story. I did though use XML files (hand written, embedded in the compiled executable using D's string import) for the menus. For GFontBrowser (https://github.com/russel/GFontBrowser for now, I may well move the mainline repository to GitLab due to better integrated CI/CD) I use Glade and a gtk.Builder instance to read the Glade file – which is embedded into the compiled executable using string import rather than being a file on the filestore. This works very well, and allows all the layout to be done using a layout system rather than fiddling with lines of code. Deciding how much of the call-backs etc. to specify in the Glad file and how much to do in the code is something there seems to be no de facto standard on, so it is down to personal taste. I choose only to build the widget tree with Glade and do all the call-backs in code. I generally start small to get the hang of things and then progress towards the final application. If the UI has any complications I use Glade for layout. Reading Ron Tarrant's http://gtkdcoding.com/ will almost certainly be worth it, even if you disagree with some of his codes. GtkD and GStreamerD (Mike Wey's work) rock – though gtk-rs and gstreamer-rs are also excellent. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: 'version'-based code selection
On Friday, May 31, 2019 9:59:13 PM MDT Yatheendra via Digitalmars-d-learn wrote: > Hi people. > > The 'version' keyword sounds like a fantastic capability, but how > far does DMD take it (and does GDC take it equally far)? This is > not a "D Improvement Proposal", I am just asking how it is now. > > Can code of multiple versions be compiled into the same > executable or library, and a particular one selected from > "later"? I guess not without some name mangling and wrangling. > > Can such selection be done at link-time for standard as well as > user-defined library code? Maybe some library file naming > conventions are followed to allow the compiler to select the > corresponding file? > > Wishful thinking, but can the selection be at runtime? That would > be language support for making some things easy, e.g. picking > from assembly-coded routines based on runtime CPU id (the video > player MPlayer picks routines that way, and I read that the D > library, Mir, has CPU id support). > > Thanks. > > P.S: I am a brand-new C++'y asylum seeker who may have missed > seeing some documentation, so RTFM is a valid response. > > P.P.S: This question was triggered by the D GSoC project for > independent-of-C implementations of malloc/free/memcpy/memset. > Could a common malloc be exposed to the D > runtime/Phobos/programs, with the C or D implementations > selectable at link-time (using a mechanism available to user code > too)? Like static ifs, version statements are completely a compile-time construct and having nothing to do with runtime beyond how they affect the code that's generated. They also have nothing to do with linking beyond how they affect what code is generated. version statements are basically just static if statements that are compiled in if the corresponding version identifier has been defined. They're esentially D's answer to C's #ifdefs. A version statement can only check a single version identifier (so, no boolean logic like with #ifdefs), but else can be used like with static ifs. e.g. version(linux) { // compile in this code on Linux } else version(Windows) { // compile in this code on Windows } else static assert(false, "This platform is not supported."); Multiple version identifiers exist when compiling. For instance, if compiling on 64-bit x86 Linux, both the linux and X86_64 version identifiers would be defined. So, it's not like there's only one version identifier when compiling. Additional version identifiers can be supplied on the command-line when compiling, and you can even define a version for just within the module (version identifers cannot be imported). You don't technically need to compile each module in a program with the same set of version identifiers, but it's usually asking for trouble if you don't, because that can cause problems when a module is imported using one set of version identifiers but actually compiled with another (e.g. totaly different symbol definitions could be used depending on what was versioned in the module, leading to linker errors). For the most part though, you don't declare your own version identifiers. It sometimes makes sense, but usually, version identifiers are used for versioning code based on the platform or architecture that it's compiled on. They're really only intended to be a saner version of #ifdefs, and if you're doing anything fancy with them, you're really not using them as intended and are probably going to have problems. The list of predefined version identifiers can be found here: https://dlang.org/spec/version.html#predefined-versions - Jonathan M Davis