Skip to content

Instantly share code, notes, and snippets.

@zbowling
Created September 29, 2014 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zbowling/0c9d00c958ece2f0d294 to your computer and use it in GitHub Desktop.
Save zbowling/0c9d00c958ece2f0d294 to your computer and use it in GitHub Desktop.
libc++ patches from google
From 4cc54e7dcd19f78a3ebaaa3c6f05885029c53b01 Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <digit@google.com>
Date: Wed, 12 Feb 2014 20:04:18 +0800
Subject: [PATCH 01/12] android: Add locale support.
This is based on the Bionic <ctype.h> declarations. Note that
unfortunately, the _ctype_ table exposed by this header has a bug
so a fixed copy is included here instead.
See src/support/android/locale_android.cpp for details.
---
include/__locale | 17 +++++-
src/locale.cpp | 25 +++++++-
src/support/android/locale_android.cpp | 101 +++++++++++++++++++++++++++++++++
3 files changed, 140 insertions(+), 3 deletions(-)
create mode 100644 src/support/android/locale_android.cpp
diff --git a/include/__locale b/include/__locale
index fb5b196..c793cfe 100644
--- a/include/__locale
+++ b/include/__locale
@@ -375,7 +375,20 @@ public:
static const mask punct = _ISPUNCT;
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
-#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__
+#elif defined(__ANDROID__)
+ typedef unsigned short mask;
+ static const mask space = _S;
+ static const mask print = _P | _U | _L | _N | _B;
+ static const mask cntrl = _C;
+ static const mask upper = _U;
+ static const mask lower = _L;
+ static const mask alpha = _U | _L;
+ static const mask digit = _N;
+ static const mask punct = _P;
+ static const mask xdigit = _N | _X;
+ // See src/support/android/locale_android.cpp for details!
+ static const mask blank = 0x100;
+#else // __ANDROID__
typedef unsigned long mask;
static const mask space = 1<<0;
static const mask print = 1<<1;
@@ -387,7 +400,7 @@ public:
static const mask punct = 1<<7;
static const mask xdigit = 1<<8;
static const mask blank = 1<<9;
-#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
+#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__ || __ANDROID__
static const mask alnum = alpha | digit;
static const mask graph = alnum | punct;
diff --git a/src/locale.cpp b/src/locale.cpp
index 4877f2b..66aaca9 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -814,6 +814,8 @@ ctype<wchar_t>::do_toupper(char_type c) const
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
+#elif defined(__ANDROID__)
+ return isascii(c) ? _toupper_tab_[c + 1] : c;
#else
return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
#endif
@@ -828,6 +830,8 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
: *low;
+#elif defined(__ANDROID__)
+ *low = isascii(*low) ? _toupper_tab_[*low + 1] : *low;
#else
*low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
#endif
@@ -841,6 +845,8 @@ ctype<wchar_t>::do_tolower(char_type c) const
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
+#elif defined(__ANDROID__)
+ return isascii(c) ? _tolower_tab_[c + 1] : c;
#else
return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
#endif
@@ -855,6 +861,8 @@ ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
: *low;
+#elif defined(__ANDROID__)
+ *low = isascii(*low) ? _tolower_tab_[*low + 1] : *low;
#else
*low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
#endif
@@ -924,6 +932,8 @@ ctype<char>::do_toupper(char_type c) const
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
return isascii(c) ?
static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
+#elif defined(__ANDROID__)
+ return isascii(c) ? _toupper_tab_[c + 1] : c;
#else
return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
#endif
@@ -941,6 +951,8 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
*low = isascii(*low) ?
static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
+#elif defined(__ANDROID__)
+ *low = isascii(*low) ? _toupper_tab_[*low + 1] : *low;
#else
*low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
#endif
@@ -958,6 +970,8 @@ ctype<char>::do_tolower(char_type c) const
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
return isascii(c) ?
static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
+#elif defined(__ANDROID__)
+ return isascii(c) ? _tolower_tab_[c + 1] : c;
#else
return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
#endif
@@ -973,6 +987,8 @@ ctype<char>::do_tolower(char_type* low, const char_type* high) const
*low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
*low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
+#elif defined(__ANDROID__)
+ *low = isascii(*low) ? _tolower_tab_[*low + 1] : *low;
#else
*low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
#endif
@@ -1018,6 +1034,11 @@ extern "C" const int ** __ctype_tolower_loc();
extern "C" const int ** __ctype_toupper_loc();
#endif
+#if defined(__ANDROID__)
+// See src/support/android/android_locale.cpp
+extern "C" const unsigned short* const _ctype_android;
+#endif
+
const ctype<char>::mask*
ctype<char>::classic_table() _NOEXCEPT
{
@@ -1035,6 +1056,8 @@ ctype<char>::classic_table() _NOEXCEPT
// going to end up dereferencing it later...
#elif defined(__EMSCRIPTEN__)
return *__ctype_b_loc();
+#elif defined(__ANDROID__)
+ return _ctype_android;
#elif defined(_AIX)
return (const unsigned int *)__lc_ctype_ptr->obj->mask;
#else
@@ -1422,7 +1445,7 @@ locale::id codecvt<wchar_t, char, mbstate_t>::id;
codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
: locale::facet(refs),
- __l(_LIBCPP_GET_C_LOCALE)
+ __l(0)
{
}
diff --git a/src/support/android/locale_android.cpp b/src/support/android/locale_android.cpp
new file mode 100644
index 0000000..7193028
--- /dev/null
+++ b/src/support/android/locale_android.cpp
@@ -0,0 +1,101 @@
+// -*- C++ -*-
+//===-------------------- support/win32/locale_win32.cpp ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <ctype.h>
+
+// Bionic exports the non-standard _ctype_ array in <ctype.h>,
+// unfortunately, cannot be used directly for libc++ because it doesn't
+// have a proper bit-flag for blank characters.
+//
+// Note that the header does define a _B flag (as 0x80), but it
+// is only set on the space (32) character, and used to implement
+// isprint() properly. The implementation of isblank() relies on
+// direct comparisons with 9 and 32 instead.
+//
+// The following is a local copy of the Bionic _ctype_ array that has
+// been modified in the following way:
+//
+// - It stores 16-bit unsigned values, instead of 8-bit char ones.
+//
+// - Bit flag _BLANK (0x100) is used to indicate blank characters.
+// It is only set for indices 9 (TAB) and 32 (SPACE).
+//
+// - Support signed char properly for indexing.
+
+// Used to tag blank characters, this doesn't appear in <ctype.h> nor
+// the original Bionic _ctype_ array.
+#define _BLANK 0x100
+
+// NOTE: A standalone forward declaration is required to ensure that this
+// variable is properly exported with a C name. In other words, this does
+// _not_ work:
+//
+// extern "C" {
+// const char* const _ctype_android = ...;
+// }
+//
+extern "C" const unsigned short* const _ctype_android;
+
+static const unsigned short ctype_android_tab[256+128] = {
+ /* -128..-1 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 80 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 88 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 90 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 98 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* A0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* A8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* B0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* B8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* C0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* C8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* D0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* D8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* E0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* E8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* F0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* F8 */
+ /* 0..127 */
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _C, _C|_S|_BLANK, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _S|_B|_BLANK, _P, _P, _P, _P, _P, _P, _P,
+ _P, _P, _P, _P, _P, _P, _P, _P,
+ _N, _N, _N, _N, _N, _N, _N, _N,
+ _N, _N, _P, _P, _P, _P, _P, _P,
+ _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
+ _U, _U, _U, _U, _U, _U, _U, _U,
+ _U, _U, _U, _U, _U, _U, _U, _U,
+ _U, _U, _U, _P, _P, _P, _P, _P,
+ _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
+ _L, _L, _L, _L, _L, _L, _L, _L,
+ _L, _L, _L, _L, _L, _L, _L, _L,
+ /* determine printability based on the IS0 8859 8-bit standard */
+ _L, _L, _L, _P, _P, _P, _P, _C,
+ /* 128..255, same as -128..127 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 80 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 88 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 90 */
+ _C, _C, _C, _C, _C, _C, _C, _C, /* 98 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* A0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* A8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* B0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* B8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* C0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* C8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* D0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* D8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* E0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* E8 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* F0 */
+ _P, _P, _P, _P, _P, _P, _P, _P, /* F8 */
+};
+
+const unsigned short* const _ctype_android = ctype_android_tab + 128;
--
1.9.1.423.g4596e3a
From 22849101b7d9413cc204af8427e7ebecc3da569c Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <digit@google.com>
Date: Wed, 12 Feb 2014 20:06:02 +0800
Subject: [PATCH 02/12] Fix GLibc-specific check.
---
include/__config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/__config b/include/__config
index ce39243..64519b7 100644
--- a/include/__config
+++ b/include/__config
@@ -317,7 +317,7 @@ typedef __char32_t char32_t;
#if defined(__FreeBSD__)
#define _LIBCPP_HAS_QUICK_EXIT
#define _LIBCPP_HAS_C11_FEATURES
-#elif defined(__linux__)
+#elif defined(__linux__) && defined(__GLIBC__)
#include <features.h>
#if __GLIBC_PREREQ(2, 15)
#define _LIBCPP_HAS_QUICK_EXIT
--
1.9.1.423.g4596e3a
From c6092cc576174fcbd433f3b34288255ef30f6510 Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Wed, 12 Feb 2014 20:07:01 +0800
Subject: [PATCH 03/12] Fallback to locale("C")
Android's newlocale() return null for anything other than "", "C",
and "POSIX", fallback to "C" to allow more tests to run and uncover
other issues.
---
src/locale.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 118 insertions(+), 6 deletions(-)
diff --git a/src/locale.cpp b/src/locale.cpp
index 66aaca9..0fba54d 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -54,6 +54,10 @@ locale_t __cloc() {
}
#endif // __cloc_defined
+inline locale_t __new_cloc() {
+ return newlocale(LC_ALL_MASK, "C", 0);
+}
+
namespace {
struct release
@@ -657,8 +661,14 @@ collate_byname<char>::collate_byname(const char* n, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("collate_byname<char>::collate_byname"
" failed to construct for " + string(n));
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -668,8 +678,14 @@ collate_byname<char>::collate_byname(const string& name, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("collate_byname<char>::collate_byname"
" failed to construct for " + name);
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -709,8 +725,14 @@ collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
" failed to construct for " + string(n));
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -720,8 +742,14 @@ collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
" failed to construct for " + name);
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -1117,8 +1145,14 @@ ctype_byname<char>::ctype_byname(const char* name, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("ctype_byname<char>::ctype_byname"
" failed to construct for " + string(name));
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -1128,8 +1162,14 @@ ctype_byname<char>::ctype_byname(const string& name, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("ctype_byname<char>::ctype_byname"
" failed to construct for " + name);
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -1174,8 +1214,14 @@ ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
" failed to construct for " + string(name));
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -1185,8 +1231,14 @@ ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
" failed to construct for " + name);
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -1455,8 +1507,14 @@ codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__l == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
" failed to construct for " + string(nm));
+#else
+ __l = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -4250,7 +4308,12 @@ numpunct_byname<char>::__init(const char* nm)
{
if (strcmp(nm, "C") != 0)
{
- __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
+ locale_t l = newlocale(LC_ALL_MASK, nm, 0);
+#if defined(__ANDROID__)
+ if (l == 0)
+ l = __new_cloc();
+#endif
+ __locale_unique_ptr loc(l, freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
if (loc == nullptr)
throw runtime_error("numpunct_byname<char>::numpunct_byname"
@@ -4293,7 +4356,12 @@ numpunct_byname<wchar_t>::__init(const char* nm)
{
if (strcmp(nm, "C") != 0)
{
- __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
+ locale_t l = newlocale(LC_ALL_MASK, nm, 0);
+#if defined(__ANDROID__)
+ if (l == 0)
+ l = __new_cloc();
+#endif
+ __locale_unique_ptr loc(l, freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
if (loc == nullptr)
throw runtime_error("numpunct_byname<char>::numpunct_byname"
@@ -4707,8 +4775,14 @@ __time_get::__time_get(const char* nm)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__loc_ == 0)
+ {
+#if !defined(__ANDROID__)
throw runtime_error("time_get_byname"
" failed to construct for " + string(nm));
+#else
+ __loc_ = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -4717,8 +4791,14 @@ __time_get::__time_get(const string& nm)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__loc_ == 0)
+ {
+# if !defined(__ANDROID__)
throw runtime_error("time_get_byname"
" failed to construct for " + nm);
+#else
+ __loc_ = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -5395,8 +5475,14 @@ __time_put::__time_put(const char* nm)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__loc_ == 0)
+ {
+# if !defined(__ANDROID__)
throw runtime_error("time_put_byname"
" failed to construct for " + string(nm));
+#else
+ __loc_ = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -5405,8 +5491,14 @@ __time_put::__time_put(const string& nm)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
if (__loc_ == 0)
+ {
+# if !defined(__ANDROID__)
throw runtime_error("time_put_byname"
" failed to construct for " + nm);
+#else
+ __loc_ = __new_cloc();
+#endif
+ }
#endif // _LIBCPP_NO_EXCEPTIONS
}
@@ -5825,7 +5917,12 @@ void
moneypunct_byname<char, false>::init(const char* nm)
{
typedef moneypunct<char, false> base;
- __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
+ locale_t l = newlocale(LC_ALL_MASK, nm, 0);
+#if defined(__ANDROID__)
+ if (l == 0)
+ l = __new_cloc();
+#endif
+ __locale_unique_ptr loc(l, freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
if (loc == nullptr)
throw runtime_error("moneypunct_byname"
@@ -5873,7 +5970,12 @@ void
moneypunct_byname<char, true>::init(const char* nm)
{
typedef moneypunct<char, true> base;
- __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
+ locale_t l = newlocale(LC_ALL_MASK, nm, 0);
+#if defined(__ANDROID__)
+ if (l == 0)
+ l = __new_cloc();
+#endif
+ __locale_unique_ptr loc(l, freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
if (loc == nullptr)
throw runtime_error("moneypunct_byname"
@@ -5938,7 +6040,12 @@ void
moneypunct_byname<wchar_t, false>::init(const char* nm)
{
typedef moneypunct<wchar_t, false> base;
- __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
+ locale_t l = newlocale(LC_ALL_MASK, nm, 0);
+#if defined(__ANDROID__)
+ if (l == 0)
+ l = __new_cloc();
+#endif
+ __locale_unique_ptr loc(l, freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
if (loc == nullptr)
throw runtime_error("moneypunct_byname"
@@ -6021,7 +6128,12 @@ void
moneypunct_byname<wchar_t, true>::init(const char* nm)
{
typedef moneypunct<wchar_t, true> base;
- __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
+ locale_t l = newlocale(LC_ALL_MASK, nm, 0);
+#if defined(__ANDROID__)
+ if (l == 0)
+ l = __new_cloc();
+#endif
+ __locale_unique_ptr loc(l, freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
if (loc == nullptr)
throw runtime_error("moneypunct_byname"
--
1.9.1.423.g4596e3a
From 8baffbc46d740e997c5c7b2958091d74beb7fa99 Mon Sep 17 00:00:00 2001
From: Logan Chien <logan.chien@mediatek.com>
Date: Wed, 12 Feb 2014 20:09:43 +0800
Subject: [PATCH 04/12] std::terminate() should not specify "throw ()" in C++
98.
---
include/exception | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/exception b/include/exception
index cad802e..681a659 100644
--- a/include/exception
+++ b/include/exception
@@ -112,7 +112,11 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
typedef void (*terminate_handler)();
_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
+#if __cplusplus >= 201103L
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
+#else
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate();
+#endif
_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
--
1.9.1.423.g4596e3a
From 939e32d87dff0fd949e54599d376bfae8381001a Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Wed, 12 Feb 2014 20:11:53 +0800
Subject: [PATCH 05/12] Fix gabi++/stlport/llvm-libc++ build
---
src/exception.cpp | 2 +-
src/new.cpp | 2 +-
src/stdexcept.cpp | 2 +-
src/typeinfo.cpp | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/exception.cpp b/src/exception.cpp
index 3ce6f2e..bd22133 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -29,7 +29,7 @@
#define __terminate_handler __cxxabiapple::__cxa_terminate_handler
#define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
#endif // _LIBCPPABI_VERSION
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
using namespace __cxxabiv1;
#if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
diff --git a/src/new.cpp b/src/new.cpp
index 3b7c341..9130ab3 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -27,7 +27,7 @@
#define __new_handler __cxxabiapple::__cxa_new_handler
#endif
#else // __APPLE__
- #if defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+ #if defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
#endif // __has_include(<cxxabi.h>)
#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
diff --git a/src/stdexcept.cpp b/src/stdexcept.cpp
index aff4b18..26de25f 100644
--- a/src/stdexcept.cpp
+++ b/src/stdexcept.cpp
@@ -18,7 +18,7 @@
#endif
/* For _LIBCPPABI_VERSION */
-#if __has_include(<cxxabi.h>) || defined(__APPLE_) || defined(LIBCXXRT)
+#if __has_include(<cxxabi.h>) || defined(__APPLE_) || defined(LIBCXXRT) || defined(__ANDROID__)
#include <cxxabi.h>
#endif
diff --git a/src/typeinfo.cpp b/src/typeinfo.cpp
index b428120..b1bceb5 100644
--- a/src/typeinfo.cpp
+++ b/src/typeinfo.cpp
@@ -14,7 +14,7 @@
#ifdef __APPLE__
#include <cxxabi.h>
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>) || defined(__ANDROID__)
#include <cxxabi.h>
#endif
--
1.9.1.423.g4596e3a
From 32d07c1ed42529efeb0664d4232bc5c94eedb6a9 Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Sun, 27 Apr 2014 22:19:17 -0700
Subject: [PATCH 06/12] Emulate __has_feature() for GCC
__config defines dozens of _LIBCPP_* flags based on the compiler support of
language features: for clang it uses __has_feature() to discover; for gcc most
flags are hard-coded based on gcc version. Unfortunately some code in libc++
still use __has_features() directly instead of _LIBCPP_* flags. This CL emulates
__has_feature() for GCC (from the default "0")
---
include/__config | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/include/__config b/include/__config
index 64519b7..df84ac6 100644
--- a/include/__config
+++ b/include/__config
@@ -434,6 +434,66 @@ using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
#define _LIBCPP_HAS_NO_ASAN
#endif
+// Emulation of clang's __has_feature() for GCC on known cases
+#ifndef __has_feature
+
+#define __gxx__cxx_access_control_sfinae !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) || !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) // Also see usage in 7 tests
+#define __gxx__cxx_alias_templates !defined(_LIBCPP_HAS_NO_TEMPLATE_ALIASES)
+#define __gxx__cxx_address_sanitizer !defined(_LIBCPP_HAS_NO_ASAN)
+#define __gxx__cxx_alignas 0 // Not sure, doesn't matter.
+#define __gxx__cxx_atomic 0 // (_GNUC_VER >= 409) seems to support _Atomic in -std=c11 not -std=c++11 !
+#define __gxx__cxx_attributes 0 // Not sure. Also see usage in libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp
+#define __gxx__cxx_auto_type !defined(_LIBCPP_HAS_NO_AUTO_TYPE)
+#define __gxx__cxx_constexpr !defined(_LIBCPP_HAS_NO_CONSTEXPR)
+#define __gxx__cxx_decltype !defined(_LIBCPP_HAS_NO_DECLTYPE)
+#define __gxx__cxx_defaulted_functions !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) // libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp
+#define __gxx__cxx_deleted_functions !defined(_LIBCPP_HAS_NO_DELETED_FUNCTIONS)
+#define __gxx__cxx_exceptions !defined(_LIBCPP_NO_EXCEPTIONS)
+#define __gxx__cxx_explicit_conversions (_GNUC_VER >= 405)
+#define __gxx__cxx_generalized_initializers !defined(_LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS)
+#define __gxx__cxx_lambdas !defined(_LIBCPP_HAS_NO_LAMBDAS)
+#define __gxx__cxx_noexcept 0 // Not sure, doesn't matter.
+#define __gxx__cxx_nullptr !defined(_LIBCPP_HAS_NO_NULLPTR)
+#define __gxx__cxx_reference_qualified_functions (_GNUC_VER >= 408) // Not if 4.7 work. 4.6 certainly not. Also see usage in libcxx/include/type_traits
+#ifdef _LIBCPP_NO_RTTI
+#define __gxx__cxx_rtti 0
+#else
+#define __gxx__cxx_rtti __GXX_RTTI
+#endif
+#define __gxx__cxx_rvalue_references !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+#define __gxx__cxx_static_assert !defined(_LIBCPP_HAS_NO_STATIC_ASSERT)
+#define __gxx__cxx_strong_enums !defined(_LIBCPP_HAS_NO_STRONG_ENUMS) // See usage in libcxx/test/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
+#define __gxx__cxx_trailing_return !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
+#define __gxx__cxx_unrestricted_unions 1 // Not sure. Also See usage in libcxx/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
+#define __gxx__cxx_variadic_templates !defined(_LIBCPP_HAS_NO_VARIADICS)
+#define __gxx__has_nothrow_assign (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__has_nothrow_constructor (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__has_nothrow_copy (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__has_trivial_constructor (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__has_trivial_destructor (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__has_virtual_destructor (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__is_base_of !defined(_LIBCPP_HAS_IS_BASE_OF) // See usage in libcxx/include/type_traits
+#define __gxx__is_class (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__is_convertible_to 0 // Not supported in GCC 4.8. Also see usage in libcxx/include/type_traits
+#define __gxx__is_empty 1 // Not sure. Also see usage in libcxx/include/type_traits
+#define __gxx__is_enum (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__is_final (_GNUC_VER >= 408) // Not if 4.7 work. 4.6 certainly not. Also see usage in libcxx/include/unordered_map,tuple,ext/hash_map,map,memory
+#define __gxx__is_literal 0 // Not supported in GCC 4.8. Also see usage in libcxx/include/type_traits
+#define __gxx__is_pod (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__is_polymorphic 1 // Not sure. Also see usage in libcxx/include/type_traits
+#define __gxx__is_standard_layout 1 // Not sure. Also see usage in libcxx/include/type_traits
+#define __gxx__is_trivial 0 // Not supported in GCC 4.8. Also see usage in libcxx/include/type_traits
+#define __gxx__is_trivially_constructible 0 // Not supported in GCC 4.8. Also see usage in libcxx/include/type_traits
+#define __gxx__is_trivially_copyable 0 // Not supported in GCC 4.8. Also see usage in libcxx/include/type_traits
+#define __gxx__is_union (_GNUC_VER >= 403) // See usage in libcxx/include/type_traits
+#define __gxx__objc_arc defined(_LIBCPP_HAS_OBJC_ARC)
+#define __gxx__objc_arc_weak defined(_LIBCPP_HAS_OBJC_ARC_WEAK)
+#define __gxx__underlying_type 1 // Not sure. Also see usage in libcxx/include/type_traits
+
+#define __has_feature(__x) __gxx__ ## __x
+
+#endif // __has_feature
+
#elif defined(_LIBCPP_MSVC)
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
--
1.9.1.423.g4596e3a
From 3754d92809b7067a98e38a19ea4e10b36ad52bc7 Mon Sep 17 00:00:00 2001
From: Carl Norum <carl@norum.ca>
Date: Sun, 27 Apr 2014 22:21:24 -0700
Subject: [PATCH 07/12] Fix libc++ compiler error when calling std::feof()
The following functions are "macro" in bionic's stdio.h and also
defined in cstdio's std:: getchar, putchar, clearerr, feof, ferror
Undef them and re-define as inlined functions otherwise use of
std::feof, for example, break compilation.
See b.android.com/66668 and b.android.com/36496
---
include/cstdio | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/include/cstdio b/include/cstdio
index ce3af4d..7787fad 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -114,12 +114,42 @@ inline _LIBCPP_INLINE_VISIBILITY int __libcpp_getc(FILE* __stream) {return getc(
inline _LIBCPP_INLINE_VISIBILITY int getc(FILE* __stream) {return __libcpp_getc(__stream);}
#endif // getc
+#ifdef getchar
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_getchar(void) {return getchar();}
+#undef getchar
+inline _LIBCPP_INLINE_VISIBILITY int getchar(void) {return __libcpp_getchar();}
+#endif // getchar
+
#ifdef putc
inline _LIBCPP_INLINE_VISIBILITY int __libcpp_putc(int __c, FILE* __stream) {return putc(__c, __stream);}
#undef putc
inline _LIBCPP_INLINE_VISIBILITY int putc(int __c, FILE* __stream) {return __libcpp_putc(__c, __stream);}
#endif // putc
+#ifdef putchar
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_putchar(int __c) {return putchar(__c);}
+#undef putchar
+inline _LIBCPP_INLINE_VISIBILITY int putchar(int __c) {return __libcpp_putchar(__c);}
+#endif // putchar
+
+#ifdef clearerr
+inline _LIBCPP_INLINE_VISIBILITY void __libcpp_clearerr(FILE* __stream) {return clearerr(__stream);}
+#undef clearerr
+inline _LIBCPP_INLINE_VISIBILITY void clearerr(FILE* __stream) {return __libcpp_clearerr(__stream);}
+#endif // clearerr
+
+#ifdef feof
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_feof(FILE* __stream) {return feof(__stream);}
+#undef feof
+inline _LIBCPP_INLINE_VISIBILITY int feof(FILE* __stream) {return __libcpp_feof(__stream);}
+#endif // feof
+
+#ifdef ferror
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_ferror(FILE* __stream) {return ferror(__stream);}
+#undef ferror
+inline _LIBCPP_INLINE_VISIBILITY int ferror(FILE* __stream) {return __libcpp_ferror(__stream);}
+#endif // ferror
+
_LIBCPP_BEGIN_NAMESPACE_STD
using ::FILE;
--
1.9.1.423.g4596e3a
From 848c37e08f93ea14fbc430d5e85517da8a6589ac Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Sun, 27 Apr 2014 22:22:32 -0700
Subject: [PATCH 08/12] Remove gcc warning about redefinition of putchar with
different visibility
In NDK bionic's stdio.h, putchar appears as both a function prototype and a macro
(later in the same header). Because it's defined as a macro, libc++ replaces
it with a function but with *different* visibility. GCC 4.x complains [-Wattributes]
include/stdio.h:236:5: warning: conflicts with previous declaration here [-Wattributes]
int putchar(int);
Undefine putchar to avoid redefinition, and putchar does exist in libc.so
---
include/cstdio | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/include/cstdio b/include/cstdio
index 7787fad..8f2a7b0 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -126,6 +126,19 @@ inline _LIBCPP_INLINE_VISIBILITY int __libcpp_putc(int __c, FILE* __stream) {ret
inline _LIBCPP_INLINE_VISIBILITY int putc(int __c, FILE* __stream) {return __libcpp_putc(__c, __stream);}
#endif // putc
+#ifdef __ANDROID__
+// In bionic's stdio.h, putchar appears as both a function prototype and a macro (later
+// in the same header). Because it's defined as a macro, the following code snippet replaces
+// it with a function but with *different* visibility. GCC 4.x complains [-Wattributes]
+//
+// include/stdio.h:236:5: warning: conflicts with previous declaration here [-Wattributes]
+// int putchar(int);
+//
+// Undefine putchar to avoid redefinition, and putchar does exist in libc.so
+//
+#undef putchar
+#endif
+
#ifdef putchar
inline _LIBCPP_INLINE_VISIBILITY int __libcpp_putchar(int __c) {return putchar(__c);}
#undef putchar
--
1.9.1.423.g4596e3a
From cee395a0340092c61a4024a2021842e9d43bc544 Mon Sep 17 00:00:00 2001
From: Pavel Chupin <pavel.v.chupin@intel.com>
Date: Sun, 27 Apr 2014 22:23:39 -0700
Subject: [PATCH 09/12] Fix locale stuff for LP64
---
include/__locale | 13 +++++++++++++
src/support/android/locale_android.cpp | 14 ++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/include/__locale b/include/__locale
index c793cfe..d078810 100644
--- a/include/__locale
+++ b/include/__locale
@@ -376,6 +376,19 @@ public:
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
#elif defined(__ANDROID__)
+# if !defined(_U)
+# if !defined(_CTYPE_U)
+# error Bionic header ctype.h does not define either _U nor _CTYPE_U
+# endif
+# define _U _CTYPE_U
+# define _L _CTYPE_L
+# define _N _CTYPE_N
+# define _S _CTYPE_S
+# define _P _CTYPE_P
+# define _C _CTYPE_C
+# define _X _CTYPE_X
+# define _B _CTYPE_B
+# endif
typedef unsigned short mask;
static const mask space = _S;
static const mask print = _P | _U | _L | _N | _B;
diff --git a/src/support/android/locale_android.cpp b/src/support/android/locale_android.cpp
index 7193028..9716458 100644
--- a/src/support/android/locale_android.cpp
+++ b/src/support/android/locale_android.cpp
@@ -43,6 +43,20 @@
//
extern "C" const unsigned short* const _ctype_android;
+#if !defined(_U)
+# if !defined(_CTYPE_U)
+# error Bionic header ctype.h does not define either _U nor _CTYPE_U
+# endif
+# define _U _CTYPE_U
+# define _L _CTYPE_L
+# define _N _CTYPE_N
+# define _S _CTYPE_S
+# define _P _CTYPE_P
+# define _C _CTYPE_C
+# define _X _CTYPE_X
+# define _B _CTYPE_B
+#endif
+
static const unsigned short ctype_android_tab[256+128] = {
/* -128..-1 */
_C, _C, _C, _C, _C, _C, _C, _C, /* 80 */
--
1.9.1.423.g4596e3a
From 71979479fd219fefa56ac8d260d756e6f9af915f Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Sun, 27 Apr 2014 22:29:20 -0700
Subject: [PATCH 11/12] Fix tests for Android
---
test/containers/Emplaceable.h | 7 +++++++
test/containers/MoveOnly.h | 7 +++++++
test/depr/depr.c.headers/float_h.pass.cpp | 8 ++++++++
test/depr/depr.c.headers/math_h.pass.cpp | 7 +++++++
test/depr/depr.c.headers/stdbool_h.pass.cpp | 6 ++++++
test/depr/depr.c.headers/stdio_h.pass.cpp | 6 ++++++
.../exception.unexpected/set.unexpected/get_unexpected.pass.cpp | 4 ++++
.../exception.unexpected/set.unexpected/set_unexpected.pass.cpp | 4 ++++
test/input.output/file.streams/c.files/cstdio.pass.cpp | 6 ++++++
.../file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp | 4 ++++
.../file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp | 4 ++++
test/input.output/iostream.format/ext.manip/get_money.pass.cpp | 4 ++++
test/input.output/iostream.format/ext.manip/get_time.pass.cpp | 4 ++++
test/input.output/iostream.format/ext.manip/put_money.pass.cpp | 4 ++++
.../ostream.inserters.arithmetic/pointer.pass.cpp | 4 ++++
test/language.support/support.start.term/quick_exit.pass.cpp | 2 ++
test/numerics/c.math/cmath.pass.cpp | 8 ++++++++
.../thread.once/thread.once.callonce/call_once.pass.cpp | 8 ++++++++
18 files changed, 97 insertions(+)
diff --git a/test/containers/Emplaceable.h b/test/containers/Emplaceable.h
index 34dd326..b5e7971 100644
--- a/test/containers/Emplaceable.h
+++ b/test/containers/Emplaceable.h
@@ -14,7 +14,14 @@
class Emplaceable
{
+#if !defined(__clang__)
+// GCC 4.8 when compile ccontainers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp, etc,
+// complains about the following being private
+public:
+ Emplaceable(const Emplaceable&) {}
+#else
Emplaceable(const Emplaceable&);
+#endif
Emplaceable& operator=(const Emplaceable&);
int int_;
diff --git a/test/containers/MoveOnly.h b/test/containers/MoveOnly.h
index e4d9f64..cf988cf 100644
--- a/test/containers/MoveOnly.h
+++ b/test/containers/MoveOnly.h
@@ -17,7 +17,14 @@
class MoveOnly
{
+#if !defined(__clang__)
+// GCC 4.8 when compile containers/associative/map/map.cons/move_alloc.pass.cpp, etc,
+// complains about the following being private
+public:
+ MoveOnly(const MoveOnly&) {}
+#else
MoveOnly(const MoveOnly&);
+#endif
MoveOnly& operator=(const MoveOnly&);
int data_;
diff --git a/test/depr/depr.c.headers/float_h.pass.cpp b/test/depr/depr.c.headers/float_h.pass.cpp
index 5b2e451..8df0937 100644
--- a/test/depr/depr.c.headers/float_h.pass.cpp
+++ b/test/depr/depr.c.headers/float_h.pass.cpp
@@ -16,8 +16,12 @@
#endif
#ifndef FLT_EVAL_METHOD
+#if !defined(__clang__) && !defined(__FLT_EVAL_METHOD__)
+// GCC defines __FLT_EVAL_METHOD__ in lib/gcc/arm-linux-androideabi/4.8/include/float.h.
+// In libc++ include/cfloat define FLT_EVAL_METHOD to __FLT_EVAL_METHOD__
#error FLT_EVAL_METHOD not defined
#endif
+#endif
#ifndef FLT_RADIX
#error FLT_RADIX not defined
@@ -36,8 +40,12 @@
#endif
#ifndef DECIMAL_DIG
+#if !defined(__clang__) && !defined(__DECIMAL_DIG__)
+// GCC defines __DECIMAL_DIG__ in lib/gcc/arm-linux-androideabi/4.8/include/float.h.
+// In libc++ include/cfloat define DECIMAL_DIG to __DECIMAL_DIG__
#error DECIMAL_DIG not defined
#endif
+#endif
#ifndef FLT_DIG
#error FLT_DIG not defined
diff --git a/test/depr/depr.c.headers/math_h.pass.cpp b/test/depr/depr.c.headers/math_h.pass.cpp
index 858e190..f26f10d 100644
--- a/test/depr/depr.c.headers/math_h.pass.cpp
+++ b/test/depr/depr.c.headers/math_h.pass.cpp
@@ -221,7 +221,10 @@ void test_isfinite()
void test_isinf()
{
static_assert((std::is_same<decltype(isinf((float)0)), bool>::value), "");
+#if !(defined(__ANDROID__) && (__LP64__ || __ANDROID_API__ >= 20))
+ // 64-bit bionic isinf(double) returns int.
static_assert((std::is_same<decltype(isinf((double)0)), bool>::value), "");
+#endif
static_assert((std::is_same<decltype(isinf((long double)0)), bool>::value), "");
assert(isinf(-1.0) == false);
}
@@ -229,7 +232,11 @@ void test_isinf()
void test_isnan()
{
static_assert((std::is_same<decltype(isnan((float)0)), bool>::value), "");
+#if !defined(__ANDROID__)
+ // bionic isnan(double) returns int. Not sure how isnan(float) and isnan(long double) pass.
+ // Mask this check to reveal/fix more seirous one: eg. lack of log2 and nettoward, etc
static_assert((std::is_same<decltype(isnan((double)0)), bool>::value), "");
+#endif
static_assert((std::is_same<decltype(isnan((long double)0)), bool>::value), "");
assert(isnan(-1.0) == false);
}
diff --git a/test/depr/depr.c.headers/stdbool_h.pass.cpp b/test/depr/depr.c.headers/stdbool_h.pass.cpp
index cd4d4c4..41aa3e3 100644
--- a/test/depr/depr.c.headers/stdbool_h.pass.cpp
+++ b/test/depr/depr.c.headers/stdbool_h.pass.cpp
@@ -15,6 +15,10 @@
#error __bool_true_false_are_defined not defined
#endif
+#if !defined(__clang__)
+// GCC defines bool, true, and false in lib/gcc/arm-linux-androideabi/4.8/include/stdbool.h
+#else
+
#ifdef bool
#error bool should not be defined
#endif
@@ -27,6 +31,8 @@
#error false should not be defined
#endif
+#endif
+
int main()
{
}
diff --git a/test/depr/depr.c.headers/stdio_h.pass.cpp b/test/depr/depr.c.headers/stdio_h.pass.cpp
index 8e236e3..058b300 100644
--- a/test/depr/depr.c.headers/stdio_h.pass.cpp
+++ b/test/depr/depr.c.headers/stdio_h.pass.cpp
@@ -130,7 +130,13 @@ int main()
static_assert((std::is_same<decltype(ftell(fp)), long>::value), "");
static_assert((std::is_same<decltype(rewind(fp)), void>::value), "");
static_assert((std::is_same<decltype(clearerr(fp)), void>::value), "");
+#if !defined(feof)
+ //check return type of feof only if it's not an macro which may be a compound expression
static_assert((std::is_same<decltype(feof(fp)), int>::value), "");
+#endif
+#if !defined(ferror)
+ //check return type of ferror only if it's not an macro which may be a compound expression
static_assert((std::is_same<decltype(ferror(fp)), int>::value), "");
+#endif
static_assert((std::is_same<decltype(perror("")), void>::value), "");
}
diff --git a/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp b/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp
index 8b0a0b9..c2d7d75 100644
--- a/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp
+++ b/test/depr/exception.unexpected/set.unexpected/get_unexpected.pass.cpp
@@ -34,6 +34,10 @@ int main()
assert(std::get_unexpected() == f2);
// verify calling original unexpected handler calls terminate
std::set_terminate(f3);
+#if !defined(__ANDROID__)
+ // Disable the following for Android whoes __gabixx::__default_terminate()
+ // causes segfault on purpose to get stack dump
(*old)();
assert(0);
+#endif
}
diff --git a/test/depr/exception.unexpected/set.unexpected/set_unexpected.pass.cpp b/test/depr/exception.unexpected/set.unexpected/set_unexpected.pass.cpp
index ed02fa6..425b606 100644
--- a/test/depr/exception.unexpected/set.unexpected/set_unexpected.pass.cpp
+++ b/test/depr/exception.unexpected/set.unexpected/set_unexpected.pass.cpp
@@ -30,6 +30,10 @@ int main()
assert(std::set_unexpected(f2) == f1);
// verify calling original unexpected handler calls terminate
std::set_terminate(f3);
+#if !defined(__ANDROID__)
+ // Disable the following for Android whoes __gabixx::__default_terminate()
+ // causes segfault on purpose to get stack dump
(*old)();
assert(0);
+#endif
}
diff --git a/test/input.output/file.streams/c.files/cstdio.pass.cpp b/test/input.output/file.streams/c.files/cstdio.pass.cpp
index 1a60dd6..e28d0cf 100644
--- a/test/input.output/file.streams/c.files/cstdio.pass.cpp
+++ b/test/input.output/file.streams/c.files/cstdio.pass.cpp
@@ -133,7 +133,13 @@ int main()
static_assert((std::is_same<decltype(std::ftell(fp)), long>::value), "");
static_assert((std::is_same<decltype(std::rewind(fp)), void>::value), "");
static_assert((std::is_same<decltype(std::clearerr(fp)), void>::value), "");
+#if !defined(feof)
+ //check return type of feof only if it's not an macro which may be a compound expression
static_assert((std::is_same<decltype(std::feof(fp)), int>::value), "");
+#endif
+#if !defined(ferror)
+ //check return type of ferror only if it's not an macro which may be a compound expression
static_assert((std::is_same<decltype(std::ferror(fp)), int>::value), "");
+#endif
static_assert((std::is_same<decltype(std::perror("")), void>::value), "");
}
diff --git a/test/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp b/test/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp
index 1da3856..f6dc14e 100644
--- a/test/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp
+++ b/test/input.output/file.streams/fstreams/filebuf.virtuals/overflow.pass.cpp
@@ -115,6 +115,9 @@ int main()
assert(f.sgetc() == L'a');
}
std::remove("overflow.dat");
+#if !defined(__ANDROID__)
+ // Remove tests setlocale() to other than "", "C", and "POSIX"
+ // for Android
{
test_buf<wchar_t> f;
f.pubimbue(std::locale(LOCALE_en_US_UTF_8));
@@ -139,4 +142,5 @@ int main()
assert(f.sbumpc() == -1);
}
std::remove("overflow.dat");
+#endif // __ANDROID__
}
diff --git a/test/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp b/test/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp
index e34bc84..a66d9d3 100644
--- a/test/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp
+++ b/test/input.output/file.streams/fstreams/filebuf.virtuals/underflow.pass.cpp
@@ -108,6 +108,9 @@ int main()
assert(*f.gptr() == L'9');
assert(f.egptr() - f.gptr() == 1);
}
+#if !defined(__ANDROID__)
+ // Remove tests setlocale() to other than "", "C", and "POSIX"
+ // for Android
{
test_buf<wchar_t> f;
f.pubimbue(std::locale(LOCALE_en_US_UTF_8));
@@ -118,4 +121,5 @@ int main()
assert(f.sbumpc() == 0x4E53);
assert(f.sbumpc() == -1);
}
+#endif // __ANDROID__
}
diff --git a/test/input.output/iostream.format/ext.manip/get_money.pass.cpp b/test/input.output/iostream.format/ext.manip/get_money.pass.cpp
index cdd762a..5b7c69d 100644
--- a/test/input.output/iostream.format/ext.manip/get_money.pass.cpp
+++ b/test/input.output/iostream.format/ext.manip/get_money.pass.cpp
@@ -38,6 +38,9 @@ public:
int main()
{
+#if !defined(__ANDROID__)
+ // Remove tests setlocale() to other than "", "C", and "POSIX"
+ // for Android
{
testbuf<char> sb(" -$1,234,567.89");
std::istream is(&sb);
@@ -70,4 +73,5 @@ int main()
is >> std::get_money(x, true);
assert(x == -123456789);
}
+#endif
}
diff --git a/test/input.output/iostream.format/ext.manip/get_time.pass.cpp b/test/input.output/iostream.format/ext.manip/get_time.pass.cpp
index 6866552..7a11319 100644
--- a/test/input.output/iostream.format/ext.manip/get_time.pass.cpp
+++ b/test/input.output/iostream.format/ext.manip/get_time.pass.cpp
@@ -54,6 +54,9 @@ int main()
assert(is.eof());
assert(!is.fail());
}
+#if !defined(__ANDROID__)
+ // Remove tests setlocale() to other than "", "C", and "POSIX"
+ // for Android
{
testbuf<wchar_t> sb(L" Sat Dec 31 23:55:59 2061");
std::wistream is(&sb);
@@ -70,4 +73,5 @@ int main()
assert(is.eof());
assert(!is.fail());
}
+#endif
}
diff --git a/test/input.output/iostream.format/ext.manip/put_money.pass.cpp b/test/input.output/iostream.format/ext.manip/put_money.pass.cpp
index 8d15dd9..aca45cd 100644
--- a/test/input.output/iostream.format/ext.manip/put_money.pass.cpp
+++ b/test/input.output/iostream.format/ext.manip/put_money.pass.cpp
@@ -50,6 +50,9 @@ protected:
int main()
{
+#if !defined(__ANDROID__)
+ // Remove tests setlocale() to other than "", "C", and "POSIX"
+ // for Android
{
testbuf<char> sb;
std::ostream os(&sb);
@@ -86,4 +89,5 @@ int main()
os << std::put_money(x, true);
assert(sb.str() == L"-USD 1,234,567.89");
}
+#endif // __ANDROID__
}
diff --git a/test/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp b/test/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp
index 114bba9..d9b23b9 100644
--- a/test/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp
+++ b/test/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp
@@ -69,8 +69,12 @@ int main()
// any leading 0x like prefix.
// In that format, we assume a null pointer will yield 2 '0' hex digits
// for each 8 bits of address space.
+#if !defined(__ANDROID__)
assert(sb.str() == "0x0" || sb.str() == "(nil)" ||
sb.str() == std::string(sizeof(void*)*2,'0'));
+#else
+ assert(sb.str() == "0");
+#endif
}
{
testbuf<char> sb;
diff --git a/test/language.support/support.start.term/quick_exit.pass.cpp b/test/language.support/support.start.term/quick_exit.pass.cpp
index 1945a1b..f001812 100644
--- a/test/language.support/support.start.term/quick_exit.pass.cpp
+++ b/test/language.support/support.start.term/quick_exit.pass.cpp
@@ -18,6 +18,8 @@ void f() {}
int main()
{
+#ifdef _LIBCPP_HAS_QUICK_EXIT
std::at_quick_exit(f);
quick_exit(0);
+#endif
}
diff --git a/test/numerics/c.math/cmath.pass.cpp b/test/numerics/c.math/cmath.pass.cpp
index 7c74d5b..b526cac 100644
--- a/test/numerics/c.math/cmath.pass.cpp
+++ b/test/numerics/c.math/cmath.pass.cpp
@@ -481,7 +481,10 @@ void test_isinf()
#error isinf defined
#endif
static_assert((std::is_same<decltype(std::isinf((float)0)), bool>::value), "");
+#if !(defined(__ANDROID__) && (__LP64__ || __ANDROID_API__ >= 20))
+ // bionic isnan(double) returns int.
static_assert((std::is_same<decltype(std::isinf((double)0)), bool>::value), "");
+#endif
static_assert((std::is_same<decltype(std::isinf(0)), bool>::value), "");
static_assert((std::is_same<decltype(std::isinf((long double)0)), bool>::value), "");
assert(std::isinf(-1.0) == false);
@@ -493,8 +496,13 @@ void test_isnan()
#error isnan defined
#endif
static_assert((std::is_same<decltype(std::isnan((float)0)), bool>::value), "");
+#if !defined(__ANDROID__)
+ // bionic isnan(double) returns int. Not sure how isnan(float) and isnan(long double) pass.
+ // Mask this check to reveal/fix more seirous one: eg. lack of log2 and nettoward, etc
+
static_assert((std::is_same<decltype(std::isnan((double)0)), bool>::value), "");
static_assert((std::is_same<decltype(std::isnan(0)), bool>::value), "");
+#endif
static_assert((std::is_same<decltype(std::isnan((long double)0)), bool>::value), "");
assert(std::isnan(-1.0) == false);
}
diff --git a/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
index b4f76b4..a60e17f 100644
--- a/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
+++ b/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
@@ -133,7 +133,15 @@ void f42()
class MoveOnly
{
+#if !defined(__clang__)
+ // GCC 4.8 complains about the following being private
+public:
+ MoveOnly(const MoveOnly&)
+ {
+ }
+#else
MoveOnly(const MoveOnly&);
+#endif
public:
MoveOnly() {}
MoveOnly(MoveOnly&&) {}
--
1.9.1.423.g4596e3a
From eef1d2c332be60e4455cbb6e7710ee3c0f8d6f31 Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Mon, 2 Jun 2014 18:01:55 +0800
Subject: [PATCH 12/12] Relax some __always_inline__ for GCC 4.9
To workaround GCC 4.9 which fails to __always_inline__ some functions
---
include/__config | 12 +++++++++++-
include/locale | 2 +-
include/string | 20 ++++++++++----------
3 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/include/__config b/include/__config
index df84ac6..0f443a9 100644
--- a/include/__config
+++ b/include/__config
@@ -191,6 +191,7 @@
#ifndef _LIBCPP_INLINE_VISIBILITY
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
+#define _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49 _LIBCPP_INLINE_VISIBILITY
#endif
#ifndef _LIBCPP_EXCEPTION_ABI
@@ -199,6 +200,7 @@
#ifndef _LIBCPP_ALWAYS_INLINE
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__))
+#define _LIBCPP_ALWAYS_INLINE_EXCEPT_GCC49 _LIBCPP_ALWAYS_INLINE
#endif
#if defined(__clang__)
@@ -358,6 +360,14 @@ namespace std {
#elif defined(__GNUC__)
+// FixME: GCC4.9 fails some always_inline cases
+# if (_GNUC_VER == 409)
+#undef _LIBCPP_ALWAYS_INLINE_EXCEPT_GCC49
+#define _LIBCPP_ALWAYS_INLINE_EXCEPT_GCC49 inline
+#undef _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
+#define _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
+#endif
+
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
@@ -454,7 +464,7 @@ using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
#define __gxx__cxx_lambdas !defined(_LIBCPP_HAS_NO_LAMBDAS)
#define __gxx__cxx_noexcept 0 // Not sure, doesn't matter.
#define __gxx__cxx_nullptr !defined(_LIBCPP_HAS_NO_NULLPTR)
-#define __gxx__cxx_reference_qualified_functions (_GNUC_VER >= 408) // Not if 4.7 work. 4.6 certainly not. Also see usage in libcxx/include/type_traits
+#define __gxx__cxx_reference_qualified_functions (_GNUC_VER >= 408) // Since 4.8.1
#ifdef _LIBCPP_NO_RTTI
#define __gxx__cxx_rtti 0
#else
diff --git a/include/locale b/include/locale
index 7191290..60c6182 100644
--- a/include/locale
+++ b/include/locale
@@ -2799,7 +2799,7 @@ public:
explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
: moneypunct<_CharT, _International>(__refs) {init(__nm);}
- _LIBCPP_ALWAYS_INLINE
+ _LIBCPP_ALWAYS_INLINE_EXCEPT_GCC49
explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
: moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
diff --git a/include/string b/include/string
index bb8f111..ba83e22 100644
--- a/include/string
+++ b/include/string
@@ -1368,26 +1368,26 @@ private:
public:
static const size_type npos = -1;
- _LIBCPP_INLINE_VISIBILITY basic_string()
+ _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49 basic_string()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
- _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a);
+ _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49 explicit basic_string(const allocator_type& __a);
basic_string(const basic_string& __str);
basic_string(const basic_string& __str, const allocator_type& __a);
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string(basic_string&& __str)
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
_LIBCPP_INLINE_VISIBILITY
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
+ _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49 basic_string(const value_type* __s);
_LIBCPP_INLINE_VISIBILITY
basic_string(const value_type* __s, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
basic_string(const value_type* __s, size_type __n);
_LIBCPP_INLINE_VISIBILITY
basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string(size_type __n, value_type __c);
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, value_type __c, const allocator_type& __a);
@@ -1972,7 +1972,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string<_CharT, _Traits, _Allocator>::basic_string()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
{
@@ -1983,7 +1983,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string()
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
: __r_(__a)
{
@@ -2042,7 +2042,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
@@ -2116,7 +2116,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
: __r_(_VSTD::move(__str.__r_))
@@ -2173,7 +2173,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
}
template <class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
{
__init(__n, __c);
--
1.9.1.423.g4596e3a
From de2427cee8c21f972a9b4df6a31a7933360b4d01 Mon Sep 17 00:00:00 2001
From: Andrew Hsieh <andrewhsieh@google.com>
Date: Tue, 3 Jun 2014 17:40:43 +0800
Subject: [PATCH 13/13] [temp] collective ndk-hackathon fixes
See https://github.com/awong-dev/ndk since 0a149253507bd702d042de32c2b6bb9aa58168a3
for log. Some are in the process of upstream
---
include/__config | 15 ++++++++
include/__mutex_base | 9 +++++
include/bitset | 4 +--
include/condition_variable | 4 +++
include/future | 4 +++
include/mutex | 4 +++
include/regex | 6 +++-
include/shared_mutex | 4 +++
include/thread | 4 +++
src/algorithm.cpp | 8 +++++
src/chrono.cpp | 7 ++++
src/condition_variable.cpp | 5 +++
src/debug.cpp | 40 +++++++++++++++++++++
src/future.cpp | 6 ++++
src/memory.cpp | 4 +--
src/mutex.cpp | 19 ++++++++++
src/shared_mutex.cpp | 6 ++++
src/thread.cpp | 9 +++++
test/re/re.alg/re.alg.match/basic.pass.cpp | 14 ++++++++
test/re/re.alg/re.alg.match/ecma.pass.cpp | 14 ++++++++
test/re/re.alg/re.alg.match/extended.pass.cpp | 14 ++++++++
test/re/re.alg/re.alg.search/awk.pass.cpp | 14 ++++++++
test/re/re.alg/re.alg.search/basic.pass.cpp | 14 ++++++++
test/re/re.alg/re.alg.search/ecma.pass.cpp | 14 ++++++++
test/re/re.alg/re.alg.search/extended.pass.cpp | 14 ++++++++
test/re/re.traits/lookup_collatename.pass.cpp | 6 ----
.../re.traits/lookup_collatename.xlocale.pass.cpp | 41 ++++++++++++++++++++++
test/re/re.traits/transform.pass.cpp | 14 ++++++++
test/re/re.traits/transform_primary.pass.cpp | 14 ++++++++
test/re/re.traits/translate_nocase.pass.cpp | 14 ++++++++
.../meta.trans.other/aligned_storage.pass.cpp | 10 ++++--
31 files changed, 341 insertions(+), 14 deletions(-)
create mode 100644 test/re/re.traits/lookup_collatename.xlocale.pass.cpp
diff --git a/include/__config b/include/__config
index 0f443a9..d2ab7ac 100644
--- a/include/__config
+++ b/include/__config
@@ -11,6 +11,8 @@
#ifndef _LIBCPP_CONFIG
#define _LIBCPP_CONFIG
+#include <unistd.h>
+
#if !defined(_MSC_VER) || defined(__clang__)
#pragma GCC system_header
#endif
@@ -119,6 +121,12 @@
# endif
#endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
+#if defined(_POSIX_THREADS) && _POSIX_THREADS > 0
+# define _LIBCPP_SINGLE_THREADED 0
+#else
+# define _LIBCPP_SINGLE_THREADED 1
+#endif
+
#ifdef _WIN32
// only really useful for a DLL
@@ -378,7 +386,14 @@ namespace std {
#endif
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+// constexpr was added to GCC in 4.6
+#if _GNUC_VER < 406
#define _LIBCPP_HAS_NO_CONSTEXPR
+// Can only use constexpr in c++11 mode.
+#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
+#define _LIBCPP_HAS_NO_CONSTEXPR
+#endif
#define _NOEXCEPT throw()
#define _NOEXCEPT_(x)
diff --git a/include/__mutex_base b/include/__mutex_base
index 293fead..122b0b7 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -22,12 +22,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !_LIBCPP_SINGLE_THREADED
+
class _LIBCPP_TYPE_VIS mutex
{
pthread_mutex_t __m_;
public:
_LIBCPP_INLINE_VISIBILITY
+
#ifndef _LIBCPP_HAS_NO_CONSTEXPR
constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}
#else
@@ -47,6 +50,7 @@ public:
typedef pthread_mutex_t* native_handle_type;
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
};
+#endif // !_LIBCPP_SINGLE_THREADED
struct _LIBCPP_TYPE_VIS defer_lock_t {};
struct _LIBCPP_TYPE_VIS try_to_lock_t {};
@@ -262,6 +266,7 @@ _LIBCPP_DECLARE_STRONG_ENUM(cv_status)
};
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
+#if !_LIBCPP_SINGLE_THREADED
class _LIBCPP_TYPE_VIS condition_variable
{
pthread_cond_t __cv_;
@@ -315,6 +320,7 @@ private:
void __do_timed_wait(unique_lock<mutex>& __lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
};
+#endif // !_LIBCPP_SINGLE_THREADED
template <class _To, class _Rep, class _Period>
inline _LIBCPP_INLINE_VISIBILITY
@@ -332,6 +338,7 @@ __ceil(chrono::duration<_Rep, _Period> __d)
return __r;
}
+#if !_LIBCPP_SINGLE_THREADED
template <class _Predicate>
void
condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
@@ -396,6 +403,8 @@ condition_variable::wait_for(unique_lock<mutex>& __lk,
_VSTD::move(__pred));
}
+#endif // !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___MUTEX_BASE
diff --git a/include/bitset b/include/bitset
index 4cc7dbd..8c278cc 100644
--- a/include/bitset
+++ b/include/bitset
@@ -249,9 +249,9 @@ inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR
__bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
#ifndef _LIBCPP_HAS_NO_CONSTEXPR
-#if __SIZE_WIDTH__ == 64
+#if __SIZEOF_SIZE_T__ == 8
: __first_{__v}
-#elif __SIZE_WIDTH__ == 32
+#elif __SIZEOF_SIZE_T__ == 4
: __first_{__v, __v >> __bits_per_word}
#else
#error This constructor has not been ported to this platform
diff --git a/include/condition_variable b/include/condition_variable
index dc67266..603ee8f 100644
--- a/include/condition_variable
+++ b/include/condition_variable
@@ -115,6 +115,8 @@ public:
#pragma GCC system_header
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS condition_variable_any
@@ -253,4 +255,6 @@ void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
_LIBCPP_END_NAMESPACE_STD
+#endif // !_LIBCPP_SINGLE_THREADED
+
#endif // _LIBCPP_CONDITION_VARIABLE
diff --git a/include/future b/include/future
index de00f25..c776c59 100644
--- a/include/future
+++ b/include/future
@@ -374,6 +374,8 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
#pragma GCC system_header
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
//enum class future_errc
@@ -2612,4 +2614,6 @@ future<void>::share()
_LIBCPP_END_NAMESPACE_STD
+#endif // !_LIBCPP_SINGLE_THREADED
+
#endif // _LIBCPP_FUTURE
diff --git a/include/mutex b/include/mutex
index e0c02ad..b7a6709 100644
--- a/include/mutex
+++ b/include/mutex
@@ -187,6 +187,8 @@ template<class Callable, class ...Args>
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !_LIBCPP_SINGLE_THREADED
+
class _LIBCPP_TYPE_VIS recursive_mutex
{
pthread_mutex_t __m_;
@@ -425,6 +427,8 @@ lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
#endif // _LIBCPP_HAS_NO_VARIADICS
+#endif // !_LIBCPP_SINGLE_THREADED
+
struct _LIBCPP_TYPE_VIS once_flag;
#ifndef _LIBCPP_HAS_NO_VARIADICS
diff --git a/include/regex b/include/regex
index bebbaf0..7d922cb 100644
--- a/include/regex
+++ b/include/regex
@@ -964,7 +964,11 @@ public:
typedef locale locale_type;
typedef ctype_base::mask char_class_type;
- static const char_class_type __regex_word = 0x80;
+ // Note that Android's whitespace bit, aka. _B (see locale_android.cpp for
+ // the details) was unfortunately defined as 0x80 which made the whitespace
+ // character be recognized as a word.
+ static const char_class_type __regex_word = 0x200;
+
private:
locale __loc_;
const ctype<char_type>* __ct_;
diff --git a/include/shared_mutex b/include/shared_mutex
index 7661054..fe16ee7 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -112,6 +112,8 @@ template <class Mutex>
#pragma GCC system_header
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS shared_timed_mutex
@@ -414,6 +416,8 @@ swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept
_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBC_HAS_PTHREADS
+
#endif // _LIBCPP_STD_VER > 11
#endif // _LIBCPP_SHARED_MUTEX
diff --git a/include/thread b/include/thread
index 1f1e4a2..0202440 100644
--- a/include/thread
+++ b/include/thread
@@ -106,6 +106,8 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
#define __STDCPP_THREADS__ __cplusplus
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
@@ -455,4 +457,6 @@ void yield() _NOEXCEPT {sched_yield();}
_LIBCPP_END_NAMESPACE_STD
+#endif // !_LIBCPP_SINGLE_THREADED
+
#endif // _LIBCPP_THREAD
diff --git a/src/algorithm.cpp b/src/algorithm.cpp
index 10c4c33..2ee8b00 100644
--- a/src/algorithm.cpp
+++ b/src/algorithm.cpp
@@ -48,12 +48,16 @@ template bool __insertion_sort_incomplete<__less<long double>&, long double*>(lo
template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
+#if !_LIBCPP_SINGLE_THREADED
static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER;
+#endif
unsigned __rs_default::__c_ = 0;
__rs_default::__rs_default()
{
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&__rs_mut);
+#endif
__c_ = 1;
}
@@ -64,8 +68,12 @@ __rs_default::__rs_default(const __rs_default&)
__rs_default::~__rs_default()
{
+#if !_LIBCPP_SINGLE_THREADED
if (--__c_ == 0)
pthread_mutex_unlock(&__rs_mut);
+#else
+ --__c_;
+#endif
}
__rs_default::result_type
diff --git a/src/chrono.cpp b/src/chrono.cpp
index 15a6f46..331de3d 100644
--- a/src/chrono.cpp
+++ b/src/chrono.cpp
@@ -120,10 +120,17 @@ steady_clock::now() _NOEXCEPT
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
+#if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK > 0
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));
+#else
+#warning posix doesn't have a monotonic clock on this system \
+ so we're falling back to std::steady_clock (which may \
+ not be monotonic, and therefore may not be conforming)
+ return time_point(system_clock::now().time_since_epoch());
+#endif
}
#endif // __APPLE__
diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp
index 061d138..f21142d 100644
--- a/src/condition_variable.cpp
+++ b/src/condition_variable.cpp
@@ -12,6 +12,8 @@
#include "system_error"
#include "cassert"
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
condition_variable::~condition_variable()
@@ -79,3 +81,6 @@ notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
}
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
diff --git a/src/debug.cpp b/src/debug.cpp
index d0e8679..05ec703 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -35,6 +35,7 @@ __get_const_db()
namespace
{
+#if !_LIBCPP_SINGLE_THREADED
typedef mutex mutex_type;
typedef lock_guard<mutex_type> WLock;
typedef lock_guard<mutex_type> RLock;
@@ -45,6 +46,7 @@ mut()
static mutex_type m;
return m;
}
+#endif // !_LIBCPP_SINGLE_THREADED
} // unnamed namespace
@@ -108,7 +110,9 @@ __libcpp_db::~__libcpp_db()
void*
__libcpp_db::__find_c_from_i(void* __i) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
_LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
@@ -117,7 +121,9 @@ __libcpp_db::__find_c_from_i(void* __i) const
void
__libcpp_db::__insert_ic(void* __i, const void* __c)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
if (__cbeg_ == __cend_)
return;
size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -138,7 +144,9 @@ __libcpp_db::__insert_ic(void* __i, const void* __c)
__c_node*
__libcpp_db::__insert_c(void* __c)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
{
size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
@@ -184,7 +192,9 @@ __libcpp_db::__insert_c(void* __c)
void
__libcpp_db::__erase_i(void* __i)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
if (__ibeg_ != __iend_)
{
size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
@@ -215,7 +225,9 @@ __libcpp_db::__erase_i(void* __i)
void
__libcpp_db::__invalidate_all(void* __c)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
if (__cend_ != __cbeg_)
{
size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -239,17 +251,23 @@ __libcpp_db::__invalidate_all(void* __c)
__c_node*
__libcpp_db::__find_c_and_lock(void* __c) const
{
+#if !_LIBCPP_SINGLE_THREADED
mut().lock();
+#endif
if (__cend_ == __cbeg_)
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
return nullptr;
}
size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
__c_node* p = __cbeg_[hc];
if (p == nullptr)
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
return nullptr;
}
while (p->__c_ != __c)
@@ -257,7 +275,9 @@ __libcpp_db::__find_c_and_lock(void* __c) const
p = p->__next_;
if (p == nullptr)
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
return nullptr;
}
}
@@ -281,13 +301,17 @@ __libcpp_db::__find_c(void* __c) const
void
__libcpp_db::unlock() const
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
}
void
__libcpp_db::__erase_c(void* __c)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
if (__cend_ != __cbeg_)
{
size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -322,7 +346,9 @@ __libcpp_db::__erase_c(void* __c)
void
__libcpp_db::__iterator_copy(void* __i, const void* __i0)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
__i_node* i0 = __find_iterator(__i0);
__c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
@@ -348,7 +374,9 @@ __libcpp_db::__iterator_copy(void* __i, const void* __i0)
bool
__libcpp_db::__dereferenceable(const void* __i) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
}
@@ -356,7 +384,9 @@ __libcpp_db::__dereferenceable(const void* __i) const
bool
__libcpp_db::__decrementable(const void* __i) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
}
@@ -364,7 +394,9 @@ __libcpp_db::__decrementable(const void* __i) const
bool
__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
}
@@ -372,7 +404,9 @@ __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
bool
__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
}
@@ -380,7 +414,9 @@ __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
bool
__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
__i_node* j = __find_iterator(__j);
__c_node* ci = i != nullptr ? i->__c_ : nullptr;
@@ -391,7 +427,9 @@ __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
void
__libcpp_db::swap(void* c1, void* c2)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
__c_node* p1 = __cbeg_[hc];
_LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
@@ -420,7 +458,9 @@ __libcpp_db::swap(void* c1, void* c2)
void
__libcpp_db::__insert_i(void* __i)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
__insert_iterator(__i);
}
diff --git a/src/future.cpp b/src/future.cpp
index c67dc58..91756e1 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -10,6 +10,8 @@
#include "future"
#include "string"
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_HIDDEN __future_error_category
@@ -298,3 +300,7 @@ shared_future<void>::operator=(const shared_future& __rhs)
}
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
+
diff --git a/src/memory.cpp b/src/memory.cpp
index 666673f..2938538 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -119,7 +119,7 @@ __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
#endif // _LIBCPP_NO_RTTI
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !_LIBCPP_SINGLE_THREADED
static const std::size_t __sp_mut_count = 16;
static pthread_mutex_t mut_back_imp[__sp_mut_count] =
@@ -172,7 +172,7 @@ __get_sp_mut(const void* p)
return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
}
-#endif // __has_feature(cxx_atomic)
+#endif // __has_feature(cxx_atomic) && LIBCPP_HAS_PTHREADS
void
declare_reachable(void*)
diff --git a/src/mutex.cpp b/src/mutex.cpp
index 0767897..18a68b1 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -14,6 +14,7 @@
#include "cassert"
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !_LIBCPP_SINGLE_THREADED
const defer_lock_t defer_lock = {};
const try_to_lock_t try_to_lock = {};
@@ -206,21 +207,27 @@ recursive_timed_mutex::unlock() _NOEXCEPT
}
}
+#endif // !_LIBCPP_SINGLE_THREADED
+
// If dispatch_once_f ever handles C++ exceptions, and if one can get to it
// without illegal macros (unexpected macros not beginning with _UpperCase or
// __lowercase), and if it stops spinning waiting threads, then call_once should
// call into dispatch_once_f instead of here. Relevant radar this code needs to
// keep in sync with: 7741191.
+#if !_LIBCPP_SINGLE_THREADED
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
+#endif
void
__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
{
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&mut);
while (flag == 1)
pthread_cond_wait(&cv, &mut);
+#endif // !_LIBCPP_SINGLE_THREADED
if (flag == 0)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -228,26 +235,38 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
{
#endif // _LIBCPP_NO_EXCEPTIONS
flag = 1;
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
func(arg);
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
flag = ~0ul;
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cv);
+#endif // !_LIBCPP_SINGLE_THREADED
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
flag = 0ul;
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cv);
+#endif // !_LIBCPP_SINGLE_THREADED
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
+#if !_LIBCPP_SINGLE_THREADED
else
pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/src/shared_mutex.cpp b/src/shared_mutex.cpp
index dd78a16..860e23a 100644
--- a/src/shared_mutex.cpp
+++ b/src/shared_mutex.cpp
@@ -10,6 +10,8 @@
#define _LIBCPP_BUILDING_SHARED_MUTEX
#include "shared_mutex"
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
shared_timed_mutex::shared_timed_mutex()
@@ -99,3 +101,7 @@ shared_timed_mutex::unlock_shared()
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
+
diff --git a/src/thread.cpp b/src/thread.cpp
index bd2b7c3..1ffef7a 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -27,6 +27,8 @@
#include <windows.h>
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
thread::~thread()
@@ -121,7 +123,11 @@ sleep_for(const chrono::nanoseconds& ns)
ts.tv_sec = ts_sec_max;
ts.tv_nsec = giga::num - 1;
}
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
nanosleep(&ts, 0);
+#else
+#warning sleep_for not yet implemented
+#endif
}
}
@@ -223,3 +229,6 @@ __thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s)
}
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
diff --git a/test/re/re.alg/re.alg.match/basic.pass.cpp b/test/re/re.alg/re.alg.match/basic.pass.cpp
index 55c7361..9d3f39d 100644
--- a/test/re/re.alg/re.alg.match/basic.pass.cpp
+++ b/test/re/re.alg/re.alg.match/basic.pass.cpp
@@ -614,6 +614,12 @@ int main()
std::regex_constants::basic)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -648,6 +654,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1282,6 +1289,12 @@ int main()
std::regex_constants::basic)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1316,6 +1329,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.alg/re.alg.match/ecma.pass.cpp b/test/re/re.alg/re.alg.match/ecma.pass.cpp
index 162a6a7..bb36831 100644
--- a/test/re/re.alg/re.alg.match/ecma.pass.cpp
+++ b/test/re/re.alg/re.alg.match/ecma.pass.cpp
@@ -576,6 +576,12 @@ int main()
assert(!std::regex_match(s, m, std::regex("[a[.hyphen.]z]")));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -621,6 +627,7 @@ int main()
assert(m.size() == 1);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1241,6 +1248,12 @@ int main()
assert(!std::regex_match(s, m, std::wregex(L"[a[.hyphen.]z]")));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1274,6 +1287,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.alg/re.alg.match/extended.pass.cpp b/test/re/re.alg/re.alg.match/extended.pass.cpp
index 683f65b..5ef8695 100644
--- a/test/re/re.alg/re.alg.match/extended.pass.cpp
+++ b/test/re/re.alg/re.alg.match/extended.pass.cpp
@@ -612,6 +612,12 @@ int main()
std::regex_constants::extended)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -646,6 +652,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1278,6 +1285,12 @@ int main()
std::regex_constants::extended)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1312,6 +1325,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.alg/re.alg.search/awk.pass.cpp b/test/re/re.alg/re.alg.search/awk.pass.cpp
index 57606c1..b03dd7b 100644
--- a/test/re/re.alg/re.alg.search/awk.pass.cpp
+++ b/test/re/re.alg/re.alg.search/awk.pass.cpp
@@ -684,6 +684,12 @@ int main()
std::regex_constants::awk)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -718,6 +724,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1455,6 +1462,12 @@ int main()
std::regex_constants::awk)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1489,6 +1502,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.alg/re.alg.search/basic.pass.cpp b/test/re/re.alg/re.alg.search/basic.pass.cpp
index 56396f3..809f870 100644
--- a/test/re/re.alg/re.alg.search/basic.pass.cpp
+++ b/test/re/re.alg/re.alg.search/basic.pass.cpp
@@ -686,6 +686,12 @@ int main()
std::regex_constants::basic)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -720,6 +726,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1444,6 +1451,12 @@ int main()
std::regex_constants::basic)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1478,6 +1491,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.alg/re.alg.search/ecma.pass.cpp b/test/re/re.alg/re.alg.search/ecma.pass.cpp
index 8149157..21e3efe 100644
--- a/test/re/re.alg/re.alg.search/ecma.pass.cpp
+++ b/test/re/re.alg/re.alg.search/ecma.pass.cpp
@@ -666,6 +666,12 @@ int main()
assert(!std::regex_search(s, m, std::regex("[a[.hyphen.]z]")));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -699,6 +705,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1445,6 +1452,12 @@ int main()
assert(!std::regex_search(s, m, std::wregex(L"[a[.hyphen.]z]")));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1478,6 +1491,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.alg/re.alg.search/extended.pass.cpp b/test/re/re.alg/re.alg.search/extended.pass.cpp
index 8240872..9cac3b2 100644
--- a/test/re/re.alg/re.alg.search/extended.pass.cpp
+++ b/test/re/re.alg/re.alg.search/extended.pass.cpp
@@ -684,6 +684,12 @@ int main()
std::regex_constants::extended)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::cmatch m;
@@ -718,6 +724,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::cmatch m;
const char s[] = "m";
@@ -1440,6 +1447,12 @@ int main()
std::regex_constants::extended)));
assert(m.size() == 0);
}
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
std::locale::global(std::locale("cs_CZ.ISO8859-2"));
{
std::wcmatch m;
@@ -1474,6 +1487,7 @@ int main()
assert(m.str(0) == s);
}
std::locale::global(std::locale("C"));
+#endif
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/re/re.traits/lookup_collatename.pass.cpp b/test/re/re.traits/lookup_collatename.pass.cpp
index 055b554..9c6f108 100644
--- a/test/re/re.traits/lookup_collatename.pass.cpp
+++ b/test/re/re.traits/lookup_collatename.pass.cpp
@@ -103,9 +103,6 @@ int main()
test("tild", std::string(""));
test("ch", std::string(""));
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
- test("ch", std::string("ch"));
- std::locale::global(std::locale("C"));
test(L"NUL", std::wstring(L"\x00", 1));
test(L"alert", std::wstring(L"\x07"));
@@ -179,7 +176,4 @@ int main()
test(L"tild", std::wstring(L""));
test(L"ch", std::wstring(L""));
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
- test(L"ch", std::wstring(L"ch"));
- std::locale::global(std::locale("C"));
}
diff --git a/test/re/re.traits/lookup_collatename.xlocale.pass.cpp b/test/re/re.traits/lookup_collatename.xlocale.pass.cpp
new file mode 100644
index 0000000..b6e563c
--- /dev/null
+++ b/test/re/re.traits/lookup_collatename.xlocale.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// template <class charT> struct regex_traits;
+
+// template <class ForwardIterator>
+// string_type
+// lookup_collatename(ForwardIterator first, ForwardIterator last) const;
+
+#include <regex>
+#include <iterator>
+#include <cassert>
+#include "test_iterators.h"
+
+template <class char_type>
+void
+test(const char_type* A, const std::basic_string<char_type>& expected)
+{
+ std::regex_traits<char_type> t;
+ typedef forward_iterator<const char_type*> F;
+ assert(t.lookup_collatename(F(A), F(A + t.length(A))) == expected);
+}
+
+int main()
+{
+#if !defined(__ANDROID__)
+ std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ test("ch", std::string("ch"));
+
+ std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ test(L"ch", std::wstring(L"ch"));
+#endif
+}
diff --git a/test/re/re.traits/transform.pass.cpp b/test/re/re.traits/transform.pass.cpp
index 9b9feb1..73d6593 100644
--- a/test/re/re.traits/transform.pass.cpp
+++ b/test/re/re.traits/transform.pass.cpp
@@ -27,8 +27,15 @@ int main()
const char B[] = "B";
typedef forward_iterator<const char*> F;
assert(t.transform(F(a), F(a+1)) > t.transform(F(B), F(B+1)));
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
t.imbue(std::locale("cs_CZ.ISO8859-2"));
assert(t.transform(F(a), F(a+1)) < t.transform(F(B), F(B+1)));
+#endif
}
{
std::regex_traits<wchar_t> t;
@@ -36,7 +43,14 @@ int main()
const wchar_t B[] = L"B";
typedef forward_iterator<const wchar_t*> F;
assert(t.transform(F(a), F(a+1)) > t.transform(F(B), F(B+1)));
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
t.imbue(std::locale("cs_CZ.ISO8859-2"));
assert(t.transform(F(a), F(a+1)) < t.transform(F(B), F(B+1)));
+#endif
}
}
diff --git a/test/re/re.traits/transform_primary.pass.cpp b/test/re/re.traits/transform_primary.pass.cpp
index 1e2aca6..a22d86d 100644
--- a/test/re/re.traits/transform_primary.pass.cpp
+++ b/test/re/re.traits/transform_primary.pass.cpp
@@ -29,9 +29,16 @@ int main()
typedef forward_iterator<const char*> F;
assert(t.transform_primary(F(A), F(A+1)) !=
t.transform_primary(F(Aacute), F(Aacute+1)));
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
t.imbue(std::locale("cs_CZ.ISO8859-2"));
assert(t.transform_primary(F(A), F(A+1)) ==
t.transform_primary(F(Aacute), F(Aacute+1)));
+#endif
}
{
std::regex_traits<wchar_t> t;
@@ -40,8 +47,15 @@ int main()
typedef forward_iterator<const wchar_t*> F;
assert(t.transform_primary(F(A), F(A+1)) !=
t.transform_primary(F(Aacute), F(Aacute+1)));
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
t.imbue(std::locale("cs_CZ.ISO8859-2"));
assert(t.transform_primary(F(A), F(A+1)) ==
t.transform_primary(F(Aacute), F(Aacute+1)));
+#endif
}
}
diff --git a/test/re/re.traits/translate_nocase.pass.cpp b/test/re/re.traits/translate_nocase.pass.cpp
index 5e042ae..bd8a7f4 100644
--- a/test/re/re.traits/translate_nocase.pass.cpp
+++ b/test/re/re.traits/translate_nocase.pass.cpp
@@ -34,6 +34,12 @@ int main()
assert(t.translate_nocase('1') == '1');
assert(t.translate_nocase('\xDA') == '\xDA');
assert(t.translate_nocase('\xFA') == '\xFA');
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
t.imbue(std::locale(LOCALE_en_US_UTF_8));
assert(t.translate_nocase(' ') == ' ');
assert(t.translate_nocase('A') == 'a');
@@ -43,6 +49,7 @@ int main()
assert(t.translate_nocase('1') == '1');
assert(t.translate_nocase('\xDA') == '\xFA');
assert(t.translate_nocase('\xFA') == '\xFA');
+#endif
}
{
std::regex_traits<wchar_t> t;
@@ -54,6 +61,12 @@ int main()
assert(t.translate_nocase(L'1') == L'1');
assert(t.translate_nocase(L'\xDA') == L'\xDA');
assert(t.translate_nocase(L'\xFA') == L'\xFA');
+/* Disable locale specific tests on Android because Android's NDK does not
+ * support locales other than "C" and "POSIX".
+ *
+ * https://code.google.com/p/android/issues/detail?id=57313
+ */
+#if !defined(__ANDROID__)
t.imbue(std::locale(LOCALE_en_US_UTF_8));
assert(t.translate_nocase(L' ') == L' ');
assert(t.translate_nocase(L'A') == L'a');
@@ -63,5 +76,6 @@ int main()
assert(t.translate_nocase(L'1') == L'1');
assert(t.translate_nocase(L'\xDA') == L'\xFA');
assert(t.translate_nocase(L'\xFA') == L'\xFA');
+#endif
}
}
diff --git a/test/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/test/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
index d1b7700..67ee23d 100644
--- a/test/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
+++ b/test/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
@@ -159,12 +159,16 @@ int main()
static_assert(std::alignment_of<T1>::value == 8, "");
static_assert(sizeof(T1) == 16, "");
}
+ // The expected values for the tests below (modulo the last one) are
+ // platform-specific which alignof deals with. In particular, the maximum
+ // alignment value on ARM is 8 bytes as opposed to 16 bytes on some other
+ // architectures that support 128 bit memory accesses.
{
typedef std::aligned_storage<16>::type T1;
#if _LIBCPP_STD_VER > 11
static_assert(std::is_same<std::aligned_storage_t<16>, T1>::value, "" );
#endif
- static_assert(std::alignment_of<T1>::value == 16, "");
+ static_assert(std::alignment_of<T1>::value == alignof(T1), "");
static_assert(sizeof(T1) == 16, "");
}
{
@@ -172,8 +176,8 @@ int main()
#if _LIBCPP_STD_VER > 11
static_assert(std::is_same<std::aligned_storage_t<17>, T1>::value, "" );
#endif
- static_assert(std::alignment_of<T1>::value == 16, "");
- static_assert(sizeof(T1) == 32, "");
+ static_assert(std::alignment_of<T1>::value == alignof(T1), "");
+ static_assert(sizeof(T1) == 16 + alignof(T1), "");
}
{
typedef std::aligned_storage<10>::type T1;
--
1.9.1.423.g4596e3a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment