]> www.ginac.de Git - cln.git/blob - src/polynomial/elem/cl_UP_named.cc
Cater to the fact that g++ 4.3 will use a different naming for
[cln.git] / src / polynomial / elem / cl_UP_named.cc
1 // find_univpoly_ring().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 CL_PROVIDE(cl_UP_named)
7
8 // Specification.
9 #include "cln/univpoly.h"
10
11
12 // Implementation.
13
14 #include "cl_UP.h"
15
16 namespace cln {
17
18 // Create a new univariate polynomial ring with a named variable.
19
20 static inline cl_heap_univpoly_ring* cl_make_univpoly_ring (const cl_ring& r, const cl_symbol& varname)
21 {
22         cl_heap_univpoly_ring* UPR = cl_make_univpoly_ring(r);
23         UPR->add_property(new cl_varname_property(cl_univpoly_varname_key,varname));
24         return UPR;
25 }
26
27 }  // namespace cln
28
29 // The table of univariate polynomial rings with named variable.
30 // A weak hash table (cl_ring,cl_symbol) -> cl_univpoly_ring.
31
32 #include "cl_rcpointer2_hashweak_rcpointer.h"
33
34 namespace cln {
35
36 // An entry can be collected when the value (the ring) isn't referenced any more
37 // except from the hash table, and when the keys (the base ring and the name)
38 // are't referenced any more except from the hash table and the ring. Note that
39 // the ring contains exactly one reference to the base ring and exactly one
40 // reference to the name (on the property list).
41
42 static bool maygc_htentry (const cl_htentry_from_rcpointer2_to_rcpointer& entry)
43 {
44         if (!entry.key1.pointer_p() || (entry.key1.heappointer->refcount == 2))
45                 if (!entry.key2.pointer_p() || (entry.key2.heappointer->refcount == 2))
46                         if (!entry.val.pointer_p() || (entry.val.heappointer->refcount == 1))
47                                 return true;
48         return false;
49 }
50
51 static const cl_wht_from_rcpointer2_to_rcpointer univpoly_ring_table = cl_wht_from_rcpointer2_to_rcpointer(maygc_htentry);
52
53 static inline cl_univpoly_ring* get_univpoly_ring (const cl_ring& r, const cl_symbol& v)
54 {
55         return (cl_univpoly_ring*) univpoly_ring_table.get(r,v);
56 }
57
58 static inline void store_univpoly_ring (const cl_univpoly_ring& R)
59 {
60         univpoly_ring_table.put(R->basering(), ((cl_varname_property*)(R->get_property(cl_univpoly_varname_key)))->varname,
61                                 R);
62 }
63
64
65 const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& varname)
66 {
67         var cl_univpoly_ring* ring_in_table = get_univpoly_ring(r,varname);
68         if (!ring_in_table) {
69                 var cl_univpoly_ring R = cl_make_univpoly_ring(r,varname);
70                 store_univpoly_ring(R);
71                 ring_in_table = get_univpoly_ring(r,varname);
72                 if (!ring_in_table)
73                         throw runtime_exception();
74         }
75         return *ring_in_table;
76 }
77
78 }  // namespace cln
79
80 CL_PROVIDE_END(cl_UP_named)