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