|
- // Copyright: 2014, Ableton AG, Berlin, all rights reserved
-
- #pragma once
-
- #include <ableton/util/Injected.hpp>
- #include <iostream>
- #include <string>
-
- namespace ableton
- {
- namespace util
- {
-
- // Null object for the Log concept
- struct NullLog
- {
- template <typename T>
- friend const NullLog& operator<<(const NullLog& log, const T&)
- {
- return log;
- }
-
- friend const NullLog& debug(const NullLog& log)
- {
- return log;
- }
-
- friend const NullLog& info(const NullLog& log)
- {
- return log;
- }
-
- friend const NullLog& warning(const NullLog& log)
- {
- return log;
- }
-
- friend const NullLog& error(const NullLog& log)
- {
- return log;
- }
-
- friend NullLog channel(const NullLog&, std::string)
- {
- return {};
- }
- };
-
- // std streams-based log
- struct StdLog
- {
- StdLog(std::string channelName = "")
- : mChannelName(std::move(channelName))
- {
- }
-
- // Stream type used by std log to prepend the channel name to log messages
- struct StdLogStream
- {
- StdLogStream(std::ostream& ioStream, const std::string& channelName)
- : mpIoStream(&ioStream)
- , mChannelName(channelName)
- {
- ioStream << "[" << mChannelName << "] ";
- }
-
- StdLogStream(StdLogStream&& rhs)
- : mpIoStream(rhs.mpIoStream)
- , mChannelName(rhs.mChannelName)
- {
- rhs.mpIoStream = nullptr;
- }
-
- ~StdLogStream()
- {
- if (mpIoStream)
- {
- (*mpIoStream) << "\n";
- }
- }
-
- template <typename T>
- std::ostream& operator<<(const T& rhs)
- {
- (*mpIoStream) << rhs;
- return *mpIoStream;
- }
-
- std::ostream* mpIoStream;
- const std::string& mChannelName;
- };
-
- friend StdLogStream debug(const StdLog& log)
- {
- return {std::clog, log.mChannelName};
- }
-
- friend StdLogStream info(const StdLog& log)
- {
- return {std::clog, log.mChannelName};
- }
-
- friend StdLogStream warning(const StdLog& log)
- {
- return {std::clog, log.mChannelName};
- }
-
- friend StdLogStream error(const StdLog& log)
- {
- return {std::cerr, log.mChannelName};
- }
-
- friend StdLog channel(const StdLog& log, const std::string& channelName)
- {
- auto compositeName =
- log.mChannelName.empty() ? channelName : log.mChannelName + "::" + channelName;
- return {std::move(compositeName)};
- }
-
- std::string mChannelName;
- };
-
- // Log adapter that adds timestamps
- template <typename Log>
- struct Timestamped
- {
- using InnerLog = typename util::Injected<Log>::type;
-
- Timestamped() = default;
-
- Timestamped(util::Injected<Log> log)
- : mLog(std::move(log))
- {
- }
-
- util::Injected<Log> mLog;
-
- friend decltype(debug(std::declval<InnerLog>())) debug(const Timestamped& log)
- {
- return log.logTimestamp(debug(*log.mLog));
- }
-
- friend decltype(info(std::declval<InnerLog>())) info(const Timestamped& log)
- {
- return log.logTimestamp(info(*log.mLog));
- }
-
- friend decltype(warning(std::declval<InnerLog>())) warning(const Timestamped& log)
- {
- return log.logTimestamp(warning(*log.mLog));
- }
-
- friend decltype(error(std::declval<InnerLog>())) error(const Timestamped& log)
- {
- return log.logTimestamp(error(*log.mLog));
- }
-
- friend Timestamped channel(const Timestamped& log, const std::string& channelName)
- {
- return {channel(*log.mLog, channelName)};
- }
-
- template <typename Stream>
- Stream logTimestamp(Stream&& streamRef) const
- {
- using namespace std::chrono;
- Stream stream = std::forward<Stream>(streamRef);
- stream << "|"
- << duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count()
- << "ms| ";
- return stream;
- }
- };
-
- } // namespace util
- } // namespace ableton
|