Hi danalbert, mclow.lists,

This basically reverts the revert in r216508, and fixes a few more cases while 
I'm at it. Reading my commit message on that commit again, I think it's bupkis.

http://reviews.llvm.org/D8237

Files:
  include/__locale
  src/locale.cpp
  
test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/__locale
===================================================================
--- include/__locale
+++ include/__locale
@@ -353,6 +353,7 @@
     static const mask punct  = _PUNCT;
     static const mask xdigit = _HEX;
     static const mask blank  = _BLANK;
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__ANDROID__)
 # ifdef __APPLE__
     typedef __uint32_t mask;
@@ -373,6 +374,7 @@
     static const mask punct  = _CTYPE_P;
 # if defined(__ANDROID__)
     static const mask xdigit = _CTYPE_X | _CTYPE_D;
+#  define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
 # else
     static const mask xdigit = _CTYPE_X;
 # endif
@@ -407,6 +409,9 @@
     static const mask punct  = _P;
     static const mask xdigit = _X | _N;
     static const mask blank  = _B;
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
 #else
     typedef unsigned long mask;
     static const mask space  = 1<<0;
Index: src/locale.cpp
===================================================================
--- src/locale.cpp
+++ src/locale.cpp
@@ -1183,16 +1183,16 @@
 #else
     bool result = false;
     wint_t ch = static_cast<wint_t>(c);
-    if (m & space) result |= (iswspace_l(ch, __l) != 0);
-    if (m & print) result |= (iswprint_l(ch, __l) != 0);
-    if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0);
-    if (m & upper) result |= (iswupper_l(ch, __l) != 0);
-    if (m & lower) result |= (iswlower_l(ch, __l) != 0);
-    if (m & alpha) result |= (iswalpha_l(ch, __l) != 0);
-    if (m & digit) result |= (iswdigit_l(ch, __l) != 0);
-    if (m & punct) result |= (iswpunct_l(ch, __l) != 0);
-    if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0);
-    if (m & blank) result |= (iswblank_l(ch, __l) != 0);
+    if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
+    if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
+    if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
+    if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
+    if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
+    if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
+    if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
+    if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
+    if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
+    if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
     return result;
 #endif
 }
@@ -1210,22 +1210,30 @@
             wint_t ch = static_cast<wint_t>(*low);
             if (iswspace_l(ch, __l))
                 *vec |= space;
+#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
             if (iswprint_l(ch, __l))
                 *vec |= print;
+#endif
             if (iswcntrl_l(ch, __l))
                 *vec |= cntrl;
             if (iswupper_l(ch, __l))
                 *vec |= upper;
             if (iswlower_l(ch, __l))
                 *vec |= lower;
+#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
             if (iswalpha_l(ch, __l))
                 *vec |= alpha;
+#endif
             if (iswdigit_l(ch, __l))
                 *vec |= digit;
             if (iswpunct_l(ch, __l))
                 *vec |= punct;
+#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
             if (iswxdigit_l(ch, __l))
                 *vec |= xdigit;
+#endif
+            if (iswblank_l(ch, __l))
+                *vec |= blank;
         }
     }
     return low;
@@ -1241,16 +1249,16 @@
             break;
 #else
         wint_t ch = static_cast<wint_t>(*low);
-        if (m & space && iswspace_l(ch, __l)) break;
-        if (m & print && iswprint_l(ch, __l)) break;
-        if (m & cntrl && iswcntrl_l(ch, __l)) break;
-        if (m & upper && iswupper_l(ch, __l)) break;
-        if (m & lower && iswlower_l(ch, __l)) break;
-        if (m & alpha && iswalpha_l(ch, __l)) break;
-        if (m & digit && iswdigit_l(ch, __l)) break;
-        if (m & punct && iswpunct_l(ch, __l)) break;
-        if (m & xdigit && iswxdigit_l(ch, __l)) break;
-        if (m & blank && iswblank_l(ch, __l)) break;
+        if ((m & space) == space && iswspace_l(ch, __l)) break;
+        if ((m & print) == print && iswprint_l(ch, __l)) break;
+        if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
+        if ((m & upper) == upper && iswupper_l(ch, __l)) break;
+        if ((m & lower) == lower && iswlower_l(ch, __l)) break;
+        if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
+        if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
+        if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
+        if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
+        if ((m & blank) == blank && iswblank_l(ch, __l)) break;
 #endif
     }
     return low;
@@ -1266,16 +1274,16 @@
             break;
 #else
         wint_t ch = static_cast<wint_t>(*low);
-        if (m & space && iswspace_l(ch, __l)) continue;
-        if (m & print && iswprint_l(ch, __l)) continue;
-        if (m & cntrl && iswcntrl_l(ch, __l)) continue;
-        if (m & upper && iswupper_l(ch, __l)) continue;
-        if (m & lower && iswlower_l(ch, __l)) continue;
-        if (m & alpha && iswalpha_l(ch, __l)) continue;
-        if (m & digit && iswdigit_l(ch, __l)) continue;
-        if (m & punct && iswpunct_l(ch, __l)) continue;
-        if (m & xdigit && iswxdigit_l(ch, __l)) continue;
-        if (m & blank && iswblank_l(ch, __l)) continue;
+        if ((m & space) == space && iswspace_l(ch, __l)) continue;
+        if ((m & print) == print && iswprint_l(ch, __l)) continue;
+        if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
+        if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
+        if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
+        if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
+        if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
+        if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
+        if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
+        if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
         break;
 #endif
     }
Index: test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp
===================================================================
--- test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp
+++ test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// template <class charT> class ctype_byname;
+
+// bool is(mask m, charT c) const;
+
+#include <locale>
+#include <type_traits>
+#include <cassert>
+
+int main()
+{
+    {
+        std::locale l("C");
+        {
+            typedef std::ctype<wchar_t> WF;
+            const WF& wf = std::use_facet<WF>(l);
+            typedef std::ctype<char> CF;
+            const CF& cf = std::use_facet<CF>(l);
+
+            // The ctype masks in Newlib don't form a proper bitmask because
+            // the mask is only 8 bits wide, and there are more than 8 mask
+            // kinds. This means that the mask for alpha is (_U | _L), which
+            // is tricky to match in the do_is implementation because in
+            // [22.4.1.1.2 2] the standard specifies that the match code behaves
+            // like (m & M) != 0, but following this exactly would give false
+            // positives for characters that are both 'upper' and 'alpha', but
+            // not 'lower', for example.
+            assert( wf.is(WF::upper, L'A'));
+            assert( cf.is(CF::upper,  'A'));
+            assert(!wf.is(WF::lower, L'A'));
+            assert(!cf.is(CF::lower,  'A'));
+            assert( wf.is(WF::alpha, L'A'));
+            assert( cf.is(CF::alpha,  'A'));
+
+            assert(!wf.is(WF::upper, L'a'));
+            assert(!cf.is(CF::upper,  'a'));
+            assert( wf.is(WF::lower, L'a'));
+            assert( cf.is(CF::lower,  'a'));
+            assert( wf.is(WF::alpha, L'a'));
+            assert( cf.is(CF::alpha,  'a'));
+        }
+    }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to