Project 3 - Currency Type

- Main Page
- Classes
- Files

- File List
- File Members

currency.hpp
Go to the documentation of this file.
1
25 #ifndef CURRENCY_HPP_
26 #define CURRENCY_HPP_
27
28 #include <iomanip>
29 #include <istream>
30 #include <locale>
31 #include <ostream>
32 #include <sstream>
33 #include <string>
34 #include <stdexcept>
35
36 #include "ioflags.hpp"
37 #include "fixed.hpp"
38 #include "rational.hpp"
39
41 template<class T=long, int N=2>
42 class currency
43 {
44 public:
45 typedef T int_type;
46 typedef fixed<T,N> value_type;
47
49 constexpr currency() : value_() {}
52 constexpr currency(T integer) : value_(integer) {}
59 currency(T integer, T fraction) : value_(integer, fraction) {}
62 currency(double value) : value_(value) {}
63
65 template<class U, int M>
66 currency(currency<U, M> const& rhs): value_(rhs.value()) {}
67
69 template<class U, int M>
70 currency& operator=(currency<U, M> rhs)
71 {
72 value_ = rhs.value();
73 return *this;
74 }
75
78 std::string as_string() const;
85 template<class Char, class Traits>
86 bool read(std::basic_istream<Char, Traits>& strm);
87
90 template<class U>
92 U convert() const { return value().template convert<U>(); }
93
95 int_type round() const { return value().round(); }
96
98 int_type integer() const { return value().integer(); }
100 template<int M>
101 int_type fraction() const { return value().template fraction<M>(); }
103 int_type fraction() const { return value().fraction(); }
104
108 currency& operator+=(currency c);
112 currency& operator-=(currency c);
116 currency& operator*=(value_type m);
120 currency& operator*=(int_type m);
124 currency& operator/=(value_type m);
128 currency& operator/=(int_type m);
129
131 void negate();
132
134 currency& operator++();
136 currency operator++(int);
138 currency& operator--();
140 currency operator--(int);
141
143 value_type value() const { return value_; }
144
145 private:
146 value_type value_;
147 };
148
149 template<class T, int N>
150 std::string currency<T,N>::as_string()
151 const
152 {
153 std::ostringstream digits;
154 digits.imbue(std::locale::classic());
155 digits << integer() << std::setw(value_type::places) << std::setfill('0') << fraction();
156
157 std::ostringstream out;
158 std::money_put<char> const& put(std::use_facet<std::money_put<char> >(std::locale()));
159 put.put(std::ostreambuf_iterator<char>(out), false, out, '0', digits.str());
160 return out.str();
161 }
162
163 template<class T, int N>
164 currency<T,N>& currency<T,N>::operator+=(currency f)
165 {
166 value_ += f.value();
167 return *this;
168 }
169
170 template<class T, int N>
171 currency<T,N>& currency<T,N>::operator-=(currency f)
172 {
173 value_ -= f.value();
174 return *this;
175 }
176
177 template<class T, int N>
178 currency<T,N>& currency<T,N>::operator*=(value_type i)
179 {
180 value_ *= i;
181 return *this;
182 }
183 template<class T, int N>
184 currency<T,N>& currency<T,N>::operator*=(int_type i)
185 {
186 value_ *= i;
187 return *this;
188 }
189
190 template<class T, int N>
191 currency<T,N>& currency<T,N>::operator/=(value_type i)
192 {
193 value_ /= i;
194 return *this;
195 }
196 template<class T, int N>
197 currency<T,N>& currency<T,N>::operator/=(int_type i)
198 {
199 value_ /= i;
200 return *this;
201 }
202
203 template<class T, int N>
204 void currency<T,N>::negate()
205 {
206 value_ = -value_;
207 }
208
209 template<class T, int N>
210 currency<T,N>& currency<T,N>::operator++()
211 {
212 ++value_;
213 return *this;
214 }
215
216 template<class T, int N>
217 currency<T,N> currency<T,N>::operator++(int)
218 {
219 currency result(*this);
220 ++value_;
221 return result;
222 }
223
224 template<class T, int N>
225 currency<T,N>& currency<T,N>::operator--()
226 {
227 --value_;
228 return *this;
229 }
230
231 template<class T, int N>
232 currency<T,N> currency<T,N>::operator--(int)
233 {
234 currency result(*this);
235 --value_;
236 return result;
237 }
238
239 template<class T, int N>
240 template<class CharT, class Traits>
241 bool currency<T,N>::read(std::basic_istream<CharT,Traits>& strm)
242 {
243 ioflags flags(strm);
244 typename std::basic_istream<CharT, Traits>::sentry sentry(strm, false);
245 if (not sentry)
246 return false;
247
248 std::ios_base::iostate error(std::ios_base::goodbit);
249 std::string digits;
250 std::money_get<CharT> const& get(
251 std::use_facet<std::money_get<CharT> >(strm.getloc()));
252 get.get(std::istreambuf_iterator<CharT>(strm), std::istreambuf_iterator<CharT>(),
253 false, strm, error, digits);
254
255 if ((error & std::ios_base::failbit) != 0)
256 return false;
257
258 std::moneypunct<CharT> const& punct(
259 std::use_facet<std::moneypunct<CharT> >(strm.getloc()));
260
261 // Set fraction to the rightmost frac_digits() characters of digits.
262 std::string fraction(digits.substr(digits.size() - punct.frac_digits(), punct.frac_digits()));
263 // Set integer to the remainder of digits.
264 std::string integer(digits.substr(0, digits.size() - punct.frac_digits()));
265
266 std::istringstream fixed_stream(integer + "." + fraction);
267 return value_.read(fixed_stream);
268 }
269
273 template<class T, int N, class Char, class Traits>
274 std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& strm, currency<T,N>& c)
275 {
276 if (not c.read(strm))
277 strm.setstate(strm.failbit);
278 return strm;
279 }
280
284 template<class T, int N, class Char, class Traits>
285 std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& strm, currency<T,N> c)
286 {
287 typename std::basic_ostream<Char, Traits>::sentry sentry(strm);
288 strm << c.as_string();
289 return strm;
290 }
291
293 template<class T, int N>
294 currency<T,N> operator-(currency<T,N> a)
295 {
296 a.negate();
297 return a;
298 }
299
303 template<class T, int N>
304 currency<T,N> operator+(currency<T,N> a, currency<T,N> b)
305 {
306 a += b;
307 return a;
308 }
309
313 template<class T, int N>
314 currency<T,N> operator-(currency<T,N> a, currency<T,N> b)
315 {
316 a -= b;
317 return a;
318 }
319
323 template<class T, int N>
324 currency<T,N> operator*(currency<T,N> a, T b)
325 {
326 a *= b;
327 return a;
328 }
329
333 template<class T, int N>
334 currency<T,N> operator*(T a, currency<T,N> b)
335 {
336 b *= a;
337 return b;
338 }
339
343 template<class T, int N>
344 currency<T,N> operator/(currency<T,N> a, T b)
345 {
346 a /= b;
347 return a;
348 }
349
353 template<class T, int N>
354 rational<T> operator/(currency<T,N> n, currency<T,N> d)
355 {
356 // Extract the underlying value of the fixed values. No adjustment
357 // to scaling is needed because the numerator and denominator are
358 // both scaled to the same amount.
359 return rational<T>(n.value().value(), d.value().value());
360 }
361
365 template<class T, int N>
366 bool operator==(currency<T,N> a, currency<T,N> b)
367 {
368 return a.value() == b.value();
369 }
373 template<class T, int N>
374 bool operator==(currency<T,N> a, T b)
375 {
376 return a.value() == b;
377 }
381 template<class T, int N>
382 bool operator==(T a, currency<T,N> b)
383 {
384 return a == b.value();
385 }
386
390 template<class T, int N>
391 inline bool operator!=(currency<T,N> a, currency<T,N> b)
392 {
393 return not (a == b);
394 }
398 template<class T, int N>
399 inline bool operator!=(currency<T,N> a, T b)
400 {
401 return not (a == b);
402 }
406 template<class T, int N>
407 inline bool operator!=(T a, currency<T,N> b)
408 {
409 return not (a == b);
410 }
411
415 template<class T, int N>
416 bool operator<(currency<T,N> a, currency<T,N> b)
417 {
418 return a.value() < b.value();
419 }
423 template<class T, int N>
424 bool operator<(currency<T,N> a, T b)
425 {
426 return a.value() < b;
427 }
431 template<class T, int N>
432 bool operator<(T a, currency<T,N> b)
433 {
434 return a < b.value();
435 }
436
440 template<class T, int N>
441 inline bool operator>(currency<T,N> a, currency<T,N> b)
442 {
443 return b < a;
444 }
448 template<class T, int N>
449 inline bool operator>(currency<T,N> a, T b)
450 {
451 return b < a;
452 }
456 template<class T, int N>
457 inline bool operator>(T a, currency<T,N> b)
458 {
459 return b < a;
460 }
461
465 template<class T, int N>
466 inline bool operator<=(currency<T,N> a, currency<T,N> b)
467 {
468 return not (b < a);
469 }
473 template<class T, int N>
474 inline bool operator<=(currency<T,N> a, T b)
475 {
476 return not (b < a);
477 }
481 template<class T, int N>
482 inline bool operator<=(T a, currency<T,N> b)
483 {
484 return not (b < a);
485 }
486
490 template<class T, int N>
491 inline bool operator>=(currency<T,N> a, currency<T,N> b)
492 {
493 return not (a < b);
494 }
498 template<class T, int N>
499 inline bool operator>=(currency<T,N> a, T b)
500 {
501 return not (a < b);
502 }
506 template<class T, int N>
507 inline bool operator>=(T a, currency<T,N> b)
508 {
509 return not (a < b);
510 }
511
512 #endif
operator+
currency< T, N > operator+(currency< T, N > a, currency< T, N > b)
Definition: currency.hpp:304
currency::operator+=
currency & operator+=(currency c)
Definition: currency.hpp:164
currency::operator--
currency & operator--()
Pre-decrement operator.
Definition: currency.hpp:225
currency::read
bool read(std::basic_istream< Char, Traits > &strm)
fixed
Implement a fixed-point number class template. Values have N places after the decimal point...
Definition: fixed.hpp:26
operator==
bool operator==(currency< T, N > a, currency< T, N > b)
Definition: currency.hpp:366
operator*
currency< T, N > operator*(currency< T, N > a, T b)
Definition: currency.hpp:324
currency::currency
constexpr currency()
Default constructor initializes the value to zero.
Definition: currency.hpp:49
currency::value_type
fixed< T, N > value_type
Type of the actual value.
Definition: currency.hpp:46
currency::value
value_type value() const
Return the internal value.
Definition: currency.hpp:143
operator/
currency< T, N > operator/(currency< T, N > a, T b)
Definition: currency.hpp:344
currency::as_string
std::string as_string() const
Definition: currency.hpp:150
ioflags.hpp
Save and restore I/O stream flags.
operator!=
bool operator!=(currency< T, N > a, currency< T, N > b)
Definition: currency.hpp:391
currency
Definition: currency.hpp:42
fixed::fraction
value_type fraction() const
Return the fractional part, e.g., 3 for 12.03.
Definition: fixed.hpp:129
fixed::round
value_type round() const
Definition: fixed.hpp:204
currency::round
int_type round() const
Round off to the nearest integer, using banker&#39;s rounding.
Definition: currency.hpp:95
currency::currency
constexpr currency(T integer)
Definition: currency.hpp:52
rational
Represent a rational number (fraction) as a numerator and denominator.
Definition: rational.hpp:16
currency::negate
void negate()
Negate this value.
Definition: currency.hpp:204
currency::currency
currency(currency< U, M > const &rhs)
Copy a value that uses a different precision.
Definition: currency.hpp:66
currency::operator=
currency & operator=(currency< U, M > rhs)
Assign a value that uses a different precision.
Definition: currency.hpp:70
currency::operator*=
currency & operator*=(value_type m)
Definition: currency.hpp:178
operator>=
bool operator>=(currency< T, N > a, currency< T, N > b)
Definition: currency.hpp:491
currency::operator-=
currency & operator-=(currency c)
Definition: currency.hpp:171
currency::currency
currency(double value)
Definition: currency.hpp:62
currency::currency
currency(T integer, T fraction)
Definition: currency.hpp:59
currency::integer
int_type integer() const
Return the integer part (which is the same as trunc()).
Definition: currency.hpp:98
fixed.hpp
currency::fraction
int_type fraction() const
Return the fractional part, to M places.
Definition: currency.hpp:101
currency::operator++
currency & operator++()
Pre-increment operator.
Definition: currency.hpp:210
ioflags
Definition: ioflags.hpp:15
fixed::integer
value_type integer() const
Return the integer part (which is the same as trunc()).
Definition: fixed.hpp:71
fixed::value
value_type value() const
Return the internal value.
Definition: fixed.hpp:97
operator>
bool operator>(currency< T, N > a, currency< T, N > b)
Definition: currency.hpp:441
currency::fraction
int_type fraction() const
Return the fractional part.
Definition: currency.hpp:103
currency::convert
U convert() const
Convert to some other type, especially floating point.
Definition: currency.hpp:92
operator>>
std::basic_istream< Char, Traits > & operator>>(std::basic_istream< Char, Traits > &strm, currency< T, N > &c)
Definition: currency.hpp:274
currency::operator/=
currency & operator/=(value_type m)
Definition: currency.hpp:191
currency::int_type
T int_type
Storage type.
Definition: currency.hpp:45
operator-
currency< T, N > operator-(currency< T, N > a)
Negate a currency value.
Definition: currency.hpp:294