File indexing completed on 2025-01-18 09:39:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
0019 #define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
0020
0021 #include <boost/config.hpp>
0022 #ifdef BOOST_HAS_PRAGMA_ONCE
0023 # pragma once
0024 #endif
0025
0026 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
0027 #define BOOST_LCAST_NO_WCHAR_T
0028 #endif
0029
0030 #include <cstddef>
0031 #include <string>
0032 #include <boost/limits.hpp>
0033 #include <boost/type_traits/integral_constant.hpp>
0034 #include <boost/type_traits/type_identity.hpp>
0035 #include <boost/type_traits/conditional.hpp>
0036 #include <boost/type_traits/is_integral.hpp>
0037 #include <boost/type_traits/is_float.hpp>
0038 #include <boost/type_traits/has_left_shift.hpp>
0039 #include <boost/type_traits/has_right_shift.hpp>
0040 #include <boost/detail/lcast_precision.hpp>
0041
0042 #include <boost/lexical_cast/detail/widest_char.hpp>
0043 #include <boost/lexical_cast/detail/is_character.hpp>
0044
0045 #include <array>
0046
0047 #include <boost/lexical_cast/detail/buffer_view.hpp>
0048 #include <boost/container/container_fwd.hpp>
0049
0050 #include <boost/lexical_cast/detail/converter_lexical_streams.hpp>
0051
0052 namespace boost {
0053
0054
0055 template<class T, std::size_t N>
0056 class array;
0057 template<class IteratorT>
0058 class iterator_range;
0059
0060 namespace detail
0061 {
0062
0063 template < class Char >
0064 struct normalize_single_byte_char
0065 {
0066 typedef Char type;
0067 };
0068
0069 template <>
0070 struct normalize_single_byte_char< signed char >
0071 {
0072 typedef char type;
0073 };
0074
0075 template <>
0076 struct normalize_single_byte_char< unsigned char >
0077 {
0078 typedef char type;
0079 };
0080 }
0081
0082 namespace detail
0083 {
0084
0085
0086 template < class T > struct deduce_character_type_later {};
0087 }
0088
0089 namespace detail
0090 {
0091
0092
0093
0094 template < typename Type >
0095 struct stream_char_common: public boost::conditional<
0096 boost::detail::is_character< Type >::value,
0097 Type,
0098 boost::detail::deduce_character_type_later< Type >
0099 > {};
0100
0101 template < typename Char >
0102 struct stream_char_common< Char* >: public boost::conditional<
0103 boost::detail::is_character< Char >::value,
0104 Char,
0105 boost::detail::deduce_character_type_later< Char* >
0106 > {};
0107
0108 template < typename Char >
0109 struct stream_char_common< const Char* >: public boost::conditional<
0110 boost::detail::is_character< Char >::value,
0111 Char,
0112 boost::detail::deduce_character_type_later< const Char* >
0113 > {};
0114
0115 template < typename Char >
0116 struct stream_char_common< boost::conversion::detail::buffer_view< Char > >
0117 {
0118 typedef Char type;
0119 };
0120
0121 template < typename Char >
0122 struct stream_char_common< boost::iterator_range< Char* > >: public boost::conditional<
0123 boost::detail::is_character< Char >::value,
0124 Char,
0125 boost::detail::deduce_character_type_later< boost::iterator_range< Char* > >
0126 > {};
0127
0128 template < typename Char >
0129 struct stream_char_common< boost::iterator_range< const Char* > >: public boost::conditional<
0130 boost::detail::is_character< Char >::value,
0131 Char,
0132 boost::detail::deduce_character_type_later< boost::iterator_range< const Char* > >
0133 > {};
0134
0135 template < class Char, class Traits, class Alloc >
0136 struct stream_char_common< std::basic_string< Char, Traits, Alloc > >
0137 {
0138 typedef Char type;
0139 };
0140
0141 template < class Char, class Traits, class Alloc >
0142 struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
0143 {
0144 typedef Char type;
0145 };
0146
0147 template < typename Char, std::size_t N >
0148 struct stream_char_common< boost::array< Char, N > >: public boost::conditional<
0149 boost::detail::is_character< Char >::value,
0150 Char,
0151 boost::detail::deduce_character_type_later< boost::array< Char, N > >
0152 > {};
0153
0154 template < typename Char, std::size_t N >
0155 struct stream_char_common< boost::array< const Char, N > >: public boost::conditional<
0156 boost::detail::is_character< Char >::value,
0157 Char,
0158 boost::detail::deduce_character_type_later< boost::array< const Char, N > >
0159 > {};
0160
0161 #ifndef BOOST_NO_CXX11_HDR_ARRAY
0162 template < typename Char, std::size_t N >
0163 struct stream_char_common< std::array<Char, N > >: public boost::conditional<
0164 boost::detail::is_character< Char >::value,
0165 Char,
0166 boost::detail::deduce_character_type_later< std::array< Char, N > >
0167 > {};
0168
0169 template < typename Char, std::size_t N >
0170 struct stream_char_common< std::array< const Char, N > >: public boost::conditional<
0171 boost::detail::is_character< Char >::value,
0172 Char,
0173 boost::detail::deduce_character_type_later< std::array< const Char, N > >
0174 > {};
0175 #endif
0176
0177 #ifdef BOOST_HAS_INT128
0178 template <> struct stream_char_common< boost::int128_type >: public boost::type_identity< char > {};
0179 template <> struct stream_char_common< boost::uint128_type >: public boost::type_identity< char > {};
0180 #endif
0181
0182 #if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
0183 template <>
0184 struct stream_char_common< wchar_t >
0185 {
0186 typedef char type;
0187 };
0188 #endif
0189 }
0190
0191 namespace detail
0192 {
0193
0194
0195
0196
0197
0198 template < class Char >
0199 struct deduce_source_char_impl
0200 {
0201 typedef typename boost::detail::normalize_single_byte_char< Char >::type type;
0202 };
0203
0204 template < class T >
0205 struct deduce_source_char_impl< deduce_character_type_later< T > >
0206 {
0207 typedef boost::has_left_shift< std::basic_ostream< char >, T > result_t;
0208
0209 #if defined(BOOST_LCAST_NO_WCHAR_T)
0210 static_assert(result_t::value,
0211 "Source type is not std::ostream`able and std::wostream`s are not supported by your STL implementation");
0212 typedef char type;
0213 #else
0214 typedef typename boost::conditional<
0215 result_t::value, char, wchar_t
0216 >::type type;
0217
0218 static_assert(result_t::value || boost::has_left_shift< std::basic_ostream< type >, T >::value,
0219 "Source type is neither std::ostream`able nor std::wostream`able");
0220 #endif
0221 };
0222 }
0223
0224 namespace detail
0225 {
0226
0227
0228
0229
0230
0231 template < class Char >
0232 struct deduce_target_char_impl
0233 {
0234 typedef typename normalize_single_byte_char< Char >::type type;
0235 };
0236
0237 template < class T >
0238 struct deduce_target_char_impl< deduce_character_type_later<T> >
0239 {
0240 typedef boost::has_right_shift<std::basic_istream<char>, T > result_t;
0241
0242 #if defined(BOOST_LCAST_NO_WCHAR_T)
0243 static_assert(result_t::value,
0244 "Target type is not std::istream`able and std::wistream`s are not supported by your STL implementation");
0245 typedef char type;
0246 #else
0247 typedef typename boost::conditional<
0248 result_t::value, char, wchar_t
0249 >::type type;
0250
0251 static_assert(result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value,
0252 "Target type is neither std::istream`able nor std::wistream`able");
0253 #endif
0254 };
0255 }
0256
0257 namespace detail
0258 {
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 template < class T >
0275 struct deduce_target_char
0276 {
0277 typedef typename stream_char_common< T >::type stage1_type;
0278 typedef typename deduce_target_char_impl< stage1_type >::type stage2_type;
0279
0280 typedef stage2_type type;
0281 };
0282
0283 template < class T >
0284 struct deduce_source_char
0285 {
0286 typedef typename stream_char_common< T >::type stage1_type;
0287 typedef typename deduce_source_char_impl< stage1_type >::type stage2_type;
0288
0289 typedef stage2_type type;
0290 };
0291 }
0292
0293 namespace detail
0294 {
0295
0296
0297 template < class Char, class T >
0298 struct extract_char_traits
0299 : boost::false_type
0300 {
0301 typedef std::char_traits< Char > trait_t;
0302 };
0303
0304 template < class Char, class Traits, class Alloc >
0305 struct extract_char_traits< Char, std::basic_string< Char, Traits, Alloc > >
0306 : boost::true_type
0307 {
0308 typedef Traits trait_t;
0309 };
0310
0311 template < class Char, class Traits, class Alloc>
0312 struct extract_char_traits< Char, boost::container::basic_string< Char, Traits, Alloc > >
0313 : boost::true_type
0314 {
0315 typedef Traits trait_t;
0316 };
0317 }
0318
0319 namespace detail
0320 {
0321 template<class T>
0322 struct array_to_pointer_decay
0323 {
0324 typedef T type;
0325 };
0326
0327 template<class T, std::size_t N>
0328 struct array_to_pointer_decay<T[N]>
0329 {
0330 typedef const T * type;
0331 };
0332 }
0333
0334 namespace detail
0335 {
0336
0337 template< class Source,
0338 class Enable = void
0339 >
0340 struct lcast_src_length
0341 {
0342 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
0343 };
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 template <class Source>
0359 struct lcast_src_length<
0360 Source, typename boost::enable_if<boost::is_integral<Source> >::type
0361 >
0362 {
0363 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0364 BOOST_STATIC_CONSTANT(std::size_t, value =
0365 std::numeric_limits<Source>::is_signed +
0366 std::numeric_limits<Source>::is_specialized +
0367 std::numeric_limits<Source>::digits10 * 2
0368 );
0369 #else
0370 BOOST_STATIC_CONSTANT(std::size_t, value = 156);
0371 static_assert(sizeof(Source) * CHAR_BIT <= 256, "");
0372 #endif
0373 };
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 template<class Source>
0386 struct lcast_src_length<
0387 Source, typename boost::enable_if<boost::is_float<Source> >::type
0388 >
0389 {
0390
0391 #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
0392 static_assert(
0393 std::numeric_limits<Source>::max_exponent10 <= 999999L &&
0394 std::numeric_limits<Source>::min_exponent10 >= -999999L
0395 , "");
0396
0397 BOOST_STATIC_CONSTANT(std::size_t, value =
0398 5 + lcast_precision<Source>::value + 6
0399 );
0400 #else
0401 BOOST_STATIC_CONSTANT(std::size_t, value = 156);
0402 #endif
0403 };
0404 }
0405
0406 namespace detail
0407 {
0408 template <class Source, class Target>
0409 struct lexical_cast_stream_traits {
0410 typedef typename boost::detail::array_to_pointer_decay<Source>::type src;
0411 typedef typename boost::remove_cv<src>::type no_cv_src;
0412
0413 typedef boost::detail::deduce_source_char<no_cv_src> deduce_src_char_metafunc;
0414 typedef typename deduce_src_char_metafunc::type src_char_t;
0415 typedef typename boost::detail::deduce_target_char<Target>::type target_char_t;
0416
0417 typedef typename boost::detail::widest_char<
0418 target_char_t, src_char_t
0419 >::type char_type;
0420
0421 #if !defined(BOOST_NO_CXX11_CHAR16_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0422 static_assert(!boost::is_same<char16_t, src_char_t>::value
0423 && !boost::is_same<char16_t, target_char_t>::value,
0424 "Your compiler does not have full support for char16_t" );
0425 #endif
0426 #if !defined(BOOST_NO_CXX11_CHAR32_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
0427 static_assert(!boost::is_same<char32_t, src_char_t>::value
0428 && !boost::is_same<char32_t, target_char_t>::value,
0429 "Your compiler does not have full support for char32_t" );
0430 #endif
0431
0432 typedef typename boost::conditional<
0433 boost::detail::extract_char_traits<char_type, Target>::value,
0434 typename boost::detail::extract_char_traits<char_type, Target>,
0435 typename boost::detail::extract_char_traits<char_type, no_cv_src>
0436 >::type::trait_t traits;
0437
0438 typedef boost::integral_constant<
0439 bool,
0440 boost::is_same<char, src_char_t>::value &&
0441 (sizeof(char) != sizeof(target_char_t)) &&
0442 (!(boost::detail::is_character<no_cv_src>::value))
0443 > is_string_widening_required_t;
0444
0445 typedef boost::integral_constant<
0446 bool,
0447 !(boost::is_integral<no_cv_src>::value ||
0448 boost::detail::is_character<
0449 typename deduce_src_char_metafunc::stage1_type
0450 >::value
0451 )
0452 > is_source_input_not_optimized_t;
0453
0454
0455
0456 BOOST_STATIC_CONSTANT(bool, requires_stringbuf =
0457 (is_string_widening_required_t::value || is_source_input_not_optimized_t::value)
0458 );
0459
0460 typedef boost::detail::lcast_src_length<no_cv_src> len_t;
0461 };
0462 }
0463
0464 namespace detail
0465 {
0466 template<typename Target, typename Source>
0467 struct lexical_converter_impl
0468 {
0469 typedef lexical_cast_stream_traits<Source, Target> stream_trait;
0470
0471 typedef detail::lexical_istream_limited_src<
0472 typename stream_trait::char_type,
0473 typename stream_trait::traits,
0474 stream_trait::requires_stringbuf,
0475 stream_trait::len_t::value + 1
0476 > i_interpreter_type;
0477
0478 typedef detail::lexical_ostream_limited_src<
0479 typename stream_trait::char_type,
0480 typename stream_trait::traits
0481 > o_interpreter_type;
0482
0483 static inline bool try_convert(const Source& arg, Target& result) {
0484 i_interpreter_type i_interpreter;
0485
0486
0487 if (!(i_interpreter.operator <<(arg)))
0488 return false;
0489
0490 o_interpreter_type out(i_interpreter.cbegin(), i_interpreter.cend());
0491
0492
0493 if(!(out.operator >>(result)))
0494 return false;
0495
0496 return true;
0497 }
0498 };
0499 }
0500
0501 }
0502
0503 #undef BOOST_LCAST_NO_WCHAR_T
0504
0505 #endif
0506