]> git.donarmstrong.com Git - lilypond.git/blob - lily/scm-hash.cc
af68717b4bccbe96ebc32f1085b845b62b6ba425
[lilypond.git] / lily / scm-hash.cc
1 /*
2   scm-hash.cc -- implement Scheme_hash_table
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1999--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "scm-hash.hh"
10
11 #include <cstdio>
12 #include <algorithm>
13 using namespace std;
14
15 #include "ly-smobs.icc"
16
17 /*
18   Return: number of objects.
19 */
20 SCM
21 copy_handle (void *closure, SCM handle)
22 {
23   SCM tab = (SCM) closure;
24   scm_hashq_set_x (tab, scm_car (handle), scm_cdr (handle));
25   return tab;
26 }
27
28 static void
29 copy_scm_hashes (SCM dest, SCM src)
30 {
31   scm_internal_hash_for_each_handle (  (SCM (*)(GUILE_ELLIPSIS)) &copy_handle, dest, src);
32 }
33
34 Scheme_hash_table::Scheme_hash_table ()
35 {
36   hash_tab_ = SCM_EOL;
37   smobify_self ();
38   hash_tab_ = scm_c_make_hash_table (119);
39 }
40
41 Scheme_hash_table::Scheme_hash_table (Scheme_hash_table const &src)
42 {
43   hash_tab_ = SCM_EOL;
44   smobify_self ();
45   copy (src);
46 }
47
48 void
49 Scheme_hash_table::copy (Scheme_hash_table const &src)
50 {
51   if (&src == this)
52     return;
53
54   hash_tab_ = scm_c_make_hash_table (SCM_HASHTABLE_N_ITEMS(src.hash_tab_));
55   copy_scm_hashes (hash_tab_, src.hash_tab_);
56 }
57
58 Scheme_hash_table::~Scheme_hash_table ()
59 {
60 }
61
62 SCM
63 Scheme_hash_table::mark_smob (SCM s)
64 {
65   Scheme_hash_table *me = (Scheme_hash_table *) SCM_CELL_WORD_1 (s);
66   scm_gc_mark (me->hash_tab_);
67   return SCM_EOL;
68 }
69
70 int
71 Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*)
72 {
73   assert (unsmob (s));
74   scm_puts ("#<Scheme_hash_table  ", p);
75   Scheme_hash_table *me = (Scheme_hash_table *) SCM_CELL_WORD_1 (s);
76   scm_display (me->hash_tab_, p);
77   scm_puts ("> ", p);
78   return 1;
79 }
80
81 bool
82 Scheme_hash_table::try_retrieve (SCM k, SCM *v){
83
84   SCM handle = scm_hashq_get_handle (hash_tab_, k);
85   if (scm_is_pair (handle))
86     {
87       *v = scm_cdr (handle);
88       return true;
89     }
90   else
91     return false;
92 }
93
94 bool
95 Scheme_hash_table::contains (SCM k) const
96 {
97   return scm_is_pair (scm_hashq_get_handle (hash_tab_, k));
98 }
99
100 void
101 Scheme_hash_table::set (SCM k, SCM v)
102 {
103   assert (scm_is_symbol (k));
104   SCM handle = scm_hashq_create_handle_x (hash_tab_, k, SCM_UNDEFINED);
105   scm_set_cdr_x (handle, v);
106 }
107
108 SCM
109 Scheme_hash_table::get (SCM k) const
110 {
111   /* SCM_UNSPECIFIED will stick out like a sore thumb, hopefully.
112   */
113   return scm_hashq_ref (hash_tab_, k, SCM_UNSPECIFIED);
114 }
115
116 void
117 Scheme_hash_table::remove (SCM k)
118 {
119   scm_hashq_remove_x (hash_tab_, k);
120 }
121
122 static SCM
123 collect_handles (void *closure, SCM key, SCM value, SCM result)
124 {
125   (void) closure;
126   return scm_acons(key, value, result);
127 }
128
129 SCM
130 Scheme_hash_table::to_alist () const
131 {
132   return scm_internal_hash_fold ((SCM (*)(GUILE_ELLIPSIS)) &collect_handles, NULL, SCM_EOL, hash_tab_);
133 }
134
135 IMPLEMENT_SMOBS (Scheme_hash_table);
136 IMPLEMENT_DEFAULT_EQUAL_P (Scheme_hash_table);