Member functions C to D

Don nospam at nospam.com
Wed Oct 7 05:07:20 PDT 2009


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.




More information about the Digitalmars-d-learn mailing list