mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									f56506be0d
								
							
						
					
					
						commit
						3632a812c0
					
				
				
				Notes:
				
					git
				
				2019-09-30 10:27:07 +09:00 
				
			
			
			
		
		
					 2 changed files with 45 additions and 39 deletions
				
			
		
							
								
								
									
										83
									
								
								id_table.c
									
										
									
									
									
								
							
							
						
						
									
										83
									
								
								id_table.c
									
										
									
									
									
								
							|  | @ -269,57 +269,62 @@ rb_id_table_delete(struct rb_id_table *tbl, ID id) | |||
| 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); | ||||
| typedef struct tuple { | ||||
|     rb_id_table_foreach_values_func_t *const func; | ||||
|     void *const data; | ||||
| } tuple; | ||||
| 
 | ||||
| 	    if (ret == ID_TABLE_DELETE) | ||||
| 		hash_delete_index(tbl, i); | ||||
| 	    else if (ret == ID_TABLE_STOP) | ||||
| 		return; | ||||
| 	} | ||||
|     } | ||||
| 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; | ||||
|     rb_id_table_foreach_with_replace( | ||||
|         tbl, cdr, 0, &(tuple) { func, data, }); | ||||
| } | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
| 	    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; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ typedef enum rb_id_table_iterator_result rb_id_table_foreach_func_t(ID id, VALUE | |||
| 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 */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 卜部昌平
						卜部昌平