DIP23 draft: Fixing properties redux

Chad Joan chadjoan at gmail.com
Mon Feb 4 22:40:33 PST 2013


On 02/04/2013 11:18 PM, Andrei Alexandrescu wrote:
> On 2/4/13 10:30 PM, Chad Joan wrote:
>>
>> I agree with Jonathan.
>>
>> Please do not make them a subset. Make them as identical as possible.
>> The subset thing makes them no longer "swappable". Allow variables to be
>> marked with @property to limit them to operations that @property
>> functions can do, and make sure @property functions are limited to what
>> @property variables can do (ex: no address-of!). With that in hand,
>> they'll be very swappable.
>
> The purpose is to replace members with properties, not to change one's
> mind back and forth. There will be no marking of variables with
> @property as that can be easily achieved by actually making them
> properties.
>
> Andrei

Related:
Is there some reason why we /need/ to be able to take the address of 
properties?

Wouldn't something like 'someFunc(PropAccessor!"prop"(foo))' work in 
cases where we need a generic way to defer reads and writes?

For clarity:

auto PropAccessor(string propertyStr, T)( T tinstance )
{
     struct Accessor(string propertyStr, U)
     {
         private U tinstance;

         auto get()
         {
             mixin("return tinstance."~propertyStr~";");
         }

         // I had to put @system here to shut up a compiler error.  Bug?
         @system void set(V)(V val)
         {
             mixin("tinstance."~propertyStr~" = val;");
         }
     }

     Accessor!(propertyStr, T) acc;
     acc.tinstance = tinstance;
     return acc;
}

auto PtrAccessor(T)( T* payload )
{
     struct Accessor(U)
     {
         private U* payload;

         U get()
         {
             return *payload;
         }

         U set(U val)
         {
             return *payload = val;
         }
     }

     Accessor!(T) acc;
     acc.payload = payload;
     return acc;
}

template isAccessor(Acc)
{
     Acc a;
     static if (
         __traits(compiles, { auto x = a.get(); } ) &&
         __traits(compiles, a.set(a.get())) )
         const bool isAccessor = true;
     else
         const bool isAccessor = false;
}

// Function that accepts the be-all-end-all of reference types.
auto someFunc(Acc)(Acc qux) if ( isAccessor!(Acc) )
{
     auto x = qux.get();
     x |= 0xF00D;
     qux.set(x);
     return qux.get();
}

struct MyStruct
{
     private int m_q;
     @property int q() { return m_q; }
     @property void q(int v) { m_q = v; }
}

unittest
{
     MyStruct s;
     s.q = 0;
     int abc = 0;
     assert(someFunc(PtrAccessor(&abc)) == 0xF00D);
     assert(someFunc(PropAccessor!"q"(s)) == 0xF00D);
}

void main()
{
}


More information about the Digitalmars-d mailing list