File indexing completed on 2025-01-30 09:58:10
0001
0002
0003
0004
0005
0006
0007
0008
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
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
0057
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
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
0143 if(i > (std::numeric_limits<signed char>::max)() ||
0144 i < (std::numeric_limits<signed char>::min)())
0145 {
0146 s.clear();
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
0168 if(i > (std::numeric_limits<unsigned char>::max)()) {
0169 s.clear();
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
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
0219
0220
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