+ public:
+ /** Log a single message */
+ template <typename ...Args>
+ void dprintf(Tick when, const std::string &name, const char *fmt,
+ const Args &...args)
+ {
+ if (!name.empty() && ignore.match(name))
+ return;
+
+ std::ostringstream line;
+ ccprintf(line, fmt, args...);
+ logMessage(when, name, line.str());
+ }
+
+ /** Dump a block of data of length len */
+ virtual void dump(Tick when, const std::string &name,
+ const void *d, int len);
+
+ /** Log formatted message */
+ virtual void logMessage(Tick when, const std::string &name,
+ const std::string &message) = 0;
+
+ /** Return an ostream that can be used to send messages to
+ * the 'same place' as formatted logMessage messages. This
+ * can be implemented to use a logger's underlying ostream,
+ * to provide an ostream which formats the output in some
+ * way, or just set to one of std::cout, std::cerr */
+ virtual std::ostream &getOstream() = 0;
+
+ /** Set objects to ignore */
+ void setIgnore(ObjectMatch &ignore_) { ignore = ignore_; }
+
+ virtual ~Logger() { }
+};
+
+/** Logging wrapper for ostreams with the format:
+ * <when>: <name>: <message-body> */
+class OstreamLogger : public Logger
+{
+ protected:
+ std::ostream &stream;