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