Collage  0.6.1
dataOStreamArchive.ipp
00001 
00002 /* Copyright (c) 2012, Daniel Nachbaur <danielnachbaur@googlemail.com>
00003  * This library is free software; you can redistribute it and/or modify it under
00004  * the terms of the GNU Lesser General Public License version 2.1 as published
00005  * by the Free Software Foundation.
00006  *
00007  * This library is distributed in the hope that it will be useful, but WITHOUT
00008  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00010  * details.
00011  *
00012  * You should have received a copy of the GNU Lesser General Public License
00013  * along with this library; if not, write to the Free Software Foundation, Inc.,
00014  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00015  */
00016 
00017 
00018 template< typename T >
00019 void DataOStreamArchive::save_array( const boost::serialization::array< T >& a,
00020                                      unsigned int )
00021 {
00022     save_binary( a.address(), a.count() * sizeof( T ));
00023 }
00024 
00025 template< class C, class T, class A >
00026 void DataOStreamArchive::save( const std::basic_string< C, T, A >& s )
00027 {
00028     // implementation only valid for narrow string
00029     BOOST_STATIC_ASSERT( sizeof(C) == sizeof(char));
00030     _stream << s;
00031 }
00032 
00033 template< typename T >
00034 typename boost::enable_if< boost::is_integral<T> >::type
00035 DataOStreamArchive::save( const T& t )
00036 {
00037 #if BOOST_VERSION < 104800
00038     namespace bs = boost::detail;
00039 #else
00040     namespace bs = boost::spirit::detail;
00041 #endif
00042 
00043     if( T temp = t )
00044     {
00045         // examine the number of bytes
00046         // needed to represent the number
00047         signed char size = 0;
00048         do
00049         {
00050             temp >>= CHAR_BIT;
00051             ++size;
00052         }
00053         while( temp != 0 && temp != (T) -1 );
00054 
00055         // encode the sign bit into the size
00056         _saveSignedChar( t > 0 ? size : -size );
00057         BOOST_ASSERT( t > 0 || boost::is_signed<T>::value) ;
00058 
00059         // we choose to use little endian because this way we just
00060         // save the first size bytes to the stream and skip the rest
00061         bs::store_little_endian<T, sizeof(T)>( &temp, t );
00062         save_binary( &temp, size );
00063     }
00064     else
00065         // zero optimization
00066         _saveSignedChar (0 );
00067 }
00068 
00069 template< typename T >
00070 typename boost::enable_if< boost::is_floating_point<T> >::type
00071 DataOStreamArchive::save( const T& t )
00072 {
00073     namespace fp = boost::spirit::math;
00074 
00075     typedef typename fp::detail::fp_traits<T>::type traits;
00076 
00077     // if the no_infnan flag is set we must throw here
00078     if( get_flags() & no_infnan && !fp::isfinite( t ))
00079         throw DataStreamArchiveException( t );
00080 
00081     // if you end here there are three possibilities:
00082     // 1. you're serializing a long double which is not portable
00083     // 2. you're serializing a double but have no 64 bit integer
00084     // 3. your machine is using an unknown floating point format
00085     // after reading the note above you still might decide to
00086     // deactivate this static assert and try if it works out.
00087     typename traits::bits bits;
00088     BOOST_STATIC_ASSERT( sizeof(bits) == sizeof(T));
00089     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_iec559 );
00090 
00091     // examine value closely
00092     switch( fp::fpclassify( t ))
00093     {
00094     case FP_ZERO:
00095         bits = 0;
00096         break;
00097     case FP_NAN:
00098         bits = traits::exponent | traits::mantissa;
00099         break;
00100     case FP_INFINITE:
00101         bits = traits::exponent | (t<0) * traits::sign;
00102         break;
00103     case FP_SUBNORMAL:
00104         assert( std::numeric_limits<T>::has_denorm );
00105     case FP_NORMAL:
00106         traits::get_bits(t, bits);
00107         break;
00108     default:
00109         throw DataStreamArchiveException( t );
00110     }
00111 
00112     save( bits );
00113 }
Generated on Mon Nov 26 2012 14:41:44 for Collage 0.6.1 by  doxygen 1.7.6.1