patch by Jeffrey Yasskin for porting to Ubuntu Hardy. Everything was accepted except there were some bug fixes needed in <locale> for the __nolocale_* series. For the apple branch I ended up using templates instead of the var_args solution because it seemed both safer and more efficient.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@104516 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant 2010-05-24 17:49:41 +00:00
parent 2a59254a44
commit adff4895b2
21 changed files with 308 additions and 120 deletions

View File

@ -7,6 +7,7 @@ DESTDIR = $(DSTROOT)
OBJROOT=. OBJROOT=.
SYMROOT=. SYMROOT=.
TRIPLE=-apple-
installsrc:: $(SRCROOT) installsrc:: $(SRCROOT)

View File

@ -37,7 +37,16 @@
#endif #endif
#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) #if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
#error unable to determine endian # include <endian.h>
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define _LIBCPP_LITTLE_ENDIAN 1
# define _LIBCPP_BIG_ENDIAN 0
# elif __BYTE_ORDER == __BIG_ENDIAN
# define _LIBCPP_LITTLE_ENDIAN 0
# define _LIBCPP_BIG_ENDIAN 1
# else
# error unable to determine endian
# endif
#endif #endif
#ifndef _LIBCPP_VISIBILITY_TAG #ifndef _LIBCPP_VISIBILITY_TAG

View File

@ -18,6 +18,7 @@
#include <mutex> #include <mutex>
#include <cstdint> #include <cstdint>
#include <cctype> #include <cctype>
#include <locale.h>
#include <xlocale.h> #include <xlocale.h>
#pragma GCC system_header #pragma GCC system_header
@ -294,6 +295,7 @@ class ctype_base {
public: public:
typedef __uint32_t mask; typedef __uint32_t mask;
#if __APPLE__
static const mask space = _CTYPE_S; static const mask space = _CTYPE_S;
static const mask print = _CTYPE_R; static const mask print = _CTYPE_R;
static const mask cntrl = _CTYPE_C; static const mask cntrl = _CTYPE_C;
@ -304,6 +306,18 @@ public:
static const mask punct = _CTYPE_P; static const mask punct = _CTYPE_P;
static const mask xdigit = _CTYPE_X; static const mask xdigit = _CTYPE_X;
static const mask blank = _CTYPE_B; static const mask blank = _CTYPE_B;
#else /* !__APPLE__ */
static const mask space = _ISspace;
static const mask print = _ISprint;
static const mask cntrl = _IScntrl;
static const mask upper = _ISupper;
static const mask lower = _ISlower;
static const mask alpha = _ISalpha;
static const mask digit = _ISdigit;
static const mask punct = _ISpunct;
static const mask xdigit = _ISxdigit;
static const mask blank = _ISblank;
#endif /* __APPLE__ */
static const mask alnum = alpha | digit; static const mask alnum = alpha | digit;
static const mask graph = alnum | punct; static const mask graph = alnum | punct;
@ -507,7 +521,11 @@ public:
static locale::id id; static locale::id id;
#ifdef _CACHED_RUNES
static const size_t table_size = _CACHED_RUNES; static const size_t table_size = _CACHED_RUNES;
#else
static const size_t table_size = 256; // FIXME: Don't hardcode this.
#endif
const mask* table() const throw() {return __tab_;} const mask* table() const throw() {return __tab_;}
static const mask* classic_table() throw(); static const mask* classic_table() throw();

View File

@ -552,16 +552,12 @@ template <class BidirectionalIterator, class Compare>
#ifdef _LIBCPP_DEBUG #ifdef _LIBCPP_DEBUG
#include <cassert> #include <cassert>
#endif #endif
//#include <cstdlib> #include <cstdlib>
#define RAND_MAX 0x7fffffff // #include <cstdlib>
extern "C" int rand(void); // #include <cstdlib>
#pragma GCC system_header #pragma GCC system_header
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
using ::rand; // #include <cstdlib>
template <class _T1, class _T2 = _T1> template <class _T1, class _T2 = _T1>
struct __equal_to struct __equal_to
{ {

View File

@ -34,6 +34,8 @@ Types:
*/ */
#include <__config> #include <__config>
#define __need_ptrdiff_t
#define __need_size_t
#include <stddef.h> #include <stddef.h>
#pragma GCC system_header #pragma GCC system_header

View File

@ -86,7 +86,7 @@ typedef fpos<char_traits<wchar_t>::state_type> wstreampos;
*/ */
#include <__config> #include <__config>
#include <_types.h> // for __darwin_mbstate_t #include <wchar.h> // for mbstate_t
#pragma GCC system_header #pragma GCC system_header
@ -153,11 +153,11 @@ typedef basic_ofstream<wchar_t> wofstream;
typedef basic_fstream<wchar_t> wfstream; typedef basic_fstream<wchar_t> wfstream;
template <class _State> class fpos; template <class _State> class fpos;
typedef fpos<__darwin_mbstate_t> streampos; typedef fpos<mbstate_t> streampos;
typedef fpos<__darwin_mbstate_t> wstreampos; typedef fpos<mbstate_t> wstreampos;
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
typedef fpos<__darwin_mbstate_t> u16streampos; typedef fpos<mbstate_t> u16streampos;
typedef fpos<__darwin_mbstate_t> u32streampos; typedef fpos<mbstate_t> u32streampos;
#endif #endif
typedef long long streamoff; // for char_traits in <string> typedef long long streamoff; // for char_traits in <string>

View File

@ -137,6 +137,9 @@ template <class charT> class messages_byname;
#include <streambuf> #include <streambuf>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
#if !__APPLE__
#include <cstdarg>
#endif
#include <cstdlib> #include <cstdlib>
#include <ctime> #include <ctime>
#include <nl_types.h> #include <nl_types.h>
@ -145,6 +148,131 @@ template <class charT> class messages_byname;
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
// OSX has nice foo_l() functions that let you turn off use of the global
// locale. Linux, not so much. The following functions avoid the locale when
// that's possible and otherwise do the wrong thing. FIXME.
#if __APPLE__
template <class _Tp>
inline
int
__nolocale_sprintf(char* __restrict __str,
const char* __restrict __format, _Tp __v)
{
return sprintf_l(__str, 0, __format, __v);
}
template <class _Tp>
inline
int
__nolocale_snprintf(char* __restrict __str, size_t __size,
const char* __restrict __format, _Tp __v)
{
return snprintf_l(__str, __size, 0, __format, __v);
}
template <class _Tp>
inline
int
__nolocale_snprintf(char* __restrict __str, size_t __size,
const char* __restrict __format, int __prec, _Tp __v)
{
return snprintf_l(__str, __size, 0, __format, __prec, __v);
}
template <class _Tp>
inline
int
__nolocale_asprintf(char** __ret, const char* __restrict __format, _Tp __v)
{
return asprintf_l(__ret, 0, __format, __v);
}
template <class _Tp>
inline
int
__nolocale_asprintf(char** __ret, const char* __restrict __format, int __prec,
_Tp __v)
{
return asprintf_l(__ret, 0, __format, __prec, __v);
}
template <class _Tp>
inline
int
__nolocale_sscanf(const char* __restrict __str,
const char* __restrict __format, _Tp* __v)
{
return sscanf_l(__str, 0, __format, __v);
}
inline
int
__nolocale_isxdigit(int __c)
{
return isxdigit_l(__c, 0);
}
inline
int
__nolocale_isdigit(int __c)
{
return isdigit_l(__c, 0);
}
#else /* !__APPLE__ */
inline int
__nolocale_sprintf(char* __restrict __str,
const char* __restrict __format, ...)
{
va_list __ap;
va_start(__ap, __format);
int __result = vsprintf(__str, __format, __ap);
va_end(__ap);
return __result;
}
inline int
__nolocale_snprintf(char* __restrict __str, size_t __size,
const char* __restrict __format, ...)
{
va_list __ap;
va_start(__ap, __format);
int __result = vsnprintf(__str, __size, __format, __ap);
va_end(__ap);
return __result;
}
inline int
__nolocale_asprintf(char** __ret,
const char* __restrict __format, ...)
{
va_list __ap;
va_start(__ap, __format);
int __result = vasprintf(__ret, __format, __ap);
va_end(__ap);
return __result;
}
inline int
__nolocale_sscanf(const char* __restrict __str,
const char* __restrict __format, ...)
{
va_list __ap;
va_start(__ap, __format);
int __result = vsscanf(__str, __format, __ap);
va_end(__ap);
return __result;
}
inline int
__nolocale_isxdigit(int __c)
{
return isxdigit(__c);
}
inline int
__nolocale_isdigit(int __c)
{
return isdigit(__c);
}
#endif /* __APPLE__ */
// __scan_keyword // __scan_keyword
// Scans [__b, __e) until a match is found in the basic_strings range // Scans [__b, __e) until a match is found in the basic_strings range
// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
@ -1002,7 +1130,7 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
break; break;
// Stage 3 // Stage 3
__a[sizeof(__a)-1] = 0; __a[sizeof(__a)-1] = 0;
if (sscanf_l(__a, 0, "%p", &__v) != 1) if (__nolocale_sscanf(__a, "%p", &__v) != 1)
__err = ios_base::failbit; __err = ios_base::failbit;
// EOF checked // EOF checked
if (__b == __e) if (__b == __e)
@ -1107,13 +1235,13 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
*__oe++ = __ct.widen(*__nf++); *__oe++ = __ct.widen(*__nf++);
*__oe++ = __ct.widen(*__nf++); *__oe++ = __ct.widen(*__nf++);
for (__ns = __nf; __ns < __ne; ++__ns) for (__ns = __nf; __ns < __ne; ++__ns)
if (!isxdigit_l(*__ns, 0)) if (!__nolocale_isxdigit(*__ns))
break; break;
} }
else else
{ {
for (__ns = __nf; __ns < __ne; ++__ns) for (__ns = __nf; __ns < __ne; ++__ns)
if (!isdigit_l(*__ns, 0)) if (!__nolocale_isdigit(*__ns))
break; break;
} }
if (__grouping.empty()) if (__grouping.empty())
@ -1310,7 +1438,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((numeric_limits<long>::digits % 3) != 0) + ((numeric_limits<long>::digits % 3) != 0)
+ 1; + 1;
char __nar[__nbuf]; char __nar[__nbuf];
int __nc = sprintf_l(__nar, 0, __fmt, __v); int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc; char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob); char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators // Stage 2 - Widen __nar while adding thousands separators
@ -1336,7 +1464,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((numeric_limits<long long>::digits % 3) != 0) + ((numeric_limits<long long>::digits % 3) != 0)
+ 1; + 1;
char __nar[__nbuf]; char __nar[__nbuf];
int __nc = sprintf_l(__nar, 0, __fmt, __v); int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc; char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob); char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators // Stage 2 - Widen __nar while adding thousands separators
@ -1362,7 +1490,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((numeric_limits<unsigned long>::digits % 3) != 0) + ((numeric_limits<unsigned long>::digits % 3) != 0)
+ 1; + 1;
char __nar[__nbuf]; char __nar[__nbuf];
int __nc = sprintf_l(__nar, 0, __fmt, __v); int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc; char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob); char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators // Stage 2 - Widen __nar while adding thousands separators
@ -1388,7 +1516,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+ ((numeric_limits<unsigned long long>::digits % 3) != 0) + ((numeric_limits<unsigned long long>::digits % 3) != 0)
+ 1; + 1;
char __nar[__nbuf]; char __nar[__nbuf];
int __nc = sprintf_l(__nar, 0, __fmt, __v); int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc; char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob); char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators // Stage 2 - Widen __nar while adding thousands separators
@ -1415,16 +1543,18 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
char* __nb = __nar; char* __nb = __nar;
int __nc; int __nc;
if (__specify_precision) if (__specify_precision)
__nc = snprintf_l(__nb, __nbuf, 0, __fmt, (int)__iob.precision(), __v); __nc = __nolocale_snprintf(__nb, __nbuf, __fmt,
(int)__iob.precision(), __v);
else else
__nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v); __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, __v);
unique_ptr<char, void(*)(void*)> __nbh(0, free); unique_ptr<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__nbuf-1)) if (__nc > static_cast<int>(__nbuf-1))
{ {
if (__specify_precision) if (__specify_precision)
__nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v); __nc = __nolocale_asprintf(&__nb, __fmt, (int)__iob.precision(),
__v);
else else
__nc = asprintf_l(&__nb, 0, __fmt, __v); __nc = __nolocale_asprintf(&__nb, __fmt, __v);
if (__nb == 0) if (__nb == 0)
__throw_bad_alloc(); __throw_bad_alloc();
__nbh.reset(__nb); __nbh.reset(__nb);
@ -1465,16 +1595,18 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
char* __nb = __nar; char* __nb = __nar;
int __nc; int __nc;
if (__specify_precision) if (__specify_precision)
__nc = snprintf_l(__nb, __nbuf, 0, __fmt, (int)__iob.precision(), __v); __nc = __nolocale_snprintf(__nb, __nbuf, __fmt,
(int)__iob.precision(), __v);
else else
__nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v); __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, __v);
unique_ptr<char, void(*)(void*)> __nbh(0, free); unique_ptr<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__nbuf-1)) if (__nc > static_cast<int>(__nbuf-1))
{ {
if (__specify_precision) if (__specify_precision)
__nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v); __nc = __nolocale_asprintf(&__nb, __fmt, (int)__iob.precision(),
__v);
else else
__nc = asprintf_l(&__nb, 0, __fmt, __v); __nc = __nolocale_asprintf(&__nb, __fmt, __v);
if (__nb == 0) if (__nb == 0)
__throw_bad_alloc(); __throw_bad_alloc();
__nbh.reset(__nb); __nbh.reset(__nb);
@ -1510,7 +1642,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
char __fmt[6] = "%p"; char __fmt[6] = "%p";
const unsigned __nbuf = 20; const unsigned __nbuf = 20;
char __nar[__nbuf]; char __nar[__nbuf];
int __nc = sprintf_l(__nar, 0, __fmt, __v); int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc; char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob); char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar // Stage 2 - Widen __nar
@ -3162,7 +3294,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
// secure memory for digit storage // secure memory for digit storage
if (__n > __bs-1) if (__n > __bs-1)
{ {
__n = asprintf_l(&__bb, 0, "%.0Lf", __units); __n = __nolocale_asprintf(&__bb, "%.0Lf", __units);
if (__bb == 0) if (__bb == 0)
__throw_bad_alloc(); __throw_bad_alloc();
__hn.reset(__bb); __hn.reset(__bb);

View File

@ -358,6 +358,7 @@ template <> struct hash<wstring>;
#include <__config> #include <__config>
#include <iosfwd> #include <iosfwd>
#include <cstring> #include <cstring>
#include <cstdio> // For EOF.
#include <cwchar> #include <cwchar>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>

View File

@ -115,6 +115,9 @@ __thread_id get_id();
class __thread_id class __thread_id
{ {
// FIXME: pthread_t is a pointer on Darwin but a long on Linux.
// NULL is the no-thread value on Darwin. Someone needs to check
// on other platforms. We assume 0 works everywhere for now.
pthread_t __id_; pthread_t __id_;
public: public:
@ -206,7 +209,7 @@ public:
void swap(thread& __t) {_STD::swap(__t_, __t.__t_);} void swap(thread& __t) {_STD::swap(__t_, __t.__t_);}
bool joinable() const {return __t_ != nullptr;} bool joinable() const {return __t_ != 0;}
void join(); void join();
void detach(); void detach();
id get_id() const {return __t_;} id get_id() const {return __t_;}

View File

@ -1118,7 +1118,7 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
if (__n > __s) if (__n > __s)
__construct_at_end(__n - __s, __u); __construct_at_end(__n - __s, __u);
else else
__destruct_at_end(this->__begin_ + __n); this->__destruct_at_end(this->__begin_ + __n);
} }
else else
{ {

View File

@ -1,41 +1,60 @@
#! /bin/sh
#
# Set the $TRIPLE environment variable to your system's triple before
# running this script. If you set $CXX, that will be used to compile
# the library. Otherwise we'll use g++.
set -e
if [ `basename $(pwd)` != "lib" ] if [ `basename $(pwd)` != "lib" ]
then then
echo "current directory must be lib" echo "current directory must be lib"
exit 1 exit 1
fi fi
if [ -z $CC ] if [ -z $CXX ]
then then
CC=g++ CXX=g++
fi fi
case $TRIPLE in
*-apple-*)
if [ -z $RC_BUILDIT ]
then
RC_CFLAGS="-arch i386 -arch ppc -arch x86_64"
fi
SOEXT=dylib
LDSHARED_FLAGS="-o libc++.1.dylib \
-dynamiclib -nodefaultlibs -current_version 1 \
-compatibility_version 1 \
-install_name /usr/lib/libc++.dylib \
-Wl,-reexport_library,/usr/lib/libc++abi.dylib \
/usr/lib/libSystem.B.dylib"
;;
*)
RC_CFLAGS="-fPIC"
SOEXT=so
LDSHARED_FLAGS="-o libc++.so.1.0 \
-shared -nodefaultlibs -Wl,-soname,libc++.so.1 \
-lstdc++ -lc"
;;
esac
if [ -z $RC_BUILDIT ] if [ -z $RC_BUILDIT ]
then then
RC_CFLAGS="-arch i386 -arch ppc -arch x86_64" rm -f libc++.1.$SOEXT*
fi
if [ -z $RC_BUILDIT ]
then
rm libc++.1.dylib
fi fi
set -x set -x
for FILE in $(ls ../src/*.cpp); do for FILE in ../src/*.cpp; do
$CC -c -g -Os $RC_CFLAGS -nostdinc++ -I../include $FILE $CXX -c -g -Os $RC_CFLAGS -nostdinc++ -I../include $FILE
done done
$CC -dynamiclib -nodefaultlibs $RC_CFLAGS -current_version 1 \ $CXX *.o $RC_CFLAGS $LDSHARED_FLAGS
-compatibility_version 1 \
-o libc++.1.dylib *.o \
-install_name /usr/lib/libc++.dylib \
-Wl,-reexport_library,/usr/lib/libc++abi.dylib \
/usr/lib/libSystem.B.dylib
#libtool -static -o libc++.a *.o #libtool -static -o libc++.a *.o
set +x
if [ -z $RC_BUILDIT ] if [ -z $RC_BUILDIT ]
then then
rm *.o rm *.o

View File

@ -9,7 +9,13 @@
#include "chrono" #include "chrono"
#include <sys/time.h> //for gettimeofday and timeval #include <sys/time.h> //for gettimeofday and timeval
#if __APPLE__
#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t #include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
#else /* !__APPLE__ */
#include <cerrno> // errno
#include <system_error> // __throw_system_error
#include <time.h> // clock_gettime, CLOCK_MONOTONIC
#endif /* __APPLE__ */
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
@ -40,6 +46,7 @@ system_clock::from_time_t(time_t t)
// monotonic_clock // monotonic_clock
#if __APPLE__
// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
// are run time constants supplied by the OS. This clock has no relationship // are run time constants supplied by the OS. This clock has no relationship
@ -96,6 +103,26 @@ monotonic_clock::now()
return time_point(duration(fp())); return time_point(duration(fp()));
} }
#else /* !APPLE */
// FIXME: We assume that clock_gettime(CLOCK_MONOTONIC) works on
// non-apple systems. Instead, we should check _POSIX_TIMERS and
// _POSIX_MONOTONIC_CLOCK and fall back to something else if those
// don't exist.
// Warning: If this is not truly monotonic, then it is non-conforming. It is
// better for it to not exist and have the rest of libc++ use system_clock
// instead.
monotonic_clock::time_point
monotonic_clock::now()
{
struct timespec tp;
if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}
#endif /* APPLE */
} }
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -72,8 +72,11 @@ bool std::uncaught_exception() throw()
// on Darwin, there is a helper function so __cxa_get_globals is private // on Darwin, there is a helper function so __cxa_get_globals is private
return __cxxabiapple::__cxa_uncaught_exception(); return __cxxabiapple::__cxa_uncaught_exception();
#else #else
__cxa_eh_globals * globals = __cxa_get_globals(); #warning uncaught_exception not yet implemented
return (globals->uncaughtExceptions != 0); ::abort();
// Not provided by Ubuntu gcc-4.2.4's cxxabi.h.
// __cxa_eh_globals * globals = __cxa_get_globals();
// return (globals->uncaughtExceptions != 0);
#endif #endif
} }
@ -168,4 +171,3 @@ void std::rethrow_exception(exception_ptr p)
::abort(); ::abort();
#endif #endif
} }

View File

@ -106,7 +106,11 @@ __iostream_category::name() const
string string
__iostream_category::message(int ev) const __iostream_category::message(int ev) const
{ {
if (ev != static_cast<int>(io_errc::stream) && ev <= ELAST) if (ev != static_cast<int>(io_errc::stream)
#ifdef ELAST
&& ev <= ELAST
#endif
)
return __do_message::message(ev); return __do_message::message(ev);
return string("unspecified iostream_category error"); return string("unspecified iostream_category error");
} }

View File

@ -17,10 +17,11 @@
#include "cstring" #include "cstring"
#include "cwctype" #include "cwctype"
#include "__sso_allocator" #include "__sso_allocator"
#include <libkern/OSAtomic.h>
#include <langinfo.h> #include <langinfo.h>
#include <stdlib.h> #include <stdlib.h>
// FIXME: Locales are hard.
#if __APPLE__
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
namespace { namespace {
@ -534,7 +535,7 @@ locale::id::__get()
void void
locale::id::__init() locale::id::__init()
{ {
__id_ = OSAtomicIncrement32Barrier(&__next_id); __id_ = __sync_add_and_fetch(&__next_id, 1);
} }
// template <> class collate_byname<char> // template <> class collate_byname<char>
@ -3678,3 +3679,4 @@ template class codecvt_byname<char32_t, char, mbstate_t>;
template class __vector_base_common<true>; template class __vector_base_common<true>;
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
#endif /* __APPLE__ */

View File

@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "memory" #include "memory"
#include <libkern/OSAtomic.h>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
@ -16,57 +15,19 @@ namespace
{ {
template <class T> template <class T>
inline inline T
typename enable_if
<
sizeof(T) * __CHAR_BIT__ == 32,
T
>::type
increment(T& t) increment(T& t)
{ {
return OSAtomicIncrement32Barrier((volatile int32_t*)&t); return __sync_add_and_fetch(&t, 1);
} }
template <class T> template <class T>
inline inline T
typename enable_if
<
sizeof(T) * __CHAR_BIT__ == 32,
T
>::type
decrement(T& t) decrement(T& t)
{ {
return OSAtomicDecrement32Barrier((volatile int32_t*)&t); return __sync_add_and_fetch(&t, -1);
} }
#ifndef __ppc__
template <class T>
inline
typename enable_if
<
sizeof(T) * __CHAR_BIT__ == 64,
T
>::type
increment(T& t)
{
return OSAtomicIncrement64Barrier((volatile int64_t*)&t);
}
template <class T>
inline
typename enable_if
<
sizeof(T) * __CHAR_BIT__ == 64,
T
>::type
decrement(T& t)
{
return OSAtomicDecrement64Barrier((volatile int64_t*)&t);
}
#endif
} // namespace } // namespace
@ -134,9 +95,9 @@ __shared_weak_count::lock()
long object_owners = __shared_owners_; long object_owners = __shared_owners_;
while (object_owners != -1) while (object_owners != -1)
{ {
if (OSAtomicCompareAndSwapLongBarrier(object_owners, if (__sync_bool_compare_and_swap(&__shared_owners_,
object_owners+1, object_owners,
&__shared_owners_)) object_owners+1))
{ {
__add_weak(); __add_weak();
return this; return this;

View File

@ -148,7 +148,7 @@ timed_mutex::unlock()
recursive_timed_mutex::recursive_timed_mutex() recursive_timed_mutex::recursive_timed_mutex()
: __count_(0), : __count_(0),
__id_(nullptr) __id_(0)
{ {
} }
@ -197,7 +197,7 @@ recursive_timed_mutex::unlock()
unique_lock<mutex> lk(__m_); unique_lock<mutex> lk(__m_);
if (--__count_ == 0) if (--__count_ == 0)
{ {
__id_ = nullptr; __id_ = 0;
lk.unlock(); lk.unlock();
__cv_.notify_one(); __cv_.notify_one();
} }

View File

@ -8,12 +8,12 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include <stdlib.h> #include <stdlib.h>
#include <cxxabi.h>
#include "new" #include "new"
#if __APPLE__ #if __APPLE__
#include <cxxabi.h>
// On Darwin, there are two STL shared libraries and a lower level ABI // On Darwin, there are two STL shared libraries and a lower level ABI
// shared libray. The global holding the current new handler is // shared libray. The global holding the current new handler is
// in the ABI library and named __cxa_new_handler. // in the ABI library and named __cxa_new_handler.

View File

@ -15,7 +15,6 @@
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
#include "system_error" #include "system_error"
#include <libkern/OSAtomic.h>
// Note: optimize for size // Note: optimize for size
@ -59,7 +58,7 @@ inline
__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) __libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s)
: str_(s.str_) : str_(s.str_)
{ {
OSAtomicIncrement32Barrier(&count()); __sync_add_and_fetch(&count(), 1);
} }
__libcpp_nmstr& __libcpp_nmstr&
@ -67,8 +66,8 @@ __libcpp_nmstr::operator=(const __libcpp_nmstr& s)
{ {
const char* p = str_; const char* p = str_;
str_ = s.str_; str_ = s.str_;
OSAtomicIncrement32Barrier(&count()); __sync_add_and_fetch(&count(), 1);
if (OSAtomicDecrement32((count_t*)(p-sizeof(count_t))) < 0) if (__sync_add_and_fetch((count_t*)(p-sizeof(count_t)), -1) < 0)
delete [] (p-offset); delete [] (p-offset);
return *this; return *this;
} }
@ -76,7 +75,7 @@ __libcpp_nmstr::operator=(const __libcpp_nmstr& s)
inline inline
__libcpp_nmstr::~__libcpp_nmstr() __libcpp_nmstr::~__libcpp_nmstr()
{ {
if (OSAtomicDecrement32(&count()) < 0) if (__sync_add_and_fetch(&count(), -1) < 0)
delete [] (str_ - offset); delete [] (str_ - offset);
} }

View File

@ -64,9 +64,11 @@ __generic_error_category::name() const
string string
__generic_error_category::message(int ev) const __generic_error_category::message(int ev) const
{ {
if (ev <= ELAST) #ifdef ELAST
return __do_message::message(ev); if (ev > ELAST)
return string("unspecified generic_category error"); return string("unspecified generic_category error");
#endif
return __do_message::message(ev);
} }
const error_category& const error_category&
@ -94,17 +96,21 @@ __system_error_category::name() const
string string
__system_error_category::message(int ev) const __system_error_category::message(int ev) const
{ {
if (ev <= ELAST) #ifdef ELAST
return __do_message::message(ev); if (ev > ELAST)
return string("unspecified system_category error"); return string("unspecified system_category error");
#endif
return __do_message::message(ev);
} }
error_condition error_condition
__system_error_category::default_error_condition(int ev) const __system_error_category::default_error_condition(int ev) const
{ {
if (ev <= ELAST) #ifdef ELAST
return error_condition(ev, generic_category()); if (ev > ELAST)
return error_condition(ev, system_category()); return error_condition(ev, system_category());
#endif
return error_condition(ev, generic_category());
} }
const error_category& const error_category&

View File

@ -15,7 +15,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
thread::~thread() thread::~thread()
{ {
if (__t_ != nullptr) if (__t_ != 0)
terminate(); terminate();
} }
@ -25,7 +25,7 @@ thread::join()
int ec = pthread_join(__t_, 0); int ec = pthread_join(__t_, 0);
if (ec) if (ec)
throw system_error(error_code(ec, system_category()), "thread::join failed"); throw system_error(error_code(ec, system_category()), "thread::join failed");
__t_ = nullptr; __t_ = 0;
} }
void void
@ -45,11 +45,17 @@ thread::detach()
unsigned unsigned
thread::hardware_concurrency() thread::hardware_concurrency()
{ {
#if defined(CTL_HW) && defined(HW_NCPU)
int n; int n;
int mib[2] = {CTL_HW, HW_NCPU}; int mib[2] = {CTL_HW, HW_NCPU};
std::size_t s = sizeof(n); std::size_t s = sizeof(n);
sysctl(mib, 2, &n, &s, 0, 0); sysctl(mib, 2, &n, &s, 0, 0);
return n; return n;
#else // !defined(CTL_HW && HW_NCPU)
// TODO: grovel through /proc or check cpuid on x86 and similar
// instructions on other architectures.
return 0; // Means not computable [thread.thread.static]
#endif
} }
namespace this_thread namespace this_thread