Member functions C to D
Jarrett Billingsley
jarrett.billingsley at gmail.com
Wed Oct 7 06:17:59 PDT 2009
On Wed, Oct 7, 2009 at 8:07 AM, Don <nospam at 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.
More information about the Digitalmars-d-learn
mailing list