Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(888)

Unified Diff: base/logging.h

Issue 1436403003: Make scoped enums output streamable. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/logging_unittest.cc » ('j') | base/logging_unittest.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/logging.h
diff --git a/base/logging.h b/base/logging.h
index 8c7f20ad193eb1a6f7f398d74788e0fd95c45546..3e7477f4f5166ce1998cb529c63b9266a482654d 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -9,6 +9,7 @@
#include <string>
#include <cstring>
#include <sstream>
+#include <type_traits>
dcheng 2015/11/13 03:30:23 Pretty sure this isn't allowed yet.
#include "base/base_export.h"
#include "base/basictypes.h"
@@ -513,18 +514,45 @@ class CheckOpResult {
#endif
+namespace internal {
+// Type trait helper to detect scoped enums.
+template <typename T>
+using is_scoped_enum =
+ std::integral_constant<bool,
+ std::is_enum<T>::value &&
+ !std::is_convertible<T, int>::value>;
+} // namespace internal
+
// Build the error message string. This is separate from the "Impl"
// function template because it is not performance critical and so can
// be out of line, while the "Impl" code should be inline. Caller
// takes ownership of the returned string.
-template<class t1, class t2>
-std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
+template <class T1,
+ class T2,
+ typename std::enable_if<!internal::is_scoped_enum<T1>::value &&
+ !internal::is_scoped_enum<T2>::value>::type* =
+ nullptr>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* names) {
std::ostringstream ss;
ss << names << " (" << v1 << " vs. " << v2 << ")";
std::string* msg = new std::string(ss.str());
return msg;
}
+// Template specialization for scoped enums. Only allows comparisons between
+// values from the same scoped enum.
+template <class T,
+ typename std::enable_if<internal::is_scoped_enum<T>::value>::type* =
+ nullptr>
+std::string* MakeCheckOpString(const T& v1, const T& v2, const char* names) {
+ using EnumIntegralType = typename std::underlying_type<T>::type;
+ std::ostringstream ss;
+ ss << names << " (" << static_cast<EnumIntegralType>(v1) << " vs. "
+ << static_cast<EnumIntegralType>(v2) << ")";
+ std::string* msg = new std::string(ss.str());
+ return msg;
+}
+
// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
// in logging.cc.
extern template BASE_EXPORT std::string* MakeCheckOpString<int, int>(
« no previous file with comments | « no previous file | base/logging_unittest.cc » ('j') | base/logging_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698