Bug 987253 - Add MOZ_EXPLICIT_CONVERSION - r=Waldo
authorBenoit Jacob <bjacob@mozilla.com>
Fri, 25 Apr 2014 22:34:04 -0400
changeset 180717 1defae2eeae9be7434de2e3624af5d2a688e6366
parent 180716 5560662e5eff6751e52f7ef34e804712c918236a
child 180718 080ff1f864652fed62dddc70ed1d5e02ef9e6809
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersWaldo
bugs987253
milestone31.0a1
Bug 987253 - Add MOZ_EXPLICIT_CONVERSION - r=Waldo
mfbt/Attributes.h
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -52,16 +52,19 @@
     * numbering schemes. Instead, use the feature checking macros."
     */
 #  ifndef __has_extension
 #    define __has_extension __has_feature /* compatibility, for older versions of clang */
 #  endif
 #  if __has_extension(cxx_constexpr)
 #    define MOZ_HAVE_CXX11_CONSTEXPR
 #  endif
+#  if __has_extension(cxx_explicit_conversions)
+#    define MOZ_HAVE_EXPLICIT_CONVERSION
+#  endif
 #  if __has_extension(cxx_deleted_functions)
 #    define MOZ_HAVE_CXX11_DELETE
 #  endif
 #  if __has_extension(cxx_override_control)
 #    define MOZ_HAVE_CXX11_OVERRIDE
 #    define MOZ_HAVE_CXX11_FINAL         final
 #  endif
 #  if __has_attribute(noinline)
@@ -74,16 +77,19 @@
 #  if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
 #    if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
 #      define MOZ_HAVE_CXX11_OVERRIDE
 #      define MOZ_HAVE_CXX11_FINAL       final
 #    endif
 #    if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0)
 #      define MOZ_HAVE_CXX11_CONSTEXPR
 #    endif
+#    if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0)
+#      define MOZ_HAVE_EXPLICIT_CONVERSION
+#    endif
 #    define MOZ_HAVE_CXX11_DELETE
 #  else
      /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */
 #    if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
 #      define MOZ_HAVE_CXX11_FINAL       __final
 #    endif
 #  endif
 #  define MOZ_HAVE_NEVER_INLINE          __attribute__((noinline))
@@ -96,16 +102,18 @@
 #    define MOZ_HAVE_CXX11_FINAL         final
 #  else
      /* MSVC <= 10 used to spell "final" as "sealed". */
 #    define MOZ_HAVE_CXX11_FINAL         sealed
 #  endif
 #  define MOZ_HAVE_CXX11_OVERRIDE
 #  define MOZ_HAVE_NEVER_INLINE          __declspec(noinline)
 #  define MOZ_HAVE_NORETURN              __declspec(noreturn)
+// Staying away from explicit conversion operators in MSVC for now, see
+// http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
 #endif
 
 /*
  * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
  * function at compile time. A constexpr function cannot examine any values
  * except its arguments and can have no side effects except its return value.
  * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's
  * value may be computed at compile time.  It should be prefered to just
@@ -117,16 +125,40 @@
 #  define MOZ_CONSTEXPR         constexpr
 #  define MOZ_CONSTEXPR_VAR     constexpr
 #else
 #  define MOZ_CONSTEXPR         /* no support */
 #  define MOZ_CONSTEXPR_VAR     const
 #endif
 
 /*
+ * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion
+ * overloaded operator that declares that a C++11 compiler should restrict
+ * this operator to allow only explicit type conversions, disallowing
+ * implicit conversions.
+ *
+ * Example:
+ *
+ *   template<typename T>
+ *   class Ptr
+ *   {
+ *      T* ptr;
+ *      MOZ_EXPLICIT_CONVERSION operator bool() const {
+ *        return ptr != nullptr;
+ *      }
+ *   };
+ *
+ */
+#ifdef MOZ_HAVE_EXPLICIT_CONVERSION
+#  define MOZ_EXPLICIT_CONVERSION explicit
+#else
+#  define MOZ_EXPLICIT_CONVERSION /* no support */
+#endif
+
+/*
  * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
  * method decorated with it must never be inlined, even if the compiler would
  * otherwise choose to inline the method.  Compilers aren't absolutely
  * guaranteed to support this, but most do.
  */
 #if defined(MOZ_HAVE_NEVER_INLINE)
 #  define MOZ_NEVER_INLINE      MOZ_HAVE_NEVER_INLINE
 #else