Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:58:10

0001 // ----------------------------------------------------------------------------
0002 // Copyright (C) 2009 Sebastian Redl
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. 
0005 // (See accompanying file LICENSE_1_0.txt or copy at 
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // For more information, see www.boost.org
0009 // ----------------------------------------------------------------------------
0010 
0011 #ifndef BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
0012 #define BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
0013 
0014 #include <boost/property_tree/ptree_fwd.hpp>
0015 
0016 #include <boost/optional/optional.hpp>
0017 #include <boost/optional/optional_io.hpp>
0018 #include <boost/core/enable_if.hpp>
0019 #include <boost/type_traits/decay.hpp>
0020 #include <boost/type_traits/integral_constant.hpp>
0021 #include <sstream>
0022 #include <string>
0023 #include <locale>
0024 #include <limits>
0025 
0026 namespace boost { namespace property_tree
0027 {
0028 
0029     template <typename Ch, typename Traits, typename E, typename Enabler = void>
0030     struct customize_stream
0031     {
0032         static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
0033             s << e;
0034         }
0035         static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
0036             s >> e;
0037             if(!s.eof()) {
0038                 s >> std::ws;
0039             }
0040         }
0041     };
0042 
0043     // No whitespace skipping for single characters.
0044     template <typename Ch, typename Traits>
0045     struct customize_stream<Ch, Traits, Ch, void>
0046     {
0047         static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) {
0048             s << e;
0049         }
0050         static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) {
0051             s.unsetf(std::ios_base::skipws);
0052             s >> e;
0053         }
0054     };
0055 
0056     // Ugly workaround for numeric_traits that don't have members when not
0057     // specialized, e.g. MSVC.
0058     namespace detail
0059     {
0060         template <bool is_specialized>
0061         struct is_inexact_impl
0062         {
0063             template <typename T>
0064             struct test
0065             {
0066                 typedef boost::false_type type;
0067             };
0068         };
0069         template <>
0070         struct is_inexact_impl<true>
0071         {
0072             template <typename T>
0073             struct test
0074             {
0075               typedef boost::integral_constant<bool,
0076                   !std::numeric_limits<T>::is_exact> type;
0077             };
0078         };
0079 
0080         template <typename F>
0081         struct is_inexact
0082         {
0083             typedef typename boost::decay<F>::type decayed;
0084             typedef typename is_inexact_impl<
0085                 std::numeric_limits<decayed>::is_specialized
0086             >::BOOST_NESTED_TEMPLATE test<decayed>::type type;
0087             static const bool value = type::value;
0088         };
0089     }
0090 
0091     template <typename Ch, typename Traits, typename F>
0092     struct customize_stream<Ch, Traits, F,
0093         typename boost::enable_if< detail::is_inexact<F> >::type
0094     >
0095     {
0096         static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) {
0097 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS 
0098             s.precision(std::numeric_limits<F>::max_digits10); 
0099 #else 
0100             s.precision(std::numeric_limits<F>::digits10 + 2); 
0101 #endif 
0102             s << e;
0103         }
0104         static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
0105             s >> e;
0106             if(!s.eof()) {
0107                 s >> std::ws;
0108             }
0109         }
0110     };
0111 
0112     template <typename Ch, typename Traits>
0113     struct customize_stream<Ch, Traits, bool, void>
0114     {
0115         static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
0116             s.setf(std::ios_base::boolalpha);
0117             s << e;
0118         }
0119         static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
0120             s >> e;
0121             if(s.fail()) {
0122                 // Try again in word form.
0123                 s.clear();
0124                 s.setf(std::ios_base::boolalpha);
0125                 s >> e;
0126             }
0127             if(!s.eof()) {
0128                 s >> std::ws;
0129             }
0130         }
0131     };
0132 
0133     template <typename Ch, typename Traits>
0134     struct customize_stream<Ch, Traits, signed char, void>
0135     {
0136         static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
0137             s << (int)e;
0138         }
0139         static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
0140             int i;
0141             s >> i;
0142             // out of range?
0143             if(i > (std::numeric_limits<signed char>::max)() ||
0144                 i < (std::numeric_limits<signed char>::min)())
0145             {
0146                 s.clear(); // guarantees eof to be unset
0147                 e = 0;
0148                 s.setstate(std::ios_base::badbit);
0149                 return;
0150             }
0151             e = (signed char)i;
0152             if(!s.eof()) {
0153                 s >> std::ws;
0154             }
0155         }
0156     };
0157 
0158     template <typename Ch, typename Traits>
0159     struct customize_stream<Ch, Traits, unsigned char, void>
0160     {
0161         static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
0162             s << (unsigned)e;
0163         }
0164         static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
0165             unsigned i;
0166             s >> i;
0167             // out of range?
0168             if(i > (std::numeric_limits<unsigned char>::max)()) {
0169                 s.clear(); // guarantees eof to be unset
0170                 e = 0;
0171                 s.setstate(std::ios_base::badbit);
0172                 return;
0173             }
0174             e = (unsigned char)i;
0175             if(!s.eof()) {
0176                 s >> std::ws;
0177             }
0178         }
0179     };
0180 
0181     /// Implementation of Translator that uses the stream overloads.
0182     template <typename Ch, typename Traits, typename Alloc, typename E>
0183     class stream_translator
0184     {
0185         typedef customize_stream<Ch, Traits, E> customized;
0186     public:
0187         typedef std::basic_string<Ch, Traits, Alloc> internal_type;
0188         typedef E external_type;
0189 
0190         explicit stream_translator(std::locale loc = std::locale())
0191             : m_loc(loc)
0192         {}
0193 
0194         boost::optional<E> get_value(const internal_type &v) {
0195             std::basic_istringstream<Ch, Traits, Alloc> iss(v);
0196             iss.imbue(m_loc);
0197             E e;
0198             customized::extract(iss, e);
0199             if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
0200                 return boost::optional<E>();
0201             }
0202             return e;
0203         }
0204         boost::optional<internal_type> put_value(const E &v) {
0205             std::basic_ostringstream<Ch, Traits, Alloc> oss;
0206             oss.imbue(m_loc);
0207             customized::insert(oss, v);
0208             if(oss) {
0209                 return oss.str();
0210             }
0211             return boost::optional<internal_type>();
0212         }
0213 
0214     private:
0215         std::locale m_loc;
0216     };
0217 
0218     // This is the default translator when basic_string is the internal type.
0219     // Unless the external type is also basic_string, in which case
0220     // id_translator takes over.
0221     template <typename Ch, typename Traits, typename Alloc, typename E>
0222     struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
0223     {
0224         typedef stream_translator<Ch, Traits, Alloc, E> type;
0225     };
0226 
0227 }}
0228 
0229 #endif