diff --git a/include/cln/null_ring.h b/include/cln/null_ring.h index 474bdea..b26f66e 100644 --- a/include/cln/null_ring.h +++ b/include/cln/null_ring.h @@ -9,7 +9,15 @@ namespace cln { class cl_null_ring : public cl_ring { public: cl_null_ring (); }; extern const cl_null_ring cl_0_ring; // math. {0} -//CL_REQUIRE(cl_0_ring) + +class cl_0_ring_init_helper +{ + static int count; +public: + cl_0_ring_init_helper(); + ~cl_0_ring_init_helper(); +}; +static cl_0_ring_init_helper cl_0_ring_init_helper_instance; } // namespace cln diff --git a/src/integer/ring/cl_0_ring.cc b/src/integer/ring/cl_0_ring.cc index 722c038..cc42acb 100644 --- a/src/integer/ring/cl_0_ring.cc +++ b/src/integer/ring/cl_0_ring.cc @@ -3,7 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_0_ring) // Specification. #include "cln/null_ring.h" @@ -74,34 +73,48 @@ static const _cl_ring_element null_expt_pos (cl_heap_ring* R, const _cl_ring_ele return _cl_ring_element(R, (cl_I)0); } -static cl_ring_setops null_setops = { - null_fprint, - null_equal -}; -static cl_ring_addops null_addops = { - null_zero, - null_zerop, - null_plus, - null_minus, - null_uminus -}; -static cl_ring_mulops null_mulops = { - null_one, - null_canonhom, - null_mul, - null_square, - null_expt_pos -}; +static cl_ring_setops& null_setops() +{ + static cl_ring_setops ops = { + null_fprint, + null_equal + }; + return ops; +} + +static cl_ring_addops& null_addops() +{ + static cl_ring_addops ops = { + null_zero, + null_zerop, + null_plus, + null_minus, + null_uminus + }; + return ops; +} + +static cl_ring_mulops& null_mulops() +{ + static cl_ring_mulops ops = { + null_one, + null_canonhom, + null_mul, + null_square, + null_expt_pos + }; + return ops; +} -extern cl_class cl_class_null_ring; +static const cl_class& cl_class_null_ring(); class cl_heap_null_ring : public cl_heap_ring { SUBCLASS_cl_heap_ring() public: // Constructor. cl_heap_null_ring () - : cl_heap_ring (&null_setops,&null_addops,&null_mulops) - { type = &cl_class_null_ring; } + : cl_heap_ring (&null_setops(),&null_addops(),&null_mulops()) + { type = &cl_class_null_ring(); } // Destructor. ~cl_heap_null_ring () {} }; @@ -117,17 +130,38 @@ static void cl_null_ring_dprint (cl_heap* pointer) fprint(cl_debugout, "(cl_null_ring) cl_0_ring"); } -cl_class cl_class_null_ring = { - cl_null_ring_destructor, - cl_class_flags_number_ring, - cl_null_ring_dprint -}; +static const cl_class& cl_class_null_ring() +{ + static const cl_class cl_class_null_ring_instance = { + cl_null_ring_destructor, + cl_class_flags_number_ring, + cl_null_ring_dprint + }; + return cl_class_null_ring_instance; +} + +cl_heap_null_ring* cl_heap_null_ring_instance; +const cl_null_ring cl_0_ring = cl_0_ring; inline cl_null_ring::cl_null_ring () - : cl_ring (new cl_heap_null_ring()) {} + : cl_ring(cl_heap_null_ring_instance) {} + +int cl_0_ring_init_helper::count = 0; -const cl_null_ring cl_0_ring; +cl_0_ring_init_helper::cl_0_ring_init_helper() +{ + if (count++ == 0) { + cl_heap_null_ring_instance = new cl_heap_null_ring(); + new ((void *)&cl_0_ring) cl_null_ring(); + } +} + +cl_0_ring_init_helper::~cl_0_ring_init_helper() +{ + if (--count == 0) { + delete cl_heap_null_ring_instance; + } +} } // namespace cln -CL_PROVIDE_END(cl_0_ring)