From 60a0a8ef24f0f3a7d351efda444bf62025c78b47 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 10 Aug 2010 20:48:29 +0000 Subject: [PATCH] patch by Jesse Towner, and bug fix by Sebastian Redl git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@110724 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__config | 103 ++++++++++++++---- include/cmath | 11 ++ include/cstddef | 36 ++++++ include/iterator | 2 +- include/memory | 2 +- include/string | 2 - include/thread | 11 +- include/type_traits | 12 +- include/utility | 6 +- .../support.types/nullptr_t.pass.cpp | 21 +++- 10 files changed, 168 insertions(+), 38 deletions(-) diff --git a/include/__config b/include/__config index a3518d9e..42797365 100644 --- a/include/__config +++ b/include/__config @@ -73,6 +73,76 @@ #define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) +#if defined(__clang__) + +#if !(__has_feature(cxx_exceptions)) +#define _LIBCPP_NO_EXCEPTIONS +#endif + +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#define _LIBCPP_HAS_NO_STRONG_USING +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ + +#define _LIBCPP_HAS_NO_DECLTYPE +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_HAS_NO_NULLPTR +#define _LIBCPP_HAS_NO_STATIC_ASSERT +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_VARIADICS + +#else + +#if __has_feature(cxx_rvalue_references) +#define _LIBCPP_MOVE +#endif + +#if !(__has_feature(cxx_decltype)) +#define _LIBCPP_HAS_NO_DECLTYPE +#endif + +#if !(__has_feature(cxx_deleted_functions)) +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#endif + +#if !(__has_feature(cxx_nullptr)) +#define _LIBCPP_HAS_NO_NULLPTR +#endif + +#if !(__has_feature(cxx_static_assert)) +#define _LIBCPP_HAS_NO_STATIC_ASSERT +#endif + +#if !(__has_feature(cxx_variadic_templates)) +#define _LIBCPP_HAS_NO_VARIADICS +#endif + +#endif + +#elif defined(__GNUC__) + +#if !__EXCEPTIONS +#define _LIBCPP_NO_EXCEPTIONS +#endif + +#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ + +#define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#define _LIBCPP_HAS_NO_DECLTYPE +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_HAS_NO_NULLPTR +#define _LIBCPP_HAS_NO_STATIC_ASSERT +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_VARIADICS + +#else + #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 #define _LIBCPP_MOVE #endif @@ -81,23 +151,22 @@ #define _LIBCPP_HAS_NO_STATIC_ASSERT #endif -#define _LIBCPP_HAS_NO_NULLPTR - -#if !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 3) -#define _LIBCPP_HAS_NO_VARIADICS -#define _LIBCPP_HAS_NO_DECLTYPE -#endif - #if !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) -#define _LIBCPP_HAS_NO_UNICODE_CHARS #define _LIBCPP_HAS_NO_ADVANCED_SFINAE +#define _LIBCPP_HAS_NO_DECLTYPE +#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_HAS_NO_UNICODE_CHARS +#define _LIBCPP_HAS_NO_VARIADICS #endif -#if defined(__clang__) -#define _LIBCPP_HAS_NO_STRONG_USING +#if !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 6) +#define _LIBCPP_HAS_NO_NULLPTR #endif -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif + +#endif #ifdef _LIBCPP_HAS_NO_STRONG_USING #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { @@ -106,6 +175,7 @@ #else #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE { #define _LIBCPP_END_NAMESPACE_STD } } +#define _STD std::_LIBCPP_NAMESPACE namespace std { namespace _LIBCPP_NAMESPACE { @@ -113,12 +183,11 @@ namespace _LIBCPP_NAMESPACE { using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); } -#define _STD std::_LIBCPP_NAMESPACE #endif #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS - typedef unsigned short char16_t; - typedef unsigned int char32_t; +typedef unsigned short char16_t; +typedef unsigned int char32_t; #endif #ifdef _LIBCPP_HAS_NO_STATIC_ASSERT @@ -133,13 +202,7 @@ template struct __static_assert_check {}; #endif #ifdef _LIBCPP_HAS_NO_DECLTYPE - #define decltype(x) __typeof__(x) - -#endif - -#if !__EXCEPTIONS -#define _LIBCPP_NO_EXCEPTIONS #endif #endif // _LIBCPP_CONFIG diff --git a/include/cmath b/include/cmath index 1fe84796..f133de98 100644 --- a/include/cmath +++ b/include/cmath @@ -297,6 +297,12 @@ long double truncl(long double x); */ +// FIXME: work around for Clang with -std=C++0x on OSX/iOS +#if defined(__clang__) && defined(__APPLE__) +# pragma push_macro("__STRICT_ANSI__") +# undef __STRICT_ANSI__ +#endif + #include <__config> #include #include @@ -1641,4 +1647,9 @@ using ::truncl; _LIBCPP_END_NAMESPACE_STD +// FIXME: work around for Clang with -std=C++0x on OSX/iOS +#if defined(__clang__) && defined(__APPLE__) +# pragma pop_macro("__STRICT_ANSI__") +#endif + #endif // _LIBCPP_CMATH diff --git a/include/cstddef b/include/cstddef index f6b34ad5..8cba5f8a 100644 --- a/include/cstddef +++ b/include/cstddef @@ -78,6 +78,42 @@ struct nullptr_t friend _LIBCPP_ALWAYS_INLINE bool operator<=(nullptr_t, nullptr_t) {return true;} friend _LIBCPP_ALWAYS_INLINE bool operator>(nullptr_t, nullptr_t) {return false;} friend _LIBCPP_ALWAYS_INLINE bool operator>=(nullptr_t, nullptr_t) {return true;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator==(nullptr_t, _Tp* __p) {return 0 == __p;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator==(_Tp* __p, nullptr_t) {return __p == 0;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator!=(nullptr_t, _Tp* __p) {return 0 != __p;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator!=(_Tp* __p, nullptr_t) {return __p != 0;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator<(nullptr_t, _Tp* __p) {return 0 < __p;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator<(_Tp* __p, nullptr_t) {return __p < 0;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator<=(nullptr_t, _Tp* __p) {return 0 <= __p;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator<=(_Tp* __p, nullptr_t) {return __p <= 0;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator>(nullptr_t, _Tp* __p) {return 0 > __p;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator>(_Tp* __p, nullptr_t) {return __p > 0;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator>=(nullptr_t, _Tp* __p) {return 0 >= __p;} + + template + friend _LIBCPP_ALWAYS_INLINE bool operator>=(_Tp* __p, nullptr_t) {return __p >= 0;} }; inline _LIBCPP_ALWAYS_INLINE nullptr_t __get_nullptr_t() {return nullptr_t(0);} diff --git a/include/iterator b/include/iterator index f2173e9e..877474bc 100644 --- a/include/iterator +++ b/include/iterator @@ -1615,7 +1615,7 @@ operator+(typename __debug_iter<_Container, _Iter>::difference_type __n, #endif // _LIBCPP_DEBUG -#ifdef _LIBCPP_MOVE +#if defined(_LIBCPP_MOVE) && !defined(_LIBCPP_HAS_NO_DECLTYPE) template inline diff --git a/include/memory b/include/memory index 8af5ed76..3358a19f 100644 --- a/include/memory +++ b/include/memory @@ -1129,7 +1129,7 @@ struct uses_allocator { }; -#ifdef _LIBCPP_MOVE +#if defined(_LIBCPP_MOVE) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) // uses-allocator construction diff --git a/include/string b/include/string index 3428fb84..2ca59863 100644 --- a/include/string +++ b/include/string @@ -1259,8 +1259,6 @@ private: _LIBCPP_INLINE_VISIBILITY const allocator_type& __alloc() const {return __r_.second();} _LIBCPP_INLINE_VISIBILITY bool __is_long() const {return bool(__r_.first().__s.__size_ & __short_mask);} - _LIBCPP_INLINE_VISIBILITY void __set_long() {__r_.first().__s.__size_ &= __short_mask;} - _LIBCPP_INLINE_VISIBILITY void __set_short() {__r_.first().__s.__size_ |= ~__short_mask;} _LIBCPP_INLINE_VISIBILITY void __set_short_size(size_type __s) #if _LIBCPP_BIG_ENDIAN diff --git a/include/thread b/include/thread index 5fcd2c98..6bf31892 100644 --- a/include/thread +++ b/include/thread @@ -178,9 +178,12 @@ class thread { pthread_t __t_; -#ifndef _LIBCPP_MOVE - thread(const thread&); // = delete; - thread& operator=(const thread&); // = delete; +#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS + thread(const thread&) = delete; + thread& operator=(const thread&) = delete; +#else + thread(const thread&); + thread& operator=(const thread&); #endif public: typedef __thread_id id; @@ -201,9 +204,7 @@ public: ~thread(); #ifdef _LIBCPP_MOVE - thread(const thread&) = delete; thread(thread&& __t) : __t_(__t.__t_) {__t.__t_ = 0;} - thread& operator=(const thread&) = delete; thread& operator=(thread&& __t); #endif diff --git a/include/type_traits b/include/type_traits index 73b7a99f..fc144716 100644 --- a/include/type_traits +++ b/include/type_traits @@ -1093,10 +1093,10 @@ private: #else static _Tp __t(); static _Up __u(); - static bool __f(); #endif + static bool __f(); public: - typedef __typeof__(__f() ? __t() : __u()) type; + typedef decltype(__f() ? __t() : __u()) type; }; #else @@ -1135,7 +1135,10 @@ struct common_type<_Tp, _Up, _Vp...> template inline _LIBCPP_INLINE_VISIBILITY typename remove_reference<_Tp>::type&& -move(_Tp&& __t) {return __t;} +move(_Tp&& __t) +{ + return static_cast::type&&>(__t); +} template (__t); + return static_cast<_Tp&&>(__t); } #else // _LIBCPP_MOVE diff --git a/include/utility b/include/utility index 578d3130..19e2893a 100644 --- a/include/utility +++ b/include/utility @@ -223,6 +223,8 @@ struct pair second(_STD::forward<_U2>(__u2)) {} +#ifndef _LIBCPP_HAS_NO_VARIADICS + template::value>::type> _LIBCPP_INLINE_VISIBILITY @@ -233,7 +235,6 @@ struct pair typename __make_tuple_types<_Tuple>::type>::type>(get<1>(__p))) {} -#ifndef _LIBCPP_HAS_NO_VARIADICS template pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) @@ -241,7 +242,6 @@ struct pair typename __make_tuple_indices::type(), typename __make_tuple_indices::type()) {} -#endif template ::value>::type> @@ -256,6 +256,8 @@ struct pair return *this; } +#endif + #else template _LIBCPP_INLINE_VISIBILITY pair(const pair<_U1, _U2>& __p) diff --git a/test/language.support/support.types/nullptr_t.pass.cpp b/test/language.support/support.types/nullptr_t.pass.cpp index b169f1a7..204d740c 100644 --- a/test/language.support/support.types/nullptr_t.pass.cpp +++ b/test/language.support/support.types/nullptr_t.pass.cpp @@ -24,9 +24,10 @@ int main() "sizeof(std::nullptr_t) == sizeof(void*)"); A* p = 0; assert(p == nullptr); + assert(nullptr == p); +#if !((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 5)) + // GCC 4.2 through 4.5 can't handle this void (A::*pmf)() = 0; -#ifdef __clang__ - // GCC 4.2 can't handle this assert(pmf == nullptr); #endif int A::*pmd = 0; @@ -41,4 +42,20 @@ int main() assert(!(nullptr != nullptr)); assert(!(nullptr < nullptr)); assert(!(nullptr > nullptr)); + assert(!(&a1 == nullptr)); + assert(!(nullptr == &a1)); + assert(&a1 != nullptr); + assert(nullptr != &a1); + assert(nullptr < &a1); + assert(nullptr <= &a1); + assert(!(nullptr < p)); + assert(nullptr <= p); + assert(!(&a1 < nullptr)); + assert(!(&a1 <= nullptr)); + assert(!(p < nullptr)); + assert(p <= nullptr); + assert(!(nullptr > &a1)); + assert(!(nullptr >= &a1)); + assert(!(nullptr > p)); + assert(nullptr >= p); }