Browse Source

Encapsulate argument vector in an object that can deduce things.

Sam Jaffe 6 years ago
parent
commit
c855c535a0

+ 25 - 0
include/logger/detail/to_string.h

@@ -0,0 +1,25 @@
+//
+//  to_string.h
+//  logger
+//
+//  Created by Sam Jaffe on 4/4/19.
+//
+
+#pragma once
+
+#include <iostream>
+#include <sstream>
+
+namespace logging { namespace detail {
+  template <typename T>
+  void to_stream(T const & obj, std::ostream & os) {
+    os << obj;
+  }
+
+  template <typename T>
+  std::string to_string(T const & obj) {
+    std::stringstream ss;
+    to_stream(obj, ss);
+    return ss.str();
+  }
+} }

+ 7 - 25
include/logger/format.h

@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "logger_fwd.h"
+#include "wrapper_object.h"
 
 namespace logging {
   class format {
@@ -29,36 +30,17 @@ namespace logging {
   private:
     std::vector<generator> gen;
   };
-  
+    
   using string_generator = std::function<std::string(logpacket const &)>;
   string_generator get_date_formatter(std::string fmt);
-  
-  inline void format_msg(std::stringstream & msg, std::string const & interp,
-                         size_t pos) {
-    msg << interp.substr(pos);
-  }
-  
-  template <typename Arg0, typename... Args>
-  inline void format_msg(std::stringstream & msg, std::string const & interp,
-                         size_t pos, Arg0 && arg0, Args && ...args) {
-    size_t next = interp.find("{}", pos);
-    msg << interp.substr(pos, next);
-    if (next == std::string::npos) {
-      return; // throw?
-    } else if (!strncmp(interp.c_str() + next - 1, "{{}}", 4)) {
-      format_msg(msg, interp, next+2, std::forward<Arg0>(arg0),
-                 std::forward<Args>(args)... );
-    } else {
-      msg << arg0;
-      format_msg(msg, interp, next+2, std::forward<Args>(args)... );
-    }
-  }
+    
+  void format_msg(std::ostream & os, std::string const & interp,
+                  size_t pos, size_t idx, std::vector<object> const & objs);
   
   template <typename... Args>
-  inline std::string format_msg(std::string const & interp,
-                                Args && ...args) {
+  std::string format_msg(std::string const & interp, Args && ...args) {
     std::stringstream msg;
-    format_msg<Args...>( msg, interp, 0, std::forward<Args>(args)... );
+    format_msg(msg, interp, 0, 0, {object(args)...});
     return msg.str();
   }
 }

+ 43 - 0
include/logger/wrapper_object.h

@@ -0,0 +1,43 @@
+//
+//  wrapper_object.hpp
+//  logging
+//
+//  Created by Sam Jaffe on 4/4/19.
+//
+
+#pragma once
+
+#include <iosfwd>
+#include <string>
+
+#include "detail/to_string.h"
+
+namespace logging {
+  class object {
+  public:
+    template <typename T>
+    explicit object(T & object);
+    
+    std::string to_string() const;
+    
+  private:
+    template <typename> static std::string to_string(void * ptr);
+    
+  private:
+    void * ptr_;
+    std::string (*to_string_)(void*);
+  };
+  
+  std::ostream & operator<<(std::ostream &, object const &);
+  
+  template <typename T>
+  std::string object::to_string(void * ptr) {
+    return logging::detail::to_string(*static_cast<T*>(ptr));
+  }
+  
+  template <typename T>
+  object::object(T & object)
+  : ptr_(&object), to_string_(&object::to_string<T>) {
+    
+  }
+}

+ 8 - 4
logger.xcodeproj/project.pbxproj

@@ -27,6 +27,7 @@
 		CD88E95F2252D3EF00927F40 /* c_logger.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD88E95D2252D3EF00927F40 /* c_logger.cxx */; };
 		CD88E9632252D67A00927F40 /* common.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CD88E9612252D67A00927F40 /* common.cxx */; };
 		CDA494DE2256D5F40041620C /* date_format.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CDA494DD2256D5F40041620C /* date_format.cxx */; };
+		CDA494E62256D8090041620C /* wrapper_object.cxx in Sources */ = {isa = PBXBuildFile; fileRef = CDA494E42256D8090041620C /* wrapper_object.cxx */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -95,6 +96,7 @@
 		CD88E9612252D67A00927F40 /* common.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = common.cxx; sourceTree = "<group>"; };
 		CD88E9642252D6C700927F40 /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
 		CDA494DD2256D5F40041620C /* date_format.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = date_format.cxx; sourceTree = "<group>"; };
+		CDA494E42256D8090041620C /* wrapper_object.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrapper_object.cxx; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -143,10 +145,10 @@
 			isa = PBXGroup;
 			children = (
 				CD1CDE862252E5B900E5B6B2 /* properties.cxx */,
-				CD1CDE882252E60900E5B6B2 /* file_appender.cxx */,
 				CD1CDEB42256C94000E5B6B2 /* pattern_layout.cxx */,
 				CD1CDEB022557FB600E5B6B2 /* default_layout.cxx */,
 				CD1CDE8A2252E61800E5B6B2 /* console_appender.cxx */,
+				CD1CDE882252E60900E5B6B2 /* file_appender.cxx */,
 			);
 			path = loggers;
 			sourceTree = "<group>";
@@ -155,14 +157,15 @@
 			isa = PBXGroup;
 			children = (
 				CD1CDE812252E54100E5B6B2 /* loggers */,
+				CD88E95D2252D3EF00927F40 /* c_logger.cxx */,
 				CD2973991D7B401F00E37217 /* logger.cxx */,
 				CD1CDEAE22556B7E00E5B6B2 /* logger_impl.cxx */,
+				CD88E9552252BDFC00927F40 /* log_manager.cxx */,
 				CD88E9642252D6C700927F40 /* common.h */,
 				CD88E9612252D67A00927F40 /* common.cxx */,
-				CD88E95D2252D3EF00927F40 /* c_logger.cxx */,
-				CD88E9552252BDFC00927F40 /* log_manager.cxx */,
-				CD3C80BE1D6A2CA300ACC795 /* format.cxx */,
 				CDA494DD2256D5F40041620C /* date_format.cxx */,
+				CD3C80BE1D6A2CA300ACC795 /* format.cxx */,
+				CDA494E42256D8090041620C /* wrapper_object.cxx */,
 			);
 			path = src;
 			sourceTree = "<group>";
@@ -352,6 +355,7 @@
 				CD3C80C01D6A2CA300ACC795 /* format.cxx in Sources */,
 				CD88E95F2252D3EF00927F40 /* c_logger.cxx in Sources */,
 				CD1CDE872252E5B900E5B6B2 /* properties.cxx in Sources */,
+				CDA494E62256D8090041620C /* wrapper_object.cxx in Sources */,
 				CD1CDE8B2252E61800E5B6B2 /* console_appender.cxx in Sources */,
 				CD1CDEAF22556B7E00E5B6B2 /* logger_impl.cxx in Sources */,
 				CD1CDE892252E60900E5B6B2 /* file_appender.cxx in Sources */,

+ 13 - 0
src/format.cxx

@@ -155,4 +155,17 @@ namespace logging {
     process(pkt, ss);
     return ss.str();
   }
+
+  void format_msg(std::ostream & os, std::string const & interp,
+                  size_t pos, size_t idx, std::vector<object> const & objs) {
+    size_t next = interp.find("{}", pos);
+    os << interp.substr(pos, next);
+    if (next == std::string::npos) {
+      return; // throw?
+    } else if (!strncmp(interp.c_str() + next - 1, "{{}}", 4)) {
+      format_msg(os, interp, next+2, idx, objs);
+    } else {
+      format_msg(os << objs[idx], interp, next+2, idx+1, objs);
+    }
+  }
 }

+ 19 - 0
src/wrapper_object.cxx

@@ -0,0 +1,19 @@
+//
+//  wrapper_object.cxx
+//  logging
+//
+//  Created by Sam Jaffe on 4/4/19.
+//
+
+#include "logger/wrapper_object.h"
+
+using namespace logging;
+
+std::string object::to_string() const {
+  return to_string_(ptr_);
+}
+
+// TODO: Call to_stream(os)
+std::ostream & logging::operator<<(std::ostream & os, object const & obj) {
+  return os << obj.to_string();
+}