format.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //
  2. // format.hpp
  3. // logger
  4. //
  5. // Created by Sam Jaffe on 8/21/16.
  6. //
  7. #pragma once
  8. #include <functional>
  9. #include <sstream>
  10. #include <string>
  11. #include <vector>
  12. #include "logger_fwd.h"
  13. namespace logging {
  14. class format {
  15. public:
  16. enum class token_id {
  17. DATE, PRIORITY, CATEGORY, MESSAGE, STRING, NEWLINE
  18. };
  19. using generator = std::function<void(logpacket const &, std::ostream &)>;
  20. static format parse_format_string(std::string const &);
  21. void process(logpacket const & pkt, std::ostream & os) const;
  22. std::string process(logpacket const & pkt) const;
  23. private:
  24. std::vector<generator> gen;
  25. };
  26. inline void format_msg(std::stringstream & msg, std::string const & interp,
  27. size_t pos) {
  28. msg << interp.substr(pos);
  29. }
  30. struct format_point_t {
  31. size_t start;
  32. size_t end;
  33. };
  34. format_point_t get_next_format_specifier(std::string const & interp,
  35. size_t pos );
  36. template <typename Arg0, typename... Args>
  37. inline void format_msg(std::stringstream & msg, std::string const & interp,
  38. size_t pos, Arg0 && arg0, Args && ...args) {
  39. format_point_t next = get_next_format_specifier( interp, pos );
  40. msg << interp.substr(pos, next.start);
  41. if (next.start == std::string::npos) {
  42. return; // throw?
  43. } else if (!strncmp(interp.c_str() + next.start - 1, "{{}}", 4)) {
  44. format_msg(msg, interp, next.end, std::forward<Arg0>(arg0),
  45. std::forward<Args>(args)... );
  46. } else {
  47. msg << arg0;
  48. format_msg(msg, interp, next.end, std::forward<Args>(args)... );
  49. }
  50. }
  51. template <typename... Args>
  52. inline std::string format_msg(std::string const & interp,
  53. Args && ...args) {
  54. std::stringstream msg;
  55. format_msg<Args...>( msg, interp, 0, std::forward<Args>(args)... );
  56. return msg.str();
  57. }
  58. }