Collage  0.6.1
dataIStreamArchive.ipp
00001 
00002 /* Copyright (c) 2012, Daniel Nachbaur <danielnachbaur@googlemail.com>
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 
00019 template< typename T >
00020 void DataIStreamArchive::load_array( boost::serialization::array< T >& a,
00021                                      unsigned int )
00022 {
00023     load_binary( a.address(), a.count() * sizeof( T ));
00024 }
00025 
00026 template< class C, class T, class A >
00027 void DataIStreamArchive::load( std::basic_string< C, T, A >& s )
00028 {
00029     // implementation only valid for narrow string
00030     BOOST_STATIC_ASSERT( sizeof(C) == sizeof(char));
00031     _stream >> s;
00032 }
00033 
00034 template< typename T >
00035 typename boost::enable_if< boost::is_integral<T> >::type
00036 DataIStreamArchive::load( T& t )
00037 {
00038 #if BOOST_VERSION < 104800
00039     namespace bs = boost::detail;
00040 #else
00041     namespace bs = boost::spirit::detail;
00042 #endif
00043 
00044     // get the number of bytes in the stream
00045     if( signed char size = _loadSignedChar( ))
00046     {
00047         // check for negative value in unsigned type
00048         if( size < 0 && boost::is_unsigned<T>::value )
00049             throw DataStreamArchiveException();
00050 
00051         // check that our type T is large enough
00052         else if( (unsigned)abs(size) > sizeof(T))
00053             throw DataStreamArchiveException( size );
00054 
00055         // reconstruct the value
00056         T temp = size < 0 ? -1 : 0;
00057         load_binary( &temp, abs(size));
00058 
00059         // load the value from little endian - is is then converted
00060         // to the target type T and fits it because size <= sizeof(T)
00061         t = bs::load_little_endian<T, sizeof(T)>( &temp );
00062     }
00063     else
00064         // zero optimization
00065         t = 0;
00066 }
00067 
00068 template< typename T >
00069 typename boost::enable_if<boost::is_floating_point<T> >::type
00070 DataIStreamArchive::load( T& t )
00071 {
00072     namespace fp = boost::spirit::math;
00073 
00074     typedef typename fp::detail::fp_traits<T>::type traits;
00075 
00076     // if you end here there are three possibilities:
00077     // 1. you're serializing a long double which is not portable
00078     // 2. you're serializing a double but have no 64 bit integer
00079     // 3. your machine is using an unknown floating point format
00080     // after reading the note above you still might decide to
00081     // deactivate this static assert and try if it works out.
00082     typename traits::bits bits;
00083     BOOST_STATIC_ASSERT( sizeof(bits) == sizeof(T));
00084     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_iec559 );
00085 
00086     load( bits );
00087     traits::set_bits( t, bits );
00088 
00089     // if the no_infnan flag is set we must throw here
00090     if( get_flags() & no_infnan && !fp::isfinite( t ))
00091         throw DataStreamArchiveException( t );
00092 
00093     // if you end here your floating point type does not support
00094     // denormalized numbers. this might be the case even though
00095     // your type conforms to IEC 559 (and thus to IEEE 754)
00096     if( std::numeric_limits<T>::has_denorm == std::denorm_absent &&
00097         fp::fpclassify(t) == (int)FP_SUBNORMAL ) // GCC4
00098     {
00099         throw DataStreamArchiveException( t );
00100     }
00101 }
Generated on Mon Nov 26 2012 14:41:44 for Collage 0.6.1 by  doxygen 1.7.6.1