Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:42

0001 // Copyright Alexander Nasonov & Paul A. Bristow 2006.
0002 
0003 // Use, modification and distribution are subject to the
0004 // Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt
0006 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
0009 #define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
0010 
0011 #include <climits>
0012 #include <ios>
0013 #include <limits>
0014 
0015 #include <boost/config.hpp>
0016 #include <boost/integer_traits.hpp>
0017 
0018 #ifndef BOOST_NO_IS_ABSTRACT
0019 // Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL
0020 #include <boost/type_traits/conditional.hpp>
0021 #include <boost/type_traits/is_abstract.hpp>
0022 #endif
0023 
0024 namespace boost { namespace detail {
0025 
0026 class lcast_abstract_stub {};
0027 
0028 // Calculate an argument to pass to std::ios_base::precision from
0029 // lexical_cast. See alternative implementation for broken standard
0030 // libraries in lcast_get_precision below. Keep them in sync, please.
0031 template<class T>
0032 struct lcast_precision
0033 {
0034 #ifdef BOOST_NO_IS_ABSTRACT
0035     typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
0036 #else
0037     typedef typename boost::conditional<
0038         boost::is_abstract<T>::value
0039       , std::numeric_limits<lcast_abstract_stub>
0040       , std::numeric_limits<T>
0041       >::type limits;
0042 #endif
0043 
0044     BOOST_STATIC_CONSTANT(bool, use_default_precision =
0045             !limits::is_specialized || limits::is_exact
0046         );
0047 
0048     BOOST_STATIC_CONSTANT(bool, is_specialized_bin =
0049             !use_default_precision &&
0050             limits::radix == 2 && limits::digits > 0
0051         );
0052 
0053     BOOST_STATIC_CONSTANT(bool, is_specialized_dec =
0054             !use_default_precision &&
0055             limits::radix == 10 && limits::digits10 > 0
0056         );
0057 
0058     BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max =
0059             boost::integer_traits<std::streamsize>::const_max
0060         );
0061 
0062     BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U);
0063 
0064     static_assert(!is_specialized_dec ||
0065             precision_dec <= streamsize_max + 0UL
0066         , "");
0067 
0068     BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
0069             2UL + limits::digits * 30103UL / 100000UL
0070         );
0071 
0072     static_assert(!is_specialized_bin ||
0073             (limits::digits + 0UL < ULONG_MAX / 30103UL &&
0074             precision_bin > limits::digits10 + 0UL &&
0075             precision_bin <= streamsize_max + 0UL)
0076         , "");
0077 
0078     BOOST_STATIC_CONSTANT(std::streamsize, value =
0079             is_specialized_bin ? precision_bin
0080                                : is_specialized_dec ? precision_dec : 6
0081         );
0082 };
0083 
0084 
0085 template<class T>
0086 inline std::streamsize lcast_get_precision(T* = 0)
0087 {
0088     return lcast_precision<T>::value;
0089 }
0090 
0091 template<class T>
0092 inline void lcast_set_precision(std::ios_base& stream, T*)
0093 {
0094     stream.precision(lcast_get_precision<T>());
0095 }
0096 
0097 template<class Source, class Target>
0098 inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
0099 {
0100     std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
0101     std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
0102     stream.precision(s > t ? s : t);
0103 }
0104 
0105 }}
0106 
0107 #endif //  BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
0108