sample_userType.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // ----------------------------------------------------------------------------
  2. // sample_userType.cc : example usage of format with a user-defined type
  3. // ----------------------------------------------------------------------------
  4. // Copyright Samuel Krempp 2003. Use, modification, and distribution are
  5. // subject to the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/libs/format for library home page
  8. // ----------------------------------------------------------------------------
  9. #include <iostream>
  10. #include <iomanip>
  11. #include "boost/format.hpp"
  12. #include <boost/cast.hpp>
  13. #if !(BOOST_WORKAROUND(__GNUC__, < 3) && defined(__STL_CONFIG_H) )
  14. // not for broken gcc stdlib
  15. #include <boost/io/ios_state.hpp>
  16. #else
  17. // not as complete, but compatible with gcc-2.95 :
  18. void copyfmt(ios& left, const ios& right) {
  19. left.fill(right.fill());
  20. left.flags(right.flags() );
  21. left.exceptions(right.exceptions());
  22. left.width(right.width());
  23. left.precision(right.precision());
  24. }
  25. namespace boost { namespace io {
  26. class ios_all_saver {
  27. std::basic_ios<char> ios_;
  28. std::ios & target_r;
  29. public:
  30. ios_all_saver(std::ios& right) : ios_(0), target_r(right) {
  31. copyfmt(ios_, right);
  32. }
  33. ~ios_all_saver() {
  34. copyfmt(target_r, ios_);
  35. }
  36. };
  37. } } // N.S. boost::io
  38. // define showpos and noshowpos :
  39. class ShowPos {
  40. public:
  41. bool showpos_;
  42. ShowPos(bool v) : showpos_(v) {}
  43. };
  44. std::ostream& operator<<(std::ostream& os, const ShowPos& x) {
  45. if(x.showpos_)
  46. os.setf(ios_base:: showpos);
  47. else
  48. os.unsetf(ios_base:: showpos);
  49. return os;
  50. }
  51. ShowPos noshowpos(false);
  52. ShowPos showpos(true);
  53. #endif // -end gcc-2.95 workarounds
  54. //---------------------------------------------------------------------------//
  55. // *** an exemple of UDT : a Rational class ****
  56. class Rational {
  57. public:
  58. Rational(int n, unsigned int d) : n_(n), d_(d) {}
  59. Rational(int n, int d); // convert denominator to unsigned
  60. friend std::ostream& operator<<(std::ostream&, const Rational&);
  61. private:
  62. int n_; // numerator
  63. unsigned int d_; // denominator
  64. };
  65. Rational::Rational(int n, int d) : n_(n)
  66. {
  67. if(d < 0) { n_ = -n_; d=-d; } // make the denominator always non-negative.
  68. d_ = static_cast<unsigned int>(d);
  69. }
  70. std::ostream& operator<<(std::ostream& os, const Rational& r) {
  71. using namespace std;
  72. streamsize n, s1, s2, s3;
  73. streamsize w = os.width(0); // width has to be zeroed before saving state.
  74. // boost::io::ios_all_saver bia_saver (os);
  75. boost::io::basic_oaltstringstream<char> oss;
  76. oss.copyfmt(os );
  77. oss << r.n_;
  78. s1 = oss.size();
  79. oss << "/" << noshowpos; // a rational number needs only one sign !
  80. s2 = oss.size();
  81. oss << r.d_ ;
  82. s3 = oss.size();
  83. n = w - s3;
  84. if(n <= 0) {
  85. os.write(oss.begin(), oss.size());
  86. }
  87. else if(os.flags() & std::ios_base::internal) {
  88. std::streamsize n1 = w/2, n2 = w - n1, t;
  89. t = (s3-s1) - n2; // is 2d part '/nnn' bigger than 1/2 w ?
  90. if(t > 0) {
  91. n1 = w -(s3-s1); // put all paddings on first part.
  92. n2 = 0; // minimal width (s3-s2)
  93. }
  94. else {
  95. n2 -= s2-s1; // adjust for '/', n2 is still w/2.
  96. }
  97. os << setw(n1) << r.n_ << "/" << noshowpos << setw(n2) << r.d_;
  98. }
  99. else {
  100. if(! (os.flags() & std::ios_base::left)) {
  101. // -> right align. (right bit is set, or no bit is set)
  102. os << string(boost::numeric_cast<std::string::size_type>(n), ' ');
  103. }
  104. os.write(oss.begin(), s3);
  105. if( os.flags() & std::ios_base::left ) {
  106. os << string(boost::numeric_cast<std::string::size_type>(n), ' ');
  107. }
  108. }
  109. return os;
  110. }
  111. int main(){
  112. using namespace std;
  113. using boost::format;
  114. using boost::io::group;
  115. using boost::io::str;
  116. string s;
  117. Rational r(16, 9);
  118. cout << "bonjour ! " << endl;
  119. // "bonjour !"
  120. cout << r << endl;
  121. // "16/9"
  122. cout << showpos << r << ", " << 5 << endl;
  123. // "+16/9, +5"
  124. cout << format("%02d : [%0+9d] \n") % 1 % r ;
  125. // "01 : [+016 / 0009]"
  126. cout << format("%02d : [%_+9d] \n") % 2 % Rational(9,160);
  127. // "02 : [+9 / 160]"
  128. cout << format("%02d : [%_+9d] \n") % 3 % r;
  129. // "03 : [+16 / 9]"
  130. cout << format("%02d : [%_9d] \n") % 4 % Rational(8,1234);
  131. // "04 : [8 / 1234]"
  132. cout << format("%02d : [%_9d] \n") % 5 % Rational(1234,8);
  133. // "05 : [1234 / 8]"
  134. cout << format("%02d : [%09d] \n") % 6 % Rational(8,1234);
  135. // "06 : [0008 / 1234]"
  136. cout << format("%02d : [%0+9d] \n") % 7 % Rational(1234,8);
  137. // "07 : [+1234 / 008]"
  138. cout << format("%02d : [%0+9d] \n") % 8 % Rational(7,12345);
  139. // "08 : [+07 / 12345]"
  140. cerr << "\n\nEverything went OK, exiting. \n";
  141. return 0;
  142. }