Skip to content

Commit 4c6ca3e

Browse files
authored
[libc++] Implement a libc++ private version of isascii (llvm#122361)
The isascii() function is not standard, so we should avoid relying on the platform providing it, especially since it's easy to implement in libc++ portably.
1 parent 749bdc8 commit 4c6ca3e

File tree

2 files changed

+44
-37
lines changed

2 files changed

+44
-37
lines changed

libcxx/include/__locale

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,8 @@ protected:
516516
};
517517
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
518518

519+
inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_isascii(int __c) { return (__c & ~0x7F) == 0; }
520+
519521
template <>
520522
class _LIBCPP_EXPORTED_FROM_ABI ctype<char> : public locale::facet, public ctype_base {
521523
const mask* __tab_;
@@ -527,25 +529,25 @@ public:
527529
explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0);
528530

529531
_LIBCPP_HIDE_FROM_ABI bool is(mask __m, char_type __c) const {
530-
return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) != 0 : false;
532+
return std::__libcpp_isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) != 0 : false;
531533
}
532534

533535
_LIBCPP_HIDE_FROM_ABI const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const {
534536
for (; __low != __high; ++__low, ++__vec)
535-
*__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
537+
*__vec = std::__libcpp_isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
536538
return __low;
537539
}
538540

539541
_LIBCPP_HIDE_FROM_ABI const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const {
540542
for (; __low != __high; ++__low)
541-
if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
543+
if (std::__libcpp_isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
542544
break;
543545
return __low;
544546
}
545547

546548
_LIBCPP_HIDE_FROM_ABI const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const {
547549
for (; __low != __high; ++__low)
548-
if (!isascii(*__low) || !(__tab_[static_cast<int>(*__low)] & __m))
550+
if (!std::__libcpp_isascii(*__low) || !(__tab_[static_cast<int>(*__low)] & __m))
549551
break;
550552
return __low;
551553
}

libcxx/src/locale.cpp

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -707,69 +707,70 @@ constinit locale::id ctype<wchar_t>::id;
707707
ctype<wchar_t>::~ctype() {}
708708

709709
bool ctype<wchar_t>::do_is(mask m, char_type c) const {
710-
return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
710+
return std::__libcpp_isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
711711
}
712712

713713
const wchar_t* ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {
714714
for (; low != high; ++low, ++vec)
715-
*vec = static_cast<mask>(isascii(*low) ? ctype<char>::classic_table()[*low] : 0);
715+
*vec = static_cast<mask>(std::__libcpp_isascii(*low) ? ctype<char>::classic_table()[*low] : 0);
716716
return low;
717717
}
718718

719719
const wchar_t* ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const {
720720
for (; low != high; ++low)
721-
if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
721+
if (std::__libcpp_isascii(*low) && (ctype<char>::classic_table()[*low] & m))
722722
break;
723723
return low;
724724
}
725725

726726
const wchar_t* ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const {
727727
for (; low != high; ++low)
728-
if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
728+
if (!(std::__libcpp_isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
729729
break;
730730
return low;
731731
}
732732

733733
wchar_t ctype<wchar_t>::do_toupper(char_type c) const {
734734
# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
735-
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
735+
return std::__libcpp_isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
736736
# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
737-
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
737+
return std::__libcpp_isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
738738
# else
739-
return (isascii(c) && __locale::__iswlower(c, _LIBCPP_GET_C_LOCALE)) ? c - L'a' + L'A' : c;
739+
return (std::__libcpp_isascii(c) && __locale::__iswlower(c, _LIBCPP_GET_C_LOCALE)) ? c - L'a' + L'A' : c;
740740
# endif
741741
}
742742

743743
const wchar_t* ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const {
744744
for (; low != high; ++low)
745745
# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
746-
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
746+
*low = std::__libcpp_isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
747747
# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
748-
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low] : *low;
748+
*low = std::__libcpp_isascii(*low) ? ctype<char>::__classic_upper_table()[*low] : *low;
749749
# else
750-
*low = (isascii(*low) && __locale::__islower(*low, _LIBCPP_GET_C_LOCALE)) ? (*low - L'a' + L'A') : *low;
750+
*low =
751+
(std::__libcpp_isascii(*low) && __locale::__islower(*low, _LIBCPP_GET_C_LOCALE)) ? (*low - L'a' + L'A') : *low;
751752
# endif
752753
return low;
753754
}
754755

755756
wchar_t ctype<wchar_t>::do_tolower(char_type c) const {
756757
# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
757-
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
758+
return std::__libcpp_isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
758759
# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
759-
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
760+
return std::__libcpp_isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
760761
# else
761-
return (isascii(c) && __locale::__isupper(c, _LIBCPP_GET_C_LOCALE)) ? c - L'A' + 'a' : c;
762+
return (std::__libcpp_isascii(c) && __locale::__isupper(c, _LIBCPP_GET_C_LOCALE)) ? c - L'A' + 'a' : c;
762763
# endif
763764
}
764765

765766
const wchar_t* ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const {
766767
for (; low != high; ++low)
767768
# ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
768-
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
769+
*low = std::__libcpp_isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
769770
# elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
770-
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low] : *low;
771+
*low = std::__libcpp_isascii(*low) ? ctype<char>::__classic_lower_table()[*low] : *low;
771772
# else
772-
*low = (isascii(*low) && __locale::__isupper(*low, _LIBCPP_GET_C_LOCALE)) ? *low - L'A' + L'a' : *low;
773+
*low = (std::__libcpp_isascii(*low) && __locale::__isupper(*low, _LIBCPP_GET_C_LOCALE)) ? *low - L'A' + L'a' : *low;
773774
# endif
774775
return low;
775776
}
@@ -783,14 +784,14 @@ const char* ctype<wchar_t>::do_widen(const char* low, const char* high, char_typ
783784
}
784785

785786
char ctype<wchar_t>::do_narrow(char_type c, char dfault) const {
786-
if (isascii(c))
787+
if (std::__libcpp_isascii(c))
787788
return static_cast<char>(c);
788789
return dfault;
789790
}
790791

791792
const wchar_t* ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {
792793
for (; low != high; ++low, ++dest)
793-
if (isascii(*low))
794+
if (std::__libcpp_isascii(*low))
794795
*dest = static_cast<char>(*low);
795796
else
796797
*dest = dfault;
@@ -816,52 +817,56 @@ ctype<char>::~ctype() {
816817

817818
char ctype<char>::do_toupper(char_type c) const {
818819
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
819-
return isascii(c) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
820+
return std::__libcpp_isascii(c) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
820821
#elif defined(__NetBSD__)
821822
return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
822823
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
823-
return isascii(c) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
824+
return std::__libcpp_isascii(c) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
824825
#else
825-
return (isascii(c) && __locale::__islower(c, _LIBCPP_GET_C_LOCALE)) ? c - 'a' + 'A' : c;
826+
return (std::__libcpp_isascii(c) && __locale::__islower(c, _LIBCPP_GET_C_LOCALE)) ? c - 'a' + 'A' : c;
826827
#endif
827828
}
828829

829830
const char* ctype<char>::do_toupper(char_type* low, const char_type* high) const {
830831
for (; low != high; ++low)
831832
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
832-
*low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
833+
*low = std::__libcpp_isascii(*low)
834+
? static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)])
835+
: *low;
833836
#elif defined(__NetBSD__)
834837
*low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
835838
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
836-
*low = isascii(*low) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
839+
*low = std::__libcpp_isascii(*low) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
837840
#else
838-
*low = (isascii(*low) && __locale::__islower(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'a' + 'A' : *low;
841+
*low = (std::__libcpp_isascii(*low) && __locale::__islower(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'a' + 'A' : *low;
839842
#endif
840843
return low;
841844
}
842845

843846
char ctype<char>::do_tolower(char_type c) const {
844847
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
845-
return isascii(c) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
848+
return std::__libcpp_isascii(c) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
846849
#elif defined(__NetBSD__)
847850
return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
848851
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
849-
return isascii(c) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
852+
return std::__libcpp_isascii(c) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
850853
#else
851-
return (isascii(c) && __locale::__isupper(c, _LIBCPP_GET_C_LOCALE)) ? c - 'A' + 'a' : c;
854+
return (std::__libcpp_isascii(c) && __locale::__isupper(c, _LIBCPP_GET_C_LOCALE)) ? c - 'A' + 'a' : c;
852855
#endif
853856
}
854857

855858
const char* ctype<char>::do_tolower(char_type* low, const char_type* high) const {
856859
for (; low != high; ++low)
857860
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
858-
*low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
861+
*low = std::__libcpp_isascii(*low)
862+
? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)])
863+
: *low;
859864
#elif defined(__NetBSD__)
860865
*low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
861866
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
862-
*low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
867+
*low = std::__libcpp_isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
863868
#else
864-
*low = (isascii(*low) && __locale::__isupper(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'A' + 'a' : *low;
869+
*low = (std::__libcpp_isascii(*low) && __locale::__isupper(*low, _LIBCPP_GET_C_LOCALE)) ? *low - 'A' + 'a' : *low;
865870
#endif
866871
return low;
867872
}
@@ -875,14 +880,14 @@ const char* ctype<char>::do_widen(const char* low, const char* high, char_type*
875880
}
876881

877882
char ctype<char>::do_narrow(char_type c, char dfault) const {
878-
if (isascii(c))
883+
if (std::__libcpp_isascii(c))
879884
return static_cast<char>(c);
880885
return dfault;
881886
}
882887

883888
const char* ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const {
884889
for (; low != high; ++low, ++dest)
885-
if (isascii(*low))
890+
if (std::__libcpp_isascii(*low))
886891
*dest = *low;
887892
else
888893
*dest = dfault;
@@ -1140,7 +1145,7 @@ bool ctype_byname<wchar_t>::do_is(mask m, char_type c) const {
11401145

11411146
const wchar_t* ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const {
11421147
for (; low != high; ++low, ++vec) {
1143-
if (isascii(*low))
1148+
if (std::__libcpp_isascii(*low))
11441149
*vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
11451150
else {
11461151
*vec = 0;

0 commit comments

Comments
 (0)