1 /**
2 ** @file mruby/hash.h - Hash class
3 **
4 ** See Copyright Notice in mruby.h
5 */
6 
7 #ifndef MRUBY_HASH_H
8 #define MRUBY_HASH_H
9 
10 #include "common.h"
11 
12 /**
13  * Hash class
14  */
15 MRB_BEGIN_DECL
16 
17 struct RHash {
18   MRB_OBJECT_HEADER;
19   struct iv_tbl *iv;
20   struct htable *ht;
21 };
22 
23 #define mrb_hash_ptr(v)    ((struct RHash*)(mrb_ptr(v)))
24 #define mrb_hash_value(p)  mrb_obj_value((void*)(p))
25 
26 MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
27 MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
28 MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
29 
30 /*
31  * Initializes a new hash.
32  *
33  * Equivalent to:
34  *
35  *      Hash.new
36  *
37  * @param mrb The mruby state reference.
38  * @return The initialized hash.
39  */
40 MRB_API mrb_value mrb_hash_new(mrb_state *mrb);
41 
42 /*
43  * Sets a keys and values to hashes.
44  *
45  * Equivalent to:
46  *
47  *      hash[key] = val
48  *
49  * @param mrb The mruby state reference.
50  * @param hash The target hash.
51  * @param key The key to set.
52  * @param val The value to set.
53  * @return The value.
54  */
55 MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
56 
57 /*
58  * Gets a value from a key. If the key is not found, the default of the
59  * hash is used.
60  *
61  * Equivalent to:
62  *
63  *     hash[key]
64  *
65  * @param mrb The mruby state reference.
66  * @param hash The target hash.
67  * @param key The key to get.
68  * @return The found value.
69  */
70 MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
71 
72 /*
73  * Gets a value from a key. If the key is not found, the default parameter is
74  * used.
75  *
76  * Equivalent to:
77  *
78  *     hash.key?(key) ? hash[key] : def
79  *
80  * @param mrb The mruby state reference.
81  * @param hash The target hash.
82  * @param key The key to get.
83  * @param def The default value.
84  * @return The found value.
85  */
86 MRB_API mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def);
87 
88 /*
89  * Deletes hash key and value pair.
90  *
91  * Equivalent to:
92  *
93  *     hash.delete(key)
94  *
95  * @param mrb The mruby state reference.
96  * @param hash The target hash.
97  * @param key The key to delete.
98  * @return The deleted value. This value is not protected from GC. Use `mrb_gc_protect()` if necessary.
99  */
100 MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
101 
102 /*
103  * Gets an array of keys.
104  *
105  * Equivalent to:
106  *
107  *     hash.keys
108  *
109  * @param mrb The mruby state reference.
110  * @param hash The target hash.
111  * @return An array with the keys of the hash.
112  */
113 MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash);
114 /*
115  * Check if the hash has the key.
116  *
117  * Equivalent to:
118  *
119  *     hash.key?(key)
120  *
121  * @param mrb The mruby state reference.
122  * @param hash The target hash.
123  * @param key The key to check existence.
124  * @return True if the hash has the key
125  */
126 MRB_API mrb_bool mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key);
127 
128 /*
129  * Check if the hash is empty
130  *
131  * Equivalent to:
132  *
133  *     hash.empty?
134  *
135  * @param mrb The mruby state reference.
136  * @param self The target hash.
137  * @return True if the hash is empty, false otherwise.
138  */
139 MRB_API mrb_bool mrb_hash_empty_p(mrb_state *mrb, mrb_value self);
140 
141 /*
142  * Gets an array of values.
143  *
144  * Equivalent to:
145  *
146  *     hash.values
147  *
148  * @param mrb The mruby state reference.
149  * @param hash The target hash.
150  * @return An array with the values of the hash.
151  */
152 MRB_API mrb_value mrb_hash_values(mrb_state *mrb, mrb_value hash);
153 
154 /*
155  * Clears the hash.
156  *
157  * Equivalent to:
158  *
159  *     hash.clear
160  *
161  * @param mrb The mruby state reference.
162  * @param hash The target hash.
163  * @return The hash
164  */
165 MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash);
166 
167 /*
168  * Get hash size.
169  *
170  * Equivalent to:
171  *
172  *      hash.size
173  *
174  * @param mrb The mruby state reference.
175  * @param hash The target hash.
176  * @return The hash size.
177  */
178 MRB_API mrb_int mrb_hash_size(mrb_state *mrb, mrb_value hash);
179 
180 /*
181  * Copies the hash.
182  *
183  *
184  * @param mrb The mruby state reference.
185  * @param hash The target hash.
186  * @return The copy of the hash
187  */
188 MRB_API mrb_value mrb_hash_dup(mrb_state *mrb, mrb_value hash);
189 
190 /*
191  * Merges two hashes. The first hash will be modified by the
192  * second hash.
193  *
194  * @param mrb The mruby state reference.
195  * @param hash1 The target hash.
196  * @param hash2 Updating hash
197  */
198 MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
199 
200 /* RHASH_TBL allocates st_table if not available. */
201 #define RHASH(obj)   ((struct RHash*)(mrb_ptr(obj)))
202 #define RHASH_TBL(h)          (RHASH(h)->ht)
203 #define RHASH_IFNONE(h)       mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone"))
204 #define RHASH_PROCDEFAULT(h)  RHASH_IFNONE(h)
205 
206 #define MRB_HASH_DEFAULT      1
207 #define MRB_HASH_PROC_DEFAULT 2
208 #define MRB_RHASH_DEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_DEFAULT)
209 #define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)
210 
211 /* GC functions */
212 void mrb_gc_mark_hash(mrb_state*, struct RHash*);
213 size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
214 void mrb_gc_free_hash(mrb_state*, struct RHash*);
215 
216 /* return non zero to break the loop */
217 typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data);
218 MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p);
219 
220 MRB_END_DECL
221 
222 #endif  /* MRUBY_HASH_H */
223