From ee4eb695119bce96515b330f9fc83ddd67da5c62 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 2 Dec 2009 12:26:05 +0200 Subject: Implement de-registering polymorphic type information This is required for DLL/shared library unloading. --- libxsd/xsd/cxx/tree/comparison-map.hxx | 4 +++ libxsd/xsd/cxx/tree/comparison-map.txx | 14 ++++++++ libxsd/xsd/cxx/tree/std-ostream-map.hxx | 4 +++ libxsd/xsd/cxx/tree/std-ostream-map.txx | 14 ++++++++ libxsd/xsd/cxx/tree/stream-extraction-map.hxx | 8 +++++ libxsd/xsd/cxx/tree/stream-extraction-map.txx | 16 +++++++++ libxsd/xsd/cxx/tree/stream-insertion-map.hxx | 4 +++ libxsd/xsd/cxx/tree/stream-insertion-map.txx | 15 +++++++++ libxsd/xsd/cxx/tree/type-factory-map.hxx | 34 +++++++++++++++---- libxsd/xsd/cxx/tree/type-factory-map.txx | 47 ++++++++++++++++++++++++++- libxsd/xsd/cxx/tree/type-serializer-map.hxx | 30 +++++++++++++---- libxsd/xsd/cxx/tree/type-serializer-map.txx | 47 ++++++++++++++++++++++++--- 12 files changed, 219 insertions(+), 18 deletions(-) (limited to 'libxsd/xsd/cxx/tree') diff --git a/libxsd/xsd/cxx/tree/comparison-map.hxx b/libxsd/xsd/cxx/tree/comparison-map.hxx index f8461a0..4f7e51b 100644 --- a/libxsd/xsd/cxx/tree/comparison-map.hxx +++ b/libxsd/xsd/cxx/tree/comparison-map.hxx @@ -29,6 +29,9 @@ namespace xsd void register_type (const type_id&, comparator, bool override = true); + void + unregister_type (const type_id&); + bool compare (const type&, const type&); @@ -99,6 +102,7 @@ namespace xsd struct comparison_initializer { comparison_initializer (); + ~comparison_initializer (); }; } } diff --git a/libxsd/xsd/cxx/tree/comparison-map.txx b/libxsd/xsd/cxx/tree/comparison-map.txx index 38f215f..3af2a42 100644 --- a/libxsd/xsd/cxx/tree/comparison-map.txx +++ b/libxsd/xsd/cxx/tree/comparison-map.txx @@ -219,6 +219,13 @@ namespace xsd } template + void comparison_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template bool comparison_map:: compare (const type& x, const type& y) { @@ -282,6 +289,13 @@ namespace xsd comparison_map_instance ().register_type ( typeid (T), &comparator_impl); } + + template + comparison_initializer:: + ~comparison_initializer () + { + comparison_map_instance ().unregister_type (typeid (T)); + } } } } diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.hxx b/libxsd/xsd/cxx/tree/std-ostream-map.hxx index 25f225f..2bf786c 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-map.hxx +++ b/libxsd/xsd/cxx/tree/std-ostream-map.hxx @@ -31,6 +31,9 @@ namespace xsd register_type (const type_id&, inserter, bool override = true); void + unregister_type (const type_id&); + + void insert (std::ostream&, const type&); public: @@ -100,6 +103,7 @@ namespace xsd struct std_ostream_initializer { std_ostream_initializer (); + ~std_ostream_initializer (); }; } } diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.txx b/libxsd/xsd/cxx/tree/std-ostream-map.txx index c1187ef..ee46f16 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-map.txx +++ b/libxsd/xsd/cxx/tree/std-ostream-map.txx @@ -219,6 +219,13 @@ namespace xsd template void std_ostream_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template + void std_ostream_map:: insert (std::ostream& os, const type& x) { if (inserter i = find (typeid (x))) @@ -274,6 +281,13 @@ namespace xsd std_ostream_map_instance ().register_type ( typeid (T), &inserter_impl); } + + template + std_ostream_initializer:: + ~std_ostream_initializer () + { + std_ostream_map_instance ().unregister_type (typeid (T)); + } } } } diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.hxx b/libxsd/xsd/cxx/tree/stream-extraction-map.hxx index 14a5423..5d31b6a 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction-map.hxx +++ b/libxsd/xsd/cxx/tree/stream-extraction-map.hxx @@ -35,6 +35,9 @@ namespace xsd extractor, bool override = true); + void + unregister_type (const qualified_name& name); + std::auto_ptr extract (istream&, flags, container*); @@ -87,6 +90,11 @@ namespace xsd struct stream_extraction_initializer { stream_extraction_initializer (const C* name, const C* ns); + ~stream_extraction_initializer (); + + private: + const C* name_; + const C* ns_; }; } } diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.txx b/libxsd/xsd/cxx/tree/stream-extraction-map.txx index 5534da6..ca0a44e 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction-map.txx +++ b/libxsd/xsd/cxx/tree/stream-extraction-map.txx @@ -226,6 +226,13 @@ namespace xsd } template + void stream_extraction_map:: + unregister_type (const qualified_name& name) + { + type_map_.erase (name); + } + + template std::auto_ptr stream_extraction_map:: extract (istream& s, flags f, container* c) { @@ -285,10 +292,19 @@ namespace xsd template stream_extraction_initializer:: stream_extraction_initializer (const C* name, const C* ns) + : name_ (name), ns_ (ns) { stream_extraction_map_instance ().register_type ( xml::qualified_name (name, ns), &extractor_impl); } + + template + stream_extraction_initializer:: + ~stream_extraction_initializer () + { + stream_extraction_map_instance ().unregister_type ( + xml::qualified_name (name_, ns_)); + } } } } diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.hxx b/libxsd/xsd/cxx/tree/stream-insertion-map.hxx index 77d930c..0fdef0b 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion-map.hxx +++ b/libxsd/xsd/cxx/tree/stream-insertion-map.hxx @@ -37,6 +37,9 @@ namespace xsd bool override = true); void + unregister_type (const type_id&); + + void insert (ostream&, const type&); public: @@ -140,6 +143,7 @@ namespace xsd struct stream_insertion_initializer { stream_insertion_initializer (const C* name, const C* ns); + ~stream_insertion_initializer (); }; } } diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.txx b/libxsd/xsd/cxx/tree/stream-insertion-map.txx index c3cf9b5..f9d5745 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion-map.txx +++ b/libxsd/xsd/cxx/tree/stream-insertion-map.txx @@ -256,6 +256,13 @@ namespace xsd template void stream_insertion_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template + void stream_insertion_map:: insert (ostream& s, const type& x) { if (const type_info* ti = find (typeid (x))) @@ -320,6 +327,14 @@ namespace xsd xml::qualified_name (name, ns), &inserter_impl); } + + template + stream_insertion_initializer:: + ~stream_insertion_initializer (const C* name, const C* ns) + { + stream_insertion_map_instance ().unregister_type ( + typeid (T)); + } } } } diff --git a/libxsd/xsd/cxx/tree/type-factory-map.hxx b/libxsd/xsd/cxx/tree/type-factory-map.hxx index 8cf916e..e191ff7 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.hxx +++ b/libxsd/xsd/cxx/tree/type-factory-map.hxx @@ -38,10 +38,17 @@ namespace xsd bool override = true); void + unregister_type (const qualified_name& name); + + void register_element (const qualified_name& root, const qualified_name& subst, factory); + void + unregister_element (const qualified_name& root, + const qualified_name& subst); + std::auto_ptr create (const C* name, // element name const C* ns, // element namespace @@ -133,14 +140,29 @@ namespace xsd template struct type_factory_initializer { - // Register type. - // type_factory_initializer (const C* name, const C* ns); + ~type_factory_initializer (); - // Register element. - // - type_factory_initializer (const C* root_name, const C* root_ns, - const C* subst_name, const C* subst_ns); + private: + const C* name_; + const C* ns_; + }; + + // + // + template + struct element_factory_initializer + { + element_factory_initializer (const C* root_name, const C* root_ns, + const C* subst_name, const C* subst_ns); + + ~element_factory_initializer (); + + private: + const C* root_name_; + const C* root_ns_; + const C* subst_name_; + const C* subst_ns_; }; } } diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx index 215f033..ee376f8 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.txx +++ b/libxsd/xsd/cxx/tree/type-factory-map.txx @@ -234,6 +234,13 @@ namespace xsd template void type_factory_map:: + unregister_type (const qualified_name& name) + { + type_map_.erase (name); + } + + template + void type_factory_map:: register_element (const qualified_name& root, const qualified_name& subst, factory f) @@ -242,6 +249,22 @@ namespace xsd } template + void type_factory_map:: + unregister_element (const qualified_name& root, + const qualified_name& subst) + { + typename element_map::iterator i (element_map_.find (root)); + + if (i != element_map_.end ()) + { + i->second.erase (subst); + + if (i->second.empty ()) + element_map_.erase (i); + } + } + + template typename type_factory_map::factory type_factory_map:: find (const qualified_name& name) const { @@ -416,6 +439,7 @@ namespace xsd template type_factory_initializer:: type_factory_initializer (const C* name, const C* ns) + : name_ (name), ns_ (ns) { type_factory_map_instance ().register_type ( xml::qualified_name (name, ns), &factory_impl); @@ -423,14 +447,35 @@ namespace xsd template type_factory_initializer:: - type_factory_initializer (const C* root_name, const C* root_ns, + ~type_factory_initializer () + { + type_factory_map_instance ().unregister_type ( + xml::qualified_name (name_, ns_)); + } + + // + // + template + element_factory_initializer:: + element_factory_initializer (const C* root_name, const C* root_ns, const C* subst_name, const C* subst_ns) + : root_name_ (root_name), root_ns_ (root_ns), + subst_name_ (subst_name), subst_ns_ (subst_ns) { type_factory_map_instance ().register_element ( xml::qualified_name (root_name, root_ns), xml::qualified_name (subst_name, subst_ns), &factory_impl); } + + template + element_factory_initializer:: + ~element_factory_initializer () + { + type_factory_map_instance ().unregister_element ( + xml::qualified_name (root_name_, root_ns_), + xml::qualified_name (subst_name_, subst_ns_)); + } } } } diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.hxx b/libxsd/xsd/cxx/tree/type-serializer-map.hxx index b1ca479..8c7bfca 100644 --- a/libxsd/xsd/cxx/tree/type-serializer-map.hxx +++ b/libxsd/xsd/cxx/tree/type-serializer-map.hxx @@ -38,11 +38,17 @@ namespace xsd bool override = true); void + unregister_type (const type_id&); + + void register_element (const qualified_name& root, const qualified_name& subst, const type_id&, serializer); + void + unregister_element (const qualified_name& root, const type_id&); + public: void serialize (const C* name, // element name @@ -196,17 +202,29 @@ namespace xsd serializer_impl (xercesc::DOMElement&, const type&); + // + // template struct type_serializer_initializer { - // Register type. - // type_serializer_initializer (const C* name, const C* ns); + ~type_serializer_initializer (); + }; - // Register element. - // - type_serializer_initializer (const C* root_name, const C* root_ns, - const C* subst_name, const C* subst_ns); + + // + // + template + struct element_serializer_initializer + { + element_serializer_initializer (const C* root_name, const C* root_ns, + const C* subst_name, const C* subst_ns); + + ~element_serializer_initializer (); + + private: + const C* root_name_; + const C* root_ns_; }; } } diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.txx b/libxsd/xsd/cxx/tree/type-serializer-map.txx index 797cb13..232e239 100644 --- a/libxsd/xsd/cxx/tree/type-serializer-map.txx +++ b/libxsd/xsd/cxx/tree/type-serializer-map.txx @@ -263,6 +263,13 @@ namespace xsd template void type_serializer_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template + void type_serializer_map:: register_element (const qualified_name& root, const qualified_name& subst, const type_id& tid, @@ -273,6 +280,21 @@ namespace xsd template void type_serializer_map:: + unregister_element (const qualified_name& root, const type_id& tid) + { + typename element_map::iterator i (element_map_.find (root)); + + if (i != element_map_.end ()) + { + i->second.erase (&tid); + + if (i->second.empty ()) + element_map_.erase (root); + } + } + + template + void type_serializer_map:: serialize (const C* name, // element name const C* ns, // element namespace bool global, @@ -508,7 +530,6 @@ namespace xsd e << static_cast (x); } - // type_serializer_initializer // template @@ -523,10 +544,18 @@ namespace xsd template type_serializer_initializer:: - type_serializer_initializer (const C* root_name, - const C* root_ns, - const C* subst_name, - const C* subst_ns) + ~type_serializer_initializer () + { + type_serializer_map_instance ().unregister_type (typeid (T)); + } + + // element_serializer_initializer + // + template + element_serializer_initializer:: + element_serializer_initializer (const C* root_name, const C* root_ns, + const C* subst_name, const C* subst_ns) + : root_name_ (root_name), root_ns_ (root_ns) { type_serializer_map_instance ().register_element ( xml::qualified_name (root_name, root_ns), @@ -534,6 +563,14 @@ namespace xsd typeid (T), &serializer_impl); } + + template + element_serializer_initializer:: + ~element_serializer_initializer () + { + type_serializer_map_instance ().unregister_element ( + xml::qualified_name (root_name_, root_ns_), typeid (T)); + } } } } -- cgit v1.1