00001 00002 /* 00003 The Extended Integer (XInt) Library 00004 A fast, portable C++ library for multi-precision integer math 00005 Copyright 2010 by Chad Nelson 00006 00007 Distributed under the Boost Software License, Version 1.0. 00008 See accompanying file LICENSE_1_0.txt or copy at 00009 http://www.boost.org/LICENSE_1_0.txt 00010 00011 See http://www.boost.org/libs/xint for library home page. 00012 */ 00013 00020 #ifndef BOOST_INCLUDED_XINT_RAW_STREAMS_HPP 00021 #define BOOST_INCLUDED_XINT_RAW_STREAMS_HPP 00022 00023 namespace boost { 00024 namespace xint { 00025 namespace detail { 00027 00028 template <typename charT, typename traits, bitsize_t Bits, bool Secure, class \ 00029 Alloc> 00030 inline std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT, 00031 traits>& out, const BOOST_XINT_RAWINT n) 00032 { 00033 int base=((out.flags() & std::ios::hex) ? 16 00034 : (out.flags() & std::ios::oct) ? 8 00035 : 10); 00036 bool upperCase=(out.flags() & std::ios::uppercase ? true : false); 00037 00038 int nsign = (n.is_zero() ? 0 : n.negative ? -1 : 1); 00039 if ((out.flags() & std::ios::showpos) && nsign >= 0) out << "+"; 00040 00041 if (out.flags() & std::ios::showbase) { 00042 if (nsign < 0) out << "-"; 00043 00044 if (base == 16 && upperCase) out << "0X"; 00045 else if (base == 16) out << "0x"; 00046 else if (base == 8) out << "0"; 00047 00048 out << to_string<charT>(n.abs(), base, upperCase); 00049 } else { 00050 out << to_string<charT>(n, base, upperCase); 00051 } 00052 return out; 00053 } 00054 00055 template <typename charT, typename traits, bitsize_t Bits, bool Secure, class \ 00056 Alloc> 00057 inline std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT, 00058 traits>& in, BOOST_XINT_RAWINT& n) 00059 { 00060 int hex=(in.flags() & std::ios::hex) ? 1 : 0; 00061 int dec=(in.flags() & std::ios::dec) ? 1 : 0; 00062 int oct=(in.flags() & std::ios::oct) ? 1 : 0; 00063 int count=hex+dec+oct; 00064 00065 std::size_t base=autobase; 00066 if (count == 1) { 00067 if (hex) base = 16; 00068 else if (oct) base = 8; 00069 else base = 10; 00070 } else if (count > 1) base = 10; 00071 // else auto-base 00072 00073 std::string s; 00074 if (in.peek()=='+') { 00075 in.ignore(); 00076 } else if (in.peek()=='-') { 00077 in.ignore(); 00078 s.push_back('-'); 00079 } 00080 00081 if (base==autobase) { 00082 if (in.peek()=='0') { 00083 in.ignore(); 00084 int c=in.peek(); 00085 if (c=='x' || c=='X') { 00086 in.ignore(); 00087 base=16; 00088 } else base=8; 00089 } else base=10; 00090 } 00091 00092 while (in) { 00093 int c=in.peek(); 00094 if ((base==8 && (c>='0' && c<='7')) || 00095 (base==10 && (c>='0' && c<='9')) || 00096 (base==16 && ((c>='0' && c<='9') || (c>='a' && c<='f') || 00097 (c>='A' && c<='F')))) 00098 { 00099 in.ignore(); 00100 s.push_back(char(c)); 00101 } else break; 00102 } 00103 00104 BOOST_XINT_TRY { 00105 n.from_string(s, base); 00106 } BOOST_XINT_CATCH { 00107 // Catch invalid strings 00108 in.setstate(std::ios::failbit); 00109 } 00110 00111 return in; 00112 } 00113 00115 } // namespace detail 00116 } // namespace xint 00117 } // namespace boost 00118 00119 #endif // BOOST_INCLUDED_XINT_RAW_STREAMS_HPP
© Copyright Chad Nelson, 2010-2011. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)