diff options
author | Christopher Wiley <wiley@google.com> | 2015-12-29 14:44:42 -0800 |
---|---|---|
committer | Christopher Wiley <wiley@google.com> | 2015-12-30 12:19:45 -0800 |
commit | 00be730ea937df52bc7bad8094aa9e58548aeaa0 (patch) | |
tree | 830a9ffb3440c65b747cc15b0b33be5870f805db /base | |
parent | 060e36d0195a2ab7118e8c637b2694627ec64d29 (diff) | |
download | libchrome-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.h | 50 |
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. // |