Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56221 - trunk/boost/archive/detail
From: ramey_at_[hidden]
Date: 2009-09-15 16:12:48


Author: ramey
Date: 2009-09-15 16:12:47 EDT (Tue, 15 Sep 2009)
New Revision: 56221
URL: http://svn.boost.org/trac/boost/changeset/56221

Log:
Formalize compiler time errors and warnings
Added:
   trunk/boost/archive/detail/check.hpp (contents, props changed)
Text files modified:
   trunk/boost/archive/detail/iserializer.hpp | 143 +++++++++++++++-------------
   trunk/boost/archive/detail/oserializer.hpp | 198 ++++++++++++++-------------------------
   2 files changed, 147 insertions(+), 194 deletions(-)

Added: trunk/boost/archive/detail/check.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/archive/detail/check.hpp 2009-09-15 16:12:47 EDT (Tue, 15 Sep 2009)
@@ -0,0 +1,169 @@
+#ifndef BOOST_ARCHIVE_DETAIL_CHECK_HPP
+#define BOOST_ARCHIVE_DETAIL_CHECK_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#pragma inline_depth(511)
+#pragma inline_recursion(on)
+#endif
+
+#if defined(__MWERKS__)
+#pragma inline_depth(511)
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// check.hpp: interface for serialization system.
+
+// (C) Copyright 2009 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.
+
+#include <boost/config.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/mpl/assert.hpp>
+
+#include <boost/serialization/static_warning.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/level.hpp>
+#include <boost/serialization/tracking.hpp>
+#include <boost/serialization/wrapper.hpp>
+
+namespace boost {
+namespace archive {
+namespace detail {
+
+// checks for objects
+
+template<class T>
+void inline check_object_level(){
+ typedef
+ BOOST_DEDUCED_TYPENAME mpl::greater_equal<
+ serialization::implementation_level<T>,
+ mpl::int_<serialization::primitive_type>
+ >::type typex;
+
+ // trap attempts to serialize objects marked
+ // not_serializable
+ BOOST_STATIC_ASSERT(typex::value);
+};
+
+template<class T>
+void inline check_object_versioning(){
+ typedef
+ BOOST_DEDUCED_TYPENAME mpl::or_<
+ BOOST_DEDUCED_TYPENAME mpl::greater<
+ serialization::implementation_level<T>,
+ mpl::int_<serialization::object_serializable>
+ >,
+ BOOST_DEDUCED_TYPENAME mpl::equal_to<
+ serialization::version<T>,
+ mpl::int_<0>
+ >
+ > typex;
+ // trap attempts to serialize with objects that don't
+ // save class information in the archive with versioning.
+ BOOST_STATIC_ASSERT(typex::value);
+};
+
+template<class T>
+void inline check_object_tracking(){
+ // presume it has already been determined that
+ // T is not a const
+ BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
+ typedef BOOST_DEDUCED_TYPENAME mpl::equal_to<
+ serialization::tracking_level<T>,
+ mpl::int_<serialization::track_never>
+ >::type typex;
+ // saving an non-const object of a type not marked "track_never)
+
+ // may be an indicator of an error usage of the
+ // serialization library and should be double checked.
+ // See documentation on object tracking. Also, see the
+ // "rationale" section of the documenation
+ // for motivation for this checking.
+
+ BOOST_STATIC_WARNING(typex::value);
+};
+
+// checks for pointers
+
+template<class T>
+void inline check_pointer_level(){
+ // we should only invoke this once we KNOW that T
+ // has been used as a pointer!!
+ typedef
+ BOOST_DEDUCED_TYPENAME mpl::or_<
+ BOOST_DEDUCED_TYPENAME mpl::greater<
+ serialization::implementation_level<T>,
+ mpl::int_<serialization::object_serializable>
+ >,
+ BOOST_DEDUCED_TYPENAME mpl::not_<
+ BOOST_DEDUCED_TYPENAME mpl::equal_to<
+ serialization::tracking_level<T>,
+ mpl::int_<serialization::track_selectively>
+ >
+ >
+ > typex;
+ // Address the following when serializing to a pointer:
+
+ // a) This type doesn't save class information in the
+ // archive. That is, the serialization trait implementation
+ // level <= object_serializable.
+ // b) Tracking for this type is set to "track selectively"
+
+ // in this case, indication that an object is tracked is
+ // not stored in the archive itself - see level == object_serializable
+ // but rather the existence of the operation ar >> T * is used to
+ // infer that an object of this type should be tracked. So, if
+ // you save via a pointer but don't load via a pointer the operation
+ // will fail on load without given any valid reason for the failure.
+
+ // So if your program traps here, consider changing the
+ // tracking or implementation level traits - or not
+ // serializing via a pointer.
+ BOOST_STATIC_WARNING(typex::value);
+}
+
+template<class T>
+void inline check_pointer_tracking(){
+ typedef BOOST_DEDUCED_TYPENAME mpl::greater<
+ serialization::tracking_level<T>,
+ mpl::int_<serialization::track_never>
+ >::type typex;
+ // serializing an object of a type marked "track_never" through a pointer
+ // could result in creating more objects than were saved!
+ BOOST_STATIC_WARNING(typex::value);
+};
+
+template<class T>
+void inline check_const_loading(){
+ typedef
+ BOOST_DEDUCED_TYPENAME mpl::or_<
+ BOOST_DEDUCED_TYPENAME boost::serialization::is_wrapper<T>,
+ BOOST_DEDUCED_TYPENAME mpl::not_<
+ BOOST_DEDUCED_TYPENAME boost::is_const<T>
+ >
+ >::type typex;
+ // cannot load data into a "const" object unless it's a
+ // wrapper around some other non-const object.
+ BOOST_STATIC_ASSERT(typex::value);
+};
+
+} // detail
+} // archive
+} // boost
+
+#endif // BOOST_ARCHIVE_DETAIL_CHECK_HPP

Modified: trunk/boost/archive/detail/iserializer.hpp
==============================================================================
--- trunk/boost/archive/detail/iserializer.hpp (original)
+++ trunk/boost/archive/detail/iserializer.hpp 2009-09-15 16:12:47 EDT (Tue, 15 Sep 2009)
@@ -34,29 +34,31 @@
 } // namespace std
 #endif
 
+#include <boost/static_assert.hpp>
+
 #include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/mpl/greater_equal.hpp>
 #include <boost/mpl/equal_to.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 
 #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
     #include <boost/serialization/extended_type_info_typeid.hpp>
 #endif
 #include <boost/serialization/throw_exception.hpp>
 #include <boost/serialization/smart_cast.hpp>
-#include <boost/static_assert.hpp>
 #include <boost/serialization/static_warning.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
 
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/is_enum.hpp>
 #include <boost/type_traits/is_const.hpp>
 #include <boost/type_traits/remove_const.hpp>
 #include <boost/type_traits/remove_extent.hpp>
-#include <boost/serialization/assume_abstract.hpp>
 #include <boost/type_traits/is_polymorphic.hpp>
 
+#include <boost/serialization/assume_abstract.hpp>
+
 #define DONT_USE_HAS_NEW_OPERATOR ( \
     defined(__BORLANDC__) \
     || defined(__IBMCPP__) \
@@ -78,6 +80,7 @@
 #include <boost/serialization/array.hpp>
 #include <boost/serialization/collection_size_type.hpp>
 #include <boost/serialization/singleton.hpp>
+#include <boost/serialization/wrapper.hpp>
 
 // the following is need only for dynamic cast of polymorphic pointers
 #include <boost/archive/archive_exception.hpp>
@@ -85,6 +88,7 @@
 #include <boost/archive/detail/basic_iserializer.hpp>
 #include <boost/archive/detail/basic_pointer_iserializer.hpp>
 #include <boost/archive/detail/archive_serializer_map.hpp>
+#include <boost/archive/detail/check.hpp>
 
 namespace boost {
 
@@ -324,11 +328,12 @@
     archive_serializer_map<Archive>::erase(this);
 }
 
-template<class Archive, class T>
+template<class Archive>
 struct load_non_pointer_type {
     // note this bounces the call right back to the archive
     // with no runtime overhead
     struct load_primitive {
+ template<class T>
         static void invoke(Archive & ar, T & t){
             load_access::load_primitive(ar, t);
         }
@@ -336,12 +341,15 @@
     // note this bounces the call right back to the archive
     // with no runtime overhead
     struct load_only {
- static void invoke(Archive & ar, T & t){
+ template<class T>
+ static void invoke(Archive & ar, const T & t){
             // short cut to user's serializer
             // make sure call is routed through the higest interface that might
             // be specialized by the user.
             boost::serialization::serialize_adl(
- ar, t, boost::serialization::version<T>::value
+ ar,
+ const_cast<T &>(t),
+ boost::serialization::version<T>::value
             );
         }
     };
@@ -349,12 +357,9 @@
     // note this save class information including version
     // and serialization level to the archive
     struct load_standard {
- static void invoke(Archive &ar, T &t){
- //BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
- // borland - for some reason T is const here - even though
- // its not called that way - so fix it her
- typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type typex;
- void * x = & const_cast<typex &>(t);
+ template<class T>
+ static void invoke(Archive &ar, const T & t){
+ void * x = & const_cast<T &>(t);
             ar.load_object(
                 x,
                 boost::serialization::singleton<
@@ -365,6 +370,7 @@
     };
 
     struct load_conditional {
+ template<class T>
         static void invoke(Archive &ar, T &t){
             //if(0 == (ar.get_flags() & no_tracking))
                 load_standard::invoke(ar, t);
@@ -373,57 +379,48 @@
         }
     };
 
- typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
- // if its primitive
- mpl::equal_to<
- boost::serialization::implementation_level<T>,
- mpl::int_<boost::serialization::primitive_type>
- >,
- mpl::identity<load_primitive>,
- // else
- BOOST_DEDUCED_TYPENAME mpl::eval_if<
- // class info / version
- mpl::greater_equal<
+ template<class T>
+ static void invoke(Archive & ar, T &t){
+ typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ // if its primitive
+ mpl::equal_to<
                     boost::serialization::implementation_level<T>,
- mpl::int_<boost::serialization::object_class_info>
+ mpl::int_<boost::serialization::primitive_type>
>,
- // do standard load
- mpl::identity<load_standard>,
- // else
- BOOST_DEDUCED_TYPENAME mpl::eval_if<
- // no tracking
- mpl::equal_to<
- boost::serialization::tracking_level<T>,
- mpl::int_<boost::serialization::track_never>
- >,
- // do a fast load
- mpl::identity<load_only>,
- // else
- // do a fast load only tracking is turned off
- mpl::identity<load_conditional>
- > > >::type typex;
-
- static void invoke(Archive & ar, T &t){
- // check that we're not trying to serialize something that
- // has been marked not to be serialized. If this your program
- // traps here, you've tried to serialize a class whose trait
- // has been marked "non-serializable". Either reset the trait
- // (see level.hpp) or change program not to serialize items of this class
- BOOST_STATIC_ASSERT((
+ mpl::identity<load_primitive>,
+ // else
+ BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ // class info / version
             mpl::greater_equal<
- boost::serialization::implementation_level<T>,
- mpl::int_<boost::serialization::primitive_type>
- >::value
- ));
+ boost::serialization::implementation_level<T>,
+ mpl::int_<boost::serialization::object_class_info>
+ >,
+ // do standard load
+ mpl::identity<load_standard>,
+ // else
+ BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ // no tracking
+ mpl::equal_to<
+ boost::serialization::tracking_level<T>,
+ mpl::int_<boost::serialization::track_never>
+ >,
+ // do a fast load
+ mpl::identity<load_only>,
+ // else
+ // do a fast load only tracking is turned off
+ mpl::identity<load_conditional>
+ > > >::type typex;
+ check_object_versioning<T>();
+ check_object_level<T>();
         typex::invoke(ar, t);
     }
 };
 
-template<class Archive, class Tptr>
+template<class Archive>
 struct load_pointer_type {
- template<class T>
     struct abstract
     {
+ template<class T>
         static const basic_pointer_iserializer * register_type(Archive & /* ar */){
             // it has? to be polymorphic
             BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);
@@ -431,9 +428,9 @@
          }
     };
 
- template<class T>
     struct non_abstract
     {
+ template<class T>
         static const basic_pointer_iserializer * register_type(Archive & ar){
             return ar.register_type(static_cast<T *>(NULL));
         }
@@ -448,10 +445,10 @@
         typedef BOOST_DEDUCED_TYPENAME
             mpl::eval_if<
                 boost::serialization::is_abstract<const T>,
- mpl::identity<abstract<T> >,
- mpl::identity<non_abstract<T> >
+ boost::mpl::identity<abstract>,
+ boost::mpl::identity<non_abstract>
>::type typex;
- return typex::register_type(ar);
+ return typex::template register_type<T>(ar);
     }
 
     template<class T>
@@ -473,7 +470,15 @@
         );
     }
 
+ template<class T>
+ static void load(Archive &ar, T & t){
+ check_pointer_level<T>();
+ check_pointer_tracking<T>();
+ }
+
+ template<class Tptr>
     static void invoke(Archive & ar, Tptr & t){
+ load(ar, *t);
         const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t);
         const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
             * reinterpret_cast<void **>(&t),
@@ -486,8 +491,9 @@
     }
 };
 
-template<class Archive, class T>
+template<class Archive>
 struct load_enum_type {
+ template<class T>
     static void invoke(Archive &ar, T &t){
         // convert integers to correct enum to load
         int i;
@@ -496,8 +502,9 @@
     }
 };
 
-template<class Archive, class T>
+template<class Archive>
 struct load_array_type {
+ template<class T>
     static void invoke(Archive &ar, T &t){
         typedef BOOST_DEDUCED_TYPENAME remove_extent<T>::type value_type;
         
@@ -524,33 +531,35 @@
 } // detail
 
 template<class Archive, class T>
-inline void load(Archive &ar, T &t){
+inline void load(Archive & ar, T &t){
     // if this assertion trips. It means we're trying to load a
     // const object with a compiler that doesn't have correct
     // funtion template ordering. On other compilers, this is
     // handled below.
- BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
+ detail::check_const_loading<T>();
     typedef
         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,
- mpl::identity<detail::load_pointer_type<Archive, T> >
+ mpl::identity<detail::load_pointer_type<Archive> >
         ,//else
         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,
- mpl::identity<detail::load_array_type<Archive, T> >
+ mpl::identity<detail::load_array_type<Archive> >
         ,//else
         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,
- mpl::identity<detail::load_enum_type<Archive, T> >
+ mpl::identity<detail::load_enum_type<Archive> >
         ,//else
- mpl::identity<detail::load_non_pointer_type<Archive, T> >
+ mpl::identity<detail::load_non_pointer_type<Archive> >
>
>
>::type typex;
     typex::invoke(ar, t);
 }
 
+#if 0
+
 // BORLAND
 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
 // borland has a couple of problems
-// a) if function is partiall specialized - see below
+// a) if function is partially specialized - see below
 // const paramters are transformed to non-const ones
 // b) implementation of base_object can't be made to work
 // correctly which results in all base_object s being const.
@@ -577,6 +586,8 @@
 #endif
 #endif
 
+#endif
+
 } // namespace archive
 } // namespace boost
 

Modified: trunk/boost/archive/detail/oserializer.hpp
==============================================================================
--- trunk/boost/archive/detail/oserializer.hpp (original)
+++ trunk/boost/archive/detail/oserializer.hpp 2009-09-15 16:12:47 EDT (Tue, 15 Sep 2009)
@@ -59,12 +59,12 @@
 #include <boost/serialization/collection_size_type.hpp>
 #include <boost/serialization/singleton.hpp>
 
-// the following is need only for dynamic cast of polymorphic pointers
 #include <boost/archive/archive_exception.hpp>
 #include <boost/archive/detail/basic_oarchive.hpp>
 #include <boost/archive/detail/basic_oserializer.hpp>
 #include <boost/archive/detail/basic_pointer_oserializer.hpp>
 #include <boost/archive/detail/archive_serializer_map.hpp>
+#include <boost/archive/detail/check.hpp>
 
 namespace boost {
 
@@ -204,17 +204,19 @@
     archive_serializer_map<Archive>::erase(this);
 }
 
-template<class Archive, class T>
+template<class Archive>
 struct save_non_pointer_type {
     // note this bounces the call right back to the archive
     // with no runtime overhead
     struct save_primitive {
+ template<class T>
         static void invoke(Archive & ar, const T & t){
             save_access::save_primitive(ar, t);
         }
     };
     // same as above but passes through serialization
     struct save_only {
+ template<class T>
         static void invoke(Archive & ar, const T & t){
             // make sure call is routed through the highest interface that might
             // be specialized by the user.
@@ -228,6 +230,7 @@
     // adds class information to the archive. This includes
     // serialization level and class version
     struct save_standard {
+ template<class T>
         static void invoke(Archive &ar, const T & t){
             ar.save_object(
                 & t,
@@ -241,6 +244,7 @@
     // adds class information to the archive. This includes
     // serialization level and class version
     struct save_conditional {
+ template<class T>
         static void invoke(Archive &ar, const T &t){
             //if(0 == (ar.get_flags() & no_tracking))
                 save_standard::invoke(ar, t);
@@ -249,58 +253,55 @@
         }
     };
 
- typedef
- BOOST_DEDUCED_TYPENAME mpl::eval_if<
- // if its primitive
- mpl::equal_to<
- boost::serialization::implementation_level<T>,
- mpl::int_<boost::serialization::primitive_type>
- >,
- mpl::identity<save_primitive>,
- // else
- BOOST_DEDUCED_TYPENAME mpl::eval_if<
- // class info / version
- mpl::greater_equal<
- boost::serialization::implementation_level<T>,
- mpl::int_<boost::serialization::object_class_info>
- >,
- // do standard save
- mpl::identity<save_standard>,
- // else
- BOOST_DEDUCED_TYPENAME mpl::eval_if<
- // no tracking
- mpl::equal_to<
- boost::serialization::tracking_level<T>,
- mpl::int_<boost::serialization::track_never>
- >,
- // do a fast save
- mpl::identity<save_only>,
- // else
- // do a fast save only tracking is turned off
- mpl::identity<save_conditional>
- > > >::type typex;
 
+ template<class T>
     static void invoke(Archive & ar, const T & t){
- // check that we're not trying to serialize something that
- // has been marked not to be serialized. If this your program
- // traps here, you've tried to serialize a class whose trait
- // has been marked "non-serializable". Either reset the trait
- // (see level.hpp) or change program not to serialize items of this class
- BOOST_STATIC_ASSERT((
- mpl::greater_equal<
- boost::serialization::implementation_level<T>,
- mpl::int_<boost::serialization::primitive_type>
- >::value
- ));
+ typedef
+ BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ // if its primitive
+ mpl::equal_to<
+ boost::serialization::implementation_level<T>,
+ mpl::int_<boost::serialization::primitive_type>
+ >,
+ mpl::identity<save_primitive>,
+ // else
+ BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ // class info / version
+ mpl::greater_equal<
+ boost::serialization::implementation_level<T>,
+ mpl::int_<boost::serialization::object_class_info>
+ >,
+ // do standard save
+ mpl::identity<save_standard>,
+ // else
+ BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ // no tracking
+ mpl::equal_to<
+ boost::serialization::tracking_level<T>,
+ mpl::int_<boost::serialization::track_never>
+ >,
+ // do a fast save
+ mpl::identity<save_only>,
+ // else
+ // do a fast save only tracking is turned off
+ mpl::identity<save_conditional>
+ > > >::type typex;
+ check_object_versioning<T>();
         typex::invoke(ar, t);
     };
+ template<class T>
+ static void invoke(Archive & ar, T & t){
+ check_object_level<T>();
+ check_object_tracking<T>();
+ invoke(ar, const_cast<const T &>(t));
+ };
 };
 
-template<class Archive, class TPtr>
+template<class Archive>
 struct save_pointer_type {
- template<class T>
     struct abstract
     {
+ template<class T>
         static const basic_pointer_oserializer * register_type(Archive & /* ar */){
             // it has? to be polymorphic
             BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);
@@ -308,9 +309,9 @@
         }
     };
 
- template<class T>
     struct non_abstract
     {
+ template<class T>
         static const basic_pointer_oserializer * register_type(Archive & ar){
             return ar.register_type(static_cast<T *>(NULL));
         }
@@ -325,15 +326,15 @@
         typedef
             BOOST_DEDUCED_TYPENAME mpl::eval_if<
                 boost::serialization::is_abstract<T>,
- mpl::identity<abstract<T> >,
- mpl::identity<non_abstract<T> >
+ mpl::identity<abstract>,
+ mpl::identity<non_abstract>
>::type typex;
- return typex::register_type(ar);
+ return typex::template register_type<T>(ar);
     }
 
- template<class T>
     struct non_polymorphic
     {
+ template<class T>
         static void save(
             Archive &ar,
             T & t
@@ -347,9 +348,9 @@
         }
     };
 
- template<class T>
     struct polymorphic
     {
+ template<class T>
         static void save(
             Archive &ar,
             T & t
@@ -426,48 +427,22 @@
         }
     };
 
- // out of line selector works around borland quirk
- template<class T>
- struct conditional {
- typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
- is_polymorphic<T>,
- mpl::identity<polymorphic<T> >,
- mpl::identity<non_polymorphic<T> >
- >::type type;
- };
-
- // used to convert TPtr in to a pointer to a T
     template<class T>
     static void save(
         Archive & ar,
         const T & t
     ){
- // if your application trips the warning it means that
- // you've invoked the following combination of events.
- // a) This type doesn't save class information in the
- // archive. That is, the serialization trait implementation
- // level <= object_serializable.
- // b) Tracking for this type is set to "track selectively"
-
- // in this case, indication that an object is tracked is
- // not stored in the archive itself - see level == object_serializable
- // but rather the existence of the operation ar >> T * is used to
- // infer that an object of this type should be tracked. So, if
- // you save via a pointer but don't load via a pointer the operation
- // will fail on load without given any valid reason for the failure.
-
- // The reason that this is permited it all is that it is results
- // in more efficient code. But it comes with it's own risk.
-
-// BOOST_STATIC_WARNING(warning_check<T>::value);
- conditional<T>::type::save(ar, const_cast<T &>(t));
- }
-
- template<class T>
- static void const_check(T & t){
- BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
+ check_pointer_level<T>();
+ check_pointer_tracking<T>();
+ typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
+ is_polymorphic<T>,
+ mpl::identity<polymorphic>,
+ mpl::identity<non_polymorphic>
+ >::type type;
+ type::save(ar, const_cast<T &>(t));
     }
 
+ template<class TPtr>
     static void invoke(Archive &ar, const TPtr t){
         register_type(ar, * t);
         if(NULL == t){
@@ -481,9 +456,10 @@
     };
 };
 
-template<class Archive, class T>
+template<class Archive>
 struct save_enum_type
 {
+ template<class T>
     static void invoke(Archive &ar, const T &t){
         // convert enum to integers on save
         const int i = static_cast<int>(t);
@@ -491,9 +467,10 @@
     }
 };
 
-template<class Archive, class T>
+template<class Archive>
 struct save_array_type
 {
+ template<class T>
     static void invoke(Archive &ar, const T &t){
         typedef BOOST_DEDUCED_TYPENAME boost::remove_extent<T>::type value_type;
         
@@ -512,59 +489,24 @@
 } // detail
 
 template<class Archive, class T>
-inline void save(Archive & ar, const T &t){
+inline void save(Archive & ar, /*const*/ T &t){
     typedef
         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,
- mpl::identity<detail::save_pointer_type<Archive, T> >,
+ mpl::identity<detail::save_pointer_type<Archive> >,
         //else
         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,
- mpl::identity<detail::save_enum_type<Archive, T> >,
+ mpl::identity<detail::save_enum_type<Archive> >,
         //else
         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,
- mpl::identity<detail::save_array_type<Archive, T> >,
+ mpl::identity<detail::save_array_type<Archive> >,
         //else
- mpl::identity<detail::save_non_pointer_type<Archive, T> >
+ mpl::identity<detail::save_non_pointer_type<Archive> >
>
>
>::type typex;
     typex::invoke(ar, t);
 }
 
-#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
-
-template<class T>
-struct check_tracking {
- typedef BOOST_DEDUCED_TYPENAME mpl::if_<
- // if its never tracked.
- BOOST_DEDUCED_TYPENAME mpl::equal_to<
- serialization::tracking_level<T>,
- mpl::int_<serialization::track_never>
- >,
- // it better not be a pointer
- mpl::not_<is_pointer<T> >,
- //else
- // otherwise if it might be tracked. So there shouldn't
- // be any problem making a const
- is_const<T>
- >::type typex;
- BOOST_STATIC_CONSTANT(bool, value = typex::value);
-};
-
-template<class Archive, class T>
-inline void save(Archive & ar, T &t){
- // if your program traps here, it indicates that your doing one of the following:
- // a) serializing an object of a type marked "track_never" through a pointer.
- // b) saving an non-const object of a type not markd "track_never)
- // Either of these conditions may be an indicator of an error usage of the
- // serialization library and should be double checked. See documentation on
- // object tracking. Also, see the "rationale" section of the documenation
- // for motivation for this checking.
- BOOST_STATIC_WARNING(check_tracking<T>::value);
- save(ar, const_cast<const T &>(t));
-}
-
-#endif
-
 } // namespace archive
 } // namespace boost
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk