]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
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> | |
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> | |
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 { | |
b32b8144 | 62 | return stream << median(value) << " ± " << width(value) / 2; |
7c673cae FG |
63 | } |
64 | } | |
65 | ||
66 | } // namespace io_wdth | |
67 | ||
68 | namespace io_prec { | |
69 | ||
70 | template<class T, class Policies, class CharType, class CharTraits> | |
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> | |
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 | |
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 | ||
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 | } |