Using string mixins for logging

From D Wiki
Revision as of 15:35, 13 December 2012 by R m r (talk | contribs) (Adding code and dpaste link)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
import std.traits : PTT=ParameterTypeTuple;
import std.stdio : stderr;
import std.datetime : Clock;

template StringOf(TS...)
{
    static if(TS.length == 0)
    {
        enum StringOf = "";
    }
    else
    {
        enum StringOf = (TS[0]).stringof ~ ( (TS.length == 1)? "" : ("," ~ StringOf!(TS[1..$])) );
    }
}

template ArgStringOf(TS...)
{
    static if(TS.length == 0)
    {
        enum ArgStringOf = "";
    }
    else
    {
        enum ArgStringOf = TS[0] ~ ( (TS.length == 1)? "" : ("," ~ ArgStringOf!(TS[1..$])) );
    }
}

template info(PS...)
{
    //pragma(msg, info);
    const char[] info = `static if(!__traits(compiles, __FUNCTION__ == ""))` ~ 
                        `{ immutable string __FUNCTION__ = __traits(identifier, __traits(parent, {})) ~` ~
                                                          `"(" ~ StringOf!(PTT!(__traits(parent, {}))) ~ ")";` ~
                        `} stderr.writeln(Clock.currTime(), " [INFO] ", __FILE__, '(', __LINE__, "): ",` ~
                                          `__FUNCTION__, ": ",` ~ ArgStringOf!(PS) ~ `);` ;
}

mixin template set_func_name(string fn)
{	
    immutable string __FUNCTION__ = fn;
}

auto foo(T)(in T val)
    if(is(T==int) || is(T==string))
{
    mixin set_func_name!("foo(" ~ T.stringof ~ ")"); //workaround for fwd ref issue
    mixin (info!(`"started"`));
    mixin (info!(`"stopped"`));
	
    static if (is(T==int))
        return 1.0123;
    else static if(is(T==string))
        return true;
    else
        static assert(false, "need int or string");	
}
									   
void main(string[] args)
{
    mixin (info!(`"started"`));
	
    mixin (info!(`"foo(1) returned: "`, `foo(1)`));
    mixin (info!(`"foo(\"bar\") returned: "`, `foo("bar")`));
	
    mixin (info!(`"stopped"`));	
}


▶ Run code