Coverage Report

Created: 2026-06-23 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/money.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2004 Decillion Pty(Ltd)
5
 Copyright (C) 2004, 2005, 2006 StatPro Italia srl
6
7
 This file is part of QuantLib, a free-software/open-source library
8
 for financial quantitative analysts and developers - http://quantlib.org/
9
10
 QuantLib is free software: you can redistribute it and/or modify it
11
 under the terms of the QuantLib license.  You should have received a
12
 copy of the license along with this program; if not, please email
13
 <quantlib-dev@lists.sf.net>. The license is also available online at
14
 <https://www.quantlib.org/license.shtml>.
15
16
 This program is distributed in the hope that it will be useful, but WITHOUT
17
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 FOR A PARTICULAR PURPOSE.  See the license for more details.
19
*/
20
21
/*! \file money.hpp
22
    \brief cash amount in a given currency
23
*/
24
25
#ifndef quantlib_money_hpp
26
#define quantlib_money_hpp
27
28
#include <ql/currency.hpp>
29
#include <ql/patterns/singleton.hpp>
30
#include <utility>
31
32
namespace QuantLib {
33
34
    //! amount of cash
35
    /*! \test money arithmetic is tested with and without currency
36
              conversions.
37
    */
38
    class Money {
39
      public:
40
        //! \name Constructors
41
        //@{
42
0
        Money() = default;
43
        Money(Currency currency, Decimal value);
44
        Money(Decimal value, Currency currency);
45
        //@}
46
        //! \name Inspectors
47
        //@{
48
        const Currency& currency() const;
49
        Decimal value() const;
50
        Money rounded() const;
51
        //@}
52
        /*! \name Money arithmetics
53
54
            See below for non-member functions and for settings which
55
            determine the behavior of the operators.
56
        */
57
        //@{
58
        Money operator+() const;
59
        Money operator-() const;
60
        Money& operator+=(const Money&);
61
        Money& operator-=(const Money&);
62
        Money& operator*=(Decimal);
63
        Money& operator/=(Decimal);
64
        //@}
65
        /*! \name Conversion settings
66
67
            These parameters are used for combining money amounts
68
            in different currencies
69
        */
70
        //@{
71
        enum ConversionType {
72
            NoConversion,           /*!< do not perform conversions */
73
            BaseCurrencyConversion, /*!< convert both operands to
74
                                         the base currency before
75
                                         converting */
76
            AutomatedConversion     /*!< return the result in the
77
                                         currency of the first
78
                                         operand */
79
        };
80
        // Money::Settings forward declaration
81
        class Settings;
82
        //@}
83
      private:
84
        Decimal value_ = 0.0;
85
        Currency currency_;
86
87
        // temporary support for old syntax
88
        struct BaseCurrencyProxy {
89
          public:
90
            BaseCurrencyProxy& operator=(const Currency&);
91
            operator Currency() const;
92
        };
93
94
        struct ConversionTypeProxy {
95
          public:
96
            ConversionTypeProxy& operator=(Money::ConversionType);
97
            operator Money::ConversionType() const;
98
        };
99
    };
100
101
    //! Per-session settings for the Money class
102
    class Money::Settings : public Singleton<Money::Settings> {
103
        friend class Singleton<Money::Settings>;
104
      private:
105
        Settings() = default;
106
107
      public:
108
        const Money::ConversionType & conversionType() const;
109
        Money::ConversionType & conversionType();
110
111
        const Currency & baseCurrency() const;
112
        Currency & baseCurrency();
113
114
      private:
115
        Money::ConversionType conversionType_ = Money::NoConversion;
116
        Currency baseCurrency_;
117
    };
118
119
    // More arithmetics and comparisons
120
121
    /*! \relates Money */
122
    Money operator+(const Money&, const Money&);
123
    /*! \relates Money */
124
    Money operator-(const Money&, const Money&);
125
    /*! \relates Money */
126
    Money operator*(const Money&, Decimal);
127
    /*! \relates Money */
128
    Money operator*(Decimal, const Money&);
129
    /*! \relates Money */
130
    Money operator/(const Money&, Decimal);
131
    /*! \relates Money */
132
    Decimal operator/(const Money&, const Money&);
133
134
    /*! \relates Money */
135
    bool operator==(const Money&, const Money&);
136
    /*! \relates Money */
137
    bool operator!=(const Money&, const Money&);
138
    /*! \relates Money */
139
    bool operator<(const Money&, const Money&);
140
    /*! \relates Money */
141
    bool operator<=(const Money&, const Money&);
142
    /*! \relates Money */
143
    bool operator>(const Money&, const Money&);
144
    /*! \relates Money */
145
    bool operator>=(const Money&, const Money&);
146
147
    /*! \relates Money */
148
    bool close(const Money&, const Money&, Size n = 42);
149
    /*! \relates Money */
150
    bool close_enough(const Money&, const Money&, Size n = 42);
151
152
    // syntactic sugar
153
154
    /*! \relates Money */
155
    Money operator*(Decimal, const Currency&);
156
    /*! \relates Money */
157
    Money operator*(const Currency&, Decimal);
158
159
    // formatting
160
161
    /*! \relates Money */
162
    std::ostream& operator<<(std::ostream&, const Money&);
163
164
165
    // inline definitions
166
167
    inline Money::Money(Currency currency, Decimal value)
168
0
    : value_(value), currency_(std::move(currency)) {}
169
170
    inline Money::Money(Decimal value, Currency currency)
171
0
    : value_(value), currency_(std::move(currency)) {}
172
173
0
    inline const Currency& Money::currency() const {
174
0
        return currency_;
175
0
    }
176
177
0
    inline Decimal Money::value() const {
178
0
        return value_;
179
0
    }
180
181
0
    inline Money Money::rounded() const {
182
0
        return Money(currency_.rounding()(value_), currency_);
183
0
    }
184
185
0
    inline Money Money::operator+() const {
186
0
        return *this;
187
0
    }
188
189
0
    inline Money Money::operator-() const {
190
0
        return Money(-value_, currency_);
191
0
    }
192
193
0
    inline Money& Money::operator*=(Decimal x) {
194
0
        value_ *= x;
195
0
        return *this;
196
0
    }
197
198
0
    inline Money& Money::operator/=(Decimal x) {
199
0
        value_ /= x;
200
0
        return *this;
201
0
    }
202
203
204
0
    inline Money operator+(const Money& m1, const Money& m2) {
205
0
        Money tmp = m1;
206
0
        tmp += m2;
207
0
        return tmp;
208
0
    }
209
210
0
    inline Money operator-(const Money& m1, const Money& m2) {
211
0
        Money tmp = m1;
212
0
        tmp -= m2;
213
0
        return tmp;
214
0
    }
215
216
0
    inline Money operator*(const Money& m, Decimal x) {
217
0
        Money tmp = m;
218
0
        tmp *= x;
219
0
        return tmp;
220
0
    }
221
222
0
    inline Money operator*(Decimal x, const Money& m) {
223
0
        return m*x;
224
0
    }
225
226
0
    inline Money operator/(const Money& m, Decimal x) {
227
0
        Money tmp = m;
228
0
        tmp /= x;
229
0
        return tmp;
230
0
    }
231
232
0
    inline bool operator!=(const Money& m1, const Money& m2) {
233
0
        return !(m1 == m2);
234
0
    }
235
236
0
    inline bool operator>(const Money& m1, const Money& m2) {
237
0
        return m2 < m1;
238
0
    }
239
240
0
    inline bool operator>=(const Money& m1, const Money& m2) {
241
0
        return m2 <= m1;
242
0
    }
243
244
0
    inline Money operator*(Decimal value, const Currency& c) {
245
0
        return Money(value,c);
246
0
    }
247
248
0
    inline Money operator*(const Currency& c, Decimal value) {
249
0
        return Money(value,c);
250
0
    }
251
252
}
253
254
255
#endif