27.08.2010 17:49, Steven Schveighoffer wrote:
i.e. LOG_IF probably does this:
if(log.level >= INFO && pred)
This is one of the only reasons I think we need a macro system.
Mixins can do this, but who wants to always write mixin when doing
logging?
lazy is traditionally used, but it has costs as well. The best
solution is to have a macro that converts:
log.info(msg);
directly into:
if(log.level >= info) log.output(msg);
which doesn't require lazy and is exactly what you *should* write.
Hmm... something like this can be done with opDispatch:
---
import std.typecons;
mixin(defineEnum!("LogLevel", "error", "info"));
struct Log
{
LogLevel level;
template isLogLevel(string m)
{
enum isLogLevel = __traits(hasMember, LogLevel, m);
}
void opDispatch(string m, Args...)(lazy Args a) if (Log.isLogLevel!(m))
{
LogLevel l;
enumFromString(m,l);
if (level >= l)
{
writef("%s ", m);
writefln(a);
}
}
}
void main()
{
Log log;
log.level = LogLevel.error;
log.error("Error!"); // printed
log.info("Info!"); // not printed
log.level = LogLevel.info;
log.error("Error!"); // printed
log.info("Info!"); // printed
log.warning("Warning!"); // does not compile
}
---
It does however use lazy, but not mixins, and does not require any
macros :) And it is safe.