io.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #include <boost/numeric/interval.hpp>
  13. #include <boost/io/ios_state.hpp>
  14. #include <cmath>
  15. #include <cassert>
  16. namespace io_std {
  17. template<class T, class Policies, class CharType, class CharTraits>
  18. std::basic_ostream<CharType, CharTraits> &operator<<
  19. (std::basic_ostream<CharType, CharTraits> &stream,
  20. const boost::numeric::interval<T, Policies> &value)
  21. {
  22. if (empty(value)) {
  23. return stream << "[]";
  24. } else {
  25. return stream << '[' << lower(value) << ',' << upper(value) << ']';
  26. }
  27. }
  28. } // namespace io_std
  29. namespace io_sngl {
  30. template<class T, class Policies, class CharType, class CharTraits>
  31. std::basic_ostream<CharType, CharTraits> &operator<<
  32. (std::basic_ostream<CharType, CharTraits> &stream,
  33. const boost::numeric::interval<T, Policies> &value)
  34. {
  35. if (empty(value)) {
  36. return stream << "[]";
  37. } else if (singleton(value)) {
  38. return stream << '[' << lower(value) << ']';
  39. } else {
  40. return stream << '[' << lower(value) << ',' << upper(value) << ']';
  41. }
  42. }
  43. } // namespace io_sngl
  44. namespace io_wdth {
  45. template<class T, class Policies, class CharType, class CharTraits>
  46. std::basic_ostream<CharType, CharTraits> &operator<<
  47. (std::basic_ostream<CharType, CharTraits> &stream,
  48. const boost::numeric::interval<T, Policies> &value)
  49. {
  50. if (empty(value)) {
  51. return stream << "nothing";
  52. } else {
  53. return stream << median(value) << " ± " << width(value) / 2;
  54. }
  55. }
  56. } // namespace io_wdth
  57. namespace io_prec {
  58. template<class T, class Policies, class CharType, class CharTraits>
  59. std::basic_ostream<CharType, CharTraits> &operator<<
  60. (std::basic_ostream<CharType, CharTraits> &stream,
  61. const boost::numeric::interval<T, Policies> &value)
  62. {
  63. if (empty(value)) {
  64. return stream << "nothing";
  65. } else if (singleton(value)) {
  66. boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
  67. return stream << lower(value);
  68. } else if (zero_in(value)) {
  69. return stream << "0~";
  70. } else {
  71. const T rel = width(value) / norm(value);
  72. int range = - (int)std::log10(rel);
  73. boost::io::ios_precision_saver state(stream, range);
  74. return stream << median(value);
  75. }
  76. }
  77. } // namespace io_prec
  78. namespace io_wide {
  79. template<class T, class Policies, class CharType, class CharTraits>
  80. std::basic_ostream<CharType, CharTraits> &operator<<
  81. (std::basic_ostream<CharType, CharTraits> &stream,
  82. const boost::numeric::interval<T, Policies> &value)
  83. {
  84. if (empty(value)) {
  85. return stream << "nothing";
  86. } else if (singleton(value)) {
  87. boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
  88. return stream << lower(value);
  89. } else if (zero_in(value)) {
  90. return stream << "0~";
  91. } else {
  92. std::streamsize p = stream.precision();
  93. // FIXME poor man's power of 10, only up to 1E-15
  94. p = (p > 15) ? 15 : p - 1;
  95. double eps = 1.0; for(; p > 0; --p) { eps /= 10; }
  96. T eps2 = static_cast<T>(eps / 2) * norm(value);
  97. boost::numeric::interval<T, Policies> r = widen(value, eps2);
  98. return stream << '[' << lower(r) << ',' << upper(r) << ']';
  99. }
  100. }
  101. } // namespace io_wide
  102. template<class T, class Policies, class CharType, class CharTraits> inline
  103. std::basic_istream<CharType, CharTraits> &operator>>
  104. (std::basic_istream<CharType, CharTraits> &stream,
  105. boost::numeric::interval<T, Policies> &value)
  106. {
  107. T l, u;
  108. char c = 0;
  109. stream >> c;
  110. if (c == '[') {
  111. stream >> l >> c;
  112. if (c == ',') stream >> u >> c; else u = l;
  113. if (c != ']') stream.setstate(stream.failbit);
  114. } else {
  115. stream.putback(c);
  116. stream >> l;
  117. u = l;
  118. }
  119. if (stream)
  120. value.assign(l, u);
  121. else
  122. value = boost::numeric::interval<T, Policies>::empty();
  123. return stream;
  124. }
  125. // Test program
  126. #include <iostream>
  127. int main()
  128. {
  129. using namespace boost;
  130. using namespace numeric;
  131. using namespace interval_lib;
  132. typedef interval<double,
  133. policies<rounded_math<double>,
  134. checking_base<double> > > I;
  135. I tab[] = { I::empty(), I(1,1), I(1,2), I(-1,1), I(12.34,12.35),
  136. I(1234.56,1234.57), I(123456.78, 123456.79), I::empty() };
  137. unsigned int len = sizeof(tab) / sizeof(I);
  138. std::cout << "Enter an interval: (it will be the last shown)\n";
  139. std::cin >> tab[len - 1];
  140. for(unsigned int i = 0; i < len; ++i) {
  141. { using namespace io_std; std::cout << tab[i] << '\n'; }
  142. { using namespace io_sngl; std::cout << tab[i] << '\n'; }
  143. { using namespace io_wdth; std::cout << tab[i] << '\n'; }
  144. { using namespace io_prec; std::cout << tab[i] << '\n'; }
  145. { using namespace io_wide; std::cout << tab[i] << '\n'; }
  146. std::cout << '\n';
  147. }
  148. }