Nullopt and InPlace should be structs, not enum values
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Jan 2016 21:32:12 +0000 (21:32 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Jan 2016 21:32:12 +0000 (21:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152915

Reviewed by Andreas Kling.

Without this,

Optional<int> o = flag ? 1 : Nullopt;

would cause Nullopt to be treated as an integer, causing o to be initialized to 0,
instead of Nullopt. With this change, the above code now causes a compile error.

Also, get rid of the CONSTEXPR macro since all compilers support constexpr properly,
and add a WTF::makeOptional to match the current iteration of std::experimental::optional.

* wtf/Compiler.h:
* wtf/Forward.h:
* wtf/Optional.h:
(WTF::NulloptTag::NulloptTag):
(WTF::makeOptional):
* wtf/StdLibExtras.h:
(std::literals::chrono_literals::operator _s):
(std::literals::chrono_literals::operator _ms):
(std::move):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194784 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/Compiler.h
Source/WTF/wtf/Forward.h
Source/WTF/wtf/Optional.h
Source/WTF/wtf/StdLibExtras.h

index 8aa65f6..62eb788 100644 (file)
@@ -1,3 +1,30 @@
+2016-01-08  Anders Carlsson  <andersca@apple.com>
+
+        Nullopt and InPlace should be structs, not enum values
+        https://bugs.webkit.org/show_bug.cgi?id=152915
+
+        Reviewed by Andreas Kling.
+
+        Without this, 
+
+        Optional<int> o = flag ? 1 : Nullopt;
+
+        would cause Nullopt to be treated as an integer, causing o to be initialized to 0,
+        instead of Nullopt. With this change, the above code now causes a compile error.
+
+        Also, get rid of the CONSTEXPR macro since all compilers support constexpr properly,
+        and add a WTF::makeOptional to match the current iteration of std::experimental::optional.
+
+        * wtf/Compiler.h:
+        * wtf/Forward.h:
+        * wtf/Optional.h:
+        (WTF::NulloptTag::NulloptTag):
+        (WTF::makeOptional):
+        * wtf/StdLibExtras.h:
+        (std::literals::chrono_literals::operator _s):
+        (std::literals::chrono_literals::operator _ms):
+        (std::move):
+
 2016-01-06  Anders Carlsson  <andersca@apple.com>
 
         Add a smart block pointer
index 69d6f8a..7b9c92b 100644 (file)
@@ -50,7 +50,6 @@
 #define WTF_COMPILER_CLANG 1
 #define WTF_COMPILER_SUPPORTS_BLOCKS __has_feature(blocks)
 #define WTF_COMPILER_SUPPORTS_C_STATIC_ASSERT __has_feature(c_static_assert)
-#define WTF_COMPILER_SUPPORTS_CXX_CONSTEXPR __has_feature(cxx_constexpr)
 #define WTF_COMPILER_SUPPORTS_CXX_REFERENCE_QUALIFIED_FUNCTIONS __has_feature(cxx_reference_qualified_functions)
 #define WTF_COMPILER_SUPPORTS_CXX_USER_LITERALS __has_feature(cxx_user_literals)
 #define WTF_COMPILER_SUPPORTS_FALLTHROUGH_WARNINGS __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
@@ -65,7 +64,6 @@
 /* Note: This section must come after the Clang section since we check !COMPILER(CLANG) here. */
 #if COMPILER(GCC_OR_CLANG) && !COMPILER(CLANG)
 #define WTF_COMPILER_GCC 1
-#define WTF_COMPILER_SUPPORTS_CXX_CONSTEXPR 1
 #define WTF_COMPILER_SUPPORTS_CXX_USER_LITERALS 1
 #define WTF_COMPILER_SUPPORTS_CXX_REFERENCE_QUALIFIED_FUNCTIONS 1
 
 #define ALWAYS_INLINE inline
 #endif
 
-/* CONSTEXPR */
-
-#if !defined(CONSTEXPR) && COMPILER_SUPPORTS(CXX_CONSTEXPR)
-#define CONSTEXPR constexpr
-#endif
-
-#if !defined(CONSTEXPR)
-#define CONSTEXPR
-#endif
-
 /* WTF_EXTERN_C_{BEGIN, END} */
 
 #ifdef __cplusplus
index eb5e490..5434284 100644 (file)
@@ -28,6 +28,7 @@ namespace WTF {
 template<typename T> class Function;
 template<typename T> class LazyNeverDestroyed;
 template<typename T> class NeverDestroyed;
+template<typename T> class Optional;
 template<typename T> class PassRefPtr;
 template<typename T> class RefPtr;
 template<typename T> class Ref;
@@ -62,6 +63,7 @@ using WTF::Function;
 using WTF::FunctionDispatcher;
 using WTF::LazyNeverDestroyed;
 using WTF::NeverDestroyed;
+using WTF::Optional;
 using WTF::OrdinalNumber;
 using WTF::PassRefPtr;
 using WTF::PrintStream;
index 979f097..fa0edf7 100644 (file)
 
 namespace WTF {
 
-enum InPlaceTag { InPlace };
-enum NulloptTag { Nullopt };
+struct InPlaceTag { };
+constexpr InPlaceTag InPlace { };
+
+struct NulloptTag { explicit constexpr NulloptTag(int) { } };
+constexpr NulloptTag Nullopt { 0 };
 
 template<typename T>
 class Optional {
@@ -193,10 +196,18 @@ private:
     typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type m_value;
 };
 
+template<typename T>
+Optional<typename std::decay<T>::type>
+makeOptional(T&& value)
+{
+    return Optional<typename std::decay<T>::type>(std::forward<T>(value));
+}
+
 } // namespace WTF
 
 using WTF::InPlace;
 using WTF::Nullopt;
 using WTF::Optional;
+using WTF::makeOptional;
 
 #endif // Optional_h
index e85ee1b..d872097 100644 (file)
@@ -359,12 +359,12 @@ T exchange(T& t, U&& newValue)
 // (User-literals need to have a leading underscore so we add it here - the "real" literals don't have underscores).
 namespace literals {
 namespace chrono_literals {
-    CONSTEXPR inline chrono::seconds operator"" _s(unsigned long long s)
+    constexpr inline chrono::seconds operator"" _s(unsigned long long s)
     {
         return chrono::seconds(static_cast<chrono::seconds::rep>(s));
     }
 
-    CONSTEXPR chrono::milliseconds operator"" _ms(unsigned long long ms)
+    constexpr chrono::milliseconds operator"" _ms(unsigned long long ms)
     {
         return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(ms));
     }
@@ -373,7 +373,7 @@ namespace chrono_literals {
 #endif
 
 template<WTF::CheckMoveParameterTag, typename T>
-ALWAYS_INLINE CONSTEXPR typename remove_reference<T>::type&& move(T&& value)
+ALWAYS_INLINE constexpr typename remove_reference<T>::type&& move(T&& value)
 {
     static_assert(is_lvalue_reference<T>::value, "T is not an lvalue reference; move() is unnecessary.");