]> www.ginac.de Git - cln.git/blob - src/polynomial/elem/cl_UP_unnamed.cc
don't expose configure generated headers to users.
[cln.git] / src / polynomial / elem / cl_UP_unnamed.cc
1 // find_univpoly_ring().
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "cln/univpoly.h"
8
9
10 // Implementation.
11
12 #include "polynomial/cl_UP.h"
13
14 // The table of univariate polynomial rings without named variable.
15 // A weak hash table cl_ring -> cl_univpoly_ring.
16 // (It could also be a weak hashuniq table cl_ring -> cl_univpoly_ring.)
17
18 #include "base/hash/cl_rcpointer_hashweak_rcpointer.h"
19
20 namespace cln {
21
22 // An entry can be collected when the value (the ring) isn't referenced any more
23 // except from the hash table, and when the key (the base ring) isn't referenced
24 // any more except from the hash table and the ring. Note that the ring contains
25 // exactly one reference to the base ring.
26
27 static bool maygc_htentry (const cl_htentry_from_rcpointer_to_rcpointer& entry)
28 {
29         if (!entry.key.pointer_p() || (entry.key.heappointer->refcount == 2))
30                 if (!entry.val.pointer_p() || (entry.val.heappointer->refcount == 1))
31                         return true;
32         return false;
33 }
34
35 class univpoly_ring_cache
36 {
37         static cl_wht_from_rcpointer_to_rcpointer* univpoly_ring_table;
38         static int count;
39 public:
40         inline cl_univpoly_ring* get_univpoly_ring(const cl_ring& r)
41         {
42                 return (cl_univpoly_ring*) univpoly_ring_table->get(r);
43         }
44         inline void store_univpoly_ring(const cl_univpoly_ring& R)
45         {
46                 univpoly_ring_table->put(R->basering(), R);
47         }
48         univpoly_ring_cache();
49         ~univpoly_ring_cache();
50 };
51
52 cl_wht_from_rcpointer_to_rcpointer* univpoly_ring_cache::univpoly_ring_table = 0;
53 int univpoly_ring_cache::count = 0;
54
55 univpoly_ring_cache::univpoly_ring_cache()
56 {
57         if (count++ == 0)
58                 univpoly_ring_table = new cl_wht_from_rcpointer_to_rcpointer(maygc_htentry);
59 }
60
61 univpoly_ring_cache::~univpoly_ring_cache()
62 {
63         if (--count == 0)
64                 delete univpoly_ring_table;
65 }
66
67 const cl_univpoly_ring find_univpoly_ring (const cl_ring& r)
68 {
69         static univpoly_ring_cache cache;
70         var cl_univpoly_ring* ring_in_table = cache.get_univpoly_ring(r);
71         if (!ring_in_table) {
72                 var cl_univpoly_ring R = cl_make_univpoly_ring(r);
73                 cache.store_univpoly_ring(R);
74                 ring_in_table = cache.get_univpoly_ring(r);
75                 if (!ring_in_table)
76                         throw runtime_exception();
77         }
78         return *ring_in_table;
79 }
80
81 }  // namespace cln
82