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:
parent
2a59254a44
commit
adff4895b2
1
Makefile
1
Makefile
@ -7,6 +7,7 @@ DESTDIR = $(DSTROOT)
|
|||||||
|
|
||||||
OBJROOT=.
|
OBJROOT=.
|
||||||
SYMROOT=.
|
SYMROOT=.
|
||||||
|
TRIPLE=-apple-
|
||||||
|
|
||||||
installsrc:: $(SRCROOT)
|
installsrc:: $(SRCROOT)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
166
include/locale
166
include/locale
@ -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);
|
||||||
|
@ -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>
|
||||||
|
@ -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_;}
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
55
lib/buildit
55
lib/buildit
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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__ */
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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&
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user