PageRenderTime 96ms CodeModel.GetById 16ms app.highlight 67ms RepoModel.GetById 6ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/property_tree/stream_translator.hpp

http://hadesmem.googlecode.com/
C++ Header | 221 lines | 183 code | 19 blank | 19 comment | 13 complexity | 5465455482a3e6fb5a6f7c0211dc5c4f MD5 | raw file
  1// ----------------------------------------------------------------------------
  2// Copyright (C) 2009 Sebastian Redl
  3//
  4// Distributed under the Boost Software License, Version 1.0. 
  5// (See accompanying file LICENSE_1_0.txt or copy at 
  6// http://www.boost.org/LICENSE_1_0.txt)
  7//
  8// For more information, see www.boost.org
  9// ----------------------------------------------------------------------------
 10
 11#ifndef BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
 12#define BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
 13
 14#include <boost/property_tree/ptree_fwd.hpp>
 15
 16#include <boost/optional.hpp>
 17#include <boost/optional/optional_io.hpp>
 18#include <boost/utility/enable_if.hpp>
 19#include <boost/type_traits/decay.hpp>
 20#include <boost/type_traits/integral_constant.hpp>
 21#include <sstream>
 22#include <string>
 23#include <locale>
 24#include <limits>
 25
 26namespace boost { namespace property_tree
 27{
 28
 29    template <typename Ch, typename Traits, typename E, typename Enabler = void>
 30    struct customize_stream
 31    {
 32        static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
 33            s << e;
 34        }
 35        static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
 36            s >> e;
 37            if(!s.eof()) {
 38                s >> std::ws;
 39            }
 40        }
 41    };
 42
 43    // No whitespace skipping for single characters.
 44    template <typename Ch, typename Traits>
 45    struct customize_stream<Ch, Traits, Ch, void>
 46    {
 47        static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) {
 48            s << e;
 49        }
 50        static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) {
 51            s.unsetf(std::ios_base::skipws);
 52            s >> e;
 53        }
 54    };
 55
 56    // Ugly workaround for numeric_traits that don't have members when not
 57    // specialized, e.g. MSVC.
 58    namespace detail
 59    {
 60        template <bool is_specialized>
 61        struct is_inexact_impl
 62        {
 63            template <typename T>
 64            struct test
 65            {
 66                typedef boost::false_type type;
 67            };
 68        };
 69        template <>
 70        struct is_inexact_impl<true>
 71        {
 72            template <typename T>
 73            struct test
 74            {
 75              typedef boost::integral_constant<bool,
 76                  !std::numeric_limits<T>::is_exact> type;
 77            };
 78        };
 79
 80        template <typename F>
 81        struct is_inexact
 82        {
 83            typedef typename boost::decay<F>::type decayed;
 84            typedef typename is_inexact_impl<
 85                std::numeric_limits<decayed>::is_specialized
 86            >::BOOST_NESTED_TEMPLATE test<decayed>::type type;
 87            static const bool value = type::value;
 88        };
 89    }
 90
 91    template <typename Ch, typename Traits, typename F>
 92    struct customize_stream<Ch, Traits, F,
 93        typename boost::enable_if< detail::is_inexact<F> >::type
 94    >
 95    {
 96        static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) {
 97            s.precision(std::numeric_limits<F>::digits10 + 1);
 98            s << e;
 99        }
100        static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
101            s >> e;
102            if(!s.eof()) {
103                s >> std::ws;
104            }
105        }
106    };
107
108    template <typename Ch, typename Traits>
109    struct customize_stream<Ch, Traits, bool, void>
110    {
111        static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
112            s.setf(std::ios_base::boolalpha);
113            s << e;
114        }
115        static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
116            s >> e;
117            if(s.fail()) {
118                // Try again in word form.
119                s.clear();
120                s.setf(std::ios_base::boolalpha);
121                s >> e;
122            }
123            if(!s.eof()) {
124                s >> std::ws;
125            }
126        }
127    };
128
129    template <typename Ch, typename Traits>
130    struct customize_stream<Ch, Traits, signed char, void>
131    {
132        static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
133            s << (int)e;
134        }
135        static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
136            int i;
137            s >> i;
138            // out of range?
139            if(i > (std::numeric_limits<signed char>::max)() ||
140                i < (std::numeric_limits<signed char>::min)())
141            {
142                s.clear(); // guarantees eof to be unset
143                return;
144            }
145            e = (signed char)i;
146            if(!s.eof()) {
147                s >> std::ws;
148            }
149        }
150    };
151
152    template <typename Ch, typename Traits>
153    struct customize_stream<Ch, Traits, unsigned char, void>
154    {
155        static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
156            s << (unsigned)e;
157        }
158        static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
159            unsigned i;
160            s >> i;
161            // out of range?
162            if(i > (std::numeric_limits<unsigned char>::max)()) {
163                s.clear(); // guarantees eof to be unset
164                return;
165            }
166            e = (unsigned char)i;
167            if(!s.eof()) {
168                s >> std::ws;
169            }
170        }
171    };
172
173    /// Implementation of Translator that uses the stream overloads.
174    template <typename Ch, typename Traits, typename Alloc, typename E>
175    class stream_translator
176    {
177        typedef customize_stream<Ch, Traits, E> customized;
178    public:
179        typedef std::basic_string<Ch, Traits, Alloc> internal_type;
180        typedef E external_type;
181
182        explicit stream_translator(std::locale loc = std::locale())
183            : m_loc(loc)
184        {}
185
186        boost::optional<E> get_value(const internal_type &v) {
187            std::basic_istringstream<Ch, Traits, Alloc> iss(v);
188            iss.imbue(m_loc);
189            E e;
190            customized::extract(iss, e);
191            if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
192                return boost::optional<E>();
193            }
194            return e;
195        }
196        boost::optional<internal_type> put_value(const E &v) {
197            std::basic_ostringstream<Ch, Traits, Alloc> oss;
198            oss.imbue(m_loc);
199            customized::insert(oss, v);
200            if(oss) {
201                return oss.str();
202            }
203            return boost::optional<internal_type>();
204        }
205
206    private:
207        std::locale m_loc;
208    };
209
210    // This is the default translator when basic_string is the internal type.
211    // Unless the external type is also basic_string, in which case
212    // id_translator takes over.
213    template <typename Ch, typename Traits, typename Alloc, typename E>
214    struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
215    {
216        typedef stream_translator<Ch, Traits, Alloc, E> type;
217    };
218
219}}
220
221#endif