Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:30

0001 #ifndef BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP
0002 #define BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP
0003 
0004 // MS compatible compilers support #pragma once
0005 #if defined(_MSC_VER)
0006 # pragma once
0007 #endif
0008 
0009 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
0010 // basic_text_oprimitive.hpp
0011 
0012 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
0013 // Use, modification and distribution is subject to the Boost Software
0014 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0015 // http://www.boost.org/LICENSE_1_0.txt)
0016 
0017 //  See http://www.boost.org for updates, documentation, and revision history.
0018 
0019 // archives stored as text - note these ar templated on the basic
0020 // stream templates to accommodate wide (and other?) kind of characters
0021 //
0022 // note the fact that on libraries without wide characters, ostream is
0023 // is not a specialization of basic_ostream which in fact is not defined
0024 // in such cases.   So we can't use basic_ostream<OStream::char_type> but rather
0025 // use two template parameters
0026 
0027 #include <iomanip>
0028 #include <locale>
0029 #include <cstddef> // size_t
0030 
0031 #include <boost/config.hpp>
0032 #include <boost/static_assert.hpp>
0033 #include <boost/io/ios_state.hpp>
0034 
0035 #include <boost/detail/workaround.hpp>
0036 #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
0037 #include <boost/archive/dinkumware.hpp>
0038 #endif
0039 
0040 #if defined(BOOST_NO_STDC_NAMESPACE)
0041 namespace std{
0042     using ::size_t;
0043     #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT)
0044         using ::locale;
0045     #endif
0046 } // namespace std
0047 #endif
0048 
0049 #include <boost/type_traits/is_floating_point.hpp>
0050 #include <boost/mpl/bool.hpp>
0051 #include <boost/limits.hpp>
0052 #include <boost/integer.hpp>
0053 #include <boost/io/ios_state.hpp>
0054 #include <boost/serialization/throw_exception.hpp>
0055 #include <boost/archive/basic_streambuf_locale_saver.hpp>
0056 #include <boost/archive/codecvt_null.hpp>
0057 #include <boost/archive/archive_exception.hpp>
0058 #include <boost/archive/detail/abi_prefix.hpp> // must be the last header
0059 
0060 namespace boost {
0061 namespace archive {
0062 
0063 /////////////////////////////////////////////////////////////////////////
0064 // class basic_text_oprimitive - output of primitives to stream
0065 template<class OStream>
0066 class BOOST_SYMBOL_VISIBLE basic_text_oprimitive
0067 {
0068 protected:
0069     OStream &os;
0070     io::ios_flags_saver flags_saver;
0071     io::ios_precision_saver precision_saver;
0072 
0073     #ifndef BOOST_NO_STD_LOCALE
0074     // note order! - if you change this, libstd++ will fail!
0075     // a) create new locale with new codecvt facet
0076     // b) save current locale
0077     // c) change locale to new one
0078     // d) use stream buffer
0079     // e) change locale back to original
0080     // f) destroy new codecvt facet
0081     boost::archive::codecvt_null<typename OStream::char_type> codecvt_null_facet;
0082     std::locale archive_locale;
0083     basic_ostream_locale_saver<
0084         typename OStream::char_type,
0085         typename OStream::traits_type
0086     > locale_saver;
0087     #endif
0088 
0089     /////////////////////////////////////////////////////////
0090     // fundamental types that need special treatment
0091     void save(const bool t){
0092         // trap usage of invalid uninitialized boolean which would
0093         // otherwise crash on load.
0094         BOOST_ASSERT(0 == static_cast<int>(t) || 1 == static_cast<int>(t));
0095         if(os.fail())
0096             boost::serialization::throw_exception(
0097                 archive_exception(archive_exception::output_stream_error)
0098             );
0099         os << t;
0100     }
0101     void save(const signed char t)
0102     {
0103         save(static_cast<short int>(t));
0104     }
0105     void save(const unsigned char t)
0106     {
0107         save(static_cast<short unsigned int>(t));
0108     }
0109     void save(const char t)
0110     {
0111         save(static_cast<short int>(t));
0112     }
0113     #ifndef BOOST_NO_INTRINSIC_WCHAR_T
0114     void save(const wchar_t t)
0115     {
0116         BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int));
0117         save(static_cast<int>(t));
0118     }
0119     #endif
0120 
0121     /////////////////////////////////////////////////////////
0122     // saving of any types not listed above
0123 
0124     template<class T>
0125     void save_impl(const T &t, boost::mpl::bool_<false> &){
0126         if(os.fail())
0127             boost::serialization::throw_exception(
0128                 archive_exception(archive_exception::output_stream_error)
0129             );
0130         os << t;
0131     }
0132 
0133     /////////////////////////////////////////////////////////
0134     // floating point types need even more special treatment
0135     // the following determines whether the type T is some sort
0136     // of floating point type.  Note that we then assume that
0137     // the stream << operator is defined on that type - if not
0138     // we'll get a compile time error. This is meant to automatically
0139     // support synthesized types which support floating point
0140     // operations. Also it should handle compiler dependent types
0141     // such long double.  Due to John Maddock.
0142 
0143     template<class T>
0144     struct is_float {
0145         typedef typename mpl::bool_<
0146             boost::is_floating_point<T>::value
0147             || (std::numeric_limits<T>::is_specialized
0148             && !std::numeric_limits<T>::is_integer
0149             && !std::numeric_limits<T>::is_exact
0150             && std::numeric_limits<T>::max_exponent)
0151         >::type type;
0152     };
0153 
0154     template<class T>
0155     void save_impl(const T &t, boost::mpl::bool_<true> &){
0156         // must be a user mistake - can't serialize un-initialized data
0157         if(os.fail()){
0158             boost::serialization::throw_exception(
0159                 archive_exception(archive_exception::output_stream_error)
0160             );
0161         }
0162         // The formulae for the number of decimal digits required is given in
0163         // http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf
0164         // which is derived from Kahan's paper:
0165         // www.eecs.berkeley.edu/~wkahan/ieee754status/ieee754.ps
0166         // const unsigned int digits = (std::numeric_limits<T>::digits * 3010) / 10000;
0167         // note: I've commented out the above because I didn't get good results.  e.g.
0168         // in one case I got a difference of 19 units.
0169         const unsigned int digits =
0170         #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
0171             std::numeric_limits<T>::max_digits10;
0172         #else
0173             std::numeric_limits<T>::digits10 + 2;
0174         #endif
0175         os << std::setprecision(digits) << std::scientific << t;
0176     }
0177 
0178     template<class T>
0179     void save(const T & t){
0180         typename is_float<T>::type tf;
0181         save_impl(t, tf);
0182     }
0183 
0184     BOOST_ARCHIVE_OR_WARCHIVE_DECL
0185     basic_text_oprimitive(OStream & os, bool no_codecvt);
0186     BOOST_ARCHIVE_OR_WARCHIVE_DECL
0187     ~basic_text_oprimitive();
0188 public:
0189     // unformatted append of one character
0190     void put(typename OStream::char_type c){
0191         if(os.fail())
0192             boost::serialization::throw_exception(
0193                 archive_exception(archive_exception::output_stream_error)
0194             );
0195         os.put(c);
0196     }
0197     // unformatted append of null terminated string
0198     void put(const char * s){
0199         while('\0' != *s)
0200             os.put(*s++);
0201     }
0202     BOOST_ARCHIVE_OR_WARCHIVE_DECL void
0203     save_binary(const void *address, std::size_t count);
0204 };
0205 
0206 } //namespace boost
0207 } //namespace archive
0208 
0209 #include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
0210 
0211 #endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP