// cl_find_univpoly_ring(). // General includes. #include "cl_sysdep.h" CL_PROVIDE(cl_UP_unnamed) // Specification. #include "cl_univpoly.h" // Implementation. #include "cl_UP.h" // The table of univariate polynomial rings without named variable. // A weak hash table cl_ring -> cl_univpoly_ring. // (It could also be a weak hashuniq table cl_ring -> cl_univpoly_ring.) #include "cl_rcpointer_hashweak_rcpointer.h" // An entry can be collected when the value (the ring) isn't referenced any more // except from the hash table, and when the key (the base ring) isn't referenced // any more except from the hash table and the ring. Note that the ring contains // exactly one reference to the base ring. static cl_boolean maygc_htentry (const cl_htentry_from_rcpointer_to_rcpointer& entry) { if (!entry.key.pointer_p() || (entry.key.heappointer->refcount == 2)) if (!entry.val.pointer_p() || (entry.val.heappointer->refcount == 1)) return cl_true; return cl_false; } static const cl_wht_from_rcpointer_to_rcpointer univpoly_ring_table = cl_wht_from_rcpointer_to_rcpointer(maygc_htentry); static inline cl_univpoly_ring* get_univpoly_ring (const cl_ring& r) { return (cl_univpoly_ring*) univpoly_ring_table.get(r); } static inline void store_univpoly_ring (const cl_univpoly_ring& R) { univpoly_ring_table.put(R->basering(),R); } const cl_univpoly_ring cl_find_univpoly_ring (const cl_ring& r) { var cl_univpoly_ring* ring_in_table = get_univpoly_ring(r); if (!ring_in_table) { var cl_univpoly_ring R = cl_make_univpoly_ring(r); store_univpoly_ring(R); ring_in_table = get_univpoly_ring(r); if (!ring_in_table) cl_abort(); } return *ring_in_table; } CL_PROVIDE_END(cl_UP_unnamed)