Craig Kuhnert wrote: > Hi > I am trying to convert some code I wrote in C++ to D to give it a try and I > have come across some code that I dont know how to convert. > I have simplified the code to illustrate the problem I have. > How do I do this in D? > > class IFieldSetter > { > public: > virtual void SetValue(void * object, const void * value) = 0; > }; > > template <class C, class T> > class FieldSetter : public IFieldSetter > { > private: > typedef T (C::* MemberField); > MemberField field; > > public: > FieldSetter(MemberField afield) > : field(afield) > {} > > void SetTypedValue(C * object, const T& value) > { > object->*field = value; > } > > void SetValue(void * object, const void * value) > { > SetTypedValue((C*) object, (const T&) value); > } > }; > > class MySampleClass > { > public: > int Status; > std::string Name; > }; > > void main(void) > { > IFieldSetter * StatusSetter = new > FieldSetter<MySampleClass,int>(&MySampleClass::Status); > IFieldSetter * NameSetter = new > FieldSetter<MySampleClass,std::string>(&MySampleClass::Name); > > MySampleClass * a = new MySampleClass(); > MySampleClass * b = new MySampleClass(); > > StatusSetter->SetValue(a, (void*)20); > StatusSetter->SetValue(b, (void*)40); > > NameSetter->SetValue(a, "2002"); > NameSetter->SetValue(b, "2002"); > } > > Thanks > Craig
If I'm getting this correctly, here's one way to do it .. module test; import std.stdio, tools.ctfe: ctReplace; // easy to write your own ctReplace function template Init(T) { T Init; } interface IFieldSetter { void setValue(Object obj, void* value); } class FieldSetter(T: Object, string Name) : IFieldSetter { override void setValue(Object obj, void* value) { auto tee = cast(T) obj; mixin("tee.%NAME = *cast(typeof(tee.%NAME)*) value; ".ctReplace("%NAME", Name)); } void setValue(T obj, typeof(mixin("Init!(T)."~Name)) value) { mixin("obj.%NAME = value; ".ctReplace("%NAME", Name)); } } class Sample { int status; string name; } void main() { auto statSetter = new FieldSetter!(Sample, "status"); auto nameSetter = new FieldSetter!(Sample, "name"); auto sample = new Sample; int i = 20; statSetter.setValue(sample, &i); statSetter.setValue(sample, 40); nameSetter.setValue(sample, "Fooblr"); }