Mixin templates as virtual function add tool
Hi, I'm unfortunately in D this construction is not possible to define: class A(T){ abstract void method(S)(T arg1,S arg2); } As adding S to function declaration makes it not virtual. But we can add this kind of functionality using mixin templates mixin template BaseMix(T,S){ abstract void method(T arg1,S arg2); } class Base{ mixin BaseMix!(int,int); } //we can create now implementation by creation of other mixin mixin template ImplMix(T,S){ override void method(T arg1,S arg2){ import std.stdio; writeln(T.strinof," ",S.stringof); //some dummy implementation } } //and initiate the class class Impl:Base{ mixin ImplMix!(int,int); } OK but i don't want to write each argument to mixin templates invocations like: mixin ImplMix!(int,int); mixin ImplMix!(int,byte); mixin ImplMix!(int,string); mixin ImplMix!(int,Object); mixin ImplMix!(int,ubyte); etc. It may produce a bug susceptible code as i would have to write it in two class definitions. I created template that automatically calls mixins with PList... passed but i can't call it with mixins having more than one template param like ImplMix(T,S) template MixinTypeIterate(alias mixinTemplate,TList...){ static if(TList.length>0){ mixin mixinTemplate!(TList[0]); static if(TList.length>1){ mixin MixinTypeIterate!(mixinTemplate,TList[1..$]); } } } how to alias mixin template to be able to pass it to this one ? class BaseClass(T){ protected alias Types=AliasSeq!(int,string,ubyte); private alias WrappedMix(S)=mixin Mix!(T,S); //not compiles - mixins are no t regular templates mixin MixinTypeIterate!(WrappedImplMix,Types); } class ImplClass(T){ private alias WrappedMix(T)=mixin ImplMix!(T,S); //not compiles - mixins are no t regular templates mixin MixinTypeIterate!(WrappedImplMix,Types); } How to make it work?
Joining AliasSeq/TypeTuple s
Hi, i want to join two or more tupples in to one, with mixing the indexes like roundRobin but in compile time. unittest{ import std.meta; alias first=AliasSeq!(int, string,bool); alias second=AliasSeq!("abc","def","ghi"); alias third=... static assert(third==AliasSeq!(int, "abc", string, "def", bool, "ghi")); } How to obtain this kind of functionality ? Is there maybe some builin template for this in phobos ? I couldn't find this. Thank you Voitech.
Re: Variant.type bug ?
On Wednesday, 23 March 2016 at 19:18:50 UTC, Chris Wright wrote: Consider the `coerce` method: http://dpldocs.info/experimental-docs/std.variant.VariantN.coerce.html Example: import std.variant; class A {} class B : A {} void main() { A b = new B; auto bb = Variant(b).coerce!B; assert (bb !is null); } Magnificent! Thank you ! :)
Re: Variant.type bug ?
On Wednesday, 23 March 2016 at 12:52:24 UTC, Adam D. Ruppe wrote: On Wednesday, 23 March 2016 at 08:01:36 UTC, Voitech wrote: Hi Variant stores variant.type as not the "highest" in hierarchy. Yeah, it stores the static type. You can use it to get that then do a normal dynamic cast to test for a more derived type. Ok but how to handle sittuation like this ? class TypeHolder{ import std.variant; Variant[TypeInfo] data; void add(T)(T value){ data[typeid(value)]=value; } T getByType(T)(){ Variant retVar=data.get(typeid(T),Variant(null)); T val=retVar.get!T; //fails return val; } } unittest{ import std.variant; A a= new A; B b= new B; C c = new C; A ab= new B; A ac = new C; TypeHolder holder = new TypeHolder; holder.add(a); holder.add(ab); holder.add(ac); assert(holder.data.length==3); A result=holder.getByType!A; assert(result==a); result=holder.getByType!B; //fails assert(result==ab); result=holder.getByType!C; //fails assert(result==ac); } I can hold objects in other AA but Object[TypeInfo] rather than Variant. Or is there a way to get super type of provided T ?
Variant.type bug ?
Hi Variant stores variant.type as not the "highest" in hierarchy. Like this A a= new A; A b = new B; //B:A Variant bVar=Variant(b); bVar.type will be typeid(A) not typeid(B). Is this intentional ? If so is there a way to get "concrete" type of "b" variable like when passing to template function ? void templateFunc(T)(T v){//just test function for B not used with other type import std.variant; typeof(v) val=v;//concrete type ?? Variant var=val; assert(var.type==typeid(B));//fails } unittest{ A b= new B; templateFunc(b); } Types and unittests: module typeTest; import std.traits; import std.meta; class A{ void a(){} } class B:A{ int b(){ return 1; } } class C:B,D{ string c(){ return ""; } override int d() { return 0; } } interface D{ int d(); } void templateFunc(T)(T v){//just test function for B not used with other import std.variant; typeof(v) val=v;//concrete type ?? Variant var=val; assert(var.type==typeid(B));//fails } unittest{ A b= new B; templateFunc(b); } unittest{ import std.variant; A a= new A; B b= new B; C c = new C; A ab= new B; A ac = new C; Variant variant; variant=a; assert(typeid(a) == variant.type); variant=b; assert(typeid(b) == variant.type); variant=c; assert(typeid(c) == variant.type); variant=ab; assert(typeid(ab) == variant.type); //fails variant=ac; assert(typeid(ac) == variant.type); //fails }
TypeInfo for highest type in hierarhy (class) when passed base type
How to handle this situation: module typeTest; class A{ void a(){} } class B:A{ int b(){ return 1; } } class C:B,D{ string c(){ return ""; } override int d() { return 0; } } interface D{ int d(); } TypeInfo __typeInfo(T)(T t){ return typeid(T); } unittest{ A a= new A; A b= new B; A c = new C; TypeInfo aInfo=__typeInfo(a); TypeInfo bInfo=__typeInfo(b); TypeInfo cInfo=__typeInfo(c); assert(aInfo!=bInfo); //fails assert(aInfo!=cInfo);//fails assert(bInfo!=cInfo);//fails }
Re: Using tango or other static lib in static lib
On Sunday, 13 March 2016 at 01:08:29 UTC, Mike Parker wrote: On Sunday, 13 March 2016 at 01:06:33 UTC, Mike Parker wrote: it. Assuming both files live in the same directory, they can be compiled with this command: Somehow I deleted that line: dmd main.d something.d Wow. Thank You very much for so wide description! I will try it and see if have any more questions. Cheers
Using tango or other static lib in static lib
At beginning I want to say that I'm Java devloper so most of linking, joining, dependent classes, libs could be solve with simple 3 click in eclipse so please be patient with me :). I'm using Mono-D under Ubuntu 14.04 to create my project it would be a library for further development process, but I'm a guy who don't want to invite wheel again and again, so i wanted to use Tango-D2 (for now HashMap implemenetation). From what i red you cant import one static library with another but somehow import o. files, or just copy sources .d to proper folder and use them as yours (with proper license of course). Tango-D2 by itself compiles nicely with bob and produces many .o files. How to use them though ? If using sources by just copping them into one folder, creating Mono-D project, dmd complains about many, many errors, mostly import errors (in tango.sys.win32). I fixed them adding version to each of included files and adding some imports first: module tango.sys.win32 version(Windows){ ... ... } But i think I'm doing something wrong, if Tango-D2 compiles with bob it should also by creating project in Mono-D (or this is linking problem ?). In Mono-D there is also possibility in Project-> Options-> Build-> Compiling to add Libraries (there is a tick Link static libraries from nested dependencies) how to use this ? Or rather how should i obtain what i want ?
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
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 ?
Create a proxy
Hi, I'm trying to create a proxy with automatic method generation . Let say i hava Service object which can be Local service and Remote service. f.e: interface Service{ string serviceInfo(); } interface LocalService:Service{ int doSmth(string param); } class LocalServiceImpl:LocalService{ override string serviceInfo(){ return "i am local"; } override int doSmth(string param){ return param.lenght; } } And now i want to create a proxy, which for client is visible as LocalService class RemoteServiceProxy:LocalService{ Serializer serializer; HttpClient client; Deserializer deserializer this(Serializer serializer,Deserializer deserializer,HttpClient client){ this.serializer=serializer; this.client=client; this.deserializer=deserializer; } override string serviceInfo(){ return "i am remote"; } override int doSmth(string param){ string json= serializer.toJson!(doSmth,int,param)(); string response=client.send(json); return deserializer.fromJson!(response,int)(); } } So RemoteServiceProxy should serialize method name, return type and parameters and send it to some server. On server this should be executed (for now i don't care about errors) and returned as proper value. The problem is i don't want to override every remote service method i will create in interface (LocalService) i want them to be generated depending on return, and parameter types. It will always the same schema: serialize ... http request ... deserialize ... return value (throw Excepion). How to handle this corectly ? I was trying to use mixins for this i created some functions but this not working don't know why string createFunction(R, alias name)(){ static if(is(R==void)){ return mixin(createVoidFunction(name)()); } static if(!is(R==void)){ return mixin(createNonVoidFunction!(R,name)()); } } string createVoidFunction(alias name)(){ return format(q{ void %s(){ writeln(" im void function"); } },name); } string createNonVoidFunction(R,alias name)(){ return format(q{ %s %s(){ writeln("im non void function"); return %s; } }, R.stringof,name,R.init); } unittest{ mixin(createFunction!(int,"nonVoid")()); } There is also a Proxy template in std.typecons but i don't understand how it works or even can it be used in this case. How to handle this ?
Re: Algebraic template instance holder
On Wednesday, 10 February 2016 at 20:53:15 UTC, ZombineDev wrote: On Wednesday, 10 February 2016 at 10:31:34 UTC, Voitech wrote: Hi, why this is not working ? class Base{ int a; } class BaseTemplate(E):Base{ E value; this(E value){ this.value=value; } } class Concrete:BaseTemplate!int{ this(int value){ super(value); } } unittest{ Algebraic!(Concrete) holder; Concrete a=new Concrete(4); holder =Algebraic!Concrete(a); } This is a bug. I filled it as: https://issues.dlang.org/show_bug.cgi?id=15670 I will see if I can fix it tomorrow. Hi @ZombineDev have you by chance looked at this bug ?
Algebraic template instance holder
Hi, why this is not working ? class Base{ int a; } class BaseTemplate(E):Base{ E value; this(E value){ this.value=value; } } class Concrete:BaseTemplate!int{ this(int value){ super(value); } } unittest{ Algebraic!(Concrete) holder; Concrete a=new Concrete(4); holder =Algebraic!Concrete(a); }
Re: Dynamic Ctors ?
On Monday, 8 February 2016 at 15:09:30 UTC, Kagamin wrote: http://dpaste.dzfl.pl/1f25ac34c1ee You need Tuple, not Algebraic. Algebraic stores only one value of one type from a set, like Variant. Thank you for answering. You right if i would want to store all types of T.. in an Inner instance. But my conception was bad from the beginning. I want to store only one type of value in Inner instance. I just wanted to create generic constructor for each of Type which is invalid, cause instance holds value of single type that's why it is not parametrized by itself.
Re: Dynamic Ctors ?
On Monday, 8 February 2016 at 07:08:58 UTC, Voitech wrote: On Saturday, 6 February 2016 at 23:35:17 UTC, Ali Çehreli wrote: On 02/06/2016 10:05 AM, Voitech wrote: > [...] You can use string mixins (makeCtor and makeCtors): string makeCtor(T)() { import std.string : format; [...] Thank you very much for answering. Cheers Unfortunately this doesn't work as I'am trying to assign value from ctor to member something like: this(%s value){ this.value=value; } it gives me Error: memcpy cannot be interpreted at compile time, because it has no available source code. Probably this is caused by declaration of member which is also parametrized with T... Member is: Algebraic!(T) value; So declaration of this mixin constructors are done before variable value is declared (compilation)? Is there any field in class that would contain ctors ? Something like __ctors ? i could try to init this(T... value) constructors in static constructor using delegates/functions. Something like: template Outer(T...){ class Inner{ Algebraic!(T) value; alias ctor(Type) =Inner delegate (Type value); static this(){ foreach(Type;T){ ctor!(Type) c={ this.value=value; }; __ctors~=c; // ? } } }
Re: Dynamic Ctors ?
On Saturday, 6 February 2016 at 23:35:17 UTC, Ali Çehreli wrote: On 02/06/2016 10:05 AM, Voitech wrote: > [...] You can use string mixins (makeCtor and makeCtors): string makeCtor(T)() { import std.string : format; [...] Thank you very much for answering. Cheers
Re: Dynamic Ctors ?
On Saturday, 6 February 2016 at 18:05:05 UTC, Voitech wrote: Hi, i have a variadic args template, with a class inside something like: template foo(T...){ class Inner(){ ... ... } } Now i want to make Inner create or i will create manually, constructor for each of T... parameter types, but don't know what is syntax for it. I found that there is possibility to initialize T... types static variables with AliasSeq!(T) but how to do this automatically, or with static ifs,for constructors ? I tried ... template foo(T...){ alias Types=AliasSeq!(T); Algebraic!(T) value; this(Types value) this.value=value; } } But this dosn't work This gives Error: memcpy cannot be interpreted at compile time, because it has no available source code
Dynamic Ctors ?
Hi, i have a variadic args template, with a class inside something like: template foo(T...){ class Inner(){ ... ... } } Now i want to make Inner create or i will create manually, constructor for each of T... parameter types, but don't know what is syntax for it. I found that there is possibility to initialize T... types static variables with AliasSeq!(T) but how to do this automatically, or with static ifs,for constructors ? I tried ... template foo(T...){ alias Types=AliasSeq!(T); Algebraic!(T) value; this(Types value) this.value=value; } } But this dosn't work
Re: Variadic template parameters T... bounding
On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote: On Tuesday, 2 February 2016 at 13:20:33 UTC, Voitech wrote: [...] Two possible solutions... If you don't need to know the number of arguments at compile time, you can use normal variadic arguments: [...] Thank you I'll try that.
Variadic template parameters T... bounding
Hi, Is it possible to bound T... in template with some type ? For single Parameter declaration it can be done by T:SomeType but variadics does not seems to have that possibility ? Cheers
Types as keys
Hello, I'm having problem with converting from Java style coding to D, probably doing wrong something. I want to have a map (associative array) which will return specific object depending on provided key. Key is a type of other object. Let say i want to hold single instances of some kind of parser for each key object types. class BaseFooBar{} class Foo:BaseFooBar{ ... } class Bar:BaseFooBar{ } BaseParser{} Parser(T) :BaseParser{ abstract string parse(T value); } ParserOne:Parser!Foo{ override string parse(Foo value){ ... } ParserTwo:Parser!Bar{ override string parse(Bar value){ ... } Parser[TypeInfo] container; container~=new ParserOne(); container~=new ParserTwo(); Now i have some data Foo and some Bar in array and each one must be parsed using proper parser parserFoobars(BaseFooBar[] values){ foreach(BaseFooBar foobar;values){ BaseParser parser=container[typeid(foobar)]; ... Now i would have to cast check if parser is ParserOne or ParserTwo and then cast foobar to Bar or Foo depending on which parser has been retrieved. This has no sense ... In Java i could place generic code in BaseParser and depending on FooBar type i will get proper parser from map, and values would be parsed without casting. How to handle this correctly?
Re: Templates, templates, templates...
On Saturday, 23 January 2016 at 13:19:34 UTC, anonymous wrote: On 23.01.2016 12:30, Voitech wrote: Ok so i want to hold different types in LogicRule maybe Algebraic implementation would do? private alias ControllTemplate(T) =Rule!(T,ControllFlag); private alias SymbolRule =ControllTemplate!(SymbolType); private alias StringRule =ControllTemplate!(SymbolRule[]); private alias LogicTemplate(T...) =Rule!(Algebraic!(ControllTemplate(T))[],LogicFlag); <--error You're missing an exclamation mark there, and you've got the order of Algebraic and ControllTemplate wrong. This compiles: private alias LogicTemplate(T...) = Rule!(ControllTemplate!(Algebraic!T)[],LogicFlag); private alias AlgebraicLogicRule = LogicTemplate!(SymbolRule,StringRule); error: Error: cannot pass type (Rule!(SymbolType, ControllFlag), Rule!(Rule!(SymbolType, ControllFlag)[], ControllFlag)) as a function argument [...] Is there any nicer way to handle this case ? Instead of Algebraic you could use a common base class, or interface, for the Rule instantiations: abstract class RuleBase { ... whatever common functionality rules have ... } class Rule(V,F) : RuleBase { ...} But I have to say that I'm having trouble making sense of all that class and template complexity, and how it helps in actually validating user input. Since this is a parsing thing, you may want to look into writing parsers an/or using a parse generator. I think Pegged is the most popular one for D. http://code.dlang.org/packages/pegged Hi, thanks for answering. The complexity is unnecessary as you said. I'm just experimenting with D language. I think i try to finish implementation in my own way and then will look how it may be done with http://code.dlang.org/packages/pegged to have a full spectrum of possibilities. I added base class for Rule -> BaseRule. But this class is just a shell without implementation. Is there any way to avoid this ?
Templates, templates, templates...
Hi, I have a problem with creating proper inheritance chain with templates. First i will give some background about my problem. I'm trying to create a validator for math calculation expressions. I don't want to use regexps as this is approach gives me headache and probably will not allow further extension i want. For now expressions should look like this: 1+2+3/4, -(5*(25-5)/19), sqrt(-5/-6*(212)) etc. So each of charactes is parsed to something like PrimaryElement class PrimaryElement { const dchar value; SymbolType symbolType; } SymbolsType is an enum which contains: EXPR_START,+,-,/,DIGIT,(,),.,EXPR_END So now i want to create validator for input so user couldn't insert something like: /00..34-+/493 but only 0.34-493. I want to divide it into phases. First phase is SymbolType validation so it will handles problems like: +-/345..3 but not .234+3-53 Second phase will take care about value validation so user cant insert .0+3 but only 0.000+3 Third phase would be executed to check expression is completed and not allow to calculate expression for situations like 0.000+3, 3-3+4.5+ or 364/4-5.3+( Now i'm trying to implement phase one. So i create PrimaryElementProcessor which will take some kind of rules and check PrimaryElement[] that way if divided parts of array fits into one of rules then it is valid. Rules will be trimmed to size of expression if necessary. Model and constants declaration looks like this: private enum ControllFlag{ none,ommitable,repeatable } private enum LogicFlag{ none,or,and } private class Rule(V,F){ V value; F flag; this(){ } this(V value){ this.value=value; } this(V value,F flag){ this.value=value; this.flag=flag; } } private alias ControllTemplate(T) =Rule!(T,ControllFlag); private alias SymbolRule =ControllTemplate!(SymbolType); private alias StringRule =ControllTemplate!(SymbolRule[]); private alias LogicTemplate(T...) =Rule!(ControllTemplate(T)[],LogicFlag); private alias LogicRule=LogicTemplate!([SymbolRule,StringRule]); <--error So i first want to handle case like D. or DD where D is Digit instantiation code: SymbolRule digitRule = new SymbolRule(SymbolType.digit,ControllFlag.repeatable); SymbolRule commaRule = new SymbolRule(SymbolType.comma); StringRule numericRule = new StringRule([digitRule,commaRule,digitRule]); LogicRule decimalRule = new LogicRule([digitRule,numericRule],LogicFlag.or); error: Error: type Rule!(Rule!(SymbolType, ControllFlag)[], ControllFlag) has no value Ok so i want to hold different types in LogicRule maybe Algebraic implementation would do? private alias ControllTemplate(T) =Rule!(T,ControllFlag); private alias SymbolRule =ControllTemplate!(SymbolType); private alias StringRule =ControllTemplate!(SymbolRule[]); private alias LogicTemplate(T...) =Rule!(Algebraic!(ControllTemplate(T))[],LogicFlag); <--error private alias AlgebraicLogicRule = LogicTemplate!(SymbolRule,StringRule); error: Error: cannot pass type (Rule!(SymbolType, ControllFlag), Rule!(Rule!(SymbolType, ControllFlag)[], ControllFlag)) as a function argument So maybe something simpler: private alias ControllTemplate(T) =Rule!(T,ControllFlag); private alias SymbolRule =ControllTemplate!(SymbolType); private alias StringRule =ControllTemplate!(SymbolRule[]); private alias SimpleLogicRule =Rule!(Algebraic!(SymbolRule,StringRule)[],LogicFlag); Compiles but... when i try to instantiate SimpleLogicRule like SymbolRule digitRule = new SymbolRule(SymbolType.digit,ControllFlag.repeatable); SymbolRule commaRule = new SymbolRule(SymbolType.comma); StringRule numericRule = new StringRule([digitRule,commaRule,digitRule]); SimpleLogicRule decimalRule = new SimpleLogicRule([digitRule,numericRule],LogicFlag.or); <--- error i get error: None of the overloads of '__ctor' are callable using argument types (Object[], LogicFlag), candidates are: ... So i understand compiler can't cast/extract array of different types to known type. I created a wrapper for this two types SymbolRule and StringRule and init it somewhere before passing to LogicRule ctor. This approach makes a lot of boilerplate code for example: alias Wrapper = Algebraic!(SymbolRule,StringRule); alias LogicRule =Rule!(Wrapper[],LogicFlag); SymbolRule digitRule = new SymbolRule(SymbolType.digit,ControllFlag.repeatable); SymbolRule commaRule = new SymbolRule(SymbolType.comma); StringRule numericRule = new StringRule([digitRule,commaRule,digitRule]); Wrapper digitRuleWrapper =digitRule; <-- how to ommit this ? Wrapper numericRuleWrapper =numericRule; <-- how to ommit this ? LogicRule decimalRule=new LogicRule([digitRuleWrapper,numericRuleWrapper],LogicFlag.or); Is there any nicer way to handle this case ? Cheers Voitech.
Java wildcards... in D
Hi. I'm trying to parse an simple string expression to something like Element array. Each Element can have a value of unknown type, which will be further combined and calculated to let say real/double/float value, no mather. In Java i had something like generics and this could be implemented like: class Element { T value; Element(T value){ this.value=value; } } class Parser{ Collectionparse(String expression){ Collection retVal = new ArrayList<>(); //"expression" would be parser but for this example lets say we just create new elements Element e1= new Element<>(); e1.value=3; Element e2 = new Element<>(); e2.value="+" retValue.add(e1); retValue.add(e2); ... return retValue; } } And then in other class not connected through module or template parameter or anything i could call it just: Parser p = new Parser(); Collection elements=p.parse("(1+2+3)/6"); and then check weather (element.value instanceof Operator) or other stuff. if i do something like this in D: module calculator; class Element(T) { T value; this(T value){ this.value=value; } } and then: Element[] parse(string expression){ Element[] returnSlice; ... //"expression" would be parser but for this example lets say we just create new elements Element!(int) e1 = new Element(); e1.value=3; Element!(string) e2= new Element(); e2.value="+"; returnSlice~=e1; returnSlice~=e2; return returnSlice; } I'm getting error: class calculator.Element used as a type. How to represent this class template parameter T of Element(T) as wildcard Element(?) ?? Cheers Voitech
Re: Java wildcards... in D
On Monday, 18 January 2016 at 21:15:51 UTC, Chris Wright wrote: On Mon, 18 Jan 2016 19:19:22 +, Voitech wrote: Hi. I'm trying to parse an simple string expression to something like Element array. Each Element can have a value of unknown type, which will be further combined and calculated to let say real/double/float value, no mather. In Java, Element is always Element behind the scenes, and there's only one type. In D, Element(T) is a template that produces a type. Element!int and Element!Object are entirely different and, thanks to what templates allow you to do, the compiler can't assume any relationship between the two. You have to establish that relationship manually by creating a base type: abstract class BaseElement { } class Element(T) : BaseElement { T value; } Alternatively, if this is not appropriate to your usecase, you may want to look at std.variant, which explicitly implements value boxing. Thank you for answering. I think i will use std.variant.Algebraic implementation for my needs. But about Algebraic... why first template parameter of it must be always int. Let say i want to store only real and string in Algebraic no int. if i try to do something like : alias Element =Algebraic!(real,string); i will get: Cannot store a int in a VariantN!(16LU, real, string) if i declare as: alias Element =Algebraic!(int,real,string); this will be ok. But anything other than Algebraic!(int,x,y,z...) doesn't compile, like: alias Element =Algebraic!(uint,bool,string); //compilation error alias Element =Algebraic!(ulong,Object,bool); //compilation error alias Element =Algebraic!(long,real,string); //compilation error Why is that ? Cheers Voitech.
Struct Union behavior
Hello, i am new to D language and trying to learn it by coding. I compile my programs on Xubuntu 14.04 with DMD64 D Compiler v2.069.2. So i have a struct/union which contains two fields representing real and string values: public union Element { private real _value; private string _rawValue; @property{ real value(){ return _value; } void value(real value){ _value=value; } } @property { ref string rawValue(){ return _rawValue; } void rawValue(ref string value){ _rawValue=value; } } public Element opBinary(string op)(Element other){ Element newElement; real value=mixin("this.value "~op~"other.value"); newElement.value=value; return newElement; } public bool opEquals(Element other){ if(this.rawValue == null && other.rawValue == null){ return this.opEquals(other.rawValue); } return this.opEquals(other.value); } public bool opEquals(real value){ return this.value==value; } public bool opEquals(string rawValue){ return this.rawValue==rawValue; } unittest{ Element e1 = {4},e2 ={5}; writeln("e1 is at address: ",); writeln("e2 is at address: ",); writeln("e1.value is at address: ",_value); writeln("e2.value is at address: ",_value); assert(e1+e2==9); } unittest{ Element s1={_rawValue:"+"},s2,s3,s4; writeln("s1 is at address: ",); writeln("s2 is at address: ",); writeln("s3 is at address: ",); writeln("s1.value is at address: ",_value); writeln("s2.value is at address: ",_value); writeln("s3.value is at address: ",_value); writeln("s4.value is at address: ",_value); writeln("s1.rawValue ",s1._rawValue); writeln("s1.value: ",s1._value); writeln("s2.value: ",s2._value); writeln("s3.value: ",s3._value); writeln("s4.value: ",s4._value ); assert(s1!=s2); } } The unit test results are: e1 is at address: 7FFCEFBA7510 e2 is at address: 7FFCEFBA7520 e1.value is at address: 7FFCEFBA7510 e2.value is at address: 7FFCEFBA7520 s1 is at address: 7FFCEFBA7500 s2 is at address: 7FFCEFBA7510 s3 is at address: 7FFCEFBA7520 s1.value is at address: 7FFCEFBA7500 s2.value is at address: 7FFCEFBA7510 s3.value is at address: 7FFCEFBA7520 s4.value is at address: 7FFCEFBA7530 s1.rawValue + s1.value: 0.125 s2.value: 4 s3.value: 5 s4.value: 9 Can anyone tell me why s2,s3,s4 have initialized _value field? Shouldn't it be collected by GC when first unit test (with e1,e2) finishes ? If not how to handle this behavior, to use union without preinitialized fields.
Re: Struct Union behavior
On Wednesday, 6 January 2016 at 12:25:31 UTC, Nicholas Wilson wrote: Probably because you are accessing uninitialised memory. the values 4,5,9 appear in the first unittest and are left on the stack. Unions ,unlike structs, do not initialise their fields because it does not make sense to do so because the memory aliases. This can be observed by looking at the size of element (16 bytes) which is less than the size of an array (on 64 bit systems) , 2*8 bytes plus size of a real (8 or 10 bytes (x86/64)). [...] Thank you for your answer it was very helpful :) Cheers.