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
This commit is contained in:
Howard Hinnant 2010-08-10 20:48:29 +00:00
parent 45783d2dfd
commit 60a0a8ef24
10 changed files with 168 additions and 38 deletions

View File

@ -73,6 +73,76 @@
#define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) #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 #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
#define _LIBCPP_MOVE #define _LIBCPP_MOVE
#endif #endif
@ -81,23 +151,22 @@
#define _LIBCPP_HAS_NO_STATIC_ASSERT #define _LIBCPP_HAS_NO_STATIC_ASSERT
#endif #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) #if !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 4)
#define _LIBCPP_HAS_NO_UNICODE_CHARS
#define _LIBCPP_HAS_NO_ADVANCED_SFINAE #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 #endif
#if defined(__clang__) #if !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 6)
#define _LIBCPP_HAS_NO_STRONG_USING #define _LIBCPP_HAS_NO_NULLPTR
#endif #endif
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #endif
#endif
#ifdef _LIBCPP_HAS_NO_STRONG_USING #ifdef _LIBCPP_HAS_NO_STRONG_USING
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
@ -106,6 +175,7 @@
#else #else
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE { #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD } } #define _LIBCPP_END_NAMESPACE_STD } }
#define _STD std::_LIBCPP_NAMESPACE
namespace std { namespace std {
namespace _LIBCPP_NAMESPACE { namespace _LIBCPP_NAMESPACE {
@ -113,12 +183,11 @@ namespace _LIBCPP_NAMESPACE {
using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
} }
#define _STD std::_LIBCPP_NAMESPACE
#endif #endif
#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef unsigned short char16_t; typedef unsigned short char16_t;
typedef unsigned int char32_t; typedef unsigned int char32_t;
#endif #endif
#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT #ifdef _LIBCPP_HAS_NO_STATIC_ASSERT
@ -133,13 +202,7 @@ template <unsigned> struct __static_assert_check {};
#endif #endif
#ifdef _LIBCPP_HAS_NO_DECLTYPE #ifdef _LIBCPP_HAS_NO_DECLTYPE
#define decltype(x) __typeof__(x) #define decltype(x) __typeof__(x)
#endif
#if !__EXCEPTIONS
#define _LIBCPP_NO_EXCEPTIONS
#endif #endif
#endif // _LIBCPP_CONFIG #endif // _LIBCPP_CONFIG

View File

@ -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 <__config>
#include <math.h> #include <math.h>
#include <type_traits> #include <type_traits>
@ -1641,4 +1647,9 @@ using ::truncl;
_LIBCPP_END_NAMESPACE_STD _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 #endif // _LIBCPP_CMATH

View File

@ -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 true;}
friend _LIBCPP_ALWAYS_INLINE bool operator>(nullptr_t, nullptr_t) {return false;} friend _LIBCPP_ALWAYS_INLINE bool operator>(nullptr_t, nullptr_t) {return false;}
friend _LIBCPP_ALWAYS_INLINE bool operator>=(nullptr_t, nullptr_t) {return true;} friend _LIBCPP_ALWAYS_INLINE bool operator>=(nullptr_t, nullptr_t) {return true;}
template <typename _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator==(nullptr_t, _Tp* __p) {return 0 == __p;}
template <typename _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator==(_Tp* __p, nullptr_t) {return __p == 0;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator!=(nullptr_t, _Tp* __p) {return 0 != __p;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator!=(_Tp* __p, nullptr_t) {return __p != 0;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator<(nullptr_t, _Tp* __p) {return 0 < __p;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator<(_Tp* __p, nullptr_t) {return __p < 0;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator<=(nullptr_t, _Tp* __p) {return 0 <= __p;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator<=(_Tp* __p, nullptr_t) {return __p <= 0;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator>(nullptr_t, _Tp* __p) {return 0 > __p;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator>(_Tp* __p, nullptr_t) {return __p > 0;}
template <class _Tp>
friend _LIBCPP_ALWAYS_INLINE bool operator>=(nullptr_t, _Tp* __p) {return 0 >= __p;}
template <class _Tp>
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);} inline _LIBCPP_ALWAYS_INLINE nullptr_t __get_nullptr_t() {return nullptr_t(0);}

View File

@ -1615,7 +1615,7 @@ operator+(typename __debug_iter<_Container, _Iter>::difference_type __n,
#endif // _LIBCPP_DEBUG #endif // _LIBCPP_DEBUG
#ifdef _LIBCPP_MOVE #if defined(_LIBCPP_MOVE) && !defined(_LIBCPP_HAS_NO_DECLTYPE)
template <class _C> template <class _C>
inline inline

View File

@ -1129,7 +1129,7 @@ struct uses_allocator
{ {
}; };
#ifdef _LIBCPP_MOVE #if defined(_LIBCPP_MOVE) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
// uses-allocator construction // uses-allocator construction

View File

@ -1259,8 +1259,6 @@ private:
_LIBCPP_INLINE_VISIBILITY const allocator_type& __alloc() const {return __r_.second();} _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 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) _LIBCPP_INLINE_VISIBILITY void __set_short_size(size_type __s)
#if _LIBCPP_BIG_ENDIAN #if _LIBCPP_BIG_ENDIAN

View File

@ -178,9 +178,12 @@ class thread
{ {
pthread_t __t_; pthread_t __t_;
#ifndef _LIBCPP_MOVE #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
thread(const thread&); // = delete; thread(const thread&) = delete;
thread& operator=(const thread&); // = delete; thread& operator=(const thread&) = delete;
#else
thread(const thread&);
thread& operator=(const thread&);
#endif #endif
public: public:
typedef __thread_id id; typedef __thread_id id;
@ -201,9 +204,7 @@ public:
~thread(); ~thread();
#ifdef _LIBCPP_MOVE #ifdef _LIBCPP_MOVE
thread(const thread&) = delete;
thread(thread&& __t) : __t_(__t.__t_) {__t.__t_ = 0;} thread(thread&& __t) : __t_(__t.__t_) {__t.__t_ = 0;}
thread& operator=(const thread&) = delete;
thread& operator=(thread&& __t); thread& operator=(thread&& __t);
#endif #endif

View File

@ -1093,10 +1093,10 @@ private:
#else #else
static _Tp __t(); static _Tp __t();
static _Up __u(); static _Up __u();
static bool __f();
#endif #endif
static bool __f();
public: public:
typedef __typeof__(__f() ? __t() : __u()) type; typedef decltype(__f() ? __t() : __u()) type;
}; };
#else #else
@ -1135,7 +1135,10 @@ struct common_type<_Tp, _Up, _Vp...>
template <class _Tp> template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
typename remove_reference<_Tp>::type&& typename remove_reference<_Tp>::type&&
move(_Tp&& __t) {return __t;} move(_Tp&& __t)
{
return static_cast<typename remove_reference<_Tp>::type&&>(__t);
}
template <class _Tp, class _Up, template <class _Tp, class _Up,
class = typename _STD::enable_if< class = typename _STD::enable_if<
@ -1148,8 +1151,7 @@ inline _LIBCPP_INLINE_VISIBILITY
_Tp&& _Tp&&
forward(_Up&& __t) forward(_Up&& __t)
{ {
return __t; // to quiet spurious warning return static_cast<_Tp&&>(__t);
// return static_cast<_Tp&&>(__t);
} }
#else // _LIBCPP_MOVE #else // _LIBCPP_MOVE

View File

@ -223,6 +223,8 @@ struct pair
second(_STD::forward<_U2>(__u2)) second(_STD::forward<_U2>(__u2))
{} {}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template<class _Tuple, template<class _Tuple,
class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type> class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
@ -233,7 +235,6 @@ struct pair
typename __make_tuple_types<_Tuple>::type>::type>(get<1>(__p))) typename __make_tuple_types<_Tuple>::type>::type>(get<1>(__p)))
{} {}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
tuple<_Args2...> __second_args) tuple<_Args2...> __second_args)
@ -241,7 +242,6 @@ struct pair
typename __make_tuple_indices<sizeof...(_Args1)>::type(), typename __make_tuple_indices<sizeof...(_Args1)>::type(),
typename __make_tuple_indices<sizeof...(_Args2) >::type()) typename __make_tuple_indices<sizeof...(_Args2) >::type())
{} {}
#endif
template <class _Tuple, template <class _Tuple,
class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type> class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type>
@ -256,6 +256,8 @@ struct pair
return *this; return *this;
} }
#endif
#else #else
template<class _U1, class _U2> template<class _U1, class _U2>
_LIBCPP_INLINE_VISIBILITY pair(const pair<_U1, _U2>& __p) _LIBCPP_INLINE_VISIBILITY pair(const pair<_U1, _U2>& __p)

View File

@ -24,9 +24,10 @@ int main()
"sizeof(std::nullptr_t) == sizeof(void*)"); "sizeof(std::nullptr_t) == sizeof(void*)");
A* p = 0; A* p = 0;
assert(p == nullptr); 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; void (A::*pmf)() = 0;
#ifdef __clang__
// GCC 4.2 can't handle this
assert(pmf == nullptr); assert(pmf == nullptr);
#endif #endif
int A::*pmd = 0; int A::*pmd = 0;
@ -41,4 +42,20 @@ int main()
assert(!(nullptr != nullptr)); assert(!(nullptr != nullptr));
assert(!(nullptr < nullptr)); 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);
} }