www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to check member function for being disable?

reply Uranuz <neuranuz gmail.com> writes:
In my code I iterate in CT over class methods marked as  property 
and I have a probleme that one of methods is  disable. So I just 
want to skip  disable members. I found possible solution, but 
it's interesting to we if we have more clear and obvious way to 
test for  disable without using __traits( compile ) for it? 
 disable "looks" like attribute but seems that I cant't get it 
through __traits( getAttributes ) or __traits( 
getFunctionAttributes ). Maybe we could add something to test for 
 disable if it's not already exists?

void fillProperties(Ctrl)(Ctrl ctrl, IDirectiveStatement 
statement, Interpreter interp)
{
	import std.meta: Alias, AliasSeq;
	import std.traits;
	import std.conv;

	TDataNode[string] attrDict = getNamedAttributesValues(statement, 
interp);

	foreach(  memberName; AliasSeq!( __traits( allMembers, Ctrl ) )  
)
	{
		static if(  __traits( compiles, __traits(getOverloads, 
Ctrl.init, memberName) )  )
		{
			alias Overloads = AliasSeq!(__traits( getOverloads, Ctrl.init, 
memberName ));
			foreach( overload; Overloads )
			{

				static if( (functionAttributes!(overload) & 
FunctionAttribute.property) )
				{

					alias params = Parameters!(overload);
					static if( params.length == 1 )
					{

						alias propType = params[0];
						static if( __traits(compiles, mixin("{ ctrl."~memberName~" 
= propType.init; }") ) )
						{
							pragma( msg, memberName, ":  ",  typeof(&overload) );
							TDataNode attrValue = attrDict.get( memberName, 
TDataNode(null) );
							if( !attrValue.empty ) {
								mixin( "ctrl." ~ memberName ~ " = 
nodeToDValue!(propType)(attrValue);" );
							}
						}
					}
				}
			}
		}
	}
}
Sep 12 2016
next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, September 13, 2016 04:58:38 Uranuz via Digitalmars-d-learn wrote:
 In my code I iterate in CT over class methods marked as  property
 and I have a probleme that one of methods is  disable. So I just
 want to skip  disable members. I found possible solution, but
 it's interesting to we if we have more clear and obvious way to
 test for  disable without using __traits( compile ) for it?
  disable "looks" like attribute but seems that I cant't get it
 through __traits( getAttributes ) or __traits(
 getFunctionAttributes ). Maybe we could add something to test for
  disable if it's not already exists?
I really don't think that it's going to scale properly to check whether something is marked with disable. The problem is that it propagates. For instance, if a struct has a member variable that has default initialization disabled via disable this(); then that struct effectively has disable this(); too even though it doesn't have it explicitly. So, ultimately what needs to be tested for is the behavior and not the presence of disable, and that means testing with __traits(compiles, ...). And I would point out that most traits test via __traits(compiles, ...) or is(typeof(...)) rather than checking for something like an attribute. So, if don't like using __traits(compiles, ...) in metaprogramming, your going to get frustrated quickly. A large portion of the time, it's exactly the solution to the problem. - Jonathan M Davis
Sep 13 2016
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, September 13, 2016 08:28:10 Jonathan M Davis via Digitalmars-d-
learn wrote:
 On Tuesday, September 13, 2016 04:58:38 Uranuz via Digitalmars-d-learn 
wrote:
 In my code I iterate in CT over class methods marked as  property
 and I have a probleme that one of methods is  disable. So I just
 want to skip  disable members. I found possible solution, but
 it's interesting to we if we have more clear and obvious way to
 test for  disable without using __traits( compile ) for it?
  disable "looks" like attribute but seems that I cant't get it
 through __traits( getAttributes ) or __traits(
 getFunctionAttributes ). Maybe we could add something to test for
  disable if it's not already exists?
I really don't think that it's going to scale properly to check whether something is marked with disable. The problem is that it propagates. For instance, if a struct has a member variable that has default initialization disabled via disable this(); then that struct effectively has disable this(); too even though it doesn't have it explicitly. So, ultimately what needs to be tested for is the behavior and not the presence of disable, and that means testing with __traits(compiles, ...). And I would point out that most traits test via __traits(compiles, ...) or is(typeof(...)) rather than checking for something like an attribute. So, if don't like using __traits(compiles, ...) in metaprogramming, your going to get frustrated quickly. A large portion of the time, it's exactly the solution to the problem.
What would make sense would be creating a trait to test for the disabled functionality in queston - e.g. there could be an eponymous template named something like hasDefaultInitializer (though that name is a bit long) which indicated whether a type had disabled this(); or not. Then you can use that trait in your code rather than using __traits(compiles, ...) all over the place. - Jonthan M Davis
Sep 13 2016
parent reply Uranuz <neuranuz gmail.com> writes:
On Tuesday, 13 September 2016 at 15:32:57 UTC, Jonathan M Davis 
wrote:
 On Tuesday, September 13, 2016 08:28:10 Jonathan M Davis via 
 Digitalmars-d- learn wrote:
 On Tuesday, September 13, 2016 04:58:38 Uranuz via 
 Digitalmars-d-learn
wrote:
 In my code I iterate in CT over class methods marked as 
  property and I have a probleme that one of methods is 
  disable. So I just want to skip  disable members. I found 
 possible solution, but it's interesting to we if we have 
 more clear and obvious way to test for  disable without 
 using __traits( compile ) for it?  disable "looks" like 
 attribute but seems that I cant't get it through __traits( 
 getAttributes ) or __traits( getFunctionAttributes ). Maybe 
 we could add something to test for  disable if it's not 
 already exists?
I really don't think that it's going to scale properly to check whether something is marked with disable. The problem is that it propagates. For instance, if a struct has a member variable that has default initialization disabled via disable this(); then that struct effectively has disable this(); too even though it doesn't have it explicitly. So, ultimately what needs to be tested for is the behavior and not the presence of disable, and that means testing with __traits(compiles, ...). And I would point out that most traits test via __traits(compiles, ...) or is(typeof(...)) rather than checking for something like an attribute. So, if don't like using __traits(compiles, ...) in metaprogramming, your going to get frustrated quickly. A large portion of the time, it's exactly the solution to the problem.
What would make sense would be creating a trait to test for the disabled functionality in queston - e.g. there could be an eponymous template named something like hasDefaultInitializer (though that name is a bit long) which indicated whether a type had disabled this(); or not. Then you can use that trait in your code rather than using __traits(compiles, ...) all over the place. - Jonthan M Davis
OK. Seems that there is nothing that I could do more about my example code.. So the best way to be sure if something is assignable property is to try assign to it and test whether it compiles. The question was because utill this moment I somehow was living without __traits(compiles..). Seems that my use cases just was not enough complicated... Thanks for the answers. It could be good idea to have __traits( isDisable ... ) or something for it. I admit that not only ' disabled this();' regular methods could me marked disable too..
Sep 13 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, September 13, 2016 17:29:26 Uranuz via Digitalmars-d-learn wrote:
 OK. Seems that there is nothing that I could do more about my
 example code.. So the best way to be sure if something is
 assignable property is to try assign to it and test whether it
 compiles. The question was because utill this moment I somehow
 was living without __traits(compiles..). Seems that my use cases
 just was not enough complicated... Thanks for the answers.

 It could be good idea to have __traits( isDisable ... ) or
 something for it. I admit that not only ' disabled this();'
 regular methods could me marked  disable too..
The main places that I can think of at the moment where disable makes sense is for disabling default initialization - disable this(); - and disabling copying - disable this(this);. It's really intended for disabling features that would normally be there. I don't know why it would ever make sense to disable a normal function. Why would it even exist if it were disabled? So, for the compiler to allow disable on normal functions sounds like a bug to me - or at least an oversight in the design and implementation of disable - but maybe there's a legitimate reason that I'm not thinking of at the moment. Regardless, testing for it is as simple as testing whether it can be called or not, and you have to worry about that in a number of cases anyway, because the access level of the function may be such that you can't call it (e.g. it's private, and the code in question is not in the module trying to call it). So, I don't really see what testing for disable specifically would buy you. - Jonathan M Davis
Sep 13 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 13 September 2016 at 17:52:48 UTC, Jonathan M Davis 
wrote:
 It's really intended for disabling features that would normally 
 be there. I don't know why it would ever make sense to  disable 
 a normal function.
Consider the case of `alias this` or a mixin template. You might make a wrapper type that disables a particular operation by writing ` disable void opBinary(op)` so it won't forward to the underlying thing.
Sep 13 2016
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, September 13, 2016 17:59:09 Adam D. Ruppe via Digitalmars-d-learn 
wrote:
 On Tuesday, 13 September 2016 at 17:52:48 UTC, Jonathan M Davis

 wrote:
 It's really intended for disabling features that would normally
 be there. I don't know why it would ever make sense to  disable
 a normal function.
Consider the case of `alias this` or a mixin template. You might make a wrapper type that disables a particular operation by writing ` disable void opBinary(op)` so it won't forward to the underlying thing.
Ah. That makes sense. Thanks for pointing out that use case. And actually, I think that that use case further supports the idea that what code should be testing for is whether an operation works and not whether it's disabled. In the general case, you don't even have any guarantee that the type being aliased has an operation that would need to be disabled. And from the caller's perspective, it shouldn't matter whether the + operator doesn't work because it wasn't declared or because it was disabled. - Jonathan M Davis
Sep 13 2016