digitalmars.D.learn - Allowing "fall through" of attributes
- Rufus Smith (16/16) Jul 19 2016 I have some functions that take other functions. I would like the
- Lodovico Giaretta (16/32) Jul 19 2016 You shall do something like this (please note that I didn't check
- Rufus Smith (6/40) Jul 19 2016 But this doesn't create a function with all the attributes of the
- Lodovico Giaretta (9/54) Jul 19 2016 Sorry, I misunderstood your question.
- Rufus Smith (8/26) Jul 19 2016 What is strange is I cannot even pass an extern(C) function to
- Lodovico Giaretta (7/35) Jul 19 2016 That's because an extern function must be called with a different
- Rufus Smith (16/56) Jul 19 2016 I don't want it to be cast to a non-extern function. What I want
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/19) Jul 20 2016 functionAttributes may be useful. SetFunctionAttributes has an example:
I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.
Jul 19 2016
On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic }
Jul 19 2016
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote:On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic }
Jul 19 2016
On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote:Sorry, I misunderstood your question. With the method I showed you, if the function is safe, pure, nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves safe, pure, nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer.On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.You shall do something like this (please note that I didn't check the docs while writing this; you shall definitely have a look at std.traits and consider the following as pseudo-code and not actual D): void foo(Fun)(Fun bar) if (isSomeFunction!Fun) // your constraint that bar is a function { // how to get your R and A types, if you need them: alias R = ReturnType!bar; alias A = Parameters!bar; alias type = Fun; pragma(msg, type); // do some magic }
Jul 19 2016
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote:On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo(&bar) fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed.On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote:Sorry, I misunderstood your question. With the method I showed you, if the function is safe, pure, nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves safe, pure, nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer.[...]But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.
Jul 19 2016
On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote:On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote:That's because an extern function must be called with a different code. So it cannot be cast to a non-extern(C) function pointer, which is what your foo accepts. If you follow my advice, and make the entire function type a parameter of foo, then foo will at least accept your extern(C) function, but it will not be extern(C) itself.On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo(&bar) fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed.On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote:Sorry, I misunderstood your question. With the method I showed you, if the function is safe, pure, nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves safe, pure, nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer.[...]But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.
Jul 19 2016
On Tuesday, 19 July 2016 at 17:10:35 UTC, Lodovico Giaretta wrote:On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote:I don't want it to be cast to a non-extern function. What I want to do is create the exact same type of function that is passed to the template except modify the arguments. If I use a general parameter for the function, it accepts extern(C), but I can't construct a function with it. mixin("alias F = extern("~functionLinkage!Q~") "~(ReturnType!Q).stringof~" function"~(Parameters!Q).stringof~";"); gives me a type that looks to be what I want but I can't really use it unless I want to declare the function that does the work inside foo as mixin string. One can't do extern(functionLinkage!Q) void baz() to create baz with the proper linkage ;/ It looks like I might have to go the mixin way ;/ Going to be messy ;/On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta wrote:That's because an extern function must be called with a different code. So it cannot be cast to a non-extern(C) function pointer, which is what your foo accepts. If you follow my advice, and make the entire function type a parameter of foo, then foo will at least accept your extern(C) function, but it will not be extern(C) itself.On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:What is strange is I cannot even pass an extern(C) function to foo. void foo(R, A...)(R function(A) bar); extern(C) void bar(); foo(&bar) fails. Remove extern and it passes. I have not figured out how to allow for extern(C) functions to be passed.On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta wrote:Sorry, I misunderstood your question. With the method I showed you, if the function is safe, pure, nogc or nothrow, foo will infer those attributes. But only if the operations you do in foo (apart from calling bar) are themselves safe, pure, nogc or nothrow. For other things, like extern(C), I don't think there's a simple solution; but I'm not an expert, so I hope someone else will give you a better answer.[...]But this doesn't create a function with all the attributes of the original? Just one that has the same return type and parameters. What if Fun is pure or extern(C) or some other attributes? I'd like to create a function that is exactly the same in all regards as the original.
Jul 19 2016
On 07/19/2016 08:55 AM, Rufus Smith wrote:I have some functions that take other functions. I would like the attributes to be able to "fall" through so I get overload like behavior. I only care that I am passing a function, not if it is shared, extern(C), pure, nogc, etc. void foo(R, A...)(R function(A) bar) { alias type = typeof(bar); pragma(msg, type); // does magic with bar } foo never uses the attributes of bar explicitly. It uses type to instantiate other functions like bar. I have to create a foo for each attribute combination, which is not worth while. The code seems to break only for extern, the best I can tell, most attributes do pass through. But type does not contain these attributes.functionAttributes may be useful. SetFunctionAttributes has an example: https://dlang.org/phobos/std_traits.html#SetFunctionAttributes Ali
Jul 20 2016