]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/property_tree/stream_translator.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / property_tree / stream_translator.hpp
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
26 namespace 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 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
98 s.precision(std::numeric_limits<F>::max_digits10);
99 #else
100 s.precision(std::numeric_limits<F>::digits10 + 2);
101 #endif
102 s << e;
103 }
104 static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
105 s >> e;
106 if(!s.eof()) {
107 s >> std::ws;
108 }
109 }
110 };
111
112 template <typename Ch, typename Traits>
113 struct customize_stream<Ch, Traits, bool, void>
114 {
115 static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
116 s.setf(std::ios_base::boolalpha);
117 s << e;
118 }
119 static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
120 s >> e;
121 if(s.fail()) {
122 // Try again in word form.
123 s.clear();
124 s.setf(std::ios_base::boolalpha);
125 s >> e;
126 }
127 if(!s.eof()) {
128 s >> std::ws;
129 }
130 }
131 };
132
133 template <typename Ch, typename Traits>
134 struct customize_stream<Ch, Traits, signed char, void>
135 {
136 static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
137 s << (int)e;
138 }
139 static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
140 int i;
141 s >> i;
142 // out of range?
143 if(i > (std::numeric_limits<signed char>::max)() ||
144 i < (std::numeric_limits<signed char>::min)())
145 {
146 s.clear(); // guarantees eof to be unset
147 e = 0;
148 s.setstate(std::ios_base::badbit);
149 return;
150 }
151 e = (signed char)i;
152 if(!s.eof()) {
153 s >> std::ws;
154 }
155 }
156 };
157
158 template <typename Ch, typename Traits>
159 struct customize_stream<Ch, Traits, unsigned char, void>
160 {
161 static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
162 s << (unsigned)e;
163 }
164 static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
165 unsigned i;
166 s >> i;
167 // out of range?
168 if(i > (std::numeric_limits<unsigned char>::max)()) {
169 s.clear(); // guarantees eof to be unset
170 e = 0;
171 s.setstate(std::ios_base::badbit);
172 return;
173 }
174 e = (unsigned char)i;
175 if(!s.eof()) {
176 s >> std::ws;
177 }
178 }
179 };
180
181 /// Implementation of Translator that uses the stream overloads.
182 template <typename Ch, typename Traits, typename Alloc, typename E>
183 class stream_translator
184 {
185 typedef customize_stream<Ch, Traits, E> customized;
186 public:
187 typedef std::basic_string<Ch, Traits, Alloc> internal_type;
188 typedef E external_type;
189
190 explicit stream_translator(std::locale loc = std::locale())
191 : m_loc(loc)
192 {}
193
194 boost::optional<E> get_value(const internal_type &v) {
195 std::basic_istringstream<Ch, Traits, Alloc> iss(v);
196 iss.imbue(m_loc);
197 E e;
198 customized::extract(iss, e);
199 if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
200 return boost::optional<E>();
201 }
202 return e;
203 }
204 boost::optional<internal_type> put_value(const E &v) {
205 std::basic_ostringstream<Ch, Traits, Alloc> oss;
206 oss.imbue(m_loc);
207 customized::insert(oss, v);
208 if(oss) {
209 return oss.str();
210 }
211 return boost::optional<internal_type>();
212 }
213
214 private:
215 std::locale m_loc;
216 };
217
218 // This is the default translator when basic_string is the internal type.
219 // Unless the external type is also basic_string, in which case
220 // id_translator takes over.
221 template <typename Ch, typename Traits, typename Alloc, typename E>
222 struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
223 {
224 typedef stream_translator<Ch, Traits, Alloc, E> type;
225 };
226
227 }}
228
229 #endif