From 51bf88bf2b6ca5c213d72c3fdadb8561e7f35b62 Mon Sep 17 00:00:00 2001 From: Robert Ramey Date: Thu, 27 Jan 2005 18:12:15 +0000 Subject: [PATCH] alterations for DLL and auto-link [SVN r26874] --- src/basic_archive.cpp | 11 +- src/basic_iarchive.cpp | 43 ++++- src/basic_iserializer.cpp | 31 +++ src/basic_oarchive.cpp | 40 +++- src/basic_oserializer.cpp | 31 +++ src/basic_pointer_iserializer.cpp | 30 +++ src/basic_pointer_oserializer.cpp | 30 +++ src/basic_serializer_map.cpp | 11 +- src/basic_text_iprimitive.cpp | 3 +- src/basic_text_oprimitive.cpp | 2 + src/basic_text_wiprimitive.cpp | 3 + src/basic_text_woprimitive.cpp | 4 +- src/basic_xml_archive.cpp | 35 +++- src/binary_iarchive.cpp | 10 +- src/binary_oarchive.cpp | 4 + src/binary_wiarchive.cpp | 2 + src/binary_woarchive.cpp | 2 + src/extended_type_info.cpp | 295 ++++++++++++++++++----------- src/extended_type_info_no_rtti.cpp | 36 +++- src/extended_type_info_typeid.cpp | 61 +++++- src/polymorphic_iarchive.cpp | 1 + src/polymorphic_oarchive.cpp | 3 +- src/text_iarchive.cpp | 1 + src/text_oarchive.cpp | 4 + src/text_wiarchive.cpp | 1 + src/text_woarchive.cpp | 5 +- src/void_cast.cpp | 229 +++++++++++++++++----- src/xml_iarchive.cpp | 9 +- src/xml_oarchive.cpp | 5 +- src/xml_wiarchive.cpp | 2 + src/xml_woarchive.cpp | 2 +- 31 files changed, 744 insertions(+), 202 deletions(-) create mode 100644 src/basic_iserializer.cpp create mode 100644 src/basic_oserializer.cpp create mode 100644 src/basic_pointer_iserializer.cpp create mode 100644 src/basic_pointer_oserializer.cpp diff --git a/src/basic_archive.cpp b/src/basic_archive.cpp index 9b920ac7..3355f53b 100644 --- a/src/basic_archive.cpp +++ b/src/basic_archive.cpp @@ -31,6 +31,7 @@ // // * required only for pointers - optional for objects +#define BOOST_ARCHIVE #include namespace boost { @@ -40,7 +41,9 @@ namespace archive { // constants used in archive signature //This should never ever change. note that is not an std::string // string. -const char * ARCHIVE_SIGNATURE = "serialization::archive"; +BOOST_DECL_ARCHIVE const char * ARCHIVE_SIGNATURE(){ + return "serialization::archive"; +} // this should change if the capabilities are added to the library // such that archives can be created which can't be read by previous @@ -48,9 +51,9 @@ const char * ARCHIVE_SIGNATURE = "serialization::archive"; // 1 - initial version // 2 - made address tracking optional // 3 - numerous changes - can't guarentee compatibility with previous versions -const version_type ARCHIVE_VERSION(3); - -const class_id_type null_pointer_tag(-1); +BOOST_DECL_ARCHIVE unsigned int ARCHIVE_VERSION(){ + return 3; +} } // namespace archive } // namespace boost diff --git a/src/basic_iarchive.cpp b/src/basic_iarchive.cpp index 6ee56fbb..8836c74c 100644 --- a/src/basic_iarchive.cpp +++ b/src/basic_iarchive.cpp @@ -23,6 +23,9 @@ namespace std{ } // namespace std #endif +#define BOOST_ARCHIVE +#include + #include #include #include @@ -30,15 +33,17 @@ namespace std{ #include #include #include +#include #include #include -#include - using namespace boost::serialization; namespace boost { +namespace serialization { + class extended_type_info; +} namespace archive { namespace detail { @@ -339,7 +344,7 @@ basic_iarchive_impl::load_pointer( class_id_type cid; load(ar, cid); - if(null_pointer_tag == cid){ + if(NULL_POINTER_TAG == cid){ t = NULL; return bpis_ptr; } @@ -426,22 +431,33 @@ basic_iarchive_impl::load_pointer( ////////////////////////////////////////////////////////////////////// // implementation of basic_iarchive functions -void +void +BOOST_DECL_ARCHIVE basic_iarchive::next_object_pointer(void *t){ pimpl->next_object_pointer(t); } +BOOST_DECL_ARCHIVE basic_iarchive::basic_iarchive() : pimpl(new basic_iarchive_impl), - archive_library_version(ARCHIVE_VERSION) + archive_library_version(ARCHIVE_VERSION()) {} +void +BOOST_DECL_ARCHIVE +basic_iarchive::init(unsigned int archive_library_version_){ + archive_library_version = archive_library_version_; +} + +BOOST_DECL_ARCHIVE basic_iarchive::~basic_iarchive() { delete pimpl; } -void basic_iarchive::load_object( +void +BOOST_DECL_ARCHIVE +basic_iarchive::load_object( void *t, const basic_iserializer & bis ){ @@ -449,6 +465,7 @@ void basic_iarchive::load_object( } // load a pointer object +BOOST_DECL_ARCHIVE const basic_pointer_iserializer * basic_iarchive::load_pointer( void * &t, @@ -460,15 +477,25 @@ basic_iarchive::load_pointer( return pimpl->load_pointer(*this, t, bpis_ptr, finder); } -void basic_iarchive::register_basic_serializer(const basic_iserializer & bis){ +void +BOOST_DECL_ARCHIVE +basic_iarchive::register_basic_serializer(const basic_iserializer & bis){ pimpl->register_type(bis); } -void basic_iarchive::delete_created_pointers() +void +BOOST_DECL_ARCHIVE +basic_iarchive::delete_created_pointers() { pimpl->delete_created_pointers(); } +unsigned int +BOOST_DECL_ARCHIVE +basic_iarchive::library_version() const{ + return archive_library_version; +} + } // namespace detail } // namespace archive } // namespace boost diff --git a/src/basic_iserializer.cpp b/src/basic_iserializer.cpp new file mode 100644 index 00000000..0d680e6e --- /dev/null +++ b/src/basic_iserializer.cpp @@ -0,0 +1,31 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE +#include + +namespace boost { +namespace archive { +namespace detail { + +BOOST_DECL_ARCHIVE +basic_iserializer::basic_iserializer( + const boost::serialization::extended_type_info & type_ +) : + basic_serializer(type_), + bpis(NULL) +{} + +BOOST_DECL_ARCHIVE +basic_iserializer::~basic_iserializer(){} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/src/basic_oarchive.cpp b/src/basic_oarchive.cpp index ab8c1c99..5011781e 100644 --- a/src/basic_oarchive.cpp +++ b/src/basic_oarchive.cpp @@ -19,18 +19,25 @@ // including this here to work around an ICC in intel 7.0 // normally this would be part of basic_oarchive.hpp below. +#define BOOST_ARCHIVE #include #include #include #include - -#include #include +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + using namespace boost::serialization; namespace boost { +namespace serialization { + class extended_type_info; +} namespace archive { namespace detail { @@ -378,33 +385,56 @@ basic_oarchive_impl::save_pointer( ////////////////////////////////////////////////////////////////////// // implementation of basic_oarchive functions +BOOST_DECL_ARCHIVE basic_oarchive::basic_oarchive() : pimpl(new basic_oarchive_impl) {} +BOOST_DECL_ARCHIVE basic_oarchive::~basic_oarchive() { delete pimpl; } -void basic_oarchive::save_object( +void +BOOST_DECL_ARCHIVE +basic_oarchive::save_object( const void *x, const basic_oserializer & bos ){ pimpl->save_object(*this, x, bos); } -void basic_oarchive::save_pointer( +void +BOOST_DECL_ARCHIVE +basic_oarchive::save_pointer( const void * t, const basic_pointer_oserializer * bpos_ptr ){ pimpl->save_pointer(*this, t, bpos_ptr); } -void basic_oarchive::register_basic_serializer(const basic_oserializer & bos){ +void +BOOST_DECL_ARCHIVE +basic_oarchive::register_basic_serializer(const basic_oserializer & bos){ pimpl->register_type(bos); } +unsigned int +BOOST_DECL_ARCHIVE +basic_oarchive::library_version() const{ + return ARCHIVE_VERSION(); +} + +void +BOOST_DECL_ARCHIVE +basic_oarchive::end_preamble(){ +} + } // namespace detail } // namespace archive } // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif diff --git a/src/basic_oserializer.cpp b/src/basic_oserializer.cpp new file mode 100644 index 00000000..6ef6fc6c --- /dev/null +++ b/src/basic_oserializer.cpp @@ -0,0 +1,31 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE +#include + +namespace boost { +namespace archive { +namespace detail { + +BOOST_DECL_ARCHIVE +basic_oserializer::basic_oserializer( + const boost::serialization::extended_type_info & type_ +) : + basic_serializer(type_), + bpos(NULL) +{} + +BOOST_DECL_ARCHIVE +basic_oserializer::~basic_oserializer(){} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/src/basic_pointer_iserializer.cpp b/src/basic_pointer_iserializer.cpp new file mode 100644 index 00000000..d4486fd6 --- /dev/null +++ b/src/basic_pointer_iserializer.cpp @@ -0,0 +1,30 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_iserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE +#include + +namespace boost { +namespace archive { +namespace detail { + +BOOST_DECL_ARCHIVE +basic_pointer_iserializer::basic_pointer_iserializer( + const boost::serialization::extended_type_info & type_ +) : + basic_serializer(type_) +{} + +BOOST_DECL_ARCHIVE +basic_pointer_iserializer::~basic_pointer_iserializer() {} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/src/basic_pointer_oserializer.cpp b/src/basic_pointer_oserializer.cpp new file mode 100644 index 00000000..fccdb790 --- /dev/null +++ b/src/basic_pointer_oserializer.cpp @@ -0,0 +1,30 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#define BOOST_ARCHIVE +#include + +namespace boost { +namespace archive { +namespace detail { + +BOOST_DECL_ARCHIVE +basic_pointer_oserializer::basic_pointer_oserializer( + const boost::serialization::extended_type_info & type_ +) : + basic_serializer(type_) +{} + +BOOST_DECL_ARCHIVE +basic_pointer_oserializer::~basic_pointer_oserializer() {} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/src/basic_serializer_map.cpp b/src/basic_serializer_map.cpp index 02e5573a..e88fd588 100644 --- a/src/basic_serializer_map.cpp +++ b/src/basic_serializer_map.cpp @@ -14,6 +14,7 @@ #include +#define BOOST_ARCHIVE #include #include @@ -24,7 +25,12 @@ namespace boost { namespace archive { namespace detail { -bool basic_serializer_map::insert(const basic_serializer * bs){ +BOOST_DECL_ARCHIVE +basic_serializer_map::basic_serializer_map(){ +} + +BOOST_DECL_ARCHIVE bool +basic_serializer_map::insert(const basic_serializer * bs){ return map.insert(bs).second; } @@ -35,7 +41,8 @@ public: {} }; -const basic_serializer * basic_serializer_map::tfind( +BOOST_DECL_ARCHIVE const basic_serializer * +basic_serializer_map::tfind( const boost::serialization::extended_type_info & type_ ) const { const basic_serializer_arg bs(type_); diff --git a/src/basic_text_iprimitive.cpp b/src/basic_text_iprimitive.cpp index a682b13d..70373f20 100644 --- a/src/basic_text_iprimitive.cpp +++ b/src/basic_text_iprimitive.cpp @@ -14,6 +14,8 @@ #include +#define BOOST_ARCHIVE +#include #include namespace boost { @@ -24,4 +26,3 @@ template class basic_text_iprimitive ; } // namespace archive } // namespace boost - diff --git a/src/basic_text_oprimitive.cpp b/src/basic_text_oprimitive.cpp index 2685bc11..6c191034 100644 --- a/src/basic_text_oprimitive.cpp +++ b/src/basic_text_oprimitive.cpp @@ -14,6 +14,8 @@ #include +#define BOOST_ARCHIVE +#include #include namespace boost { diff --git a/src/basic_text_wiprimitive.cpp b/src/basic_text_wiprimitive.cpp index 536d097a..c80a8628 100644 --- a/src/basic_text_wiprimitive.cpp +++ b/src/basic_text_wiprimitive.cpp @@ -9,6 +9,7 @@ // See http://www.boost.org for updates, documentation, and revision history. #include + #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else @@ -19,6 +20,8 @@ #include +#define BOOST_WARCHIVE +#include #include namespace boost { diff --git a/src/basic_text_woprimitive.cpp b/src/basic_text_woprimitive.cpp index 2ce61944..4fd6320e 100644 --- a/src/basic_text_woprimitive.cpp +++ b/src/basic_text_woprimitive.cpp @@ -19,12 +19,14 @@ #endif #include + +#define BOOST_WARCHIVE +#include #include namespace boost { namespace archive { -// explicitly instantiate for this type of xml stream template class basic_text_oprimitive ; } // namespace archive diff --git a/src/basic_xml_archive.cpp b/src/basic_xml_archive.cpp index e7f1d305..7d2ace93 100644 --- a/src/basic_xml_archive.cpp +++ b/src/basic_xml_archive.cpp @@ -8,17 +8,36 @@ // See http://www.boost.org for updates, documentation, and revision history. +#define BOOST_ARCHIVE +#include + namespace boost { namespace archive { -const char * OBJECT_ID = "object_id"; -const char * OBJECT_REFERENCE = "object_id_reference"; -const char * CLASS_ID = "class_id"; -const char * CLASS_ID_REFERENCE = "class_id_reference"; -const char * CLASS_NAME = "class_name"; -const char * TRACKING = "tracking_level"; -const char * VERSION = "version"; -const char * SIGNATURE = "signature"; +BOOST_DECL_ARCHIVE const char * OBJECT_ID(){ + return "object_id"; +} +BOOST_DECL_ARCHIVE const char * OBJECT_REFERENCE(){ + return "object_id_reference"; +} +BOOST_DECL_ARCHIVE const char * CLASS_ID(){ + return "class_id"; +} +BOOST_DECL_ARCHIVE const char * CLASS_ID_REFERENCE(){ + return "class_id_reference"; +} +BOOST_DECL_ARCHIVE const char * CLASS_NAME(){ + return "class_name"; +} +BOOST_DECL_ARCHIVE const char * TRACKING(){ + return "tracking_level"; +} +BOOST_DECL_ARCHIVE const char * VERSION(){ + return "version"; +} +BOOST_DECL_ARCHIVE const char * SIGNATURE(){ + return "signature"; +} }// namespace archive }// namespace boost diff --git a/src/binary_iarchive.cpp b/src/binary_iarchive.cpp index 8896fc05..3fb8f320 100644 --- a/src/binary_iarchive.cpp +++ b/src/binary_iarchive.cpp @@ -9,16 +9,20 @@ // See http://www.boost.org for updates, documentation, and revision history. #include -#include -#include -// explicitly instantiate for this type of text stream +#define BOOST_ARCHIVE +#include + #include +#include +#include namespace boost { namespace archive { +// explicitly instantiate for this type of stream template class basic_binary_iprimitive ; +template class basic_binary_iarchive ; template class binary_iarchive_impl ; template class detail::archive_pointer_iserializer ; diff --git a/src/binary_oarchive.cpp b/src/binary_oarchive.cpp index 7cd99bab..d593a1fd 100644 --- a/src/binary_oarchive.cpp +++ b/src/binary_oarchive.cpp @@ -9,9 +9,12 @@ // See http://www.boost.org for updates, documentation, and revision history. #include + +#define BOOST_ARCHIVE #include #include +#include #include namespace boost { @@ -19,6 +22,7 @@ namespace archive { // explicitly instantiate for this type of binary stream template class basic_binary_oprimitive ; +template class basic_binary_oarchive ; template class binary_oarchive_impl ; template class detail::archive_pointer_oserializer ; diff --git a/src/binary_wiarchive.cpp b/src/binary_wiarchive.cpp index 29d6d770..23b8e66e 100644 --- a/src/binary_wiarchive.cpp +++ b/src/binary_wiarchive.cpp @@ -14,9 +14,11 @@ #error "wide char i/o not supported on this platform" #else +#define BOOST_WARCHIVE #include #include +#include #include namespace boost { diff --git a/src/binary_woarchive.cpp b/src/binary_woarchive.cpp index 9c30fce5..59a43a1e 100644 --- a/src/binary_woarchive.cpp +++ b/src/binary_woarchive.cpp @@ -14,9 +14,11 @@ #error "wide char i/o not supported on this platform" #else +#define BOOST_WARCHIVE #include #include +#include #include namespace boost { diff --git a/src/extended_type_info.cpp b/src/extended_type_info.cpp index 00dfeb6e..67ba0079 100644 --- a/src/extended_type_info.cpp +++ b/src/extended_type_info.cpp @@ -8,6 +8,7 @@ // See http://www.boost.org for updates, documentation, and revision history. + #include // msvc needs this to suppress warning #include @@ -15,164 +16,240 @@ namespace std{ using ::strcmp; } #endif +#include #include #include +#define BOOST_SERIALIZATION_SOURCE #include namespace boost { namespace serialization { +// remove all registrations corresponding to a given type +void unregister_void_casts(extended_type_info *eti); + namespace { // anonymous -struct type_info_compare -{ - bool - operator()(const extended_type_info * lhs, const extended_type_info * rhs) const +// it turns out that at least one compiler (msvc 6.0) doesn't guarentee +// to destroy static objects in exactly the reverse sequence that they +// are constructed. To guarentee this, use a singleton pattern +class tkmap { + struct type_info_compare { - return *lhs < *rhs; + bool + operator()(const extended_type_info * lhs, const extended_type_info * rhs) const + { + return *lhs < *rhs; + } + }; + typedef std::multiset type; + tkmap(){} + type m_map; + static tkmap * m_self; +public: + ~tkmap(){ + m_self = NULL; } -}; -struct key_compare -{ - bool - operator()(const extended_type_info * lhs, const extended_type_info * rhs) const - { - // shortcut to exploit string pooling - if(lhs->key == rhs->key) - return false; - if(NULL == lhs->key) - return true; - if(NULL == rhs->key) - return false; - return std::strcmp(lhs->key, rhs->key) < 0; + static void + insert(const extended_type_info * eti){ + if(NULL == m_self){ + static tkmap instance; + m_self = & instance; + } + m_self->m_map.insert(eti); + } + static const extended_type_info * + find(const extended_type_info * t){ + if(NULL == m_self) + return NULL; + tkmap::type::const_iterator it; + it = m_self->m_map.find(t); + if(it == m_self->m_map.end()) + return NULL; + return *it; + } + static void + purge(const extended_type_info * eti){ + if(NULL == m_self) + return; + tkmap::type::iterator i = m_self->m_map.begin(); + tkmap::type::iterator k = m_self->m_map.end(); + while(i != k){ + // note that the erase might invalidate i so save it here + tkmap::type::iterator j = i++; + if(*j == eti) + m_self->m_map.erase(j); + } } }; -// use static local variables to ensure that collections are -// initialized before being used. -typedef std::set tkmap_type; -static tkmap_type & -tkmap(){ - static tkmap_type map; - return map; -} +tkmap * tkmap::m_self = NULL; -typedef std::set ktmap_type; -static ktmap_type & -ktmap(){ - static ktmap_type map; - return map; -} +class ktmap { + struct key_compare + { + bool + operator()(const extended_type_info * lhs, const extended_type_info * rhs) const + { + // shortcut to exploit string pooling + if(lhs->key == rhs->key) + return false; + if(NULL == lhs->key) + return true; + if(NULL == rhs->key) + return false; + return std::strcmp(lhs->key, rhs->key) < 0; + } + }; + typedef std::multiset type; + type m_map; + static ktmap * m_self; + ktmap(){} +public: + ~ktmap(){ + m_self = NULL; + } + static void + insert(const extended_type_info * eti){ + if(NULL == m_self){ + static ktmap instance; + m_self = & instance; + } + m_self->m_map.insert(eti); + } + static void + purge(const extended_type_info * eti){ + if(NULL == m_self) + return; + ktmap::type::iterator i = m_self->m_map.begin(); + ktmap::type::iterator k = m_self->m_map.end(); + while(i == k){ + // note that the erase might invalidate i so save it here + ktmap::type::iterator j = i++; + if(*j == eti) + m_self->m_map.erase(j); + } + } + class extended_type_info_arg : public extended_type_info + { + public: + extended_type_info_arg(const char * search_key_) + : extended_type_info(NULL) + { + key = search_key_; + } + virtual bool + less_than(const extended_type_info &rhs) const + { + assert(false); + return false; // to prevent a syntax error + } + virtual bool + equal_to(const extended_type_info &rhs) const{ + assert(false); + return false; // to prevent a syntax error + } + virtual bool + not_equal_to(const extended_type_info &rhs) const{ + assert(false); + return false; // to prevent a syntax error + } + }; + static const extended_type_info * + find(const char *key) + { + if(NULL == m_self) + return NULL; + extended_type_info_arg arg(key); + ktmap::type::const_iterator it; + it = m_self->m_map.find(&arg); + if(it == m_self->m_map.end()) + return NULL; + return *it; + } + +}; + +ktmap * ktmap::m_self = NULL; } // anonymous -void extended_type_info::self_register() +BOOST_SERIALIZATION_DECL const extended_type_info * +extended_type_info::find(const char *key) { - tkmap().insert(this); + return ktmap::find(key); } -void extended_type_info::key_register(const char *key_) { +BOOST_SERIALIZATION_DECL void +extended_type_info::self_register() +{ + tkmap::insert(this); +} + +BOOST_SERIALIZATION_DECL void +extended_type_info::key_register(const char *key_) { if(NULL == key_) return; key = key_; - ktmap().insert(this); + ktmap::insert(this); } -namespace { +BOOST_SERIALIZATION_DECL +extended_type_info::extended_type_info(const char * type_info_key_) : + type_info_key(type_info_key_), + key(NULL) +{} -class extended_type_info_arg : public extended_type_info -{ -public: - extended_type_info_arg(const char * search_key_) - : extended_type_info(NULL) - { - key = search_key_; - } - virtual bool - less_than(const extended_type_info &rhs) const - { - assert(false); - return false; // to prevent a syntax error - } - virtual bool - equal_to(const extended_type_info &rhs) const{ - assert(false); - return false; // to prevent a syntax error - } - virtual bool - not_equal_to(const extended_type_info &rhs) const{ - assert(false); - return false; // to prevent a syntax error - } -}; -} // anonymous - -const extended_type_info * extended_type_info::find(const char *key) -{ - - extended_type_info_arg arg(key); - ktmap_type::const_iterator it; - it = ktmap().find(&arg); - if(it == ktmap().end()) - return NULL; - - return *it; +BOOST_SERIALIZATION_DECL +extended_type_info::~extended_type_info(){ + // remove entries in maps which correspond to this type + tkmap::purge(this); + ktmap::purge(this); + unregister_void_casts(this); } -const extended_type_info * extended_type_info::find(const extended_type_info * t) -{ - tkmap_type::const_iterator it; - it = tkmap().find(t); - if(it == tkmap().end()) - return NULL; - return *it; -} -namespace { // anonymous -int type_info_key_cmp( - const extended_type_info & lhs, - const extended_type_info & rhs -) { - if(lhs.type_info_key == rhs.type_info_key) +int BOOST_SERIALIZATION_DECL +extended_type_info::type_info_key_cmp(const extended_type_info & rhs) const { + if(type_info_key == rhs.type_info_key) return 0; //return strcmp(lhs.type_info_key, rhs.type_info_key); // all we require is that the type_info_key be unique // so just compare the addresses - return lhs.type_info_key < rhs.type_info_key ? -1 : 1; + return type_info_key < rhs.type_info_key ? -1 : 1; } -} // anonymous -bool operator<( - const extended_type_info &lhs, - const extended_type_info &rhs -){ - int i = type_info_key_cmp(lhs, rhs); +BOOST_SERIALIZATION_DECL const extended_type_info * +extended_type_info::find(const extended_type_info * t) +{ + return tkmap::find(t); +} + +bool BOOST_SERIALIZATION_DECL +extended_type_info::operator<(const extended_type_info &rhs) const { + int i = type_info_key_cmp(rhs); if(i < 0) return true; if(i > 0) return false; - return lhs.less_than(rhs); + return less_than(rhs); } -bool operator==( - const extended_type_info &lhs, - const extended_type_info &rhs -){ - int i = type_info_key_cmp(lhs, rhs); +bool BOOST_SERIALIZATION_DECL +extended_type_info::operator==(const extended_type_info &rhs) const { + int i = type_info_key_cmp(rhs); if(i != 0) return false; - return lhs.equal_to(rhs); + return equal_to(rhs); } -bool operator!=( - const extended_type_info &lhs, - const extended_type_info &rhs -){ - int i = type_info_key_cmp(lhs, rhs); +bool BOOST_SERIALIZATION_DECL +extended_type_info::operator!=(const extended_type_info &rhs) const { + int i = type_info_key_cmp(rhs); if(i != 0) return true; - return lhs.not_equal_to(rhs); + return not_equal_to(rhs); } } // namespace serialization diff --git a/src/extended_type_info_no_rtti.cpp b/src/extended_type_info_no_rtti.cpp index a7b5a025..91542c41 100644 --- a/src/extended_type_info_no_rtti.cpp +++ b/src/extended_type_info_no_rtti.cpp @@ -9,13 +9,45 @@ // See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::strcmp; } +#endif + +#define BOOST_SERIALIZATION_SOURCE #include namespace boost { namespace serialization { -const char * extended_type_info_no_rtti_base::type_info_key - = "extended_type_info_no_rtti"; +BOOST_SERIALIZATION_DECL bool +extended_type_info_no_rtti_base::less_than( + const boost::serialization::extended_type_info &rhs) const +{ + return std::strcmp(key, rhs.key) < 0; +} +BOOST_SERIALIZATION_DECL bool +extended_type_info_no_rtti_base::equal_to( + const boost::serialization::extended_type_info &rhs) const +{ + return std::strcmp(key, rhs.key) == 0; +} +BOOST_SERIALIZATION_DECL bool +extended_type_info_no_rtti_base::not_equal_to( + const boost::serialization::extended_type_info &rhs) const +{ + return std::strcmp(key, rhs.key) != 0; +} + +BOOST_SERIALIZATION_DECL +extended_type_info_no_rtti_base::extended_type_info_no_rtti_base() : + boost::serialization::extended_type_info("extended_type_info_no_rtti") +{} + +BOOST_SERIALIZATION_DECL +extended_type_info_no_rtti_base::~extended_type_info_no_rtti_base() +{} } // namespace serialization } // namespace boost diff --git a/src/extended_type_info_typeid.cpp b/src/extended_type_info_typeid.cpp index 33a0a6eb..a2af7df4 100644 --- a/src/extended_type_info_typeid.cpp +++ b/src/extended_type_info_typeid.cpp @@ -9,14 +9,71 @@ // See http://www.boost.org for updates, documentation, and revision history. +#define BOOST_SERIALIZATION_SOURCE #include namespace boost { namespace serialization { namespace detail { -const char * extended_type_info_typeid_0::type_info_key - = "extended_type_info_typeid"; +BOOST_SERIALIZATION_DECL bool +extended_type_info_typeid_0::less_than(const extended_type_info &rhs) const +{ + return 0 != get_type().before( + static_cast(rhs).get_type() + ); +} +BOOST_SERIALIZATION_DECL bool +extended_type_info_typeid_0::equal_to(const extended_type_info &rhs) const +{ + return 0 != get_type().operator==( + static_cast(rhs).get_type() + ); +} +BOOST_SERIALIZATION_DECL bool +extended_type_info_typeid_0::not_equal_to(const extended_type_info &rhs) const +{ + return 0 != get_type().operator!=( + static_cast(rhs).get_type() + ); +} + +BOOST_SERIALIZATION_DECL +extended_type_info_typeid_0::extended_type_info_typeid_0() : + extended_type_info("extended_type_info_typeid") +{} + +BOOST_SERIALIZATION_DECL +extended_type_info_typeid_0::~extended_type_info_typeid_0() +{} + +// this derivation is used for creating search arguments +class extended_type_info_typeid_arg : + public extended_type_info_typeid_0 +{ +private: + const std::type_info & ti; + virtual const std::type_info &get_type() const + { + return ti; + } +public: + extended_type_info_typeid_arg(const std::type_info & ti_) + : ti(ti_) + { + // note absense of self register and key as this is used only as + // search argument given a type_info reference and is not to + // be added to the map. + } +}; + +BOOST_SERIALIZATION_DECL const extended_type_info * +extended_type_info_typeid_0::get_derived_extended_type_info( + const std::type_info & ti +){ + detail::extended_type_info_typeid_arg etia(ti); + return extended_type_info::find(& etia); +} } // namespace detail } // namespace serialization diff --git a/src/polymorphic_iarchive.cpp b/src/polymorphic_iarchive.cpp index 968ae19f..1d0a09ae 100644 --- a/src/polymorphic_iarchive.cpp +++ b/src/polymorphic_iarchive.cpp @@ -14,6 +14,7 @@ #include +#define BOOST_ARCHIVE #include // explicitly instantiate for this type of text stream diff --git a/src/polymorphic_oarchive.cpp b/src/polymorphic_oarchive.cpp index 958d3f42..078d21dc 100644 --- a/src/polymorphic_oarchive.cpp +++ b/src/polymorphic_oarchive.cpp @@ -14,6 +14,7 @@ #include +#define BOOST_ARCHIVE #include // explicitly instantiate for this type of text stream @@ -24,5 +25,5 @@ namespace archive { template class detail::archive_pointer_oserializer ; -} // namespace serialization +} // namespace archive } // namespace boost diff --git a/src/text_iarchive.cpp b/src/text_iarchive.cpp index d12b7b34..583cee61 100644 --- a/src/text_iarchive.cpp +++ b/src/text_iarchive.cpp @@ -8,6 +8,7 @@ // See http://www.boost.org for updates, documentation, and revision history. +#define BOOST_ARCHIVE #include // explicitly instantiate for this type of text stream diff --git a/src/text_oarchive.cpp b/src/text_oarchive.cpp index bf80d2fa..d76789a8 100644 --- a/src/text_oarchive.cpp +++ b/src/text_oarchive.cpp @@ -12,15 +12,19 @@ # pragma warning (disable : 4786) // too long name, harmless warning #endif +#define BOOST_ARCHIVE #include // explicitly instantiate for this type of text stream +#include #include #include namespace boost { namespace archive { +//template class basic_text_oprimitive ; +template class basic_text_oarchive ; template class text_oarchive_impl ; template class detail::archive_pointer_oserializer ; diff --git a/src/text_wiarchive.cpp b/src/text_wiarchive.cpp index c91f170b..c50d9a0e 100644 --- a/src/text_wiarchive.cpp +++ b/src/text_wiarchive.cpp @@ -14,6 +14,7 @@ #error "wide char i/o not supported on this platform" #else +#define BOOST_WARCHIVE #include // explicitly instantiate for this type of text stream diff --git a/src/text_woarchive.cpp b/src/text_woarchive.cpp index 10a47112..36afdd08 100644 --- a/src/text_woarchive.cpp +++ b/src/text_woarchive.cpp @@ -9,20 +9,21 @@ // See http://www.boost.org for updates, documentation, and revision history. #include - #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else +#define BOOST_WARCHIVE #include -// explicitly instantiate for this type of text stream +#include #include #include namespace boost { namespace archive { +template class basic_text_oarchive ; template class text_woarchive_impl ; template class detail::archive_pointer_oserializer ; diff --git a/src/void_cast.cpp b/src/void_cast.cpp index e0897de8..45658b66 100644 --- a/src/void_cast.cpp +++ b/src/void_cast.cpp @@ -9,7 +9,11 @@ // See http://www.boost.org for updates, documentation, and revision history. -#include // msvc needs this to suppress warning +#if (defined _MSC_VER) && (_MSC_VER == 1200) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +#include // STL #include @@ -18,6 +22,8 @@ #include // BOOST +#define BOOST_SERIALIZATION_SOURCE +#include #include #include @@ -29,53 +35,174 @@ namespace void_cast_detail { struct void_caster_compare { bool - operator()( void_caster const* lhs, void_caster const* rhs ) const + operator()( + shared_ptr lhs, + shared_ptr rhs ) const { - if( lhs->m_derived_type < rhs->m_derived_type ) + if( lhs.get()->m_derived_type < rhs.get()->m_derived_type ) return true; - if( rhs->m_derived_type < lhs->m_derived_type) + if( rhs.get()->m_derived_type < lhs.get()->m_derived_type) return false; - if( lhs->m_base_type < rhs->m_base_type ) + if( lhs.get()->m_base_type < rhs.get()->m_base_type ) return true; return false; } }; -struct void_caster_registry +struct null_deleter { - typedef std::set set_type; - typedef set_type::iterator iterator; - set_type m_set; + void operator()(void const *) const + {} }; -// note: using accessing through this singleton guarentees that the -// constructor for the set is invoked before any entries are added to it. -void_caster_registry & -global_registry() +// it turns out that at least one compiler (msvc 6.0) doesn't guarentee +// to destroy static objects in exactly the reverse sequence that they +// are constructed. To guarentee this, use a singleton pattern +class void_caster_registry { - static void_caster_registry instance; - return instance; + typedef shared_ptr value_type; + typedef std::set set_type; + set_type m_set; + static void_caster_registry * m_self; + static void_caster_registry * + self(){ + if(NULL == m_self){ + static void_caster_registry instance; + m_self = & instance; + } + return m_self; + } + void_caster_registry(){} +public: + ~void_caster_registry(){ + m_self = 0; + } + typedef set_type::iterator iterator; + typedef set_type::const_iterator const_iterator; + static iterator + begin() { + return self()->m_set.begin(); + } + static iterator + end() { + return self()->m_set.end(); + } + static const_iterator + find(void_caster * vcp){ + return self()->m_set.find(value_type(vcp, null_deleter())); + } + static std::pair + insert(const value_type & vcp){ + return self()->m_set.insert(vcp); + } + static bool + empty(){ + if(NULL == m_self) + return true; + return m_self->m_set.empty(); + } + static void + purge(const extended_type_info * eti); +}; + +void_caster_registry * void_caster_registry::m_self = NULL; + +void +void_caster_registry::purge(const extended_type_info * eti){ + if(! empty()){ + iterator i = m_self->m_set.begin(); + while(i != m_self->m_set.end()){ + // note that the erase might invalidate i so save it here + iterator j = i++; + if((*j)->includes(eti)) + m_self->m_set.erase(j); + } + } } -void -void_caster::self_register() -{ - // from/to pairs are registered when created - // and there should only be one instance of each pair - if(! global_registry().m_set.insert(this).second) +BOOST_SERIALIZATION_DECL +void_caster::void_caster( + extended_type_info const & derived_type_, + extended_type_info const & base_type_ +) : + m_derived_type( derived_type_), + m_base_type(base_type_) +{} + +BOOST_SERIALIZATION_DECL +void_caster::~void_caster(){} + +bool +void_caster::includes(const extended_type_info * eti) const { + return & m_derived_type == eti || & m_base_type == eti; +} + +void BOOST_SERIALIZATION_DECL +void_caster::static_register(const void_caster * vcp) +{ + void_caster_registry::insert(shared_ptr(vcp, null_deleter())); +} + +class void_caster_derived : public void_caster +{ + std::ptrdiff_t difference; + virtual void const* + upcast( void const* t ) const{ + return static_cast ( t ) + difference; + } + virtual void const* + downcast( void const* t ) const{ + return static_cast ( t ) - difference; + } +public: + void_caster_derived( + extended_type_info const& derived_type_, + extended_type_info const& base_type_, + std::ptrdiff_t difference_ + ) : + void_caster(derived_type_, base_type_), + difference( difference_ ) + {} +}; + +// just used as a search key +class void_caster_argument : public void_caster +{ + virtual void const* + upcast( void const* t ) const { assert(false); -} + return NULL; + } + virtual void const* + downcast( void const* t ) const { + assert(false); + return NULL; + } +public: + void_caster_argument( + extended_type_info const& derived_type_, + extended_type_info const& base_type_ + ) : + void_caster(derived_type_, base_type_) + {} +}; -} // void_cast_detail +} // namespace void_cast_detail + +void BOOST_SERIALIZATION_DECL +unregister_void_casts(extended_type_info *eti) +{ + void_cast_detail::void_caster_registry::purge(eti); +} // Given a void *, assume that it really points to an instance of one type // and alter it so that it would point to an instance of a related type. // Return the altered pointer. If there exists no sequence of casts that // can transform from_type to to_type, return a NULL. -const void * +BOOST_SERIALIZATION_DECL const void * void_upcast( const extended_type_info & derived_type, const extended_type_info & base_type, @@ -87,20 +214,21 @@ void_upcast( return t; // check to see if base/derived pair is found in the registry - void_cast_detail::void_caster ca(derived_type, base_type ); - void_cast_detail::void_caster_registry::iterator it; - it = void_cast_detail::global_registry().m_set.find( &ca ); + void_cast_detail::void_caster_argument ca(derived_type, base_type ); + void_cast_detail::void_caster_registry::const_iterator it; + it = void_cast_detail::void_caster_registry::find( &ca ); + const void * t_new = NULL; + // if so - if (it != void_cast_detail::global_registry().m_set.end()) + if (it != void_cast_detail::void_caster_registry::end()) // we're done return (*it)->upcast(t); - const void * t_new = NULL; // try to find a chain that gives us what we want for( - it = void_cast_detail::global_registry().m_set.begin(); - it != void_cast_detail::global_registry().m_set.end(); + it = void_cast_detail::void_caster_registry::begin(); + it != void_cast_detail::void_caster_registry::end(); ++it ){ // if the current candidate doesn't cast to the desired target type @@ -118,10 +246,14 @@ void_upcast( if(top){ // register the this pair so we will have to go through // keep this expensive search process more than once. - new void_cast_detail::void_caster_derived( - derived_type, - base_type, - static_cast(t_new) - static_cast(t) + void_cast_detail::void_caster * vcp = + new void_cast_detail::void_caster_derived( + derived_type, + base_type, + static_cast(t_new) - static_cast(t) + ); + void_cast_detail::void_caster_registry::insert( + shared_ptr(vcp) ); } break; @@ -131,7 +263,7 @@ void_upcast( return t_new; } -const void * +BOOST_SERIALIZATION_DECL const void * void_downcast( const extended_type_info & derived_type, const extended_type_info & base_type, @@ -143,20 +275,20 @@ void_downcast( return t; // check to see if base/derived pair is found in the registry - void_cast_detail::void_caster ca(derived_type, base_type ); - void_cast_detail::void_caster_registry::iterator it; - it = void_cast_detail::global_registry().m_set.find( &ca ); + void_cast_detail::void_caster_argument ca(derived_type, base_type ); + void_cast_detail::void_caster_registry::const_iterator it; + it = void_cast_detail::void_caster_registry::find( &ca ); // if so - if (it != void_cast_detail::global_registry().m_set.end()) + if (it != void_cast_detail::void_caster_registry::end()) // we're done return (*it)->downcast(t); const void * t_new = NULL; // try to find a chain that gives us what we want for( - it = void_cast_detail::global_registry().m_set.begin(); - it != void_cast_detail::global_registry().m_set.end(); + it = void_cast_detail::void_caster_registry::begin(); + it != void_cast_detail::void_caster_registry::end(); ++it ){ // if the current candidate doesn't cast from the desired target type @@ -174,10 +306,14 @@ void_downcast( if(top){ // register the this pair so we will have to go through // keep this expensive search process more than once. - new void_cast_detail::void_caster_derived( - derived_type, - base_type, - static_cast(t) - static_cast(t_new) + void_cast_detail::void_caster * vcp = + new void_cast_detail::void_caster_derived( + derived_type, + base_type, + static_cast(t) - static_cast(t_new) + ); + void_cast_detail::void_caster_registry::insert( + shared_ptr(vcp) ); } break; @@ -187,7 +323,6 @@ void_downcast( return t_new; } - } // namespace serialization } // namespace boost diff --git a/src/xml_iarchive.cpp b/src/xml_iarchive.cpp index 3a3e51c9..66d10582 100644 --- a/src/xml_iarchive.cpp +++ b/src/xml_iarchive.cpp @@ -12,12 +12,13 @@ # pragma warning (disable : 4786) // too long name, harmless warning #endif -#include -#include +#define BOOST_ARCHIVE // the following works around an issue between spirit 1.61 and borland. // it turns out the the certain spirit stuff must be defined before // certain parts of mpl. including this here makes sure that happens +#include +#include #if BOOST_WORKAROUND(__BORLANDC__, <= 0x564 ) #include #endif @@ -26,15 +27,15 @@ // explicitly instantiate for this type of xml stream #include -#include #include +#include namespace boost { namespace archive { template class basic_xml_iarchive ; -template class xml_iarchive_impl ; template class detail::archive_pointer_iserializer ; +template class xml_iarchive_impl ; } // namespace archive } // namespace boost diff --git a/src/xml_oarchive.cpp b/src/xml_oarchive.cpp index 897d08dc..43d47a44 100644 --- a/src/xml_oarchive.cpp +++ b/src/xml_oarchive.cpp @@ -12,19 +12,20 @@ # pragma warning (disable : 4786) // too long name, harmless warning #endif +#define BOOST_ARCHIVE #include #include -#include #include +#include namespace boost { namespace archive { // explicitly instantiate for this type of xml stream template class basic_xml_oarchive ; -template class xml_oarchive_impl ; template class detail::archive_pointer_oserializer ; +template class xml_oarchive_impl ; } // namespace archive } // namespace boost diff --git a/src/xml_wiarchive.cpp b/src/xml_wiarchive.cpp index 2be732d9..0410dd9f 100644 --- a/src/xml_wiarchive.cpp +++ b/src/xml_wiarchive.cpp @@ -19,6 +19,8 @@ # pragma warning (disable : 4786) // too long name, harmless warning #endif +#define BOOST_WARCHIVE + // the following works around an issue between spirit 1.61 and borland. // it turns out the the certain spirit stuff must be defined before // certain parts of mpl. including this here makes sure that happens diff --git a/src/xml_woarchive.cpp b/src/xml_woarchive.cpp index 5faa9849..43ac03a5 100644 --- a/src/xml_woarchive.cpp +++ b/src/xml_woarchive.cpp @@ -13,6 +13,7 @@ #error "wide char i/o not supported on this platform" #else +#define BOOST_WARCHIVE #include #include @@ -22,7 +23,6 @@ namespace boost { namespace archive { -// explicitly instantiate for this type of xml stream template class basic_xml_oarchive ; template class xml_woarchive_impl ; template class detail::archive_pointer_oserializer ;