00001
00002
00003
00004
00005 #ifndef RUBY_ST_H
00006 #define RUBY_ST_H 1
00007
00008 #if defined(__cplusplus)
00009 extern "C" {
00010 #if 0
00011 }
00012 #endif
00013 #endif
00014
00015 #include "ruby/defines.h"
00016
00017 RUBY_SYMBOL_EXPORT_BEGIN
00018
00019 #if SIZEOF_LONG == SIZEOF_VOIDP
00020 typedef unsigned long st_data_t;
00021 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
00022 typedef unsigned LONG_LONG st_data_t;
00023 #else
00024 # error ---->> st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
00025 #endif
00026 #define ST_DATA_T_DEFINED
00027
00028 #ifndef CHAR_BIT
00029 # ifdef HAVE_LIMITS_H
00030 # include <limits.h>
00031 # else
00032 # define CHAR_BIT 8
00033 # endif
00034 #endif
00035 #ifndef _
00036 # define _(args) args
00037 #endif
00038 #ifndef ANYARGS
00039 # ifdef __cplusplus
00040 # define ANYARGS ...
00041 # else
00042 # define ANYARGS
00043 # endif
00044 #endif
00045
00046 typedef struct st_table st_table;
00047
00048 typedef st_data_t st_index_t;
00049 typedef int st_compare_func(st_data_t, st_data_t);
00050 typedef st_index_t st_hash_func(st_data_t);
00051
00052 typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1];
00053 #define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
00054
00055 struct st_hash_type {
00056 int (*compare)(ANYARGS );
00057 st_index_t (*hash)(ANYARGS );
00058 };
00059
00060 #define ST_INDEX_BITS (sizeof(st_index_t) * CHAR_BIT)
00061
00062 #if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
00063 # define ST_DATA_COMPATIBLE_P(type) \
00064 __builtin_choose_expr(__builtin_types_compatible_p(type, st_data_t), 1, 0)
00065 #else
00066 # define ST_DATA_COMPATIBLE_P(type) 0
00067 #endif
00068
00069 struct st_table {
00070 const struct st_hash_type *type;
00071 st_index_t num_bins;
00072 unsigned int entries_packed : 1;
00073 #ifdef __GNUC__
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 __extension__
00084 #endif
00085 st_index_t num_entries : ST_INDEX_BITS - 1;
00086 union {
00087 struct {
00088 struct st_table_entry **bins;
00089 struct st_table_entry *head, *tail;
00090 } big;
00091 struct {
00092 struct st_packed_entry *entries;
00093 st_index_t real_entries;
00094 } packed;
00095 } as;
00096 };
00097
00098 #define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
00099
00100 enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
00101
00102 st_table *st_init_table(const struct st_hash_type *);
00103 st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
00104 st_table *st_init_numtable(void);
00105 st_table *st_init_numtable_with_size(st_index_t);
00106 st_table *st_init_strtable(void);
00107 st_table *st_init_strtable_with_size(st_index_t);
00108 st_table *st_init_strcasetable(void);
00109 st_table *st_init_strcasetable_with_size(st_index_t);
00110 int st_delete(st_table *, st_data_t *, st_data_t *);
00111 int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
00112 int st_shift(st_table *, st_data_t *, st_data_t *);
00113 int st_insert(st_table *, st_data_t, st_data_t);
00114 int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
00115 int st_lookup(st_table *, st_data_t, st_data_t *);
00116 int st_get_key(st_table *, st_data_t, st_data_t *);
00117 typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
00118 int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
00119 int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
00120 int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
00121 int st_reverse_foreach(st_table *, int (*)(ANYARGS), st_data_t);
00122 st_index_t st_keys(st_table *table, st_data_t *keys, st_index_t size);
00123 st_index_t st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
00124 st_index_t st_values(st_table *table, st_data_t *values, st_index_t size);
00125 st_index_t st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
00126 void st_add_direct(st_table *, st_data_t, st_data_t);
00127 void st_free_table(st_table *);
00128 void st_cleanup_safe(st_table *, st_data_t);
00129 void st_clear(st_table *);
00130 st_table *st_copy(st_table *);
00131 int st_numcmp(st_data_t, st_data_t);
00132 st_index_t st_numhash(st_data_t);
00133 int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
00134 int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
00135 #define st_strcasecmp st_locale_insensitive_strcasecmp
00136 #define st_strncasecmp st_locale_insensitive_strncasecmp
00137 size_t st_memsize(const st_table *);
00138 st_index_t st_hash(const void *ptr, size_t len, st_index_t h);
00139 st_index_t st_hash_uint32(st_index_t h, uint32_t i);
00140 st_index_t st_hash_uint(st_index_t h, st_index_t i);
00141 st_index_t st_hash_end(st_index_t h);
00142 st_index_t st_hash_start(st_index_t h);
00143 #define st_hash_start(h) ((st_index_t)(h))
00144
00145 RUBY_SYMBOL_EXPORT_END
00146
00147 #if defined(__cplusplus)
00148 #if 0
00149 {
00150 #endif
00151 }
00152 #endif
00153
00154 #endif
00155