1 /* Boost examples/io.cpp
2 * show some exampleso of i/o operators
3 * thanks to all the people who commented on this point, particularly on
4 * the Boost mailing-list
5 *
6 * Copyright 2003 Guillaume Melquiond
7 *
8 * Distributed under the Boost Software License, Version 1.0.
9 * (See accompanying file LICENSE_1_0.txt or
10 * copy at http://www.boost.org/LICENSE_1_0.txt)
11 */
12
13 #include <boost/numeric/interval.hpp>
14 #include <boost/io/ios_state.hpp>
15 #include <cmath>
16 #include <cassert>
17
18 namespace io_std {
19
20 template<class T, class Policies, class CharType, class CharTraits>
operator <<(std::basic_ostream<CharType,CharTraits> & stream,const boost::numeric::interval<T,Policies> & value)21 std::basic_ostream<CharType, CharTraits> &operator<<
22 (std::basic_ostream<CharType, CharTraits> &stream,
23 const boost::numeric::interval<T, Policies> &value)
24 {
25 if (empty(value)) {
26 return stream << "[]";
27 } else {
28 return stream << '[' << lower(value) << ',' << upper(value) << ']';
29 }
30 }
31
32 } // namespace io_std
33
34 namespace io_sngl {
35
36 template<class T, class Policies, class CharType, class CharTraits>
operator <<(std::basic_ostream<CharType,CharTraits> & stream,const boost::numeric::interval<T,Policies> & value)37 std::basic_ostream<CharType, CharTraits> &operator<<
38 (std::basic_ostream<CharType, CharTraits> &stream,
39 const boost::numeric::interval<T, Policies> &value)
40 {
41 if (empty(value)) {
42 return stream << "[]";
43 } else if (singleton(value)) {
44 return stream << '[' << lower(value) << ']';
45 } else {
46 return stream << '[' << lower(value) << ',' << upper(value) << ']';
47 }
48 }
49
50 } // namespace io_sngl
51
52 namespace io_wdth {
53
54 template<class T, class Policies, class CharType, class CharTraits>
operator <<(std::basic_ostream<CharType,CharTraits> & stream,const boost::numeric::interval<T,Policies> & value)55 std::basic_ostream<CharType, CharTraits> &operator<<
56 (std::basic_ostream<CharType, CharTraits> &stream,
57 const boost::numeric::interval<T, Policies> &value)
58 {
59 if (empty(value)) {
60 return stream << "nothing";
61 } else {
62 return stream << median(value) << " ± " << width(value) / 2;
63 }
64 }
65
66 } // namespace io_wdth
67
68 namespace io_prec {
69
70 template<class T, class Policies, class CharType, class CharTraits>
operator <<(std::basic_ostream<CharType,CharTraits> & stream,const boost::numeric::interval<T,Policies> & value)71 std::basic_ostream<CharType, CharTraits> &operator<<
72 (std::basic_ostream<CharType, CharTraits> &stream,
73 const boost::numeric::interval<T, Policies> &value)
74 {
75 if (empty(value)) {
76 return stream << "nothing";
77 } else if (singleton(value)) {
78 boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
79 return stream << lower(value);
80 } else if (zero_in(value)) {
81 return stream << "0~";
82 } else {
83 const T rel = width(value) / norm(value);
84 int range = - (int)std::log10(rel);
85 boost::io::ios_precision_saver state(stream, range);
86 return stream << median(value);
87 }
88 }
89
90 } // namespace io_prec
91
92 namespace io_wide {
93
94 template<class T, class Policies, class CharType, class CharTraits>
operator <<(std::basic_ostream<CharType,CharTraits> & stream,const boost::numeric::interval<T,Policies> & value)95 std::basic_ostream<CharType, CharTraits> &operator<<
96 (std::basic_ostream<CharType, CharTraits> &stream,
97 const boost::numeric::interval<T, Policies> &value)
98 {
99 if (empty(value)) {
100 return stream << "nothing";
101 } else if (singleton(value)) {
102 boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
103 return stream << lower(value);
104 } else if (zero_in(value)) {
105 return stream << "0~";
106 } else {
107 std::streamsize p = stream.precision();
108 // FIXME poor man's power of 10, only up to 1E-15
109 p = (p > 15) ? 15 : p - 1;
110 double eps = 1.0; for(; p > 0; --p) { eps /= 10; }
111 T eps2 = static_cast<T>(eps / 2) * norm(value);
112 boost::numeric::interval<T, Policies> r = widen(value, eps2);
113 return stream << '[' << lower(r) << ',' << upper(r) << ']';
114 }
115 }
116
117 } // namespace io_wide
118
119 template<class T, class Policies, class CharType, class CharTraits> inline
operator >>(std::basic_istream<CharType,CharTraits> & stream,boost::numeric::interval<T,Policies> & value)120 std::basic_istream<CharType, CharTraits> &operator>>
121 (std::basic_istream<CharType, CharTraits> &stream,
122 boost::numeric::interval<T, Policies> &value)
123 {
124 T l, u;
125 char c = 0;
126 stream >> c;
127 if (c == '[') {
128 stream >> l >> c;
129 if (c == ',') stream >> u >> c; else u = l;
130 if (c != ']') stream.setstate(stream.failbit);
131 } else {
132 stream.putback(c);
133 stream >> l;
134 u = l;
135 }
136 if (stream)
137 value.assign(l, u);
138 else
139 value = boost::numeric::interval<T, Policies>::empty();
140 return stream;
141 }
142
143 // Test program
144
145 #include <iostream>
146
main()147 int main()
148 {
149 using namespace boost;
150 using namespace numeric;
151 using namespace interval_lib;
152
153 typedef interval<double,
154 policies<rounded_math<double>,
155 checking_base<double> > > I;
156
157 I tab[] = { I::empty(), I(1,1), I(1,2), I(-1,1), I(12.34,12.35),
158 I(1234.56,1234.57), I(123456.78, 123456.79), I::empty() };
159 unsigned int len = sizeof(tab) / sizeof(I);
160 std::cout << "Enter an interval: (it will be the last shown)\n";
161 std::cin >> tab[len - 1];
162
163 for(unsigned int i = 0; i < len; ++i) {
164 { using namespace io_std; std::cout << tab[i] << '\n'; }
165 { using namespace io_sngl; std::cout << tab[i] << '\n'; }
166 { using namespace io_wdth; std::cout << tab[i] << '\n'; }
167 { using namespace io_prec; std::cout << tab[i] << '\n'; }
168 { using namespace io_wide; std::cout << tab[i] << '\n'; }
169 std::cout << '\n';
170 }
171
172 }
173