1 #ifndef INTERNAL_HASH_H /*-*-C-*-vi:se ft=c:*/
2 #define INTERNAL_HASH_H
4 * @author Ruby developers <ruby-core@ruby-lang.org>
5 * @copyright This file is a part of the programming language Ruby.
6 * Permission is hereby granted, to either redistribute and/or
7 * modify this file, provided that the conditions mentioned in the
8 * file COPYING are met. Consult the file for details.
9 * @brief Internal header for Hash.
11 #include "ruby/internal/config.h"
12 #include <stddef.h> /* for size_t */
13 #include "ruby/internal/stdbool.h" /* for bool */
14 #include "ruby/ruby.h" /* for struct RBasic */
15 #include "ruby/st.h" /* for struct st_table */
17 #define RHASH_AR_TABLE_MAX_SIZE SIZEOF_VALUE
19 struct ar_table_struct
;
20 typedef unsigned char ar_hint_t
;
22 enum ruby_rhash_flags
{
23 RHASH_PASS_AS_KEYWORDS
= FL_USER1
, /* FL 1 */
24 RHASH_PROC_DEFAULT
= FL_USER2
, /* FL 2 */
25 RHASH_ST_TABLE_FLAG
= FL_USER3
, /* FL 3 */
26 RHASH_AR_TABLE_SIZE_MASK
= (FL_USER4
|FL_USER5
|FL_USER6
|FL_USER7
), /* FL 4..7 */
27 RHASH_AR_TABLE_SIZE_SHIFT
= (FL_USHIFT
+4),
28 RHASH_AR_TABLE_BOUND_MASK
= (FL_USER8
|FL_USER9
|FL_USER10
|FL_USER11
), /* FL 8..11 */
29 RHASH_AR_TABLE_BOUND_SHIFT
= (FL_USHIFT
+8),
31 #if USE_TRANSIENT_HEAP
32 RHASH_TRANSIENT_FLAG
= FL_USER12
, /* FL 12 */
35 // we can not put it in "enum" because it can exceed "int" range.
36 #define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
37 FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
39 RHASH_LEV_SHIFT
= (FL_USHIFT
+ 13),
40 RHASH_LEV_MAX
= 127, /* 7 bits */
47 struct ar_table_struct
*ar
; /* possibly 0 */
51 ar_hint_t ary
[RHASH_AR_TABLE_MAX_SIZE
];
56 #define RHASH(obj) ((struct RHash *)(obj))
71 void rb_hash_st_table_set(VALUE hash
, st_table
*st
);
72 VALUE
rb_hash_default_value(VALUE hash
, VALUE key
);
73 VALUE
rb_hash_set_default_proc(VALUE hash
, VALUE proc
);
74 long rb_dbl_long_hash(double d
);
75 st_table
*rb_init_identtable(void);
76 st_index_t
rb_any_hash(VALUE a
);
77 int rb_any_cmp(VALUE a
, VALUE b
);
78 VALUE
rb_to_hash_type(VALUE obj
);
79 VALUE
rb_hash_key_str(VALUE
);
80 VALUE
rb_hash_values(VALUE hash
);
81 VALUE
rb_hash_rehash(VALUE hash
);
82 int rb_hash_add_new_element(VALUE hash
, VALUE key
, VALUE val
);
83 VALUE
rb_hash_set_pair(VALUE hash
, VALUE pair
);
84 int rb_hash_stlike_delete(VALUE hash
, st_data_t
*pkey
, st_data_t
*pval
);
85 int rb_hash_stlike_foreach_with_replace(VALUE hash
, st_foreach_check_callback_func
*func
, st_update_callback_func
*replace
, st_data_t arg
);
86 int rb_hash_stlike_update(VALUE hash
, st_data_t key
, st_update_callback_func
*func
, st_data_t arg
);
87 VALUE
rb_ident_hash_new_with_size(st_index_t size
);
89 static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h
);
90 static inline VALUE
RHASH_IFNONE(VALUE h
);
91 static inline size_t RHASH_SIZE(VALUE h
);
92 static inline bool RHASH_EMPTY_P(VALUE h
);
93 static inline bool RHASH_AR_TABLE_P(VALUE h
);
94 static inline bool RHASH_ST_TABLE_P(VALUE h
);
95 static inline struct ar_table_struct
*RHASH_AR_TABLE(VALUE h
);
96 static inline st_table
*RHASH_ST_TABLE(VALUE h
);
97 static inline size_t RHASH_ST_SIZE(VALUE h
);
98 static inline void RHASH_ST_CLEAR(VALUE h
);
99 static inline bool RHASH_TRANSIENT_P(VALUE h
);
100 static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h
);
101 static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h
);
103 RUBY_SYMBOL_EXPORT_BEGIN
104 /* hash.c (export) */
105 VALUE
rb_hash_delete_entry(VALUE hash
, VALUE key
);
106 VALUE
rb_ident_hash_new(void);
107 int rb_hash_stlike_foreach(VALUE hash
, st_foreach_callback_func
*func
, st_data_t arg
);
108 RUBY_SYMBOL_EXPORT_END
110 VALUE
rb_hash_new_with_size(st_index_t size
);
111 VALUE
rb_hash_resurrect(VALUE hash
);
112 int rb_hash_stlike_lookup(VALUE hash
, st_data_t key
, st_data_t
*pval
);
113 VALUE
rb_hash_keys(VALUE hash
);
114 VALUE
rb_hash_has_key(VALUE hash
, VALUE key
);
115 VALUE
rb_hash_compare_by_id_p(VALUE hash
);
117 st_table
*rb_hash_tbl_raw(VALUE hash
, const char *file
, int line
);
118 #define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
120 VALUE
rb_hash_compare_by_id(VALUE hash
);
123 RHASH_AR_TABLE_P(VALUE h
)
125 return ! FL_TEST_RAW(h
, RHASH_ST_TABLE_FLAG
);
128 static inline struct ar_table_struct
*
129 RHASH_AR_TABLE(VALUE h
)
131 return RHASH(h
)->as
.ar
;
134 static inline st_table
*
135 RHASH_ST_TABLE(VALUE h
)
137 return RHASH(h
)->as
.st
;
141 RHASH_IFNONE(VALUE h
)
143 return RHASH(h
)->ifnone
;
149 if (RHASH_AR_TABLE_P(h
)) {
150 return RHASH_AR_TABLE_SIZE_RAW(h
);
153 return RHASH_ST_SIZE(h
);
158 RHASH_EMPTY_P(VALUE h
)
160 return RHASH_SIZE(h
) == 0;
164 RHASH_ST_TABLE_P(VALUE h
)
166 return ! RHASH_AR_TABLE_P(h
);
170 RHASH_ST_SIZE(VALUE h
)
172 return RHASH_ST_TABLE(h
)->num_entries
;
176 RHASH_ST_CLEAR(VALUE h
)
178 RHASH(h
)->as
.st
= NULL
;
179 FL_UNSET_RAW(h
, RHASH_ST_TABLE_FLAG
);
182 static inline unsigned
183 RHASH_AR_TABLE_SIZE_RAW(VALUE h
)
185 VALUE ret
= FL_TEST_RAW(h
, RHASH_AR_TABLE_SIZE_MASK
);
186 ret
>>= RHASH_AR_TABLE_SIZE_SHIFT
;
187 return (unsigned)ret
;
191 RHASH_TRANSIENT_P(VALUE h
)
193 #if USE_TRANSIENT_HEAP
194 return FL_TEST_RAW(h
, RHASH_TRANSIENT_FLAG
);
201 RHASH_SET_TRANSIENT_FLAG(VALUE h
)
203 #if USE_TRANSIENT_HEAP
204 FL_SET_RAW(h
, RHASH_TRANSIENT_FLAG
);
209 RHASH_UNSET_TRANSIENT_FLAG(VALUE h
)
211 #if USE_TRANSIENT_HEAP
212 FL_UNSET_RAW(h
, RHASH_TRANSIENT_FLAG
);
216 #endif /* INTERNAL_HASH_H */