about summary refs log tree commit diff
path: root/absl/numeric
diff options
context:
space:
mode:
Diffstat (limited to 'absl/numeric')
-rw-r--r--absl/numeric/int128.h21
-rw-r--r--absl/numeric/int128_have_intrinsic.inc2
-rw-r--r--absl/numeric/int128_no_intrinsic.inc2
3 files changed, 18 insertions, 7 deletions
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index f9c83cafec40..9c36c57116c6 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -37,10 +37,19 @@
 #include "absl/base/macros.h"
 #include "absl/base/port.h"
 
-#if defined(_MSC_VER) && defined(_WIN64)
+#if defined(_MSC_VER)
+// In very old versions of MSVC and when the /Zc:wchar_t flag is off, wchar_t is
+// a typedef for unsigned short.  Otherwise wchar_t is mapped to the __wchar_t
+// builtin type.  We need to make sure not to define operator wchar_t()
+// alongside operator unsigned short() in these instances.
+#define ABSL_INTERNAL_WCHAR_T __wchar_t
+#if defined(_WIN64)
 #include <intrin.h>
 #pragma intrinsic(_umul128)
-#endif  // defined(_MSC_VER) && defined(_WIN64)
+#endif  // defined(_WIN64)
+#else   // defined(_MSC_VER)
+#define ABSL_INTERNAL_WCHAR_T wchar_t
+#endif  // defined(_MSC_VER)
 
 namespace absl {
 
@@ -131,7 +140,7 @@ class
   constexpr explicit operator unsigned char() const;
   constexpr explicit operator char16_t() const;
   constexpr explicit operator char32_t() const;
-  constexpr explicit operator wchar_t() const;
+  constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const;
   constexpr explicit operator short() const;  // NOLINT(runtime/int)
   // NOLINTNEXTLINE(runtime/int)
   constexpr explicit operator unsigned short() const;
@@ -468,8 +477,8 @@ constexpr uint128::operator char32_t() const {
   return static_cast<char32_t>(lo_);
 }
 
-constexpr uint128::operator wchar_t() const {
-  return static_cast<wchar_t>(lo_);
+constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const {
+  return static_cast<ABSL_INTERNAL_WCHAR_T>(lo_);
 }
 
 // NOLINTNEXTLINE(runtime/int)
@@ -719,4 +728,6 @@ inline uint128& uint128::operator--() {
 
 }  // namespace absl
 
+#undef ABSL_INTERNAL_WCHAR_T
+
 #endif  // ABSL_NUMERIC_INT128_H_
diff --git a/absl/numeric/int128_have_intrinsic.inc b/absl/numeric/int128_have_intrinsic.inc
index ee2a093018d9..0c8164a5444e 100644
--- a/absl/numeric/int128_have_intrinsic.inc
+++ b/absl/numeric/int128_have_intrinsic.inc
@@ -15,4 +15,4 @@
 
 // This file contains :int128 implementation details that depend on internal
 // representation when ABSL_HAVE_INTRINSIC_INT128 is defined. This file is
-// included by int128.h.
+// included by int128.h and relies on ABSL_INTERNAL_WCHAR_T being defined.
diff --git a/absl/numeric/int128_no_intrinsic.inc b/absl/numeric/int128_no_intrinsic.inc
index 0d0b3cfdeb12..08d68ac3ea58 100644
--- a/absl/numeric/int128_no_intrinsic.inc
+++ b/absl/numeric/int128_no_intrinsic.inc
@@ -15,4 +15,4 @@
 
 // This file contains :int128 implementation details that depend on internal
 // representation when ABSL_HAVE_INTRINSIC_INT128 is *not* defined. This file
-// is included by int128.h.
+// is included by int128.h and relies on ABSL_INTERNAL_WCHAR_T being defined.