Member functions C to D

downs default_357-line at yahoo.de
Wed Oct 7 01:37:34 PDT 2009


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


More information about the Digitalmars-d-learn mailing list