1// Copyright Alexander Nasonov & Paul A. Bristow 2006.
2
3// Use, modification and distribution are subject to the
4// Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt
6// or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
9#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
10
11#include <climits>
12#include <ios>
13#include <limits>
14
15#include <boost/config.hpp>
16#include <boost/integer_traits.hpp>
17
18namespace boost { namespace detail {
19
20class lcast_abstract_stub {};
21
22// Calculate an argument to pass to std::ios_base::precision from
23// lexical_cast. See alternative implementation for broken standard
24// libraries in lcast_get_precision below. Keep them in sync, please.
25template<class T>
26struct lcast_precision
27{
28 using limits = std::numeric_limits<T>;
29
30 BOOST_STATIC_CONSTANT(bool, use_default_precision =
31 !limits::is_specialized || limits::is_exact
32 );
33
34 BOOST_STATIC_CONSTANT(bool, is_specialized_bin =
35 !use_default_precision &&
36 limits::radix == 2 && limits::digits > 0
37 );
38
39 BOOST_STATIC_CONSTANT(bool, is_specialized_dec =
40 !use_default_precision &&
41 limits::radix == 10 && limits::digits10 > 0
42 );
43
44 BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max =
45 boost::integer_traits<std::streamsize>::const_max
46 );
47
48 BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U);
49
50 static_assert(!is_specialized_dec ||
51 precision_dec <= streamsize_max + 0UL
52 , "");
53
54 BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
55 2UL + limits::digits * 30103UL / 100000UL
56 );
57
58 static_assert(!is_specialized_bin ||
59 (limits::digits + 0UL < ULONG_MAX / 30103UL &&
60 precision_bin > limits::digits10 + 0UL &&
61 precision_bin <= streamsize_max + 0UL)
62 , "");
63
64 BOOST_STATIC_CONSTANT(std::streamsize, value =
65 is_specialized_bin ? precision_bin
66 : is_specialized_dec ? precision_dec : 6
67 );
68};
69
70
71template<class T>
72inline std::streamsize lcast_get_precision(T* = 0)
73{
74 return lcast_precision<T>::value;
75}
76
77template<class T>
78inline void lcast_set_precision(std::ios_base& stream, T*)
79{
80 stream.precision(lcast_get_precision<T>());
81}
82
83template<class Source, class Target>
84inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
85{
86 std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
87 std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
88 stream.precision(prec: s > t ? s : t);
89}
90
91}}
92
93#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
94
95

source code of boost/libs/lexical_cast/include/boost/detail/lcast_precision.hpp