summaryrefslogtreecommitdiff
path: root/handy.h
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2011-09-24 15:10:01 -0600
committerKarl Williamson <public@khwilliamson.com>2011-10-01 09:58:09 -0600
commiteb0052d12453d188c7a1927092ec86ea704a0e60 (patch)
tree65c637f6dd98734dfcbfef6f227dc3b12b5301b6 /handy.h
parent7b952154426e53253db1065e8e73307cafb4c28b (diff)
downloadperl-eb0052d12453d188c7a1927092ec86ea704a0e60.tar.gz
handy.h: Don't call _uni fcns if have applicable macro
This patch avoids the overhead of calling eg. is_uni_alpha() if the result is known to Perl's core. This can avoid a swash load.
Diffstat (limited to 'handy.h')
-rw-r--r--handy.h35
1 files changed, 23 insertions, 12 deletions
diff --git a/handy.h b/handy.h
index 0247728e4d..9261a2267e 100644
--- a/handy.h
+++ b/handy.h
@@ -859,26 +859,37 @@ EXTCONST U32 PL_charclass[];
#define isPSXSPC_LC(c) (isSPACE_LC(c) || (c) == '\v')
#define isBLANK_LC(c) isBLANK(c) /* could be wrong */
-#define isALNUM_uni(c) is_uni_alnum(c)
-#define isIDFIRST_uni(c) is_uni_idfirst(c)
-#define isALPHA_uni(c) is_uni_alpha(c)
-#define isSPACE_uni(c) is_uni_space(c)
-#define isDIGIT_uni(c) is_uni_digit(c)
-#define isUPPER_uni(c) is_uni_upper(c)
-#define isLOWER_uni(c) is_uni_lower(c)
+/* For use in the macros just below. If the input is Latin1, use the Latin1
+ * (_L1) version of the macro; otherwise use the function. Won't compile if
+ * 'c' isn't unsigned, as won't match function prototype. The macros do bounds
+ * checking, so have duplicate checks here, so could create versions of the
+ * macros that don't, but experiments show that gcc optimizes them out anyway.
+ */
+#define generic_uni(macro, function, c) ((c) < 256 \
+ ? CAT2(macro, _L1)(c) \
+ : function(c))
+
+#define isALNUM_uni(c) generic_uni(isWORDCHAR, is_uni_alnum, c)
+#define isIDFIRST_uni(c) generic_uni(isIDFIRST, is_uni_idfirst, c)
+#define isALPHA_uni(c) generic_uni(isALPHA, is_uni_alpha, c)
+#define isSPACE_uni(c) generic_uni(isSPACE, is_uni_space, c)
+#define isDIGIT_uni(c) generic_uni(isDIGIT, is_uni_digit, c)
+#define isUPPER_uni(c) generic_uni(isUPPER, is_uni_upper, c)
+#define isLOWER_uni(c) generic_uni(isLOWER, is_uni_lower, c)
#define isASCII_uni(c) isASCII(c)
/* All controls are in Latin1 */
#define isCNTRL_uni(c) ((c) < 256 ? isCNTRL_L1(c) : 0)
-#define isGRAPH_uni(c) is_uni_graph(c)
-#define isPRINT_uni(c) is_uni_print(c)
-#define isPUNCT_uni(c) is_uni_punct(c)
-#define isXDIGIT_uni(c) is_uni_xdigit(c)
+#define isGRAPH_uni(c) generic_uni(isGRAPH, is_uni_graph, c)
+#define isPRINT_uni(c) generic_uni(isPRINT, is_uni_print, c)
+#define isPUNCT_uni(c) generic_uni(isPUNCT, is_uni_punct, c)
+#define isXDIGIT_uni(c) generic_uni(isXDIGIT, is_uni_xdigit, c)
#define toUPPER_uni(c,s,l) to_uni_upper(c,s,l)
#define toTITLE_uni(c,s,l) to_uni_title(c,s,l)
#define toLOWER_uni(c,s,l) to_uni_lower(c,s,l)
#define toFOLD_uni(c,s,l) to_uni_fold(c,s,l)
-#define isPSXSPC_uni(c) (isSPACE_uni(c) ||(c) == '\f')
+/* Posix and regular space differ only in U+000B, which is in Latin1 */
+#define isPSXSPC_uni(c) ((c) < 256 ? isPSXSPC_L1(c) : isSPACE_uni(c))
#define isBLANK_uni(c) isBLANK(c) /* could be wrong */
#define isALNUM_LC_uvchr(c) (c < 256 ? isALNUM_LC(c) : is_uni_alnum_lc(c))