Selaa lähdekoodia

Make logging::level less x-macro-y.
A further extension would be to submodule with magic_enum.

Sam Jaffe 5 vuotta sitten
vanhempi
commit
7cb4c61d7d
2 muutettua tiedostoa jossa 24 lisäystä ja 16 poistoa
  1. 3 4
      include/logger/level.h
  2. 21 12
      src/common.cxx

+ 3 - 4
include/logger/level.h

@@ -18,10 +18,9 @@
 #endif
 
 #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,
+  trace, debug, info, warning, error, critical, fatal, none
+
 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

+ 21 - 12
src/common.cxx

@@ -10,9 +10,28 @@
 #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;
@@ -20,28 +39,18 @@ namespace logging {
     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
+    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);