| 
							- // 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
 
 
  |