On Wed, Oct 7, 2009 at 8:07 AM, Don <nos...@nospam.com> wrote: > Craig Kuhnert wrote: >> >> downs Wrote: >> >>> 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"); >>> } >> >> Thanks >> Thats brilliant! D rocks! >> I never though of using mixin for that purpose. > > There's almost NOTHING which is impossible with string mixins. With just > recursive string mixins, coupled with .stringof and is(typeof()), you can > get access to most of the compiler's semantic analysis, and its symbol > table. > Deep in the final semantic pass, just before code generation, when you have > access to all the type information, you can generate new source code for the > compiler to start again at the beginning with parsing. > It's insanely powerful.
It's also insanely kludgy and ugly. Bleh.