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