 Chromium Code Reviews
 Chromium Code Reviews Issue 1436403003:
  Make scoped enums output streamable.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1436403003:
  Make scoped enums output streamable.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: base/logging.h | 
| diff --git a/base/logging.h b/base/logging.h | 
| index 8c7f20ad193eb1a6f7f398d74788e0fd95c45546..3613cd5eec580093dcb214ab30d7fc076c1218d5 100644 | 
| --- a/base/logging.h | 
| +++ b/base/logging.h | 
| @@ -9,6 +9,7 @@ | 
| #include <string> | 
| #include <cstring> | 
| #include <sstream> | 
| +#include <type_traits> | 
| #include "base/base_export.h" | 
| #include "base/basictypes.h" | 
| @@ -513,12 +514,37 @@ class CheckOpResult { | 
| #endif | 
| +namespace internal { | 
| +// Type trait helper to detect scoped enums. | 
| 
danakj
2015/11/20 21:33:58
Can you add comments here about how unscoped enums
 
dcheng
2015/11/23 18:42:13
Done.
 | 
| +template <typename T> | 
| +using is_scoped_enum = | 
| + std::integral_constant<bool, | 
| + std::is_enum<T>::value && | 
| + !std::is_convertible<T, int>::value>; | 
| +} // namespace internal | 
| + | 
| +template <class T, | 
| + typename std::enable_if<internal::is_scoped_enum<T>::value && | 
| + std::is_signed<T>::value>::type* = nullptr> | 
| +std::ostream& operator<<(std::ostream& os, T v) { | 
| + os << static_cast<intmax_t>(v); | 
| 
danakj
2015/11/20 21:33:58
can you mention underlying_type with a TODO here a
 
dcheng
2015/11/23 18:42:13
Done (though I just made it a top-level comment ab
 | 
| + return os; | 
| +} | 
| + | 
| +template <class T, | 
| + typename std::enable_if<internal::is_scoped_enum<T>::value && | 
| + !std::is_signed<T>::value>::type* = nullptr> | 
| +std::ostream& operator<<(std::ostream& os, T v) { | 
| + os << static_cast<uintmax_t>(v); | 
| + return os; | 
| +} | 
| + | 
| // 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 << ")"; | 
| std::string* msg = new std::string(ss.str()); |