Detecting a property setter?

Rory McGuire rmcguire at neonova.co.za
Mon Jul 19 14:35:07 PDT 2010


On Mon, 19 Jul 2010 22:06:14 +0200, Simen kjaeraas  
<simen.kjaras at gmail.com> wrote:

> Rory McGuire <rmcguire at neonova.co.za> wrote:
>
>> Does anyone know how to detect if there is a setter for a property? The
>> code below prints the same thing for both
>> the setter and the getter of "front":
>>
>> ==============================
>> import std.traits;
>>
>> class Foo {
>>      uint num;
>>
>>      @property ref uint front() {
>>          return num;
>>      }
>>      @property void front(uint i) {
>>          num = i;
>>      }
>>
>>      ref uint front2() {
>>      	return num;
>>      }
>> }
>>
>> template isProperty(alias func) if (isCallable!(func)) {
>> 	enum isProperty = (functionAttributes!(func) &
>> FunctionAttribute.PROPERTY)==0 ? false : true;
>> }
>>
>> template hasSetter(alias func) if (isCallable!(func)) {
>> 	enum hasSetter = (isProperty!(func) &&  
>> ParameterTypeTuple!(func).length >
>> 0 && ReturnType!(func).stringof != "void") ? true : false;
>> }
>
> For what it's worth, I would simply check if the property allows  
> assignment. i.e.:
>
> template hasSetter(alias func) if (isCallable!(func)) {
>      enum hasSetter = isProperty!(func) &&
>          is( typeof( (){ func = ReturnType!(func).init; } ) );
> }
>

Hehe good solution, never even crossed my mind.
And it doesn't match ref return types such as the following signature.

ref uint front() { return num; }

My test code below:
===================================
import std.traits;

class Foo {
     uint num;

     @property ref uint front() {
         return num;
     }
/+    @property void front(uint i) {
         num = i;
     }+/

     ref uint front2() {return num;}
}

template isProperty(alias func) if (isCallable!(func)) {
	enum isProperty = (functionAttributes!(func) &  
FunctionAttribute.PROPERTY)==0 ? false : true;
}

template hasSetter(alias func) if (isCallable!(func)) {
     enum hasSetter = isProperty!(func) &&
         is( typeof( (){ func = ReturnType!(func).init; } ) );
}

void main() {
     Foo foo;
	pragma(msg, hasSetter!(foo.front)); // is the return type null (setter)
	
	static if (isProperty!(foo.front)) {
		pragma(msg, "property");
	} else {
		pragma(msg, "not a property");
	}

	alias MemberFunctionsTuple!(Foo,"front") fronts;
	foreach (s; fronts) {
		pragma(msg, hasSetter!(s));
	}

}
================================

Could be used in a GUI library for checking which properties of a class  
are editable and which are only for display.
And tell you about it at compile time.


Thanks!


More information about the Digitalmars-d-learn mailing list