summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorChristopher Wiley <wiley@google.com>2015-12-29 14:44:42 -0800
committerChristopher Wiley <wiley@google.com>2015-12-30 12:19:45 -0800
commit00be730ea937df52bc7bad8094aa9e58548aeaa0 (patch)
tree830a9ffb3440c65b747cc15b0b33be5870f805db /base
parent060e36d0195a2ab7118e8c637b2694627ec64d29 (diff)
downloadlibchrome-00be730ea937df52bc7bad8094aa9e58548aeaa0.tar.gz
Fix sign promotion errors
These turned out be be entirely related to logging enum values, where the compiler would get confused about the overload to pick among the signed/unsigned/long/int stream operators. Fix this by providing a special template specialization that is enabled only for enum types. Special thanks to avakulenko@ who suggested this fix. Bug: 26228533 Test: Compiles under gcc/clang Change-Id: If0eb6ea8f2998fc826387816d54882462e526650
Diffstat (limited to 'base')
-rw-r--r--base/logging.h50
1 files changed, 29 insertions, 21 deletions
diff --git a/base/logging.h b/base/logging.h
index ea096d19f7..6fb0dd972f 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -9,6 +9,7 @@
#include <string>
#include <cstring>
#include <sstream>
+#include <typeinfo>
#include "base/base_export.h"
#include "base/basictypes.h"
@@ -135,6 +136,34 @@
// There is the special severity of DFATAL, which logs FATAL in debug mode,
// ERROR in normal mode.
+// Note that "The behavior of a C++ program is undefined if it adds declarations
+// or definitions to namespace std or to a namespace within namespace std unless
+// otherwise specified." --C++11[namespace.std]
+//
+// We've checked that this particular definition has the intended behavior on
+// our implementations, but it's prone to breaking in the future, and please
+// don't imitate this in your own definitions without checking with some
+// standard library experts.
+namespace std {
+// These functions are provided as a convenience for logging, which is where we
+// use streams (it is against Google style to use streams in other places). It
+// is designed to allow you to emit non-ASCII Unicode strings to the log file,
+// which is normally ASCII. It is relatively slow, so try not to use it for
+// common cases. Non-ASCII characters will be converted to UTF-8 by these
+// operators.
+BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
+inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
+ return out << wstr.c_str();
+}
+
+template<typename T>
+typename std::enable_if<std::is_enum<T>::value, std::ostream&>::type operator<<(
+ std::ostream& out, T value) {
+ return out << static_cast<typename std::underlying_type<T>::type>(value);
+}
+
+} // namespace std
+
namespace logging {
// TODO(avi): do we want to do a unification of character types here?
@@ -867,27 +896,6 @@ BASE_EXPORT std::wstring GetLogFileFullPath();
} // namespace logging
-// Note that "The behavior of a C++ program is undefined if it adds declarations
-// or definitions to namespace std or to a namespace within namespace std unless
-// otherwise specified." --C++11[namespace.std]
-//
-// We've checked that this particular definition has the intended behavior on
-// our implementations, but it's prone to breaking in the future, and please
-// don't imitate this in your own definitions without checking with some
-// standard library experts.
-namespace std {
-// These functions are provided as a convenience for logging, which is where we
-// use streams (it is against Google style to use streams in other places). It
-// is designed to allow you to emit non-ASCII Unicode strings to the log file,
-// which is normally ASCII. It is relatively slow, so try not to use it for
-// common cases. Non-ASCII characters will be converted to UTF-8 by these
-// operators.
-BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
-inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
- return out << wstr.c_str();
-}
-} // namespace std
-
// The NOTIMPLEMENTED() macro annotates codepaths which have
// not been implemented yet.
//