1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
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)
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
21 ////////////////////////////////////////////////////////////////////////////
24 // Data-to-string converter for std::string
25 inline std::string
data_to_string(const std::string
&data
)
30 // Data-to-string converter for std::basic_string<Ch>
32 std::string
data_to_string(const std::basic_string
<Ch
> &data
)
34 return narrow(data
.c_str());
38 struct array_to_pointer_decay
43 template<class T
, std::size_t N
>
44 struct array_to_pointer_decay
<T
[N
]>
46 typedef const T
*type
;
49 ////////////////////////////////////////////////////////////////////////////
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
60 // 4. Allow recognizing various bool strings (0, 1, true, false)
62 template<class Ch
, class T
>
65 inline bool operator()(const std::basic_string
<Ch
> &data
,
67 const std::locale
&loc
) const
69 std::basic_istringstream
<Ch
> stream(data
);
74 return stream
.eof() && !stream
.fail() && !stream
.bad();
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
91 struct extractor
<Ch
, Ch
>
93 inline bool operator()(const std::basic_string
<Ch
> &data
,
95 const std::locale
&loc
) const
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
);
120 if (stream
.eof() && !stream
.fail() && !stream
.bad())
122 extracted
= static_cast<signed char>(tmp
);
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
);
143 if (stream
.eof() && !stream
.fail() && !stream
.bad())
145 extracted
= static_cast<unsigned char>(tmp
);
154 struct extractor
<Ch
, bool>
156 inline bool operator()(const std::basic_string
<Ch
> &data
,
158 const std::locale
&loc
) const
160 std::basic_istringstream
<Ch
> stream(data
);
163 stream
>> std::boolalpha
>> tmp
;
166 if (stream
.eof() && !stream
.fail() && !stream
.bad())
173 std::basic_istringstream
<Ch
> stream2(data
);
179 if (stream2
.eof() && !stream2
.fail() && !stream2
.bad())
189 ////////////////////////////////////////////////////////////////////////////
192 template<class Ch
, class T
>
195 inline bool operator()(std::basic_string
<Ch
> &data
,
197 const std::locale
&loc
) const
199 typedef typename
detail::array_to_pointer_decay
<T
>::type T2
;
200 std::basic_ostringstream
<Ch
> stream
;
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
;
207 return !stream
.fail() && !stream
.bad();
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
);
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
);
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
247 inline translator::translator()
251 inline translator::translator(const std::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
);