From c26020c84584eb37f9383fb5ad3f5537a20cb321 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 19:49:28 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_UP_named) with portable code. 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 | 1 - src/polynomial/elem/cl_UP_named.cc | 46 +++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/cln/univpoly.h b/include/cln/univpoly.h index 2ede66f..d716da4 100644 --- a/include/cln/univpoly.h +++ b/include/cln/univpoly.h @@ -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) diff --git a/src/polynomial/elem/cl_UP_named.cc b/src/polynomial/elem/cl_UP_named.cc index dd79734..70175b1 100644 --- a/src/polynomial/elem/cl_UP_named.cc +++ b/src/polynomial/elem/cl_UP_named.cc @@ -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)