summaryrefslogtreecommitdiffstats
path: root/libcxx/src
diff options
context:
space:
mode:
authorAlexis Hunt <alercah@gmail.com>2011-07-09 00:56:23 +0000
committerAlexis Hunt <alercah@gmail.com>2011-07-09 00:56:23 +0000
commit3f60bca9e90da3805d82a7651d4b26596c475959 (patch)
tree922094472523923b9cfd21601caf8b86da0d50c2 /libcxx/src
parentb8e8a5f3ee11fe58983f11a54941f04f2a8dbd53 (diff)
downloadbcm5719-llvm-3f60bca9e90da3805d82a7651d4b26596c475959.tar.gz
bcm5719-llvm-3f60bca9e90da3805d82a7651d4b26596c475959.zip
Implement generalized table lookups for upper, lower, and character
traits. To the best of my knowledge, this will not break the ABI for Apple. However, it does introduce three publicly visible (although with reserved name) functions that will fail to link against the just-shipped Apple version of libc++. Since they are not used in any inline functions, no actual breakage should occur. If Howard doesn't want to put undefined functions (even internal ones) into a header, they could be surrounded by additional conditional compilation. llvm-svn: 134781
Diffstat (limited to 'libcxx/src')
-rw-r--r--libcxx/src/locale.cpp126
1 files changed, 57 insertions, 69 deletions
diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index 5d1d607ff6b..eafd7639c67 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -116,6 +116,18 @@ namespace with_locale { namespace {
_LIBCPP_BEGIN_NAMESPACE_STD
+locale_t __cloc() {
+ // In theory this could create a race condition. In practice
+ // the race condition is non-fatal since it will just create
+ // a little resource leak. Better approach would be appreciated.
+#ifdef __APPLE__
+ return 0;
+#else
+ static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
+ return result;
+#endif
+}
+
namespace {
struct release
@@ -767,93 +779,64 @@ ctype<wchar_t>::~ctype()
bool
ctype<wchar_t>::do_is(mask m, char_type c) const
{
-#ifdef __APPLE__
- return isascii(c) ? _DefaultRuneLocale.__runetype[c] & m : false;
-#else
- return false;
-#endif
+ return isascii(c) ? ctype<char>::classic_table()[c] & m : false;
}
const wchar_t*
ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
{
-#ifdef __APPLE__
for (; low != high; ++low, ++vec)
- *vec = static_cast<mask>(isascii(*low) ? _DefaultRuneLocale.__runetype[*low] : 0);
+ *vec = static_cast<mask>(isascii(*low) ?
+ ctype<char>::classic_table()[*low] : 0);
return low;
-#else
- return NULL;
-#endif
}
const wchar_t*
ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
{
-#ifdef __APPLE__
for (; low != high; ++low)
- if (isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m))
+ if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
break;
return low;
-#else
- return NULL;
-#endif
}
const wchar_t*
ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
{
-#ifdef __APPLE__
for (; low != high; ++low)
- if (!(isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m)))
+ if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
break;
return low;
-#else
- return NULL;
-#endif
}
wchar_t
ctype<wchar_t>::do_toupper(char_type c) const
{
-#ifdef __APPLE__
- return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
-#else
- return 0;
-#endif
+ return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
}
const wchar_t*
ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
{
-#ifdef __APPLE__
for (; low != high; ++low)
- *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
+ *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
+ : *low;
return low;
-#else
- return NULL;
-#endif
}
wchar_t
ctype<wchar_t>::do_tolower(char_type c) const
{
-#ifdef __APPLE__
- return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
-#else
- return 0;
-#endif
+ return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
}
const wchar_t*
ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
{
-#ifdef __APPLE__
for (; low != high; ++low)
- *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
+ *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
+ : *low;
return low;
-#else
- return NULL;
-#endif
}
wchar_t
@@ -898,10 +881,8 @@ ctype<char>::ctype(const mask* tab, bool del, size_t refs)
__tab_(tab),
__del_(del)
{
-#ifdef __APPLE__
- if (__tab_ == 0)
- __tab_ = _DefaultRuneLocale.__runetype;
-#endif
+ if (__tab_ == 0)
+ __tab_ = classic_table();
}
ctype<char>::~ctype()
@@ -913,45 +894,29 @@ ctype<char>::~ctype()
char
ctype<char>::do_toupper(char_type c) const
{
-#ifdef __APPLE__
- return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
-#else
- return 0;
-#endif
+ return isascii(c) ? __classic_upper_table()[c] : c;
}
const char*
ctype<char>::do_toupper(char_type* low, const char_type* high) const
{
-#ifdef __APPLE__
for (; low != high; ++low)
- *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
+ *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
return low;
-#else
- return NULL;
-#endif
}
char
ctype<char>::do_tolower(char_type c) const
{
-#ifdef __APPLE__
- return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
-#else
- return 0;
-#endif
+ return isascii(c) ? __classic_lower_table()[c] : c;
}
const char*
ctype<char>::do_tolower(char_type* low, const char_type* high) const
{
-#ifdef __APPLE__
for (; low != high; ++low)
- *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
+ *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
return low;
-#else
- return NULL;
-#endif
}
char
@@ -992,6 +957,33 @@ ctype<char>::classic_table() _NOEXCEPT
{
#ifdef __APPLE__
return _DefaultRuneLocale.__runetype;
+#elif defined(__GLIBC__)
+ return __cloc()->__ctype_b;
+// This is assumed to be safe.
+#else
+ return NULL;
+#endif
+}
+
+const int*
+ctype<char>::__classic_lower_table() _NOEXCEPT
+{
+#ifdef __APPLE__
+ return _DefaultRuneLocale.__maplower;
+#elif defined(__GLIBC__)
+ return __cloc()->__ctype_tolower;
+#else
+ return NULL;
+#endif
+}
+
+const int*
+ctype<char>::__classic_upper_table() _NOEXCEPT
+{
+#ifdef __APPLE__
+ return _DefaultRuneLocale.__mapupper;
+#elif defined(__GLIBC__)
+ return __cloc()->__ctype_toupper;
#else
return NULL;
#endif
@@ -1092,11 +1084,10 @@ ctype_byname<wchar_t>::do_is(mask m, char_type c) const
const wchar_t*
ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
{
-#ifdef __APPLE__
for (; low != high; ++low, ++vec)
{
if (isascii(*low))
- *vec = static_cast<mask>(_DefaultRuneLocale.__runetype[*low]);
+ *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
else
{
*vec = 0;
@@ -1121,9 +1112,6 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask*
}
}
return low;
-#else
- return NULL;
-#endif
}
const wchar_t*
OpenPOWER on IntegriCloud