Bläddra i källkod

Merge branch 'cleanup'

* cleanup:
  Move log_here into correct file.
  Make logging::level less x-macro-y. A further extension would be to submodule with magic_enum.
  Add clang-format, re-arrange some classes
  Return direct object from format factory.
  Switch to using a format_factory class to contain state better.
  Remove macros, re-arrange structs.
Sam Jaffe 5 år sedan
förälder
incheckning
cd2c9f0d4a

+ 108 - 0
.clang-format

@@ -0,0 +1,108 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:   
+  AfterClass:      false
+  AfterControlStatement: false
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: true
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: false
+ForEachMacros:   
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeCategories: 
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+  - Regex:           '.*'
+    Priority:        1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: All
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Middle
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        8
+UseTab:          Never
+...
+

+ 27 - 26
include/logger/c_logger.h

@@ -15,31 +15,37 @@
 
 #include "level.h"
 
-#define VA_LOGN(level, size)          \
-  do {                                \
-    va_list vargs;                    \
-    va_start( vargs, fmt );           \
-    vlognf( level, size, fmt, vargs );\
-    va_end( vargs );                  \
-  } while(0)
+#define VA_LOGN(level, size)                                                   \
+  do {                                                                         \
+    va_list vargs;                                                             \
+    va_start(vargs, fmt);                                                      \
+    vlognf(level, size, fmt, vargs);                                           \
+    va_end(vargs);                                                             \
+  } while (0)
 
 #define VA_LOG(level) VA_LOGN(level, c_logger::LOGF_MAX_SIZE)
 
-#define MAKE_LOGGER_FMT(lvl)                                        \
-  inline void lvl##f(char const * fmt, ...) { VA_LOG(level::lvl); } \
-  inline void lvl##nf(size_t n, char const * fmt, ...) {            \
-    VA_LOGN(level::lvl, n);                                         \
-  }                                                                 \
-  inline void lvl(char const * msg) { log(level::lvl, msg); }       \
+#define MAKE_LOGGER_FMT(lvl)                                                   \
+  inline void lvl##f(char const * fmt, ...) { VA_LOG(level::lvl); }            \
+  inline void lvl##nf(size_t n, char const * fmt, ...) {                       \
+    VA_LOGN(level::lvl, n);                                                    \
+  }                                                                            \
+  inline void lvl(char const * msg) { log(level::lvl, msg); }                  \
   inline void lvl(std::string const & msg) { log(level::lvl, msg); }
 
 namespace logging {
   enum class level : int;
   class logger_impl;
-  
+
   class c_logger {
+  private:
+    friend class manager;
+    std::string logger_name_;
+    std::shared_ptr<logger_impl> impl_;
+
   public:
     static const size_t LOGF_MAX_SIZE = 2048;
+
   public:
     MAKE_LOGGER_FMT(trace)
     MAKE_LOGGER_FMT(debug)
@@ -48,25 +54,20 @@ namespace logging {
     MAKE_LOGGER_FMT(error)
     MAKE_LOGGER_FMT(critical)
     MAKE_LOGGER_FMT(fatal)
-    
+
     template <typename... Args>
-    inline void log(level ll, std::string const & interp, Args && ...args);
-    
+    inline void log(level ll, std::string const & interp, Args &&... args);
+
     void flush();
-    
+
     ~c_logger();
-    
+
   protected:
-    friend class manager;
     c_logger(std::string const & name, std::shared_ptr<logger_impl> impl);
 
   private:
-    void vlognf(level, size_t, char const*, va_list);
-    void log(level, std::string const&);
-    
-  private:
-    std::string logger_name_;
-    std::shared_ptr<logger_impl> impl_;
+    void vlognf(level, size_t, char const *, va_list);
+    void log(level, std::string const &);
   };
 }
 #undef VA_LOG

+ 5 - 5
include/logger/detail/appender.h

@@ -7,7 +7,7 @@ namespace logging {
   struct logpacket;
   class properties;
   enum class level : int;
-  
+
   struct appender {
     virtual ~appender() = default;
     virtual std::ostream & stream() = 0;
@@ -15,15 +15,15 @@ namespace logging {
     virtual bool should_log(level ll) const = 0;
     virtual void flush() = 0;
   };
-  
+
   struct simple_appender : appender {
+    level threshold;
+
     simple_appender() = default;
     simple_appender(properties const & props);
-    
+
     void write(logpacket const & packet, layout & withLayout) override;
     bool should_log(level ll) const override;
     void flush() override;
-    
-    level threshold;
   };
 }

+ 6 - 6
include/logger/detail/data_accessors.h

@@ -14,23 +14,23 @@ namespace logging { namespace detail {
     std::string thread_id() const;
     std::string thread_name() const;
   };
-  
+
   class calling_class_helper {
   private:
     size_t max_components_;
-    
+
   public:
     calling_class_helper(size_t max_components = 0)
-      : max_components_(max_components) {}
-    
+        : max_components_(max_components) {}
+
     std::vector<std::string> full_name(logpacket const & lp) const;
     std::string full_name(logpacket const & lp, std::string const & join) const;
   };
-  
+
   class time_elapsed_helper {
   private:
     long long created_;
-    
+
   public:
     time_elapsed_helper();
     std::string elapsed(logpacket const & packet) const;

+ 4 - 13
include/logger/level.h

@@ -7,21 +7,12 @@
 
 #pragma once
 
-#include <string>
+#include <iosfwd>
 
-#if defined (_MSC_VER)
-#define log_here { __FILE__, __LINE__, __FUNCTION__, __FUNCSIG__ }
-#else
-#define log_here { __FILE__, __LINE__, __FUNCTION__, __PRETTY_FUNCTION__ }
-#endif
+#define LIST_OF_LOGGING_LEVELS                                                 \
+  trace, debug, info, warning, error, critical, fatal, none
 
-#define LIST_OF_LOGGING_LEVELS \
-  X(trace) X(debug) X(info) X(warning) X(error) X(critical) X(fatal) X(none)
-#define X(token) token,
 namespace logging {
-  enum class level : int {
-    LIST_OF_LOGGING_LEVELS warn = warning
-  };
+  enum class level : int { LIST_OF_LOGGING_LEVELS, warn = warning };
   std::ostream & operator<<(std::ostream & os, level l);
 }
-#undef X

+ 11 - 11
include/logger/log_manager.h

@@ -12,7 +12,7 @@
 
 namespace objects { namespace prototype {
   template <typename, typename...> class factory;
-} }
+}}
 
 namespace logging {
   class appender;
@@ -20,11 +20,14 @@ namespace logging {
   class layout;
   class logger;
   class properties;
-  
+
   class manager {
+  private:
+    std::unique_ptr<struct manager_impl> pimpl_;
+
   public:
     static manager & instance();
-    
+
     logger get();
     logger get(std::string const & name);
     c_logger c_get();
@@ -34,13 +37,10 @@ namespace logging {
 
     manager();
     ~manager();
-    
-  private:
-    std::unique_ptr<struct manager_impl> pimpl_;
   };
-  
-  using appenders = objects::prototype::factory<
-      std::shared_ptr<appender>, properties const &>;
-  using layouts = objects::prototype::factory<
-      std::shared_ptr<layout>, properties const &>;
+
+  using appenders = objects::prototype::factory<std::shared_ptr<appender>,
+                                                properties const &>;
+  using layouts =
+      objects::prototype::factory<std::shared_ptr<layout>, properties const &>;
 }

+ 13 - 13
include/logger/logger.h

@@ -25,7 +25,7 @@
 
 #include "message.h"
 
-#define log_message( logger, lvl, ... )   \
+#define log_message(logger, lvl, ...)                                          \
   logger.log(level::lvl, log_here, __VA_ARGS__)
 
 namespace logging {
@@ -35,33 +35,33 @@ namespace logging {
   struct logpacket;
 
   class logger {
+  private:
+    friend class manager;
+    std::string const logger_name_;
+    std::shared_ptr<logger_impl> impl_;
+
   public:
     ~logger();
 
     template <typename... Args>
-    inline void log(level ll, std::string const & interp, Args && ...args) {
+    inline void log(level ll, std::string const & interp, Args &&... args) {
       log(ll, message(interp, std::forward<Args>(args)...));
     }
-    
+
     template <typename... Args>
     inline void log(level ll, location_info const & info,
-                    std::string const & interp, Args && ...args) {
+                    std::string const & interp, Args &&... args) {
       log(ll, info, message(interp, std::forward<Args>(args)...));
     }
-    
-    void log(level ll, message const&);
+
+    void log(level ll, message const &);
 
     void flush();
-    
+
   protected:
     logger(std::string const & name, std::shared_ptr<logger_impl> impl);
-    
-  private:
-    friend class manager;
-    void log(level ll, location_info const & info, message const&);
 
   private:
-    std::string const logger_name_;
-    std::shared_ptr<logger_impl> impl_;
+    void log(level ll, location_info const & info, message const &);
   };
 }

+ 11 - 3
include/logger/logpacket.h

@@ -4,6 +4,14 @@
 #include "level.h"
 #include "message.h"
 
+#if defined(_MSC_VER)
+#define log_here                                                               \
+  { __FILE__, __LINE__, __FUNCTION__, __FUNCSIG__ }
+#else
+#define log_here                                                               \
+  { __FILE__, __LINE__, __FUNCTION__, __PRETTY_FUNCTION__ }
+#endif
+
 namespace logging {
   struct location_info {
     char const * filename = "???";
@@ -11,7 +19,7 @@ namespace logging {
     char const * function = "";
     char const * pretty_function = "";
   };
-  
+
   struct logpacket {
     struct timeval time;
     //    int thread_id;
@@ -20,8 +28,8 @@ namespace logging {
     std::string logger;
     message message;
   };
-  
-#if defined( _WIN32 )
+
+#if defined(_WIN32)
   constexpr char const * const NEWLINE_TOKEN{"\r\n"};
 #else
   constexpr char const * const NEWLINE_TOKEN{"\n"};

+ 10 - 11
include/logger/message.h

@@ -12,24 +12,23 @@
 
 #include "wrapper_object.h"
 
-namespace logging {  
+namespace logging {
   class message {
+  private:
+    std::string format_code;
+    std::vector<detail::object> objects;
+
   public:
     message() = default;
     message(char const * fmt) : format_code(fmt) {}
     template <typename... Args>
-    message(std::string const & fmt, Args && ...args);
-    
+    message(std::string const & fmt, Args &&... args);
+
     std::string str() const;
     Json::Value json() const;
-  private:
-    std::string format_code;
-    std::vector<detail::object> objects;
   };
-  
+
   template <typename... Args>
-  message::message(std::string const & fmt, Args && ...args)
-  : format_code(fmt), objects({detail::object(args)...}) {
-    
-  }
+  message::message(std::string const & fmt, Args &&... args)
+      : format_code(fmt), objects({detail::object(args)...}) {}
 }

+ 8 - 8
include/logger/properties.h

@@ -20,11 +20,13 @@ namespace logging {
   using array_t = std::vector<properties>;
 
   struct properties {
+    variant<object_t, array_t, std::string, int, bool> data;
+
     properties mergedWith(properties const & other) const;
-    
+
     bool contains(std::string const & key) const;
     bool contains(std::size_t idx) const;
-    
+
     object_t const & object() const;
     array_t const & array() const;
 
@@ -37,20 +39,18 @@ namespace logging {
     std::string const & str() const;
     operator int() const;
     operator bool() const;
-
-    variant<object_t, array_t, std::string, int, bool> data;
   };
-  
+
   namespace property {
-    inline properties _obj(object_t const& m) { return {m}; }
-    inline properties _arr(array_t const& l) { return {l}; }
+    inline properties _obj(object_t const & m) { return {m}; }
+    inline properties _arr(array_t const & l) { return {l}; }
     inline properties _v(std::string const & t) { return {t}; }
     // [char const *] will cast to [int] over [std::string const &]
     inline properties _v(char const * t) { return {std::string(t)}; }
     inline properties _v(int t) { return {t}; }
     inline properties _v(bool t) { return {t}; }
   }
-  
+
   extern properties const DEFAULT_APPENDER_SCHEMA;
   extern properties const DEFAULT_LOGGER_SCHEMA;
 }

+ 21 - 30
include/logger/wrapper_object.h

@@ -8,63 +8,54 @@
 #pragma once
 
 #include <iostream>
-#include <string>
 #include <sstream>
+#include <string>
 
 #include <json/json.h>
 
 namespace logging { namespace detail {
   class object {
+  private:
+    void * ptr_;
+    std::string (*to_string_)(void *);
+    Json::Value (*to_json_)(void *);
+
   public:
     template <typename T> explicit object(T & object);
-    
     Json::Value json() const { return to_json_(ptr_); }
-    
+
   private:
     friend std::ostream & operator<<(std::ostream & os, object const & obj) {
       return os << obj.to_string_(obj.ptr_);
     }
     template <typename> static std::string to_string_impl(void * ptr);
     template <typename> static Json::Value to_json_impl(void * ptr);
-
-  private:
-    void * ptr_;
-    std::string (*to_string_)(void*);
-    Json::Value (*to_json_)(void*);
   };
-  
-  template <typename T>
-  void to_stream(T const & obj, std::ostream & os) {
+
+  template <typename T> void to_stream(T const & obj, std::ostream & os) {
     os << obj;
   }
-  
-  template <typename T>
-  std::string to_string(T const & obj) {
+
+  template <typename T> std::string to_string(T const & obj) {
     std::stringstream ss;
     to_stream(obj, ss);
     return ss.str();
   }
-  
-  template <typename T>
-  Json::Value to_json(T const & obj) {
+
+  template <typename T> Json::Value to_json(T const & obj) {
     return to_string(obj);
   }
-  
-  template <typename T>
-  std::string object::to_string_impl(void * ptr) {
-    return to_string(*static_cast<T*>(ptr));
+
+  template <typename T> std::string object::to_string_impl(void * ptr) {
+    return to_string(*static_cast<T *>(ptr));
   }
 
-  template <typename T>
-  Json::Value object::to_json_impl(void * ptr) {
-    return to_json(*static_cast<T*>(ptr));
+  template <typename T> Json::Value object::to_json_impl(void * ptr) {
+    return to_json(*static_cast<T *>(ptr));
   }
 
   template <typename T>
   object::object(T & object)
-  : ptr_(&object),
-  to_string_(&object::to_string_impl<T>),
-  to_json_(&object::to_json_impl<T>) {
-    
-  }
-} }
+      : ptr_(&object), to_string_(&object::to_string_impl<T>),
+        to_json_(&object::to_json_impl<T>) {}
+}}

+ 9 - 15
src/c_logger.cxx

@@ -8,37 +8,31 @@
 #include "logger/c_logger.h"
 
 #include "common.h"
-#include "logger_impl.h"
 #include "logger/logpacket.h"
+#include "logger_impl.h"
 
 using namespace logging;
 
-c_logger::c_logger(std::string const & name,
-                   std::shared_ptr<logger_impl> impl)
-: logger_name_(name), impl_(impl)
-{
-}
+c_logger::c_logger(std::string const & name, std::shared_ptr<logger_impl> impl)
+    : logger_name_(name), impl_(impl) {}
 
 c_logger::~c_logger() {
   if (impl_) impl_->flush();
 }
 
-void c_logger::vlognf(level level, size_t num_bytes, char const* fmt,
+void c_logger::vlognf(level level, size_t num_bytes, char const * fmt,
                       va_list args) {
   if (!impl_->should_log(level)) return;
   const std::unique_ptr<char[]> data(new char[num_bytes]);
   int n = vsnprintf(data.get(), num_bytes, fmt, args);
   if (n >= 0) {
-    data[num_bytes-1] = '\0';
-    impl_->write({ now(), level, {}, logger_name_, {data.get()} });
+    data[num_bytes - 1] = '\0';
+    impl_->write({now(), level, {}, logger_name_, {data.get()}});
   }
 }
 
-void c_logger::log(level level, std::string const& msg) {
-  impl_->write({ now(), level, {}, logger_name_, msg });
-}
-
-void c_logger::flush() {
-  impl_->flush();
+void c_logger::log(level level, std::string const & msg) {
+  impl_->write({now(), level, {}, logger_name_, msg});
 }
 
+void c_logger::flush() { impl_->flush(); }

+ 28 - 13
src/common.cxx

@@ -10,33 +10,48 @@
 #include <cassert>
 #include <ctime>
 
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/variadic/to_seq.hpp>
+
 #include "logger/exception.h"
 #include "logger/logpacket.h"
 
+#define STRING2(A) #A
+#define STRING(A) STRING2(A)
+#define TO_SEQ(...) BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)
+#define FOR_EACH(F, DATA, SEQ) BOOST_PP_SEQ_FOR_EACH(F, DATA, SEQ)
+#define APPLY(F, ...) FOR_EACH(F, _, TO_SEQ(__VA_ARGS__))
+
+#define FROM_STRING(r, data, token)                                            \
+  if (lower_case == STRING(token))                                             \
+    return level::token;                                                       \
+  else
+
+#define TO_STRING(r, data, token)                                              \
+  if (lvl == level::token)                                                     \
+    return STRING(token);                                                      \
+  else
+
 namespace logging {
   timeval now() {
     struct timeval tv;
-    gettimeofday( &tv, nullptr );
+    gettimeofday(&tv, nullptr);
     return tv;
   }
-  
-#define X(token) if (lower_case == #token) return level::token; else
+
   level level_from_string(std::string const & str) {
     std::string lower_case;
-    std::transform(str.begin(), str.end(),
-                   std::back_inserter(lower_case), &tolower);
-    LIST_OF_LOGGING_LEVELS
+    std::transform(str.begin(), str.end(), std::back_inserter(lower_case),
+                   &tolower);
+    APPLY(FROM_STRING, LIST_OF_LOGGING_LEVELS)
     throw invalid_property{str + " is not a log level"};
   }
-#undef X
-  
-#define X(token) if (lvl == level::token) return #token; else
+
   char const * level_to_string(level lvl) {
-    LIST_OF_LOGGING_LEVELS
+    APPLY(TO_STRING, LIST_OF_LOGGING_LEVELS)
     throw std::domain_error{"unknown logging level in switch"};
   }
-#undef X
-  
+
   std::string to_string(level lvl, bool uppercase) {
     std::string str = level_to_string(lvl);
     if (uppercase) {
@@ -44,7 +59,7 @@ namespace logging {
     }
     return str;
   }
-  
+
   std::ostream & operator<<(std::ostream & os, level l) {
     return os << std::string(to_string(l, true));
   }

+ 14 - 20
src/data_accessors.cxx

@@ -16,11 +16,9 @@
 namespace {
   void erase_prefix(std::string & str, char const * prefix) {
     size_t size = strlen(prefix);
-    if (str.find(prefix, 0, size) == 0) {
-      str.erase(0, size);
-    }
+    if (str.find(prefix, 0, size) == 0) { str.erase(0, size); }
   }
-  
+
   void trim_upto_prefix_alpha(std::string & str, char const * prefix) {
     size_t size = strlen(prefix);
     for (size_t i = str.find(prefix); i != std::string::npos;
@@ -31,37 +29,33 @@ namespace {
       }
     }
   }
-  
-  long long millis(timeval tv) {
-    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-  }
+
+  long long millis(timeval tv) { return tv.tv_sec * 1000 + tv.tv_usec / 1000; }
 }
 
 namespace logging { namespace detail {
   static thread_local std::string THREAD_NAME;
-  
+
   void thread_info_helper::set_name(std::string const & name) {
     THREAD_NAME = name;
   }
-  
+
   std::string thread_info_helper::thread_id() const {
     std::stringstream ss;
     ss << std::this_thread::get_id();
     return ss.str();
   }
-  
+
   std::string thread_info_helper::thread_name() const {
     return THREAD_NAME.size() ? THREAD_NAME : thread_id();
   }
-  
+
   std::vector<std::string>
   calling_class_helper::full_name(logpacket const & packet) const {
     std::string pf = packet.info.pretty_function;
     std::string func = std::string(packet.info.function) + "(";
     // If this is a function in the global namespace, return just the empty str
-    if (pf[pf.find(func)-1] == ' ') {
-      return {""};
-    }
+    if (pf[pf.find(func) - 1] == ' ') { return {""}; }
     // Delete the function name, and everything after
     pf.erase(pf.find(func));
     // Since this may be a class function, delete the ending bit
@@ -80,16 +74,16 @@ namespace logging { namespace detail {
     std::vector<std::string> rval;
     size_t i = 0, n = pf.find("::");
     rval.emplace_back(pf.substr(i, n));
-    for (i = n, n = pf.find("::", i+2); i != std::string::npos;
-         i = n, n = pf.find("::", i+2)) {
-      rval.emplace_back(pf.substr(i+2, n));
+    for (i = n, n = pf.find("::", i + 2); i != std::string::npos;
+         i = n, n = pf.find("::", i + 2)) {
+      rval.emplace_back(pf.substr(i + 2, n));
     }
     if (max_components_ && max_components_ < rval.size()) {
       rval.erase(rval.begin(), rval.end() - max_components_);
     }
     return rval;
   }
-  
+
   std::string calling_class_helper::full_name(logpacket const & packet,
                                               std::string const & join) const {
     auto tokens = full_name(packet);
@@ -99,7 +93,7 @@ namespace logging { namespace detail {
     std::for_each(tokens.begin() + 1, tokens.end(), append);
     return ss.str();
   }
-  
+
   time_elapsed_helper::time_elapsed_helper() : created_(millis(now())) {}
   std::string time_elapsed_helper::elapsed(logpacket const & packet) const {
     return std::to_string(millis(packet.time) - created_);

+ 6 - 13
src/log_manager.cxx

@@ -14,11 +14,11 @@
 #include "resource_factory/prototype_factory.hpp"
 
 #include "common.h"
-#include "logger_impl.h"
 #include "logger/c_logger.h"
 #include "logger/exception.h"
 #include "logger/logger.h"
 #include "logger/properties.h"
+#include "logger_impl.h"
 
 INSTANTIATE_PROTOTYPE_FACTORY_2(logging::appenders);
 INSTANTIATE_PROTOTYPE_FACTORY_2(logging::layouts);
@@ -30,7 +30,7 @@ using p_logger = std::shared_ptr<logger_impl>;
 
 struct logging::manager_impl {
   template <typename V> using cache = std::unordered_map<std::string, V>;
-  
+
   manager_impl();
   p_logger get_logger(properties const & props);
   void configure_appenders(properties const & props);
@@ -81,8 +81,7 @@ static p_layout load_layout(std::string const & source,
   return layouts::instance().get("default", {});
 }
 
-template <typename T>
-void inject_log_level(properties const & props, T & val) {
+template <typename T> void inject_log_level(properties const & props, T & val) {
   if (props.contains("threshold")) {
     val.min_log_level = level_from_string(props["threshold"]);
   }
@@ -103,26 +102,20 @@ void manager_impl::configure_loggers(properties const & props) {
     inject_log_level(log.second, *plog);
     loggers[log.first] = plog;
   }
-  if (loggers.count("root")) {
-    default_logger = loggers["root"];
-  }
+  if (loggers.count("root")) { default_logger = loggers["root"]; }
 }
 
 manager::manager() : pimpl_(new manager_impl) {}
 
 manager::~manager() {}
 
-logger manager::get() {
-  return logger("", pimpl_->default_logger);
-}
+logger manager::get() { return logger("", pimpl_->default_logger); }
 
 logger manager::get(std::string const & name) {
   return logger(name, pimpl_->loggers.at(name));
 }
 
-c_logger manager::c_get() {
-  return c_logger("", pimpl_->default_logger);
-}
+c_logger manager::c_get() { return c_logger("", pimpl_->default_logger); }
 
 c_logger manager::c_get(std::string const & name) {
   return c_logger(name, pimpl_->loggers.at(name));

+ 10 - 14
src/logger.cxx

@@ -8,28 +8,24 @@
 #include "logger/logger.h"
 
 #include "common.h"
-#include "logger_impl.h"
 #include "logger/logpacket.h"
+#include "logger_impl.h"
 
 namespace logging {
   logger::logger(std::string const & name, std::shared_ptr<logger_impl> impl)
-  : logger_name_(name), impl_(impl) {
-  }
-  
+      : logger_name_(name), impl_(impl) {}
+
   logger::~logger() {
     if (impl_) impl_->flush();
   }
-  
+
   void logger::log(level ll, message const & msg) {
-    impl_->write({ now(), ll, {}, logger_name_, msg });
-  }
-  
-  void logger::log(level ll, location_info const & info,
-                   message const & msg) {
-    impl_->write({ now(), ll, info, logger_name_, msg });
+    impl_->write({now(), ll, {}, logger_name_, msg});
   }
-  
-  void logger::flush() {
-    impl_->flush();
+
+  void logger::log(level ll, location_info const & info, message const & msg) {
+    impl_->write({now(), ll, info, logger_name_, msg});
   }
+
+  void logger::flush() { impl_->flush(); }
 }

+ 9 - 26
src/logger_impl.cxx

@@ -16,36 +16,25 @@
 using namespace logging;
 
 simple_appender::simple_appender(properties const & props)
-: threshold(level_from_string(props["threshold"])) {}
+    : threshold(level_from_string(props["threshold"])) {}
 
 void simple_appender::write(logpacket const & packet, layout & withLayout) {
   withLayout.format(stream(), packet);
 }
 
-bool simple_appender::should_log(level ll) const {
-  return ll >= threshold;
-}
+bool simple_appender::should_log(level ll) const { return ll >= threshold; }
 
-void simple_appender::flush() {
-  stream().flush();
-}
+void simple_appender::flush() { stream().flush(); }
 
 log_appender::log_appender(p_appender append, p_layout layout)
-: appender_(append),
-  layout_(layout),
-  has_logged_(false)
-{
+    : appender_(append), layout_(layout), has_logged_(false) {
   appender_->stream() << layout_->header();
 }
 
-log_appender::~log_appender() {
-  appender_->stream() << layout_->footer();
-}
+log_appender::~log_appender() { appender_->stream() << layout_->footer(); }
 
 void log_appender::write(logpacket const & packet) {
-  if (has_logged_) {
-    appender_->stream() << layout_->separator();
-  }
+  if (has_logged_) { appender_->stream() << layout_->separator(); }
   appender_->write(packet, *layout_);
   has_logged_ = true;
 }
@@ -54,20 +43,14 @@ bool log_appender::should_log(level ll) const {
   return appender_->should_log(ll);
 }
 
-void log_appender::flush() {
-  appender_->flush();
-}
+void log_appender::flush() { appender_->flush(); }
 
-bool logger_impl::should_log(level ll) const {
-  return ll >= min_log_level;
-}
+bool logger_impl::should_log(level ll) const { return ll >= min_log_level; }
 
 void logger_impl::write(logpacket const & pkt) {
   if (!should_log(pkt.level)) return;
   for (auto & appender : impls) {
-    if (appender->should_log(pkt.level)) {
-      appender->write(pkt);
-    }
+    if (appender->should_log(pkt.level)) { appender->write(pkt); }
   }
 }
 

+ 10 - 10
src/logger_impl.h

@@ -1,8 +1,8 @@
 #pragma once
 
 #include <memory>
-#include <vector>
 #include <utility>
+#include <vector>
 
 namespace logging {
   class appender;
@@ -13,26 +13,26 @@ namespace logging {
   using p_layout = std::shared_ptr<layout>;
 
   class log_appender {
+  private:
+    p_appender appender_;
+    p_layout layout_;
+    bool has_logged_;
+
   public:
     log_appender(p_appender append, p_layout layout);
     ~log_appender();
-    
+
     void write(logpacket const & packet);
     bool should_log(level ll) const;
     void flush();
-    
-  private:
-    p_appender appender_;
-    p_layout layout_;
-    bool has_logged_;
   };
 
   struct logger_impl {
+    std::vector<std::shared_ptr<log_appender>> impls;
+    level min_log_level;
+
     bool should_log(level ll) const;
     void write(logpacket const & pkt);
     void flush();
-
-    std::vector<std::shared_ptr<log_appender>> impls;
-    level min_log_level;
   };
 }

+ 11 - 8
src/loggers/console_appender.cxx

@@ -19,22 +19,25 @@ using namespace logging;
 
 class console_appender : public simple_appender {
 public:
-  static std::shared_ptr<appender> create(properties const& props);
-  
-  explicit console_appender(properties const& props);
-  
+  static std::shared_ptr<appender> create(properties const & props);
+
+  explicit console_appender(properties const & props);
+
   std::ostream & stream() override { return out_; }
+
 private:
-  std::ostream& out_;
+  std::ostream & out_;
 };
 
 using namespace logging::property;
+// clang-format off
 properties const DEFAULT_CONSOLE_APPENDER{_obj({
   {"target", {}},
   {"threshold", _v("ERROR")}
 })};
+// clang-format on
 
-std::shared_ptr<appender> console_appender::create(properties const& props) {
+std::shared_ptr<appender> console_appender::create(properties const & props) {
   properties const actual = DEFAULT_CONSOLE_APPENDER.mergedWith(props);
   return std::make_shared<console_appender>(actual);
 }
@@ -49,8 +52,8 @@ static std::ostream & get_ostream(std::string const & target) {
   }
 }
 
-console_appender::console_appender(properties const& props)
-: simple_appender(props), out_(get_ostream(props["target"])) {}
+console_appender::console_appender(properties const & props)
+    : simple_appender(props), out_(get_ostream(props["target"])) {}
 
 namespace {
   bool _ = appenders::instance().bind("Console", console_appender::create);

+ 9 - 7
src/loggers/file_appender.cxx

@@ -19,17 +19,18 @@ using namespace logging;
 
 struct buffer : std::filebuf {
   buffer(properties const & props);
-  buffer * setbuf(char* data, std::streamsize n);
+  buffer * setbuf(char * data, std::streamsize n);
 };
 
 class file_appender : public simple_appender {
 public:
   static std::shared_ptr<appender> create(properties const & props);
-  
+
   explicit file_appender(properties const & props);
-  
+
   std::ostream & stream() override { return out_; }
   void write(logpacket const & packet, layout & withLayout) override;
+
 private:
   bool flush_immediately_;
   buffer rdbuf_;
@@ -38,6 +39,7 @@ private:
 };
 
 using namespace logging::property;
+// clang-format off
 properties const DEFAULT_FILE_APPENDER{_obj({
   {"immediateFlush", _v(true)},
   {"threshold", _v("ERROR")},
@@ -46,6 +48,7 @@ properties const DEFAULT_FILE_APPENDER{_obj({
   {"bufferedIO", _v(false)},
   {"bufferSize", _v(8192)}
 })};
+// clang-format on
 
 std::shared_ptr<appender> file_appender::create(properties const & props) {
   properties const actual = DEFAULT_FILE_APPENDER.mergedWith(props);
@@ -62,15 +65,14 @@ buffer::buffer(properties const & props) : std::filebuf() {
   }
 }
 
-buffer * buffer::setbuf(char* data, std::streamsize n) {
+buffer * buffer::setbuf(char * data, std::streamsize n) {
   std::filebuf::setbuf(data, n);
   return this;
 }
 
 file_appender::file_appender(properties const & props)
-: simple_appender(props),
-  flush_immediately_(props["immediateFlush"]),
-  rdbuf_(props), out_(&rdbuf_) {
+    : simple_appender(props), flush_immediately_(props["immediateFlush"]),
+      rdbuf_(props), out_(&rdbuf_) {
   if (props["bufferedIO"]) {
     int const size = props["bufferSize"];
     buffer_.reset(new char[size]);

+ 10 - 16
src/loggers/json_layout.cxx

@@ -21,7 +21,7 @@ using namespace logging;
 class json_layout : public layout {
 public:
   static std::shared_ptr<layout> create(properties const &);
-  
+
   json_layout(properties const & props);
   void format(std::ostream & os, logpacket const & pkt) const override;
   std::string header() const override { return complete_ ? "[" : ""; }
@@ -34,6 +34,7 @@ private:
 };
 
 using namespace logging::property;
+// clang-format off
 properties const DEFAULT_JSON_LAYOUT{_obj({
   {"charset", _v("en_US.UTF-8")},
   {"compact", _v(false)},
@@ -43,6 +44,7 @@ properties const DEFAULT_JSON_LAYOUT{_obj({
   {"includeNullDelimiter", _v(false)},
   {"objectMessageAsJsonObject", _v(false)}
 })};
+// clang-format on
 
 std::shared_ptr<layout> json_layout::create(properties const & props) {
   properties const actual = DEFAULT_JSON_LAYOUT.mergedWith(props);
@@ -50,21 +52,16 @@ std::shared_ptr<layout> json_layout::create(properties const & props) {
 }
 
 json_layout::json_layout(properties const & props)
-: eol_(props["eventEol"]),
-  log_as_json_(props["objectMessageAsJsonObject"]),
-  include_location_(props["locationInfo"]),
-  complete_(props["complete"])
-{
+    : eol_(props["eventEol"]), log_as_json_(props["objectMessageAsJsonObject"]),
+      include_location_(props["locationInfo"]), complete_(props["complete"]) {
   build["indentation"] = props["compact"] ? "" : "  ";
 }
 
-char const * filename(char const * str) {
-  return strrchr(str, '/')+1;
-}
+char const * filename(char const * str) { return strrchr(str, '/') + 1; }
 
 void json_layout::format(std::ostream & os, logpacket const & pkt) const {
   Json::Value root;
-  root["instant"]["epochSecond"] = (Json::UInt64) pkt.time.tv_sec;
+  root["instant"]["epochSecond"] = (Json::UInt64)pkt.time.tv_sec;
   root["instant"]["nanoOfSecond"] = pkt.time.tv_usec * 1000;
   root["level"] = to_string(pkt.level, true);
   root["loggerName"] = pkt.logger;
@@ -81,12 +78,9 @@ void json_layout::format(std::ostream & os, logpacket const & pkt) const {
   std::string data = Json::writeString(build, root);
   // jsoncpp is dumb and writes a newline after each ':' token if
   // the child is an object or array.
-  std::regex_replace(std::ostreambuf_iterator<char>(os),
-                     data.begin(), data.end(),
-                     std::regex(": \n(  )*(\\{|\\[)"), ": $2");
-  if (eol_) {
-    os << NEWLINE_TOKEN;
-  }
+  std::regex_replace(std::ostreambuf_iterator<char>(os), data.begin(),
+                     data.end(), std::regex(": \n(  )*(\\{|\\[)"), ": $2");
+  if (eol_) { os << NEWLINE_TOKEN; }
 }
 
 namespace {

+ 5 - 7
src/loggers/pattern_layout.cxx

@@ -16,7 +16,7 @@ using namespace logging;
 
 struct pattern_layout : public layout {
   static std::shared_ptr<layout> create(properties const &);
-  
+
   pattern_layout(properties const & props);
   void format(std::ostream & os, logpacket const & pkt) const override;
   std::string header() const override { return header_; }
@@ -28,6 +28,7 @@ struct pattern_layout : public layout {
 };
 
 using namespace logging::property;
+// clang-format off
 properties const DEFAULT_PATTERN_LAYOUT{_obj({
   {"charset", _v("en_US.UTF-8")},
   {"pattern", {}},
@@ -38,6 +39,7 @@ properties const DEFAULT_PATTERN_LAYOUT{_obj({
   {"disableAnsi", _v(false)},
   {"noConsoleNoAnsi", _v(false)}
 })};
+// clang-format on
 
 std::shared_ptr<layout> pattern_layout::create(properties const & props) {
   properties const actual = DEFAULT_PATTERN_LAYOUT.mergedWith(props);
@@ -45,12 +47,8 @@ std::shared_ptr<layout> pattern_layout::create(properties const & props) {
 }
 
 pattern_layout::pattern_layout(properties const & props)
-: formatter(format::parse_format_string(props["pattern"])),
-  header_(props["header"]),
-  footer_(props["footer"])
-{
-  
-}
+    : formatter(format_factory(props["pattern"]).create()),
+      header_(props["header"]), footer_(props["footer"]) {}
 
 void pattern_layout::format(std::ostream & os, logpacket const & pkt) const {
   os << formatter.process(pkt);

+ 41 - 13
src/loggers/pattern_layout.h

@@ -15,22 +15,50 @@ namespace logging {
   struct logpacket;
   class format {
   public:
-    struct generator_t {
-      virtual ~generator_t() = default;
-      std::string str(logpacket const & lp) const;
-      virtual void write(logpacket const & lp, std::ostream & os) const = 0;
-    };
-  public:
-    enum class token_id {
-      DATE, PRIORITY, CATEGORY, MESSAGE, STRING, NEWLINE
-    };
-    
+    struct generator_t;
     using generator = std::shared_ptr<generator_t>;
-    
-    static format parse_format_string(std::string const &);
+
+  private:
+    friend class format_factory;
+    std::vector<generator> gen;
+
+  public:
     void process(logpacket const & pkt, std::ostream & os) const;
     std::string process(logpacket const & pkt) const;
+
   private:
-    std::vector<generator> gen;
+    format(std::vector<generator> const & gen) : gen(gen) {}
+  };
+
+  class format_factory {
+  private:
+    std::string data_string_;
+    char const * curr_;
+    char const * const end_;
+    char const * next_ = nullptr;
+    std::vector<format::generator> generators_{};
+
+  public:
+    format_factory(std::string const & str);
+    format create();
+
+  private:
+    bool is(char c) const { return next_ && *next_ == c; }
+    bool is(char const * str) const {
+      return next_ && !strncmp(next_, str, strlen(str));
+    }
+    template <typename T, typename... Args> void append(Args &&... args) {
+      generators_.push_back(std::make_shared<T>(std::forward<Args>(args)...));
+    }
+
+    void create_date();
+    void create_size_bounded();
+    format::generator create_impl();
+  };
+
+  struct format::generator_t {
+    virtual ~generator_t() = default;
+    std::string str(logpacket const & lp) const;
+    virtual void write(logpacket const & lp, std::ostream & os) const = 0;
   };
 }

+ 28 - 26
src/loggers/pattern_layout_date.cxx

@@ -30,36 +30,40 @@ static std::string fmt_time(struct timeval round, char const * const fmt) {
 static std::string fmt_time_with_milis(struct timeval round,
                                        std::string const & fmt) {
   char buf[64] = {'\0'};
-  snprintf(buf, sizeof(buf), fmt.c_str(), round.tv_usec/1000);
+  snprintf(buf, sizeof(buf), fmt.c_str(), round.tv_usec / 1000);
   return fmt_time(round, buf);
 }
 
 namespace logging {
-  struct time_gen : public format::generator_t {
+  class time_gen : public format::generator_t {
+  public:
     enum resolution { seconds, milis };
-    
+
+  private:
+    std::string predef_format;
+    resolution res;
+
+  public:
     time_gen(std::string const & pre, resolution res)
-    : predef_format(pre), res(res) {}
-    
+        : predef_format(pre), res(res) {}
+
     void write(logpacket const & lp, std::ostream & os) const override {
       switch (res) {
-        case seconds:
-          os << fmt_time(lp.time, predef_format.c_str());
-          break;
-        case milis:
-          os << fmt_time_with_milis(lp.time, predef_format);
+      case seconds:
+        os << fmt_time(lp.time, predef_format.c_str());
+        break;
+      case milis:
+        os << fmt_time_with_milis(lp.time, predef_format);
         break;
       }
     }
-    std::string predef_format;
-    resolution res;
   };
 
-  format::generator parse_date_format_string(char const * str) {
+  time_gen parse_date_format_string(char const * str) {
     char const * const end = strchr(str, '}');
     if (end == nullptr) {
-      std::string error_msg{"expected date-format specifier to terminate"};
-      throw format_parsing_exception{error_msg};
+      throw format_parsing_exception{
+          "expected date-format specifier to terminate"};
     }
     std::string fmt(str, end);
     if (fmt.find("%_ms") != std::string::npos) {
@@ -69,25 +73,23 @@ namespace logging {
         pos += 2;
       }
       fmt.replace(fmt.find("%%_ms"), 5, "%.03d");
-      return std::make_shared<time_gen>(fmt, time_gen::milis);
+      return time_gen(fmt, time_gen::milis);
     } else {
-      return std::make_shared<time_gen>(fmt, time_gen::seconds);
+      return time_gen(fmt, time_gen::seconds);
     }
   }
-  
-#define is( chr ) *next == chr
-#define is_string( str ) ! strncmp(next, str, strlen(str))
-  format::generator date_token(char const * next) {
+
+  void format_factory::create_date() {
     std::string predef_format = "%%Y-%%m-%%d %%H:%%M:%%S,%.03d";
-    if (is_string("{ISO8601}")) {
+    if (is("{ISO8601}")) {
       predef_format = "%%Y-%%m-%%dT%%H:%%M:%%S.%.03dZ";
-    } else if (is_string("{ABSOLUTE}")) {
+    } else if (is("{ABSOLUTE}")) {
       predef_format = "%%H:%%M:%%S,%.03d";
-    } else if (is_string("{DATE}")) {
+    } else if (is("{DATE}")) {
       predef_format = "%%d %%b %%Y %%H:%%M:%%S,%.03d";
     } else if (is('{')) {
-      return parse_date_format_string(next+1);
+      return append<time_gen>(parse_date_format_string(next_ + 1));
     }
-    return std::make_shared<time_gen>(predef_format, time_gen::milis);
+    append<time_gen>(predef_format, time_gen::milis);
   }
 }

+ 104 - 117
src/loggers/pattern_layout_format.cxx

@@ -28,7 +28,7 @@ namespace logging { namespace {
       os << lp.logger;
     }
   };
-  
+
   struct thread_name_gen : public detail::thread_info_helper,
                            public format::generator_t {
     void write(logpacket const & lp, std::ostream & os) const override {
@@ -48,15 +48,27 @@ namespace logging { namespace {
       os << to_string(lp.level, true);
     }
   };
-  
+
+  struct message_gen : public format::generator_t {
+    void write(logpacket const & lp, std::ostream & os) const override {
+      os << lp.message.str();
+    }
+  };
+
+  struct literal_gen : public format::generator_t {
+    std::string value;
+
+    literal_gen(std::string const & value) : value(value) {}
+
+    void write(logpacket const & lp, std::ostream & os) const override {
+      os << value;
+    }
+  };
+
   struct class_info_gen : public detail::calling_class_helper,
                           public format::generator_t {
     static size_t components(char const * token) {
-      if (token && *token == '{') {
-        return atol(token + 1);
-      } else {
-        return 0;
-      }
+      return (token && *token == '{') ? atol(token + 1) : 0;
     }
 
     class_info_gen(char const * token)
@@ -66,9 +78,10 @@ namespace logging { namespace {
       os << full_name(lp, "::");
     }
   };
-  
+
   struct location_info_gen : public format::generator_t {
     enum { method, line, file, classname, location } where;
+    // clang-format off
     constexpr static const decltype(where) format_codes[] = {
       ['F'] = file,
       ['M'] = method,
@@ -76,75 +89,60 @@ namespace logging { namespace {
       ['C'] = classname,
       ['l'] = location
     };
+    // clang-format on
 
     location_info_gen(char wh) : where(format_codes[wh]) {}
-    
+
     static void write(logpacket const & lp, std::ostream & os,
                       decltype(where) wh) {
       switch (wh) {
-        case file:
-          os << lp.info.filename;
-          break;
-        case line:
-          os << std::to_string(lp.info.line);
-          break;
-        case method:
-          os << lp.info.function;
-          break;
-        case classname:
-          class_info_gen(0).write(lp, os);
-          break;
-        case location:
-          write(lp, os, classname);
-          os << "::";
-          write(lp, os, method);
-          os << " (";
-          write(lp, os, file);
-          os << ", ";
-          write(lp, os, line);
-          os << ")";
+      case file:
+        os << lp.info.filename;
+        break;
+      case line:
+        os << std::to_string(lp.info.line);
+        break;
+      case method:
+        os << lp.info.function;
+        break;
+      case classname:
+        class_info_gen(0).write(lp, os);
+        break;
+      case location:
+        write(lp, os, classname);
+        os << "::";
+        write(lp, os, method);
+        os << " (";
+        write(lp, os, file);
+        os << ", ";
+        write(lp, os, line);
+        os << ")";
         break;
       }
     }
-    
+
     void write(logpacket const & lp, std::ostream & os) const override {
       write(lp, os, where);
     }
   };
 
-  struct message_gen : public format::generator_t {
-    void write(logpacket const & lp, std::ostream & os) const override {
-      os << lp.message.str();
-    }
-  };
-  
-  struct literal_gen : public format::generator_t {
-    literal_gen(std::string const & value) : value(value) {}
-
-    void write(logpacket const & lp, std::ostream & os) const override {
-      os << value;
-    }
-    std::string value;
-  };
-  
   struct bounds_gen : public format::generator_t {
+    format::generator impl;
+    bool is_left;
+    int min;
+    size_t max;
+
     bounds_gen(format::generator impl, bool is_left, int min, size_t max)
-    : impl(impl), is_left(is_left), min(min), max(max) {}
-    
+        : impl(impl), is_left(is_left), min(min), max(max) {}
+
     void write(logpacket const & lp, std::ostream & os) const override {
       auto align = is_left ? std::left : std::right;
       std::string str = impl->str(lp);
-      if (str.length() > max) {
-        str.erase(str.begin()+max, str.end());
-      }
+      if (str.length() > max) { str.erase(max); }
       os << align << std::setw(min) << str;
     }
-    format::generator impl;
-    bool is_left;
-    int min;
-    size_t max;
   };
-} }
+}}
 
 namespace logging {
   std::string format::generator_t::str(logpacket const & lp) const {
@@ -152,12 +150,10 @@ namespace logging {
     write(lp, ss);
     return ss.str();
   }
-  
-#define is( chr ) *next == chr
-#define is_string( str ) ! strncmp(next, str, strlen(str))
+
   format::generator date_token(char const * next);
 
-  format::generator handle( char const * & next ) {
+  format::generator format_factory::create_impl() {
     if (is('c')) {
       return std::make_shared<log_handle_gen>();
     } else if (is('p')) {
@@ -167,86 +163,77 @@ namespace logging {
     } else if (is('t')) {
       return std::make_shared<thread_name_gen>();
     } else {
-      std::string error_msg{"unknown format character: '"};
-      throw unknown_format_specifier{error_msg + *next + "'"};
+      throw unknown_format_specifier{
+          std::string("unknown format character: '") + *next_ + "'"};
     }
   }
-  
-  int eat(char const * & token) {
+
+  int eat(char const *& token) {
     size_t chars = 0;
     int rval = std::stoi(token, &chars);
     token += chars;
     return rval;
   }
-  
-  std::pair<int, size_t> get_bounds(char const * & next) {
-    int min = *next == '.' ? 0 : eat(next);
-    size_t max = *next == '.' ? eat(++next) : std::string::npos;
-    return std::make_pair(min, max);
-  }
-  
-  format::generator parse_with_bounds(char const * & next) {
-    bool const is_left = *next == '-';
-    if (is_left) ++next;
-    
-    auto bounds = get_bounds(next);
-    
-    bounds_gen gen{handle(next), is_left, bounds.first, bounds.second};
-    return std::make_shared<bounds_gen>(gen);
+
+  void format_factory::create_size_bounded() {
+    bool const is_left = is('-');
+    if (is_left) ++next_;
+
+    int const min = is('.') ? 0 : eat(next_);
+    size_t const max = is('.') ? eat(++next_) : std::string::npos;
+
+    append<bounds_gen>(create_impl(), is_left, min, max);
   }
-  
-  format format::parse_format_string( std::string const & fmt ) {
-    format out;
-    char const * curr = fmt.c_str();
-    char const * next = nullptr;
-    char const * const end = curr + fmt.size();
-    
-    while ((next = std::strchr(curr, '%')) != nullptr) {
-      ++next;
-      if (end == next) {
-        std::string error_msg{"expected format specifier, got end of string"};
-        throw format_parsing_exception{error_msg}; // TODO
+
+  format format_factory::create() {
+    while ((next_ = std::strchr(curr_, '%')) != nullptr) {
+      ++next_;
+      if (end_ == next_) {
+        throw format_parsing_exception{
+            "expected format specifier, got end of string"};
       }
-      
-      if (curr < next-1) {
-        std::string lit{curr, next - 1};
-        out.gen.push_back(std::make_shared<literal_gen>(lit));
+
+      if (curr_ < next_ - 1) {
+        append<literal_gen>(std::string(curr_, next_ - 1));
       }
 
       if (is('d')) {
-        ++next;
-        out.gen.push_back(date_token(next));
-        if (is('{')) next = std::strchr(next, '}');
+        ++next_;
+        create_date();
+        if (is('{')) next_ = std::strchr(next_, '}');
       } else if (is('n')) {
-        out.gen.push_back(std::make_shared<literal_gen>(NEWLINE_TOKEN));
+        append<literal_gen>(NEWLINE_TOKEN);
       } else if (is('%')) {
-        out.gen.push_back(std::make_shared<literal_gen>("%"));
-      } else if (is('.') || is('-') || isdigit( *next )) {
-        out.gen.push_back(parse_with_bounds(next));
+        append<literal_gen>("%");
+      } else if (is('.') || is('-') || isdigit(*next_)) {
+        create_size_bounded();
       } else if (is('C')) {
-        out.gen.push_back(std::make_shared<class_info_gen>(++next));
-        if (is('{')) next = std::strchr(next, '}');
+        append<class_info_gen>(++next_);
+        if (is('{')) next_ = std::strchr(next_, '}');
       } else if (is('F') || is('M') || is('L') || is('l')) {
-        out.gen.push_back(std::make_shared<location_info_gen>(*next));
+        append<location_info_gen>(*next_);
       } else if (is('r')) {
-        out.gen.push_back(std::make_shared<time_elapsed_gen>());
+        append<time_elapsed_gen>();
       } else {
-        out.gen.push_back(handle(next));
+        generators_.push_back(create_impl());
       }
-      curr = ++next;
+      curr_ = ++next_;
     }
-    if (curr < end) {
-      std::string lit{curr, end};
-      out.gen.push_back(std::make_shared<literal_gen>(lit));
-    }
-    return out;
+    if (curr_ < end_) { append<literal_gen>(std::string(curr_, end_)); }
+
+    return format(generators_);
   }
-#undef is
-  
+
+  format_factory::format_factory(std::string const & fmt)
+      : data_string_(fmt), curr_(data_string_.c_str()),
+        end_(curr_ + data_string_.size()) {}
+
   void format::process(logpacket const & pkt, std::ostream & os) const {
-    for (auto func : gen) { func->write(pkt, os); }
+    for (auto func : gen) {
+      func->write(pkt, os);
+    }
   }
-  
+
   std::string format::process(logpacket const & pkt) const {
     std::stringstream ss;
     process(pkt, ss);

+ 15 - 14
src/loggers/properties.cxx

@@ -31,10 +31,11 @@ namespace logging {
    * %n      := platform-specific line separator
    *
    */
-  
+
   extern properties const DEFAULT_APPENDER_SCHEMA;
   extern properties const DEFAULT_LOGGER_SCHEMA;
-  
+
+  // clang-format off
   properties const DEFAULT_APPENDER_SCHEMA{_obj({
     {"appenders", _obj({
       {"Console", _obj({
@@ -56,13 +57,13 @@ namespace logging {
       })}
     })}
   })};
-  
-  static properties mergeKey(std::string const & key,
-                             properties const & defVal,
+  // clang-format on
+
+  static properties mergeKey(std::string const & key, properties const & defVal,
                              properties const & other) {
     return other.contains(key) ? defVal.mergedWith(other[key]) : defVal;
   }
-  
+
   properties properties::mergedWith(properties const & other) const {
     if (data.is<object_t>()) {
       properties out = property::_obj({});
@@ -75,20 +76,20 @@ namespace logging {
       return other.data.valid() ? other : *this;
     }
   }
-  
+
   bool properties::contains(std::string const & key) const {
     return data.is<object_t>() && object().count(key);
   }
-  
+
   bool properties::contains(std::size_t idx) const {
     return data.is<array_t>() && array().size() > idx;
   }
-  
+
   object_t const & properties::object() const {
     expects(data.is<object_t>(), invalid_property_type, "expected OBJECT");
     return data.get<object_t>();
   }
-  
+
   array_t const & properties::array() const {
     expects(data.is<array_t>(), invalid_property_type, "expected ARRAY");
     return data.get<array_t>();
@@ -106,22 +107,22 @@ namespace logging {
             "Out of bounds: " + std::to_string(idx));
     return array().at(idx);
   }
-  
+
   properties::operator std::string const &() const {
     expects(data.is<std::string>(), invalid_property_type, "expected STRING");
     return data.get<std::string>();
   }
-  
+
   properties::operator int() const {
     expects(data.is<int>(), invalid_property_type, "expected INT");
     return data.get<int>();
   }
-  
+
   properties::operator bool() const {
     expects(data.is<bool>(), invalid_property_type, "expected BOOL");
     return data.get<bool>();
   }
-  
+
   std::string const & properties::str() const { return *this; }
 
 }

+ 5 - 7
src/message.cxx

@@ -17,19 +17,17 @@ namespace logging {
     if (next == std::string::npos) {
       return; // throw?
     } else if (!strncmp(interp.c_str() + next - 1, "{{}}", 4)) {
-      format_msg(os, interp, next+2, objs, idx);
+      format_msg(os, interp, next + 2, objs, idx);
     } else {
-      format_msg(os << objs[idx], interp, next+2, objs, idx+1);
+      format_msg(os << objs[idx], interp, next + 2, objs, idx + 1);
     }
   }
-  
+
   std::string message::str() const {
     std::stringstream ss;
     format_msg(ss, format_code, 0, objects, 0);
     return ss.str();
   }
-  
-  Json::Value message::json() const {
-    return objects[0].json();
-  }
+
+  Json::Value message::json() const { return objects[0].json(); }
 }

+ 4 - 4
test/c_logger_test.cxx

@@ -12,10 +12,10 @@
 using namespace logging;
 
 namespace {
-struct t_logger : public c_logger {
-  t_logger(std::string const & name, std::shared_ptr<logger_impl> impl)
-  : c_logger(name, impl) {}
-};
+  struct t_logger : public c_logger {
+    t_logger(std::string const & name, std::shared_ptr<logger_impl> impl)
+        : c_logger(name, impl) {}
+  };
 }
 
 using CLoggerTest = LoggerTest;

+ 5 - 9
test/common_test.cxx

@@ -9,8 +9,8 @@
 
 #include <gmock/gmock.h>
 
-#include "logger/exception.h"
 #include "../src/common.h"
+#include "logger/exception.h"
 
 using level_info = std::pair<logging::level, std::string>;
 struct SerializerTest : testing::TestWithParam<level_info> {};
@@ -46,14 +46,10 @@ TEST_P(SerializerTest, ToStringCanWriteBothCases) {
 }
 
 level_info pairs[] = {
-  {level::trace, "trace"},
-  {level::debug, "debug"},
-  {level::info, "info"},
-  {level::warning, "warning"},
-  {level::error, "error"},
-  {level::critical, "critical"},
-  {level::fatal, "fatal"},
-  {level::none, "none"},
+    {level::trace, "trace"}, {level::debug, "debug"},
+    {level::info, "info"},   {level::warning, "warning"},
+    {level::error, "error"}, {level::critical, "critical"},
+    {level::fatal, "fatal"}, {level::none, "none"},
 };
 INSTANTIATE_TEST_CASE_P(LogLevel, SerializerTest, testing::ValuesIn(pairs));
 

+ 12 - 20
test/console_appender_test.cxx

@@ -19,11 +19,11 @@ class ConsoleAppenderTest : public testing::Test {
 protected:
   void SetUp() override;
   void TearDown() override;
-  
+
   std::string cout() const { return cout_->str(); }
   std::string cerr() const { return cerr_->str(); }
-  std::shared_ptr<logging::log_appender>
-  get(logging::properties const &) const;
+  std::shared_ptr<logging::log_appender> get(logging::properties const &) const;
+
 private:
   std::shared_ptr<StubLayout> playout;
   std::unique_ptr<scoped_buffer_capture_t> cout_, cerr_;
@@ -49,10 +49,8 @@ ConsoleAppenderTest::get(logging::properties const & props) const {
 
 TEST_F(ConsoleAppenderTest, ErrorOnUnknownTarget) {
   using namespace logging::property;
-  logging::properties props{_obj({
-    {"target", _v("COUT")}
-  })};
-  
+  logging::properties props{_obj({{"target", _v("COUT")}})};
+
   EXPECT_THROW(logging::appenders::instance().get("Console", props),
                std::logic_error);
 }
@@ -60,10 +58,8 @@ TEST_F(ConsoleAppenderTest, ErrorOnUnknownTarget) {
 TEST_F(ConsoleAppenderTest, LogsToStdOut) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"target", _v("SYSTEM_OUT")}
-  })};
-  
+  properties props{_obj({{"target", _v("SYSTEM_OUT")}})};
+
   using testing::Eq;
   using testing::IsEmpty;
   logpacket pkt{{}, level::error, {}, {}, "This is a test message"};
@@ -75,10 +71,8 @@ TEST_F(ConsoleAppenderTest, LogsToStdOut) {
 TEST_F(ConsoleAppenderTest, WillNotLogBelowThreshold) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"target", _v("SYSTEM_OUT")}
-  })};
-  
+  properties props{_obj({{"target", _v("SYSTEM_OUT")}})};
+
   EXPECT_FALSE(get(props)->should_log(level::warn));
   EXPECT_TRUE(get(props)->should_log(level::error));
 }
@@ -86,11 +80,9 @@ TEST_F(ConsoleAppenderTest, WillNotLogBelowThreshold) {
 TEST_F(ConsoleAppenderTest, LogsToStdErr) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"target", _v("SYSTEM_ERR")},
-    {"threshold", _v("FATAL")}
-  })};
-  
+  properties props{
+      _obj({{"target", _v("SYSTEM_ERR")}, {"threshold", _v("FATAL")}})};
+
   using testing::Eq;
   using testing::IsEmpty;
   logpacket pkt{{}, level::error, {}, {}, "This is a test message"};

+ 19 - 30
test/file_appender_test.cxx

@@ -21,10 +21,10 @@ class FileAppenderTest : public testing::Test {
 protected:
   void SetUp() override;
   void TearDown() override;
-  
+
   std::string filename() const { return data; }
-  std::shared_ptr<logging::log_appender>
-  get(logging::properties const &) const;
+  std::shared_ptr<logging::log_appender> get(logging::properties const &) const;
+
 private:
   std::shared_ptr<StubLayout> playout;
   char data[24];
@@ -68,10 +68,8 @@ std::string slurp(std::string const & filename) {
 TEST_F(FileAppenderTest, WritesFile) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"filename", _v(filename())}
-  })};
-  
+  properties props{_obj({{"filename", _v(filename())}})};
+
   using testing::Eq;
   logpacket pkt{{}, level::error, {}, {}, "This is a test message"};
   EXPECT_NO_THROW(get(props)->write(pkt));
@@ -81,10 +79,8 @@ TEST_F(FileAppenderTest, WritesFile) {
 TEST_F(FileAppenderTest, WillNotLogBelowThreshold) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"filename", _v(filename())}
-  })};
-  
+  properties props{_obj({{"filename", _v(filename())}})};
+
   EXPECT_FALSE(get(props)->should_log(level::warn));
   EXPECT_TRUE(get(props)->should_log(level::error));
 }
@@ -92,10 +88,8 @@ TEST_F(FileAppenderTest, WillNotLogBelowThreshold) {
 TEST_F(FileAppenderTest, AppendsToFile) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"filename", _v(filename())}
-  })};
-  
+  properties props{_obj({{"filename", _v(filename())}})};
+
   using testing::Eq;
   logpacket pkt{{}, level::error, {}, {}, "Test"};
   for (int i = 0; i < 2; ++i) {
@@ -107,11 +101,9 @@ TEST_F(FileAppenderTest, AppendsToFile) {
 TEST_F(FileAppenderTest, OverwritesFileWithSetting) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"filename", _v(filename())},
-    {"fileAppend", _v(false)}
-  })};
-  
+  properties props{
+      _obj({{"filename", _v(filename())}, {"fileAppend", _v(false)}})};
+
   using testing::Eq;
   logpacket pkt{{}, level::error, {}, {}, "Test"};
   for (int i = 0; i < 2; ++i) {
@@ -123,13 +115,11 @@ TEST_F(FileAppenderTest, OverwritesFileWithSetting) {
 TEST_F(FileAppenderTest, CanWriteBufferedData) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"immediateFlush", _v(false)},
-    {"filename", _v(filename())},
-    {"bufferedIO", _v(true)},
-    {"bufferSize", _v(256)}
-  })};
-  
+  properties props{_obj({{"immediateFlush", _v(false)},
+                         {"filename", _v(filename())},
+                         {"bufferedIO", _v(true)},
+                         {"bufferSize", _v(256)}})};
+
   using testing::Eq;
   logpacket pkt{{}, level::error, {}, {}, "Test"};
   EXPECT_NO_THROW(get(props)->write(pkt));
@@ -140,8 +130,7 @@ TEST_F(FileAppenderTest, CanWriteBufferedData) {
 TEST_F(FileAppenderTest, WillThrowIfCannotOpenFile) {
   using namespace logging;
   using namespace logging::property;
-  properties props{_obj({
-    {"filename", _v("./fake_directory_for_testing/file.log")}
-  })};
+  properties props{
+      _obj({{"filename", _v("./fake_directory_for_testing/file.log")}})};
   EXPECT_THROW(get(props), std::runtime_error);
 }

+ 3 - 3
test/header_test_obj.h

@@ -16,17 +16,17 @@ class HeaderFooterTest : public testing::Test {
 protected:
   void SetUp() override {
     appender = std::make_shared<StubAppender>();
-    auto GetStub = [this](logging::properties const &) {
-      return appender;
-    };
+    auto GetStub = [this](logging::properties const &) { return appender; };
     abinding_ = logging::appenders::instance().bind_scoped("Stub", GetStub);
   }
   void TearDown() override {
     abinding_.reset();
     appender.reset();
   }
+
 protected:
   std::shared_ptr<StubAppender> appender;
+
 private:
   logging::appenders::scoped_binding abinding_;
 };

+ 61 - 55
test/json_layout_test.cxx

@@ -36,31 +36,36 @@ std::string const formatted_output = R"({
 TEST(JsonLayoutTest, LogsInformationInJSON) {
   using namespace logging;
   auto playout = layouts::instance().get("JsonLayout", {});
-  
+
   std::stringstream ss;
-  playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
-    "This is a test message"});
-  
+  playout->format(ss, {{NOW, 123456},
+                       level::warning,
+                       {},
+                       "UnitTest",
+                       "This is a test message"});
+
   using testing::Eq;
   EXPECT_THAT(ss.str(), Eq(formatted_output));
 }
 
-std::string const compact_output = "{\"instant\":{\"epochSecond\":"
-  "1554401840,\"nanoOfSecond\":123456000},\"level\":\"WARNING\","
-  "\"loggerName\":\"UnitTest\",\"message\":\"This is a test message\"}";
+std::string const compact_output =
+    "{\"instant\":{\"epochSecond\":"
+    "1554401840,\"nanoOfSecond\":123456000},\"level\":\"WARNING\","
+    "\"loggerName\":\"UnitTest\",\"message\":\"This is a test message\"}";
 
 TEST(JsonLayoutTest, CompactMeansNoWhitespace) {
   using namespace logging;
   using namespace logging::property;
-  properties const props{_obj({
-    {"compact", _v(true)}
-  })};
+  properties const props{_obj({{"compact", _v(true)}})};
   auto playout = layouts::instance().get("JsonLayout", props);
-  
+
   std::stringstream ss;
-  playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
-    "This is a test message"});
-  
+  playout->format(ss, {{NOW, 123456},
+                       level::warning,
+                       {},
+                       "UnitTest",
+                       "This is a test message"});
+
   using testing::Eq;
   EXPECT_THAT(ss.str(), Eq(compact_output));
 }
@@ -75,7 +80,7 @@ std::string const location_output = R"({
   "message" : "This is a test message",
   "source" : {
     "file" : "json_layout_test.cxx",
-    "line" : 92,
+    "line" : 97,
     "method" : "TestBody"
   }
 })";
@@ -83,15 +88,16 @@ std::string const location_output = R"({
 TEST(JsonLayoutTest, ShowsLocationInfo) {
   using namespace logging;
   using namespace logging::property;
-  properties const props{_obj({
-    {"locationInfo", _v(true)}
-  })};
+  properties const props{_obj({{"locationInfo", _v(true)}})};
   auto playout = layouts::instance().get("JsonLayout", props);
 
   std::stringstream ss;
-  playout->format(ss, {{NOW, 123456}, level::warning, log_here, "UnitTest",
-    "This is a test message"});
-  
+  playout->format(ss, {{NOW, 123456},
+                       level::warning,
+                       log_here,
+                       "UnitTest",
+                       "This is a test message"});
+
   using testing::Eq;
   EXPECT_THAT(ss.str(), Eq(location_output));
 }
@@ -99,15 +105,16 @@ TEST(JsonLayoutTest, ShowsLocationInfo) {
 TEST(JsonLayoutTest, EOLPropertyAppendsNewline) {
   using namespace logging;
   using namespace logging::property;
-  properties const props{_obj({
-    {"eventEol", _v(true)}
-  })};
+  properties const props{_obj({{"eventEol", _v(true)}})};
   auto playout = layouts::instance().get("JsonLayout", props);
-  
+
   std::stringstream ss;
-  playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
-    "This is a test message"});
-  
+  playout->format(ss, {{NOW, 123456},
+                       level::warning,
+                       {},
+                       "UnitTest",
+                       "This is a test message"});
+
   using testing::EndsWith;
   using testing::StartsWith;
   EXPECT_THAT(ss.str(), StartsWith(formatted_output));
@@ -158,16 +165,17 @@ Json::Value to_json(json_example const & ex) {
 TEST(JsonLayoutTest, MessageCanBeLoggedAsJSON) {
   using namespace logging;
   using namespace logging::property;
-  properties const props{_obj({
-    {"objectMessageAsJsonObject", _v(true)}
-  })};
+  properties const props{_obj({{"objectMessageAsJsonObject", _v(true)}})};
   auto playout = layouts::instance().get("JsonLayout", props);
-  
+
   std::stringstream ss;
   json_example ex{225};
-  playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
-    {"This is a test message", ex}});
-  
+  playout->format(ss, {{NOW, 123456},
+                       level::warning,
+                       {},
+                       "UnitTest",
+                       {"This is a test message", ex}});
+
   using testing::Eq;
   EXPECT_THAT(ss.str(), Eq(struct_json_output));
 }
@@ -175,16 +183,17 @@ TEST(JsonLayoutTest, MessageCanBeLoggedAsJSON) {
 TEST(JsonLayoutTest, ObjectLackingJsonDefaultsToString) {
   using namespace logging;
   using namespace logging::property;
-  properties const props{_obj({
-    {"objectMessageAsJsonObject", _v(true)}
-  })};
+  properties const props{_obj({{"objectMessageAsJsonObject", _v(true)}})};
   auto playout = layouts::instance().get("JsonLayout", props);
-  
+
   std::stringstream ss;
   example ex{225};
-  playout->format(ss, {{NOW, 123456}, level::warning, {}, "UnitTest",
-    {"This is a test message", ex}});
-  
+  playout->format(ss, {{NOW, 123456},
+                       level::warning,
+                       {},
+                       "UnitTest",
+                       {"This is a test message", ex}});
+
   using testing::Eq;
   EXPECT_THAT(ss.str(), Eq(struct_output));
 }
@@ -194,6 +203,7 @@ TEST(JsonLayoutTest, ObjectLackingJsonDefaultsToString) {
 
 using namespace logging;
 using namespace logging::property;
+// clang-format off
 properties const JSON_HEADER_SCHEMA{_obj({
   {"configuration", _obj({
     {"appenders", _obj({
@@ -210,6 +220,7 @@ properties const JSON_HEADER_SCHEMA{_obj({
     })}
   })}
 })};
+// clang-format on
 
 using JsonLayoutHeaderTest = HeaderFooterTest;
 
@@ -235,19 +246,14 @@ TEST_F(JsonLayoutHeaderTest, SeparatesLogsWithComma) {
   // So the dividing comma gets attached to the next log
   EXPECT_THAT(appender->sstream.str(), StartsWith(",{"));
 }
-  
+
 struct JsonLayoutIncompleteTest : public JsonLayoutHeaderTest {
-  properties OVERRIDE{_obj({
-    {"configuration", _obj({
-      {"appenders", _obj({
-        {"Stub", _obj({
-          {"JsonLayout", _obj({
-            {"complete", _v(false)}
-          })}
-        })}
-      })}
-    })}
-  })};
+  properties OVERRIDE{
+      _obj({{"configuration",
+             _obj({{"appenders",
+                    _obj({{"Stub",
+                           _obj({{"JsonLayout",
+                                  _obj({{"complete", _v(false)}})}})}})}})}})};
 };
 
 TEST_F(JsonLayoutIncompleteTest, NoLogsMeansNoOutput) {
@@ -258,7 +264,7 @@ TEST_F(JsonLayoutIncompleteTest, NoLogsMeansNoOutput) {
   using testing::Eq;
   EXPECT_THAT(appender->sstream.str(), Eq(""));
 }
-  
+
 TEST_F(JsonLayoutIncompleteTest, NonCompleteLogProducesJsonPerLine) {
   using testing::EndsWith;
   using testing::StartsWith;

+ 10 - 7
test/log_manager_test.cxx

@@ -22,9 +22,11 @@ class LogManagerTest : public ::testing::Test {
 public:
   void SetUp() override;
   void TearDown() override;
+
 protected:
   std::shared_ptr<MockAppender> appender;
   std::shared_ptr<MockLayout> layout;
+
 private:
   appenders::scoped_binding abinding_;
   layouts::scoped_binding lbinding_;
@@ -60,7 +62,6 @@ extern properties const LOGGER_LEVEL_PROPERTY_SCHEMA;
 extern properties const MIN_PROPERTY_SCHEMA;
 extern properties const MULTIPLEX_PROPERTY_SCHEMA;
 
-
 TEST_F(LogManagerTest, CanInjectMock) {
   manager().configure(MIN_PROPERTY_SCHEMA);
   EXPECT_THAT(appender, ::testing::NotNull());
@@ -75,6 +76,7 @@ TEST_F(LogManagerTest, IfNoLayoutIsProvidedThenWeUseTheDefault) {
 
 TEST_F(LogManagerTest, WillThrowIfSchemaError) {
   using namespace logging::property;
+  // clang-format off
   properties const BAD_SCHEMA = _obj({
     {"configuration", _obj({
       {"loggers", _obj({
@@ -85,6 +87,7 @@ TEST_F(LogManagerTest, WillThrowIfSchemaError) {
       {"appenders", _obj({})}
     })}
   });
+  // clang-format on
   EXPECT_THROW(manager().configure(BAD_SCHEMA), invalid_property_type);
 }
 
@@ -94,7 +97,7 @@ using ::testing::AnyNumber;
 TEST_F(LogManagerTest, CanFetchInjectedMock) {
   manager mgr;
   mgr.configure(MIN_PROPERTY_SCHEMA);
-  
+
   EXPECT_CALL(*appender, flush()).Times(AnyNumber());
   EXPECT_CALL(*appender, write(MessageEq("TEST MESSAGE"), _));
 
@@ -105,7 +108,7 @@ TEST_F(LogManagerTest, CanFetchInjectedMock) {
 TEST_F(LogManagerTest, MultiplexMockLogsToMultipleImpls) {
   manager mgr;
   mgr.configure(MULTIPLEX_PROPERTY_SCHEMA);
-  
+
   EXPECT_CALL(*appender, flush()).Times(AnyNumber());
   EXPECT_CALL(*appender, write(MessageEq("TEST MESSAGE"), _)).Times(2);
 
@@ -116,11 +119,11 @@ TEST_F(LogManagerTest, MultiplexMockLogsToMultipleImpls) {
 TEST_F(LogManagerTest, LevelCanBeBakedIntoAppenderProperties) {
   manager mgr;
   mgr.configure(APPENDER_LEVEL_PROPERTY_SCHEMA);
-  
+
   EXPECT_CALL(*appender, flush()).Times(AnyNumber());
   EXPECT_CALL(*appender, write(MessageEq("TEST MESSAGE"), _)).Times(1);
   EXPECT_CALL(*appender, write(MessageEq("LOWER MESSAGE"), _)).Times(0);
-  
+
   c_logger l = mgr.c_get();
   l.warn("TEST MESSAGE");
   l.info("LOWER MESSAGE");
@@ -129,10 +132,10 @@ TEST_F(LogManagerTest, LevelCanBeBakedIntoAppenderProperties) {
 TEST_F(LogManagerTest, LevelCanBeBakedIntoLoggerProperties) {
   manager mgr;
   mgr.configure(LOGGER_LEVEL_PROPERTY_SCHEMA);
-  
+
   EXPECT_CALL(*appender, flush()).Times(AnyNumber());
   EXPECT_CALL(*appender, write(_, _)).Times(0);
-  
+
   c_logger l = mgr.c_get();
   l.warn("TEST MESSAGE");
 }

+ 6 - 6
test/logger_test.cxx

@@ -12,10 +12,10 @@
 using namespace logging;
 
 namespace {
-struct t_logger : public logger {
-  t_logger(std::string const & name, std::shared_ptr<logger_impl> impl)
-  : logger(name, impl) {}
-};
+  struct t_logger : public logger {
+    t_logger(std::string const & name, std::shared_ptr<logger_impl> impl)
+        : logger(name, impl) {}
+  };
 }
 
 TEST_F(LoggerTest, FlushesOnClose) {
@@ -49,8 +49,8 @@ TEST_F(LoggerTest, LogCurlyBraceLiteralByDoubling) {
 
 MATCHER_P3(LocationInfoNear, file, line, function, "") {
   return !strcmp(arg.info.filename, file) &&
-      !strcmp(arg.info.function, function) &&
-      std::abs(arg.info.line - line) < 5;
+         !strcmp(arg.info.function, function) &&
+         std::abs(arg.info.line - line) < 5;
 }
 
 TEST_F(LoggerTest, LogMacroInjectsLocationInfo) {

+ 3 - 3
test/logger_test_obj.h

@@ -19,10 +19,10 @@ struct LoggerTest : public testing::Test {
     auto layout = std::make_shared<StubLayout>();
     auto log = std::make_shared<logging::log_appender>(appender, layout);
     pimpl->impls.push_back(log);
-    
+
     using testing::_;
     using testing::AnyNumber;
-    
+
     EXPECT_CALL(*appender, write(_, _)).Times(AnyNumber());
     EXPECT_CALL(*appender, flush()).Times(AnyNumber());
   }
@@ -30,7 +30,7 @@ struct LoggerTest : public testing::Test {
     pimpl.reset();
     appender.reset();
   }
-  
+
   std::shared_ptr<MockAppender> appender;
   std::shared_ptr<logging::logger_impl> pimpl;
 };

+ 10 - 16
test/mock_logger.h

@@ -19,13 +19,13 @@
 namespace logging {
   inline void PrintTo(location_info const & info, std::ostream * os) {
     if (info.line) {
-      (*os) << "{\"" << info.filename << "\", \"" <<
-      info.function << "\", " << info.line << "}";
+      (*os) << "{\"" << info.filename << "\", \"" << info.function << "\", "
+            << info.line << "}";
     } else {
       (*os) << "NULL";
     }
   }
-  
+
   inline void PrintTo(logpacket const & pkt, std::ostream * os) {
     (*os) << "{ " << pkt.level << ", ";
     PrintTo(pkt.info, os);
@@ -34,41 +34,35 @@ namespace logging {
 }
 
 struct StubAppender : public logging::appender {
-  StubAppender() : threshold(logging::level::trace) { }
+  StubAppender() : threshold(logging::level::trace) {}
   std::ostream & stream() override { return sstream; }
   void flush() override {}
   void write(logging::logpacket const & pkt, logging::layout & lay) override {
     lay.format(sstream, pkt);
   }
-  bool should_log(logging::level ll) const override {
-    return ll >= threshold;
-  }
+  bool should_log(logging::level ll) const override { return ll >= threshold; }
   logging::level threshold;
   std::stringstream sstream;
 };
 
 struct MockAppender : public StubAppender {
-  MockAppender() { }
+  MockAppender() {}
   MOCK_METHOD0(flush, void());
   MOCK_METHOD2(write, void(logging::logpacket const &, logging::layout &));
 };
 
 struct MockLayout : public logging::layout {
-  MOCK_CONST_METHOD2(format, void(std::ostream&, logging::logpacket const&));
+  MOCK_CONST_METHOD2(format, void(std::ostream &, logging::logpacket const &));
 };
 
 struct StubLayout : public logging::layout {
-  void format(std::ostream& os, logging::logpacket const& pkt) const {
+  void format(std::ostream & os, logging::logpacket const & pkt) const {
     os << pkt.message.str();
   }
 };
 
-ACTION(LogMessage) {
-  arg0 << arg1.message.str();
-}
+ACTION(LogMessage) { arg0 << arg1.message.str(); }
 
-MATCHER_P(MessageEq, value, "") {
-  return arg.message.str() == value;
-}
+MATCHER_P(MessageEq, value, "") { return arg.message.str() == value; }
 
 #endif /* mock_logger_h */

+ 2 - 0
test/mock_properties.cxx

@@ -16,6 +16,7 @@ extern properties const LOGGER_LEVEL_PROPERTY_SCHEMA;
 extern properties const MIN_PROPERTY_SCHEMA;
 extern properties const MULTIPLEX_PROPERTY_SCHEMA;
 
+// clang-format off
 properties const MIN_PROPERTY_SCHEMA{_obj({
   {"configuration", _obj({
     {"appenders", _obj({
@@ -102,3 +103,4 @@ properties const MULTIPLEX_PROPERTY_SCHEMA{_obj({
     })}
   })}
 })};
+// clang-format on

+ 41 - 74
test/pattern_layout_test.cxx

@@ -23,16 +23,14 @@ namespace {
   constexpr const int NOW = 1554401840;
 }
 
-std::shared_ptr<logging::layout>
-GetPatternLayout(std::string const & fmt) {
+std::shared_ptr<logging::layout> GetPatternLayout(std::string const & fmt) {
   using namespace logging;
   using namespace logging::property;
   properties props{_obj({{"pattern", _v(fmt)}})};
   return layouts::instance().get("PatternLayout", props);
 }
 
-std::string DoFormat(std::string const & fmt,
-                     logging::logpacket const & pkt) {
+std::string DoFormat(std::string const & fmt, logging::logpacket const & pkt) {
   std::stringstream ss;
   GetPatternLayout(fmt)->format(ss, pkt);
   return ss.str();
@@ -49,8 +47,7 @@ TEST(PatternLayoutTest, EmptyFormatterCanParse) {
 }
 
 TEST(PatternLayoutTest, ThrowsForEndOfStringAfterPct) {
-  EXPECT_THROW(GetPatternLayout("%"),
-               logging::format_parsing_exception);
+  EXPECT_THROW(GetPatternLayout("%"), logging::format_parsing_exception);
 }
 
 TEST(PatternLayoutTest, RawStringFmtReturnsSelf) {
@@ -80,30 +77,27 @@ TEST(PatternLayoutTest, CatchesRawContentAfterFmt) {
 
 TEST(PatternLayoutTest, HandlesDateFormatter) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d", {{NOW,0}}),
-              Eq("2019-04-04 18:17:20,000"));
+  EXPECT_THAT(DoFormat("%d", {{NOW, 0}}), Eq("2019-04-04 18:17:20,000"));
 }
 
 TEST(PatternLayoutTest, FormatsMilliseconds) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d", {{NOW,123000}}),
-              Eq("2019-04-04 18:17:20,123"));
+  EXPECT_THAT(DoFormat("%d", {{NOW, 123000}}), Eq("2019-04-04 18:17:20,123"));
 }
 
 TEST(PatternLayoutTest, ThrowsIfCustomFmtUnterminated) {
   using testing::Eq;
-  EXPECT_THROW(GetPatternLayout("%d{%"),
-               logging::format_parsing_exception);
+  EXPECT_THROW(GetPatternLayout("%d{%"), logging::format_parsing_exception);
 }
 
 TEST(PatternLayoutTest, SupportsCustomFormatWithBrace) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d{%Y}", {{NOW,0}}), Eq("2019"));
+  EXPECT_THAT(DoFormat("%d{%Y}", {{NOW, 0}}), Eq("2019"));
 }
 
 TEST(PatternLayoutTest, FormatsCustomMilliseconds) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d{%_ms}", {{NOW,123000}}), Eq("123"));
+  EXPECT_THAT(DoFormat("%d{%_ms}", {{NOW, 123000}}), Eq("123"));
 }
 
 MATCHER(IsTimeZoneOffsetLike, "") {
@@ -117,48 +111,41 @@ MATCHER(IsTimeZoneOffsetLike, "") {
 }
 
 TEST(PatternLayoutTest, FormatsTimeZone) {
-  EXPECT_THAT(DoFormat("%d{%z}", {{NOW,0}}), IsTimeZoneOffsetLike());
+  EXPECT_THAT(DoFormat("%d{%z}", {{NOW, 0}}), IsTimeZoneOffsetLike());
 }
 
 TEST(PatternLayoutTest, SupportsISO8601Format) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d{ISO8601}", {{NOW,0}}),
+  EXPECT_THAT(DoFormat("%d{ISO8601}", {{NOW, 0}}),
               Eq("2019-04-04T18:17:20.000Z"));
 }
 
 TEST(PatternLayoutTest, SupportsSingleDayFormat) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d{ABSOLUTE}", {{NOW,0}}),
-              Eq("18:17:20,000"));
+  EXPECT_THAT(DoFormat("%d{ABSOLUTE}", {{NOW, 0}}), Eq("18:17:20,000"));
 }
 
 TEST(PatternLayoutTest, SupportsHumanDateFormat) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%d{DATE}", {{NOW,0}}),
-              Eq("04 Apr 2019 18:17:20,000"));
+  EXPECT_THAT(DoFormat("%d{DATE}", {{NOW, 0}}), Eq("04 Apr 2019 18:17:20,000"));
 }
 
 TEST(PatternLayoutTest, LoggerIdIsCToken) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%c", getpkt("HELLO")),
-              Eq("UNIT_TEST"));
+  EXPECT_THAT(DoFormat("%c", getpkt("HELLO")), Eq("UNIT_TEST"));
 }
 
 TEST(PatternLayoutTest, LogLevelIsPToken) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%p", getpkt("HELLO")),
-              Eq("ERROR"));
+  EXPECT_THAT(DoFormat("%p", getpkt("HELLO")), Eq("ERROR"));
 }
 
 TEST(PatternLayoutTest, LogMessageIsMToken) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%m", getpkt("HELLO")),
-              Eq("HELLO"));
+  EXPECT_THAT(DoFormat("%m", getpkt("HELLO")), Eq("HELLO"));
 }
 
-MATCHER_P2(Near, value, error, "") {
-  return std::abs(arg - value) < error;
-}
+MATCHER_P2(Near, value, error, "") { return std::abs(arg - value) < error; }
 
 TEST(PatternLayoutTest, CanOutputTimeSinceCreation) {
   // Because we're passing in a timestamp of {0, 0} with getpkt(), %r should
@@ -171,22 +158,19 @@ TEST(PatternLayoutTest, CanOutputTimeSinceCreation) {
 
 TEST(PatternLayoutTest, CanOutputLineNumber) {
   EXPECT_THAT(std::stoi(DoFormat("%L", getpkt("", log_here))),
-             testing::Eq(__LINE__ - 1));
+              testing::Eq(__LINE__ - 1));
 }
 
 TEST(PatternLayoutTest, CanOutputFileName) {
   EXPECT_THAT(DoFormat("%F", getpkt("", log_here)),
-             testing::EndsWith("pattern_layout_test.cxx"));
+              testing::EndsWith("pattern_layout_test.cxx"));
 }
 
 TEST(PatternLayoutTest, CanOutputCallingMethod) {
-  EXPECT_THAT(DoFormat("%M", getpkt("", log_here)),
-             testing::Eq("TestBody"));
+  EXPECT_THAT(DoFormat("%M", getpkt("", log_here)), testing::Eq("TestBody"));
 }
 
-logging::logpacket packet() {
-  return getpkt("", log_here);
-}
+logging::logpacket packet() { return getpkt("", log_here); }
 struct stub {
   std::map<int, int> rval;
   std::map<int, int> operator()(logging::logpacket & out) {
@@ -197,30 +181,20 @@ struct stub {
     out = getpkt("", log_here);
     return rval;
   }
-  logging::logpacket operator()() {
-    return getpkt("", log_here);
-  }
-  static logging::logpacket packet() {
-    return getpkt("", log_here);
-  }
+  logging::logpacket operator()() { return getpkt("", log_here); }
+  static logging::logpacket packet() { return getpkt("", log_here); }
 };
 namespace ns {
-  logging::logpacket packet() {
-    return getpkt("", log_here);
-  }
+  logging::logpacket packet() { return getpkt("", log_here); }
   struct stub {
-    logging::logpacket operator()() {
-      return getpkt("", log_here);
-    }
-    static logging::logpacket packet() {
-      return getpkt("", log_here);
-    }
+    logging::logpacket operator()() { return getpkt("", log_here); }
+    static logging::logpacket packet() { return getpkt("", log_here); }
   };
 }
 
 TEST(PatternLayoutTest, CanOutputClassName) {
   EXPECT_THAT(DoFormat("%C", getpkt("", log_here)),
-             testing::Eq("PatternLayoutTest_CanOutputClassName_Test"));
+              testing::Eq("PatternLayoutTest_CanOutputClassName_Test"));
 }
 
 TEST(PatternLayoutTest, GlobalNamespaceClassIsEmptyString) {
@@ -238,14 +212,14 @@ TEST(PatternLayoutTest, StaticMethodClassIsClass) {
 TEST(PatternLayoutTest, NCMethodReturningComplexTypeReturnsCorrectClass) {
   logging::logpacket pkt;
   stub st{};
-  (void) st(pkt);
+  (void)st(pkt);
   EXPECT_THAT(DoFormat("%C", pkt), testing::Eq("stub"));
 }
 
 TEST(PatternLayoutTest, ConstMethodReturningComplexTypeReturnsCorrectClass) {
   logging::logpacket pkt;
   stub const st{};
-  (void) st(pkt);
+  (void)st(pkt);
   EXPECT_THAT(DoFormat("%C", pkt), testing::Eq("stub"));
 }
 
@@ -256,7 +230,8 @@ TEST(PatternLayoutTest, CanLimitClassToNTokens) {
 
 TEST(PatternLayoutTest, CanOutputLocation) {
   auto message = DoFormat("%l", getpkt("", log_here));
-  std::string regex = "PatternLayoutTest_CanOutputLocation_Test::TestBody ..*pattern_layout_test.cxx, [1-9][0-9]*.";
+  std::string regex = "PatternLayoutTest_CanOutputLocation_Test::TestBody "
+                      "..*pattern_layout_test.cxx, [1-9][0-9]*.";
   EXPECT_THAT(message, testing::MatchesRegex(regex));
 }
 
@@ -277,47 +252,37 @@ TEST(PatternLayoutTest, OutputsThreadNameIfAvailable) {
 TEST(PatternLayoutTest, ThreadNameIsThreadLocalStorage) {
   using testing::Ne;
   ::logging::detail::thread_info_helper::set_name("main");
-  std::thread tr([](){
-    EXPECT_THAT(DoFormat("%t", getpkt("")), Ne("main"));
-  });
+  std::thread tr([]() { EXPECT_THAT(DoFormat("%t", getpkt("")), Ne("main")); });
   tr.join();
   ::logging::detail::thread_info_helper::set_name("");
 }
 
 TEST(PatternLayoutTest, ThrowsOnUnknownToken) {
   using testing::Eq;
-  EXPECT_THROW(GetPatternLayout("%q"),
-               logging::unknown_format_specifier);
+  EXPECT_THROW(GetPatternLayout("%q"), logging::unknown_format_specifier);
 }
 
 TEST(PatternLayoutTest, TokenCanBeTruncatedInFormat) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%.3m", getpkt("HELLO")),
-              Eq("HEL"));
-  EXPECT_THAT(DoFormat("%.5c", getpkt("HELLO")),
-              Eq("UNIT_"));
-  EXPECT_THAT(DoFormat("%.2t", getpkt("HELLO")),
-              Eq("0x"));
+  EXPECT_THAT(DoFormat("%.3m", getpkt("HELLO")), Eq("HEL"));
+  EXPECT_THAT(DoFormat("%.5c", getpkt("HELLO")), Eq("UNIT_"));
+  EXPECT_THAT(DoFormat("%.2t", getpkt("HELLO")), Eq("0x"));
 }
 
 TEST(PatternLayoutTest, TokenCanBeLeftPadded) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%6m", getpkt("HELLO")),
-              Eq(" HELLO"));
+  EXPECT_THAT(DoFormat("%6m", getpkt("HELLO")), Eq(" HELLO"));
 }
 
 TEST(PatternLayoutTest, TokenCanBeRightPadded) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%-6m", getpkt("HELLO")),
-              Eq("HELLO "));
+  EXPECT_THAT(DoFormat("%-6m", getpkt("HELLO")), Eq("HELLO "));
 }
 
 TEST(PatternLayoutTest, TokenCanBeSizeBound) {
   using testing::Eq;
-  EXPECT_THAT(DoFormat("%6.8m", getpkt("HELLO")),
-              Eq(" HELLO"));
-  EXPECT_THAT(DoFormat("%6.8m", getpkt("HELLO FRIEND")),
-              Eq("HELLO FR"));
+  EXPECT_THAT(DoFormat("%6.8m", getpkt("HELLO")), Eq(" HELLO"));
+  EXPECT_THAT(DoFormat("%6.8m", getpkt("HELLO FRIEND")), Eq("HELLO FR"));
 }
 
 #include "header_test_obj.h"
@@ -325,6 +290,7 @@ TEST(PatternLayoutTest, TokenCanBeSizeBound) {
 
 using namespace logging;
 using namespace logging::property;
+// clang-format off
 properties const PATTERN_HEADER_SCHEMA{_obj({
   {"configuration", _obj({
     {"appenders", _obj({
@@ -341,6 +307,7 @@ properties const PATTERN_HEADER_SCHEMA{_obj({
     })}
   })}
 })};
+// clang-format on
 
 using PatternLayoutHeaderTest = HeaderFooterTest;
 

+ 49 - 74
test/properties_test.cxx

@@ -13,67 +13,60 @@
 
 namespace logging {
   void indent(int i, std::ostream * os) {
-    while (i-->0) {
+    while (i-- > 0) {
       (*os) << ' ' << ' ';
     }
   }
   void PrintTo(properties const & props, std::ostream * os, int level = 1) {
     switch (props.data.index()) {
-      case 0:
-        (*os) << '{' << '\n';
-        for (auto & [k, v] : props.object()) {
-          indent(level + 1, os);
-          (*os) << k << ':' << ' ';
-          PrintTo(v, os, level + 1);
-        }
-        (*os) << '\n';
-        indent(level, os);
-        (*os) << '}' << '\n';
-        break;
-      case 1:
-        (*os) << '[' << '\n';
-        for (auto & v : props.array()) {
-          indent(level + 1, os);
-          PrintTo(v, os, level + 1);
-        }
-        (*os) << '\n';
-        indent(level, os);
-        (*os) << ']' << '\n';
-        break;
-      case 2:
-        (*os) << props.str();
-        break;
-      case 3:
-        (*os) << int(props);
-        break;
-      case 4:
-        (*os) << std::boolalpha << bool(props);
-        break;
-      default:
-        (*os) << "null";
-        break;
+    case 0:
+      (*os) << '{' << '\n';
+      for (auto & [k, v] : props.object()) {
+        indent(level + 1, os);
+        (*os) << k << ':' << ' ';
+        PrintTo(v, os, level + 1);
+      }
+      (*os) << '\n';
+      indent(level, os);
+      (*os) << '}' << '\n';
+      break;
+    case 1:
+      (*os) << '[' << '\n';
+      for (auto & v : props.array()) {
+        indent(level + 1, os);
+        PrintTo(v, os, level + 1);
+      }
+      (*os) << '\n';
+      indent(level, os);
+      (*os) << ']' << '\n';
+      break;
+    case 2:
+      (*os) << props.str();
+      break;
+    case 3:
+      (*os) << int(props);
+      break;
+    case 4:
+      (*os) << std::boolalpha << bool(props);
+      break;
+    default:
+      (*os) << "null";
+      break;
     }
   }
 }
 
-MATCHER(Valid, "") {
-  return arg.data.valid();
-}
+MATCHER(Valid, "") { return arg.data.valid(); }
 
-MATCHER_P(Contains, key, "") {
-  return arg.contains(key);
-}
+MATCHER_P(Contains, key, "") { return arg.contains(key); }
 
-MATCHER_P(IsOfType, type, "") {
-  return arg.data.template is<decltype(type)>();
-}
+MATCHER_P(IsOfType, type, "") { return arg.data.template is<decltype(type)>(); }
 
 MATCHER_P(ArraySizeIs, size, "") {
   return arg.data.template is<logging::array_t>() && arg.array().size() == size;
 }
 
-template <typename T>
-auto IsOfType() { return IsOfType(T()); }
+template <typename T> auto IsOfType() { return IsOfType(T()); }
 
 using namespace logging;
 using namespace ::logging::property;
@@ -141,8 +134,8 @@ TEST(PropertiesTest, ObjectCannotContainIndex) {
 TEST(PropertiesTest, MistypingWillThrow) {
   properties prop;
   // Avoid most vexing parse/unused variable
-  EXPECT_THROW((void) bool(prop), invalid_property_type);
-  EXPECT_THROW((void) int(prop), invalid_property_type);
+  EXPECT_THROW((void)bool(prop), invalid_property_type);
+  EXPECT_THROW((void)int(prop), invalid_property_type);
   EXPECT_THROW(prop.str(), invalid_property_type);
   EXPECT_THROW(prop.array(), invalid_property_type);
   EXPECT_THROW(prop.object(), invalid_property_type);
@@ -164,23 +157,13 @@ TEST(PropertiesTest, IndexingNonExistantPathWillThrouw) {
   EXPECT_THROW(_arr({{}})[1], missing_property);
 }
 
-properties const EXAMPLE_PROPERTIES = _obj({
-  {"data", _obj({
-    {"files", _arr({_v("a.txt")})},
-    {"config", _obj({
-      {"append", _v(false)}
-    })}
-  })}
-});
+properties const EXAMPLE_PROPERTIES =
+    _obj({{"data", _obj({{"files", _arr({_v("a.txt")})},
+                         {"config", _obj({{"append", _v(false)}})}})}});
 
 TEST(PropertiesTest, MergeWithWillNotAddNewProperties) {
-  properties const input = _obj({
-    {"data", _obj({
-      {"config", _obj({
-        {"compact", _v(true)}
-      })}
-    })}
-  });
+  properties const input =
+      _obj({{"data", _obj({{"config", _obj({{"compact", _v(true)}})}})}});
   properties const output = EXAMPLE_PROPERTIES.mergedWith(input);
   EXPECT_THAT(output, Contains("data"));
   EXPECT_THAT(output["data"], Contains("files"));
@@ -191,13 +174,8 @@ TEST(PropertiesTest, MergeWithWillNotAddNewProperties) {
 }
 
 TEST(PropertiesTest, MergeWithWillOverwriteProperties) {
-  properties const input = _obj({
-    {"data", _obj({
-      {"config", _obj({
-        {"append", _v(true)}
-      })}
-    })}
-  });
+  properties const input =
+      _obj({{"data", _obj({{"config", _obj({{"append", _v(true)}})}})}});
   properties const output = EXAMPLE_PROPERTIES.mergedWith(input);
   EXPECT_THAT(output, Contains("data"));
   EXPECT_THAT(output["data"], Contains("files"));
@@ -208,11 +186,8 @@ TEST(PropertiesTest, MergeWithWillOverwriteProperties) {
 }
 
 TEST(PropertiesTest, ArraysWillBeOverwritten) {
-  properties const input = _obj({
-    {"data", _obj({
-      {"files", _arr({_v("b.txt"), _v("c.txt")})}
-    })}
-  });
+  properties const input =
+      _obj({{"data", _obj({{"files", _arr({_v("b.txt"), _v("c.txt")})}})}});
   properties const output = EXAMPLE_PROPERTIES.mergedWith(input);
   EXPECT_THAT(output, Contains("data"));
   EXPECT_THAT(output["data"], Contains("files"));