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

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: Meh Created 4 years, 8 months 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') | no next file with comments »
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 07674698e0220dbd7d2ab1662556e2853adc275d..40414532344e60488d39f6493abe21b82eb1f63b 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -11,6 +11,7 @@
#include <cstring>
#include <sstream>
#include <string>
+#include <type_traits>
#include "base/base_export.h"
#include "base/debug/debugger.h"
@@ -513,14 +514,77 @@ class CheckOpResult {
#endif
+namespace internal {
+// Type trait helper to detect scoped enums. Unscoped enums are always
+// implicitly convertible to ints, per C++11 4.7.1:
+// A prvalue of an unscoped enumeration type can be converted to a prvalue of
+// an integer type.
+// while a scoped enum requires an explicit conversion per C++11 5.2.9.9.
+//
+// Note that these helper traits don't use std::integral_constant, because
+// less-than and greater-than operators don't work well inside a template
+// parameter list.
+template <typename T>
+using is_scoped_enum =
+ std::integral_constant<bool,
+ std::is_enum<T>::value &&
+ !std::is_convertible<T, int>::value>;
+
+template <typename T, bool = is_scoped_enum<T>::value>
+struct is_signed_scoped_enum {
+ static const bool value = static_cast<T>(-1) < static_cast<T>(0);
+};
+
+template <typename T>
+struct is_signed_scoped_enum<T, false> : std::false_type {};
+
+template <typename T, bool = is_scoped_enum<T>::value>
+struct is_unsigned_scoped_enum {
+ static const bool value = static_cast<T>(-1) > static_cast<T>(0);
+};
+
+template <typename T>
+struct is_unsigned_scoped_enum<T, false> : public std::false_type {};
+
+} // namespace internal
+
+// Default value logger just uses operator<<.
+template <class T,
+ typename std::enable_if<!internal::is_scoped_enum<T>::value>::type* =
+ nullptr>
+void MakeCheckOpValueString(const T& v, std::ostream* os) {
+ *os << v;
+}
+
+// TODO(dcheng): Once all platforms support the std::underlying_type trait, use
+// it here. For now, there is no universal library support, so cheat and convert
+// it to the max-width integral type.
+template <class T,
+ typename std::enable_if<
+ internal::is_signed_scoped_enum<T>::value>::type* = nullptr>
+void MakeCheckOpValueString(const T& v, std::ostream* os) {
+ *os << static_cast<intmax_t>(v);
+}
+
+template <class T,
+ typename std::enable_if<
+ internal::is_unsigned_scoped_enum<T>::value>::type* = nullptr>
+void MakeCheckOpValueString(const T& v, std::ostream* os) {
+ *os << static_cast<uintmax_t>(v);
+}
+
// 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>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* names) {
std::ostringstream ss;
- ss << names << " (" << v1 << " vs. " << v2 << ")";
+ ss << names << " (";
+ MakeCheckOpValueString(v1, &ss);
+ ss << " vs. ";
+ MakeCheckOpValueString(v2, &ss);
+ ss << ")";
std::string* msg = new std::string(ss.str());
return msg;
}
« no previous file with comments | « no previous file | base/logging_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698