]> www.ginac.de Git - cln.git/commitdiff
Replace CL_REQUIRE/CL_PROVIDE(cl_UP_named) with portable code.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Thu, 21 Aug 2008 15:49:28 +0000 (19:49 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Wed, 27 Aug 2008 04:41:08 +0000 (08:41 +0400)
The order of initialization of non-local objects in different compilation units
is not specified in C++. Hence special care should be taken to avoid static
initialization order fiasco. CLN solved the problem with some evil (GCC
specific, and even GCC-version-specific) hack. Replace it with a technique
similar to one used in STL to initialize std::cout and friends.

include/cln/univpoly.h
src/polynomial/elem/cl_UP_named.cc

index 2ede66fb517765f04c0ad5d3a40d35d9e39218b5..d716da4034a9d1b58753cff460592d891d280196 100644 (file)
@@ -351,7 +351,6 @@ extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r);
 
 // Lookup or create a univariate polynomial ring with a named variable over r.
 extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& varname);
-//CL_REQUIRE(cl_UP_named)
 
 CL_REQUIRE(cl_UP)
 
index dd797347e9067d8429f63545f3c6f01a3c25e354..70175b198f42219f957b5264f41a310a5ebcce27 100644 (file)
@@ -3,8 +3,6 @@
 // General includes.
 #include "cl_sysdep.h"
 
-CL_PROVIDE(cl_UP_named)
-
 // Specification.
 #include "cln/univpoly.h"
 
@@ -48,27 +46,50 @@ static bool maygc_htentry (const cl_htentry_from_rcpointer2_to_rcpointer& entry)
        return false;
 }
 
-static const cl_wht_from_rcpointer2_to_rcpointer univpoly_ring_table = cl_wht_from_rcpointer2_to_rcpointer(maygc_htentry);
+class named_univpoly_ring_cache
+{
+       static cl_wht_from_rcpointer2_to_rcpointer* univpoly_ring_table;
+       static int count;
+public:
+       named_univpoly_ring_cache();
+       ~named_univpoly_ring_cache();
+
+       inline cl_univpoly_ring* get_univpoly_ring(const cl_ring& r, const cl_symbol& v)
+       {
+               return (cl_univpoly_ring*) univpoly_ring_table->get(r,v);
+       }
+       inline void store_univpoly_ring(const cl_univpoly_ring& R)
+       {
+               univpoly_ring_table->put(R->basering(),
+                                        ((cl_varname_property*)(R->get_property(cl_univpoly_varname_key)))->varname,
+                                        R);
+       }
+};
 
-static inline cl_univpoly_ring* get_univpoly_ring (const cl_ring& r, const cl_symbol& v)
+cl_wht_from_rcpointer2_to_rcpointer* named_univpoly_ring_cache::univpoly_ring_table = 0;
+int named_univpoly_ring_cache::count = 0;
+
+named_univpoly_ring_cache::named_univpoly_ring_cache()
 {
-       return (cl_univpoly_ring*) univpoly_ring_table.get(r,v);
+       if (count++ == 0)
+               univpoly_ring_table = new cl_wht_from_rcpointer2_to_rcpointer(maygc_htentry);
 }
 
-static inline void store_univpoly_ring (const cl_univpoly_ring& R)
+
+named_univpoly_ring_cache::~named_univpoly_ring_cache()
 {
-       univpoly_ring_table.put(R->basering(), ((cl_varname_property*)(R->get_property(cl_univpoly_varname_key)))->varname,
-                               R);
+       if (--count == 0)
+               delete univpoly_ring_table;
 }
 
-
 const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& varname)
 {
-       var cl_univpoly_ring* ring_in_table = get_univpoly_ring(r,varname);
+       static named_univpoly_ring_cache cache;
+       var cl_univpoly_ring* ring_in_table = cache.get_univpoly_ring(r,varname);
        if (!ring_in_table) {
                var cl_univpoly_ring R = cl_make_univpoly_ring(r,varname);
-               store_univpoly_ring(R);
-               ring_in_table = get_univpoly_ring(r,varname);
+               cache.store_univpoly_ring(R);
+               ring_in_table = cache.get_univpoly_ring(r,varname);
                if (!ring_in_table)
                        throw runtime_exception();
        }
@@ -77,4 +98,3 @@ const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& va
 
 }  // namespace cln
 
-CL_PROVIDE_END(cl_UP_named)