]> www.ginac.de Git - cln.git/blob - src/base/symbol/cl_symbol.cc
Remove cl_null_string defintion.
[cln.git] / src / base / symbol / cl_symbol.cc
1 // class cl_symbol.
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "cln/symbol.h"
8
9
10 // Implementation.
11
12 #include "base/hash/cl_hashuniqweak.h"
13
14 namespace cln {
15
16 inline const cl_string hashkey (const cl_symbol& sym)
17 {
18         return (cl_string)sym;
19 }
20
21 // A symbol points to a string, so to convert cl_string -> cl_symbol, we just
22 // take the pointer and put it into a cl_symbol.
23 inline cl_symbol::cl_symbol (struct hashuniq * null, const cl_string& s)
24         : cl_rcpointer (as_cl_private_thing(s)) { unused null; }
25
26 typedef cl_htuniqentry<cl_string,cl_symbol> cl_htentry_from_string_to_symbol;
27
28 typedef cl_heap_weak_hashtable_uniq<cl_string,cl_symbol> cl_heap_hashtable_from_string_to_symbol;
29
30 typedef _cl_hashtable_iterator<cl_htentry_from_string_to_symbol> cl_hashtable_from_string_to_symbol_iterator;
31
32 static void cl_hashtable_from_string_to_symbol_destructor (cl_heap* pointer)
33 {
34 #if (defined(__mips__) || defined(__mips64__)) && !defined(__GNUC__) // workaround SGI CC bug
35         (*(cl_heap_hashtable_from_string_to_symbol*)pointer).~cl_heap_weak_hashtable_uniq();
36 #else
37         (*(cl_heap_hashtable_from_string_to_symbol*)pointer).~cl_heap_hashtable_from_string_to_symbol();
38 #endif
39 }
40
41
42 struct cl_ht_from_string_to_symbol : public cl_gcpointer {
43         // Constructors.
44         cl_ht_from_string_to_symbol ();
45         cl_ht_from_string_to_symbol (const cl_ht_from_string_to_symbol&);
46         // Assignment operators.
47         cl_ht_from_string_to_symbol& operator= (const cl_ht_from_string_to_symbol&);
48         // Iterator.
49         cl_hashtable_from_string_to_symbol_iterator iterator () const
50         { return ((cl_heap_hashtable_from_string_to_symbol*)pointer)->iterator(); }
51         // Lookup.
52         cl_symbol * get (const cl_string& s) const;
53         // Store.
54         void put (const cl_string& s) const;
55 };
56
57 // These are not inline, because they tend to duplicate a lot of template code.
58
59 cl_ht_from_string_to_symbol::cl_ht_from_string_to_symbol ()
60 {
61         static const cl_class cl_class_hashtable_from_string_to_symbol = {
62                 cl_hashtable_from_string_to_symbol_destructor,
63                 0
64         };
65         var cl_heap_hashtable_from_string_to_symbol* ht = new cl_heap_hashtable_from_string_to_symbol ();
66         ht->refcount = 1;
67         ht->type = &cl_class_hashtable_from_string_to_symbol;
68         pointer = ht;
69 }
70
71 cl_symbol * cl_ht_from_string_to_symbol::get (const cl_string& s) const
72 {
73         return ((cl_heap_hashtable_from_string_to_symbol*)pointer)->get(s);
74 }
75
76 void cl_ht_from_string_to_symbol::put (const cl_string& s) const
77 {
78         ((cl_heap_hashtable_from_string_to_symbol*)pointer)->put(s);
79 }
80
81 // The global symbol table.
82 class global_symbol_table
83 {
84         static int count;
85         static cl_ht_from_string_to_symbol* symbol_table;
86 public:
87         inline cl_symbol* get(const cl_string& s)
88         {
89                 return symbol_table->get(s);
90         }
91
92         inline void put(const cl_string& s)
93         {
94                 symbol_table->put(s);
95         }
96
97         global_symbol_table();
98         ~global_symbol_table();
99 };
100
101 int global_symbol_table::count = 0;
102 cl_ht_from_string_to_symbol* global_symbol_table::symbol_table;
103
104 global_symbol_table::global_symbol_table()
105 {
106         if (count++ == 0)
107                 symbol_table = new cl_ht_from_string_to_symbol();
108 }
109
110 global_symbol_table::~global_symbol_table()
111 {
112         if (--count == 0)
113                 delete symbol_table;
114 }
115
116 // Create or lookup a symbol from its name.
117 cl_symbol::cl_symbol (const cl_string& s)
118 {
119         static global_symbol_table symbol_table;
120         var cl_symbol * sym_in_table;
121         sym_in_table = symbol_table.get(s);
122         if (!sym_in_table) {
123                 symbol_table.put(s);
124                 sym_in_table = symbol_table.get(s);
125                 if (!sym_in_table)
126                         throw runtime_exception();
127         }
128         var cl_heap* p = sym_in_table->heappointer;
129         cl_inc_pointer_refcount(p);
130         pointer = p;
131 }
132
133 }  // namespace cln
134