[前][次][番号順一覧][スレッド一覧]

ruby-changes:58030

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 30 Sep 2019 10:27:00 +0900 (JST)
Subject: [ruby-changes:58030] 3632a812c0 (master): refactor add rb_id_table_foreach_with_replace_with_key

https://git.ruby-lang.org/ruby.git/commit/?id=3632a812c0

From 3632a812c0b1e0bd1c75b2426cbfe9ec1715bb56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Wed, 25 Sep 2019 13:00:56 +0900
Subject: refactor add rb_id_table_foreach_with_replace_with_key

This is a pure refactoring to reduce copy & paste.  Also the new
function is made visible from other parts of the interpreter, to
be used later.

diff --git a/id_table.c b/id_table.c
index f566582..b383fcf 100644
--- a/id_table.c
+++ b/id_table.c
@@ -269,57 +269,62 @@ rb_id_table_delete(struct rb_id_table *tbl, ID id) https://github.com/ruby/ruby/blob/trunk/id_table.c#L269
 void
 rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data)
 {
-    int i, capa = tbl->capa;
-
-    for (i=0; i<capa; i++) {
-        if (ITEM_KEY_ISSET(tbl, i)) {
-            const id_key_t key = ITEM_GET_KEY(tbl, i);
-            enum rb_id_table_iterator_result ret = (*func)(Qundef, tbl->items[i].val, data);
-            assert(key != 0);
-
-            if (ret == ID_TABLE_REPLACE) {
-                VALUE val = tbl->items[i].val;
-                ret = (*replace)(NULL, &val, data, TRUE);
-                tbl->items[i].val = val;
-            }
-            else if (ret == ID_TABLE_STOP)
-                return;
-        }
-    }
+    rb_id_table_foreach_with_replace_with_key(tbl, func, replace, data, false);
 }
 
 void
 rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data)
 {
-    int i, capa = tbl->capa;
+    rb_id_table_foreach_with_replace_with_key(tbl, func, 0, data, true);
+}
 
-    for (i=0; i<capa; i++) {
-	if (ITEM_KEY_ISSET(tbl, i)) {
-	    const id_key_t key = ITEM_GET_KEY(tbl, i);
-	    enum rb_id_table_iterator_result ret = (*func)(key2id(key), tbl->items[i].val, data);
-	    assert(key != 0);
-
-	    if (ret == ID_TABLE_DELETE)
-		hash_delete_index(tbl, i);
-	    else if (ret == ID_TABLE_STOP)
-		return;
-	}
-    }
+typedef struct tuple {
+    rb_id_table_foreach_values_func_t *const func;
+    void *const data;
+} tuple;
+
+static enum rb_id_table_iterator_result
+cdr(ID car, VALUE cdr, void *data)
+{
+    const tuple *ptr = data;
+    return ptr->func(cdr, ptr->data);
 }
 
 void
 rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data)
 {
-    int i, capa = tbl->capa;
-
-    for (i=0; i<capa; i++) {
-	if (ITEM_KEY_ISSET(tbl, i)) {
-	    enum rb_id_table_iterator_result ret = (*func)(tbl->items[i].val, data);
+    rb_id_table_foreach_with_replace(
+        tbl, cdr, 0, &(tuple) { func, data, });
+}
 
-	    if (ret == ID_TABLE_DELETE)
-		hash_delete_index(tbl, i);
-	    else if (ret == ID_TABLE_STOP)
-		return;
-	}
+void
+rb_id_table_foreach_with_replace_with_key(
+    struct rb_id_table *tbl,
+    rb_id_table_foreach_func_t *func,
+    rb_id_table_update_callback_func_t *replace,
+    void *data,
+    bool needkey)
+{
+    for (int i = 0; i < tbl->capa; i++) {
+        if (ITEM_KEY_ISSET(tbl, i)) {
+            const id_key_t key = ITEM_GET_KEY(tbl, i);
+            assert(key != 0);
+            ID k = needkey ? key2id(key) : 0;
+            VALUE v = tbl->items[i].val;
+            switch (func(k, v, data)) {
+              case ID_TABLE_DELETE:
+                hash_delete_index(tbl, i);
+                /* FALLTHROUGH */
+              case ID_TABLE_CONTINUE:
+                continue;
+              case ID_TABLE_STOP:
+                return;
+              case ID_TABLE_REPLACE:
+                if (replace) {
+                    replace(&k, &v, data, true);
+                    tbl->items[i].val = v;
+                }
+            }
+        }
     }
 }
diff --git a/id_table.h b/id_table.h
index 07ad1b8..1918119 100644
--- a/id_table.h
+++ b/id_table.h
@@ -28,6 +28,7 @@ typedef enum rb_id_table_iterator_result rb_id_table_foreach_func_t(ID id, VALUE https://github.com/ruby/ruby/blob/trunk/id_table.h#L28
 typedef enum rb_id_table_iterator_result rb_id_table_foreach_values_func_t(VALUE val, void *data);
 void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data);
 void rb_id_table_foreach_with_replace(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data);
+void rb_id_table_foreach_with_replace_with_key(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, rb_id_table_update_callback_func_t *replace, void *data, bool needkey);
 void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data);
 
 #endif	/* RUBY_ID_TABLE_H */
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]