fix doc example typo
[boost.git] / boost / property_tree / detail / translator_implementation.hpp
blobfbf9d7362508c1f5f763387937505d3ec3ca883e
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
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 #ifndef BOOST_PROPERTY_TREE_DETAIL_TRANSLATOR_IMPLEMENTATION_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_DETAIL_TRANSLATOR_IMPLEMENTATION_HPP_INCLUDED
13 #include <boost/limits.hpp>
15 namespace boost { namespace property_tree
18 namespace detail
21 ////////////////////////////////////////////////////////////////////////////
22 // Helpers
24 // Data-to-string converter for std::string
25 inline std::string data_to_string(const std::string &data)
27 return data;
30 // Data-to-string converter for std::basic_string<Ch>
31 template<class Ch>
32 std::string data_to_string(const std::basic_string<Ch> &data)
34 return narrow(data.c_str());
37 template<class T>
38 struct array_to_pointer_decay
40 typedef T type;
43 template<class T, std::size_t N>
44 struct array_to_pointer_decay<T[N]>
46 typedef const T *type;
49 ////////////////////////////////////////////////////////////////////////////
50 // Extractor
52 // Various specializations of extractors and inserters are provided to:
53 // 1. Optimize use of strings by copying them directly instead through stringstream
54 // 2. Optimize use of native char (i.e the same char as used by data string) by copying
55 // it directly instead of through stringstream
56 // 3. Treat signed and unsigned chars as integers, not as characters, i.e.
57 // pt.put_value(signed char(65)) produces data equal to "65", instead of "A".
58 // Only plain char is treated as a character type, i.e pt.put_value(char(65)) will
59 // produce "A"
60 // 4. Allow recognizing various bool strings (0, 1, true, false)
62 template<class Ch, class T>
63 struct extractor
65 inline bool operator()(const std::basic_string<Ch> &data,
66 T &extracted,
67 const std::locale &loc) const
69 std::basic_istringstream<Ch> stream(data);
70 stream.imbue(loc);
71 stream >> extracted;
72 if (!stream.eof())
73 stream >> std::ws;
74 return stream.eof() && !stream.fail() && !stream.bad();
78 template<class Ch>
79 struct extractor<Ch, std::basic_string<Ch> >
81 inline bool operator()(const std::basic_string<Ch> &data,
82 std::basic_string<Ch> &extracted,
83 const std::locale &loc) const
85 extracted = data;
86 return true;
90 template<class Ch>
91 struct extractor<Ch, Ch>
93 inline bool operator()(const std::basic_string<Ch> &data,
94 Ch &extracted,
95 const std::locale &loc) const
97 if (data.size() == 1)
99 extracted = data[0];
100 return true;
102 else
103 return false;
107 template<class Ch>
108 struct extractor<Ch, signed char>
110 inline bool operator()(const std::basic_string<Ch> &data,
111 signed char &extracted,
112 const std::locale &loc) const
114 std::basic_istringstream<Ch> stream(data);
115 stream.imbue(loc);
116 int tmp;
117 stream >> tmp;
118 if (!stream.eof())
119 stream >> std::ws;
120 if (stream.eof() && !stream.fail() && !stream.bad())
122 extracted = static_cast<signed char>(tmp);
123 return true;
125 else
126 return false;
130 template<class Ch>
131 struct extractor<Ch, unsigned char>
133 inline bool operator()(const std::basic_string<Ch> &data,
134 unsigned char &extracted,
135 const std::locale &loc) const
137 std::basic_istringstream<Ch> stream(data);
138 stream.imbue(loc);
139 unsigned int tmp;
140 stream >> tmp;
141 if (!stream.eof())
142 stream >> std::ws;
143 if (stream.eof() && !stream.fail() && !stream.bad())
145 extracted = static_cast<unsigned char>(tmp);
146 return true;
148 else
149 return false;
153 template<class Ch>
154 struct extractor<Ch, bool>
156 inline bool operator()(const std::basic_string<Ch> &data,
157 bool &extracted,
158 const std::locale &loc) const
160 std::basic_istringstream<Ch> stream(data);
161 stream.imbue(loc);
162 bool tmp;
163 stream >> std::boolalpha >> tmp;
164 if (!stream.eof())
165 stream >> std::ws;
166 if (stream.eof() && !stream.fail() && !stream.bad())
168 extracted = tmp;
169 return true;
171 else
173 std::basic_istringstream<Ch> stream2(data);
174 stream2.imbue(loc);
175 bool tmp;
176 stream2 >> tmp;
177 if (!stream2.eof())
178 stream >> std::ws;
179 if (stream2.eof() && !stream2.fail() && !stream2.bad())
181 extracted = tmp;
182 return true;
185 return false;
189 ////////////////////////////////////////////////////////////////////////////
190 // Inserter
192 template<class Ch, class T>
193 struct inserter
195 inline bool operator()(std::basic_string<Ch> &data,
196 const T &to_insert,
197 const std::locale &loc) const
199 typedef typename detail::array_to_pointer_decay<T>::type T2;
200 std::basic_ostringstream<Ch> stream;
201 stream.imbue(loc);
202 if (std::numeric_limits<T2>::is_specialized
203 && !std::numeric_limits<T2>::is_exact)
204 stream.precision(std::numeric_limits<T2>::digits10 + 1);
205 stream << std::boolalpha << to_insert;
206 data = stream.str();
207 return !stream.fail() && !stream.bad();
211 template<class Ch>
212 struct inserter<Ch, signed char>
214 inline bool operator()(std::basic_string<Ch> &data,
215 const signed char &to_insert,
216 const std::locale &loc) const
218 return detail::inserter<Ch, int>()(data, static_cast<int>(to_insert), loc);
222 template<class Ch>
223 struct inserter<Ch, unsigned char>
225 inline bool operator()(std::basic_string<Ch> &data,
226 const unsigned char &to_insert,
227 const std::locale &loc) const
229 return detail::inserter<Ch, unsigned int>()(data, static_cast<unsigned int>(to_insert), loc);
233 template<class Ch>
234 struct inserter<Ch, std::basic_string<Ch> >
236 inline bool operator()(std::basic_string<Ch> &data,
237 const std::basic_string<Ch> &to_insert,
238 const std::locale &loc) const
240 data = to_insert;
241 return true;
247 inline translator::translator()
251 inline translator::translator(const std::locale &loc):
252 m_locale(loc)
256 template<class Ptree, class T>
257 bool translator::get_value(const Ptree &pt, T &value) const
259 typedef typename Ptree::data_type::value_type Ch;
260 return detail::extractor<Ch, T>()(pt.data(), value, m_locale);
263 template<class Ptree, class T>
264 bool translator::put_value(Ptree &pt, const T &value) const
267 typedef typename Ptree::data_type::value_type Ch;
269 // Make sure that no pointer other than char_type * is allowed
270 BOOST_STATIC_ASSERT((is_pointer<T>::value == false ||
271 is_same<Ch, typename remove_const<typename remove_pointer<T>::type>::type>::value == true));
273 return detail::inserter<Ch, T>()(pt.data(), value, m_locale);
279 #endif