From: Vincent Pit <perl@profvince.com>
Date: Mon, 31 Jul 2017 11:30:26 +0000 (+0200)
Subject: Add separate hint values for keys/values
X-Git-Tag: v0.17~6
X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=0cd4c2a91f46cbca31aca9a100adbcbb7aa51894;p=perl%2Fmodules%2Fautovivification.git

Add separate hint values for keys/values
---

diff --git a/autovivification.xs b/autovivification.xs
index 34cd2da..ddc4dd7 100644
--- a/autovivification.xs
+++ b/autovivification.xs
@@ -22,15 +22,17 @@
 #define A_HINT_WARN   2
 #define A_HINT_FETCH  4
 #define A_HINT_STORE  8
-#define A_HINT_EXISTS 16
-#define A_HINT_DELETE 32
+#define A_HINT_KEYS   16
+#define A_HINT_VALUES 32
+#define A_HINT_EXISTS 64
+#define A_HINT_DELETE 128
 #define A_HINT_NOTIFY (A_HINT_STRICT|A_HINT_WARN)
-#define A_HINT_DO     (A_HINT_FETCH|A_HINT_STORE|A_HINT_EXISTS|A_HINT_DELETE)
+#define A_HINT_DO     (A_HINT_FETCH|A_HINT_STORE|A_HINT_KEYS|A_HINT_VALUES|A_HINT_EXISTS|A_HINT_DELETE)
 #define A_HINT_MASK   (A_HINT_NOTIFY|A_HINT_DO)
 
 /* Only used in op flags */
-#define A_HINT_ROOT   64
-#define A_HINT_DEREF  128
+#define A_HINT_ROOT   256
+#define A_HINT_DEREF  512
 
 #define XSH_HINTS_TYPE_UV 1
 
@@ -294,8 +296,10 @@ static UV a_map_resolve(const OP *o, const a_op_info *oi) {
  if (root->op_flags & OPf_MOD) {
   if (rflags & A_HINT_STORE)
    flags = (A_HINT_STORE|A_HINT_DEREF);
- } else if (rflags & A_HINT_FETCH)
-   flags = (A_HINT_FETCH|A_HINT_DEREF);
+ } else {
+  if (rflags & (A_HINT_FETCH|A_HINT_KEYS|A_HINT_VALUES))
+   flags = (rflags|A_HINT_DEREF);
+ }
 
  if (!flags) {
 cancel:
@@ -1001,12 +1005,12 @@ static OP *a_ck_root(pTHX_ OP *o) {
   case OP_KEYS:
    old_ck  = a_old_ck_keys;
    new_pp  = a_pp_root_unop;
-   enabled = hint & A_HINT_FETCH;
+   enabled = hint & A_HINT_KEYS;
    break;
   case OP_VALUES:
    old_ck  = a_old_ck_values;
    new_pp  = a_pp_root_unop;
-   enabled = hint & A_HINT_FETCH;
+   enabled = hint & A_HINT_VALUES;
    break;
  }
  o = old_ck(aTHX_ o);
@@ -1138,6 +1142,8 @@ static void xsh_user_local_setup(pTHX) {
  newCONSTSUB(stash, "A_HINT_WARN",   newSVuv(A_HINT_WARN));
  newCONSTSUB(stash, "A_HINT_FETCH",  newSVuv(A_HINT_FETCH));
  newCONSTSUB(stash, "A_HINT_STORE",  newSVuv(A_HINT_STORE));
+ newCONSTSUB(stash, "A_HINT_KEYS",   newSVuv(A_HINT_KEYS));
+ newCONSTSUB(stash, "A_HINT_VALUES", newSVuv(A_HINT_VALUES));
  newCONSTSUB(stash, "A_HINT_EXISTS", newSVuv(A_HINT_EXISTS));
  newCONSTSUB(stash, "A_HINT_DELETE", newSVuv(A_HINT_DELETE));
  newCONSTSUB(stash, "A_HINT_MASK",   newSVuv(A_HINT_MASK));
diff --git a/lib/autovivification.pm b/lib/autovivification.pm
index 8b1e152..30974ea 100644
--- a/lib/autovivification.pm
+++ b/lib/autovivification.pm
@@ -144,7 +144,7 @@ When C<@opts> is empty, it defaults to C<< qw<fetch exists delete> >>.
 my %bits = (
  strict => A_HINT_STRICT,
  warn   => A_HINT_WARN,
- fetch  => A_HINT_FETCH,
+ fetch  => A_HINT_FETCH|A_HINT_KEYS|A_HINT_VALUES,
  store  => A_HINT_STORE,
  exists => A_HINT_EXISTS,
  delete => A_HINT_DELETE,