Implement p0137r1 - std::launder. Reviewed as https://reviews.llvm.org/D40144

llvm-svn: 318864
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 9180eb1f4ab96481413e93d35f35c3685de3084c
diff --git a/include/new b/include/new
index 06cf4a3..6541e02 100644
--- a/include/new
+++ b/include/new
@@ -46,6 +46,8 @@
 new_handler set_new_handler(new_handler new_p) noexcept;
 new_handler get_new_handler() noexcept;
 
+// 21.6.4, pointer optimization barrier
+template <class T> constexpr T* launder(T* p) noexcept; // C++17
 }  // std
 
 void* operator new(std::size_t size);                                   // replaceable
@@ -250,6 +252,29 @@
 }
 #endif
 
+template <class _Tp>
+_LIBCPP_NODISCARD_AFTER_CXX17 inline 
+_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
+{
+    static_assert (!(is_function<_Tp>::value), "can't launder functions" );
+    static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" );
+#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
+    return __builtin_launder(__p);
+#else
+    return __p;
+#endif
+}
+
+
+#if _LIBCPP_STD_VER > 14
+template <class _Tp>
+_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
+constexpr _Tp* launder(_Tp* __p) noexcept
+{
+    return __launder(__p);
+}
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_NEW