Is there an alternative to "__FUNCTION__" that gives the actual function symbol and not the name as a string?
Simon
simon.vanbernem at yahoo.de
Sun Oct 24 14:05:35 UTC 2021
On Saturday, 23 October 2021 at 20:24:32 UTC, Tim wrote:
> import std.traits, std.stdio;
> string generateLogCode(alias func)()
> {
> string code = "writeln(";
> code ~= "\"" ~ fullyQualifiedName!func ~ "(\"";
> foreach(i, param; ParameterIdentifierTuple!func)
> {
> if(i)
> code ~= ", \", \"";
> code ~= ", " ~ param;
> }
> code ~= ", \");\");";
> return code;
> }
> enum OUTPUT_REPRO_CASE = q{
> pragma(msg, generateLogCode!(__traits(parent, {}))());
> mixin(generateLogCode!(__traits(parent, {}))());
> };
> void test(int a, int[] b)
> {
> mixin(OUTPUT_REPRO_CASE);
> }
> void main()
> {
> test(1, [2, 3]);
> }
That worked! I needed to modify it a bit, since there is the
"execution_count_to_log_reproduction_on"-template parameterto the
enum. If I try to use that inside the token string, it just says
it can't find the identifier, so I had to inject some non-token
string in the middle that plays nice with the token string, where
I can actually reference the parameter.
For completeness, here is how the code looks like now (I am
completely horrified by the result):
> string generate_call_to_log_reproduction(alias func)(){
> string code =
> "dlog(generate_reproduction_for_current_function_call!("~fullyQualifiedName!func~", [get_string_argument_list_of_function!([ParameterIdentifierTuple!(__traits(parent, {}))])])(context.temp_allocator";
>
> foreach(i, param; ParameterIdentifierTuple!func)
> code ~= "," ~ param;
>
> code ~= "));";
> return code;
> }
>
> string generate_call_to_log_execution_count(alias func)(){
> return "dlog(\""~fullyQualifiedName!(func)~" execution count:
> %lld\", execution_count);";
> }
>
> enum OUTPUT_REPRO_CASE(s64
> execution_count_to_log_reproduction_on = -1) = q{
> static s64 execution_count = 0;
>
> if(context.settings.debug_.output_call_counts_for_reproducible_functions){
>
> mixin(generate_call_to_log_execution_count!(__traits(parent,
> {})));
> }
> } ~ "if(execution_count ==
> "~execution_count_to_log_reproduction_on.stringof~")"~q{
> {
> mixin(generate_call_to_log_reproduction!(__traits(parent,
> {}))());
> trigger_breakpoint();
> }
>
> execution_count++;
> };
and the usage just looks like this:
> void some_function(int a, int b){
> mixin(OUTPUT_REPRO_CASE!());
> return a + b;
> }
The "mixin(OUTPUT_REPRO_CASE!());" then expands to:
> static s64 execution_count = 0;
> if(context.settings.debug_.output_call_counts_for_reproducible_functions){
> mixin(generate_call_to_log_execution_count!(__traits(parent,
> {})));
> }
>
> if(execution_count == -1L){
> mixin(generate_call_to_log_reproduction!(__traits(parent,
> {}))());
> trigger_breakpoint();
> }
>
> execution_count++;
Thanks for your help!!!
More information about the Digitalmars-d-learn
mailing list