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");
}

Reply via email to