Calculator Step 6

- Main Page
- Classes
- Files

- File List
- File Members

number_impl.cpp
Go to the documentation of this file.
1 #include <istream>
2 #include <ostream>
3 #include <sstream>
4 #include <utility>
5
6 #include "calc_error.hpp"
7 #include "number_impl.hpp"
8
9 number_impl::~number_impl()
10 {}
11
12 void number_impl::save(std::ostream& stream)
13 const
14 {
15 do_save(stream);
16 }
17
18 std::shared_ptr<number_impl> number_impl::read_library(std::istream& stream)
19 {
20 std::string type{};
21 if (not (stream >> type))
22 throw calc_error{"malformed library, missing number type"};
23
24 if (type == "void")
25 return std::make_shared<number_void>();
26
27 if (type == "long") {
28 long long x{};
29 if (not (stream >> x))
30 throw calc_error{"malformed library, missing long value"};
31 return std::make_shared<number_long>(x);
32 }
33
34 if (type == "double") {
35 double x{};
36 if (not (stream >> x))
37 throw calc_error{"malformed library, missing double value"};
38 return std::make_shared<number_double>(x);
39 }
40
41 throw calc_error{"malformed library, unknown number type: " + type};
42 }
43
44 void number_impl::print(std::ostream& stream)
45 const
46 {
47 stream << to_string();
48 }
49
50 std::string number_impl::to_string()
51 const
52 {
53 return do_to_string();
54 }
55
56 std::shared_ptr<number_impl> number_impl::promote(number_impl& rhs)
57 const
58 {
59 return do_promote(rhs);
60 }
61
62 bool number_impl::equals(number_impl const& rhs)
63 const
64 {
65 return do_equals(rhs);
66 }
67
68 bool number_impl::less(number_impl const& rhs)
69 const
70 {
71 return do_less(rhs);
72 }
73
74 std::shared_ptr<number_impl> number_impl::add(number_impl const& rhs)
75 {
76 return do_add(rhs);
77 }
78
79 std::shared_ptr<number_impl> number_impl::subtract(number_impl const& rhs)
80 {
81 return do_subtract(rhs);
82 }
83
84 std::shared_ptr<number_impl> number_impl::multiply(number_impl const& rhs)
85 {
86 return do_multiply(rhs);
87 }
88
89 std::shared_ptr<number_impl> number_impl::divide(number_impl const& rhs)
90 {
91 return do_divide(rhs);
92 }
93
94 // Default is not to promote.
95 // The return value from the promote_to_*() functions is either
96 // a brand-new number_impl object, or this.
97 std::shared_ptr<number_impl> number_impl::promote_to_void()
98 {
99 return shared_from_this();
100 }
101
102 std::shared_ptr<number_impl> number_impl::promote_to_long()
103 {
104 return shared_from_this();
105 }
106
107 std::shared_ptr<number_impl> number_impl::promote_to_rational()
108 {
109 return shared_from_this();
110 }
111
112 std::shared_ptr<number_impl> number_impl::promote_to_double()
113 {
114 return shared_from_this();
115 }
116
117
118
119 std::string number_void::do_to_string()
120 const
121 {
122 return std::string{};
123 }
124
125 void number_void::do_save(std::ostream& stream)
126 const
127 {
128 stream << "void ";
129 }
130
131 // void never equals anything, even another void
132 bool number_void::do_equals(number_impl const&)
133 const
134 {
135 return false;
136 }
137
138 // void is never less than anything
139 bool number_void::do_less(number_impl const&)
140 const
141 {
142 return false;
143 }
144
145 // void plus void equal void
146 std::shared_ptr<number_impl> number_void::do_add(number_impl const&)
147 {
148 return shared_from_this();
149 }
150
151 std::shared_ptr<number_impl> number_void::do_subtract(number_impl const&)
152 {
153 return shared_from_this();
154 }
155
156 std::shared_ptr<number_impl> number_void::do_multiply(number_impl const&)
157 {
158 return shared_from_this();
159 }
160
161 std::shared_ptr<number_impl> number_void::do_divide(number_impl const&)
162 {
163 return shared_from_this();
164 }
165
166 std::shared_ptr<number_impl> number_void::do_promote(number_impl& rhs)
167 const
168 {
169 return rhs.promote_to_void();
170 }
171
172
173
174 std::string number_long::do_to_string()
175 const
176 {
177 std::ostringstream stream{};
178 stream << value();
179 return stream.str();
180 }
181
182 void number_long::do_save(std::ostream& stream)
183 const
184 {
185 stream << "long " << value() << ' ';
186 }
187
188 bool number_long::do_equals(number_impl const& rhs)
189 const
190 {
191 return value() == dynamic_cast<number_long const&>(rhs).value();
192 }
193
194 bool number_long::do_less(number_impl const& rhs)
195 const
196 {
197 return value() < dynamic_cast<number_long const&>(rhs).value();
198 }
199
200 std::shared_ptr<number_impl> number_long::do_add(number_impl const& rhs)
201 {
202 return std::make_shared<number_long>(value_ + dynamic_cast<number_long const&>(rhs).value());
203 }
204
205 std::shared_ptr<number_impl> number_long::do_subtract(number_impl const& rhs)
206 {
207 return std::make_shared<number_long>(value_ - dynamic_cast<number_long const&>(rhs).value());
208 }
209
210 std::shared_ptr<number_impl> number_long::do_multiply(number_impl const& rhs)
211 {
212 return std::make_shared<number_long>(value_ * dynamic_cast<number_long const&>(rhs).value());
213 }
214
215 std::shared_ptr<number_impl> number_long::do_divide(number_impl const& rhs)
216 {
217 long long right = dynamic_cast<number_long const&>(rhs).value();
218 if (right == 0)
219 throw calc_error{"division by zero"};
220 return std::make_shared<number_rational>(value_, right);
221 }
222
223 std::shared_ptr<number_impl> number_long::do_promote(number_impl& rhs)
224 const
225 {
226 return rhs.promote_to_long();
227 }
228
229 std::shared_ptr<number_impl> number_long::promote_to_void()
230 {
231 return std::make_shared<number_void>();
232 }
233
234 std::shared_ptr<number_impl> number_long::promote_to_rational()
235 {
236 return std::make_shared<number_rational>(value());
237 }
238
239 std::shared_ptr<number_impl> number_long::promote_to_double()
240 {
241 return std::make_shared<number_double>(value());
242 }
243
244
245 std::string number_rational::do_to_string()
246 const
247 {
248 std::ostringstream stream{};
249 stream << value();
250 return stream.str();
251 }
252
253 void number_rational::do_save(std::ostream& stream)
254 const
255 {
256 stream << "rational " << value() << ' ';
257 }
258
259 bool number_rational::do_equals(number_impl const& rhs)
260 const
261 {
262 return value() == dynamic_cast<number_rational const&>(rhs).value();
263 }
264
265 bool number_rational::do_less(number_impl const& rhs)
266 const
267 {
268 return value() < dynamic_cast<number_rational const&>(rhs).value();
269 }
270
271 std::shared_ptr<number_impl> number_rational::do_add(number_impl const& rhs)
272 {
273 rational<long long> result{ value_ + dynamic_cast<number_rational const&>(rhs).value() };
274 if (result.denominator() == 1)
275 return std::make_shared<number_long>(result.numerator());
276 else
277 return std::make_shared<number_rational>(result);
278 }
279
280 std::shared_ptr<number_impl> number_rational::do_subtract(number_impl const& rhs)
281 {
282 rational<long long> result{ value_ - dynamic_cast<number_rational const&>(rhs).value() };
283 if (result.denominator() == 1)
284 return std::make_shared<number_long>(result.numerator());
285 else
286 return std::make_shared<number_rational>(result);
287 }
288
289 std::shared_ptr<number_impl> number_rational::do_multiply(number_impl const& rhs)
290 {
291 rational<long long> result{ value_ * dynamic_cast<number_rational const&>(rhs).value() };
292 if (result.denominator() == 1)
293 return std::make_shared<number_long>(result.numerator());
294 else
295 return std::make_shared<number_rational>(result);
296 }
297
298 std::shared_ptr<number_impl> number_rational::do_divide(number_impl const& rhs)
299 {
300 rational<long long> right{ dynamic_cast<number_rational const&>(rhs).value() };
301 if (right.numerator() == 0)
302 throw calc_error{"division by zero"};
303 rational<long long> result = value_ / right;
304 if (result.denominator() == 1)
305 return std::make_shared<number_long>(result.numerator());
306 else
307 return std::make_shared<number_rational>(result);
308 }
309
310 std::shared_ptr<number_impl> number_rational::do_promote(number_impl& rhs)
311 const
312 {
313 return rhs.promote_to_rational();
314 }
315
316 std::shared_ptr<number_impl> number_rational::promote_to_void()
317 {
318 return std::make_shared<number_void>();
319 }
320
321 std::shared_ptr<number_impl> number_rational::promote_to_double()
322 {
323 return std::make_shared<number_double>(static_cast<double>(value()));
324 }
325
326
327
328 std::string number_double::do_to_string()
329 const
330 {
331 std::ostringstream stream{};
332 stream << value();
333 return stream.str();
334 }
335
336 void number_double::do_save(std::ostream& stream)
337 const
338 {
339 stream << "double " << value() << ' ';
340 }
341
342 bool number_double::do_equals(number_impl const& rhs)
343 const
344 {
345 return value() == dynamic_cast<number_double const&>(rhs).value();
346 }
347
348 bool number_double::do_less(number_impl const& rhs)
349 const
350 {
351 return value() < dynamic_cast<number_double const&>(rhs).value();
352 }
353
354 std::shared_ptr<number_impl> number_double::do_add(number_impl const& rhs)
355 {
356 return std::make_shared<number_double>(value_ + dynamic_cast<number_double const&>(rhs).value());
357 }
358
359 std::shared_ptr<number_impl> number_double::do_subtract(number_impl const& rhs)
360 {
361 return std::make_shared<number_double>(value_ - dynamic_cast<number_double const&>(rhs).value());
362 }
363
364 std::shared_ptr<number_impl> number_double::do_multiply(number_impl const& rhs)
365 {
366 return std::make_shared<number_double>(value_ * dynamic_cast<number_double const&>(rhs).value());
367 }
368
369 std::shared_ptr<number_impl> number_double::do_divide(number_impl const& rhs)
370 {
371 double right{ dynamic_cast<number_double const&>(rhs).value() };
372 if (right == 0.0)
373 throw calc_error{"division by zero"};
374 return std::make_shared<number_double>(value_ / right);
375 }
376
377 std::shared_ptr<number_impl> number_double::do_promote(number_impl& rhs)
378 const
379 {
380 return rhs.promote_to_double();
381 }
382
383 std::shared_ptr<number_impl> number_double::promote_to_void()
384 {
385 return std::make_shared<number_void>();
386 }
number_rational::do_less
virtual bool do_less(number_impl const &rhs) const
Definition: number_impl.cpp:265
number_double::do_save
virtual void do_save(std::ostream &stream) const
Definition: number_impl.cpp:336
number_void::do_save
virtual void do_save(std::ostream &stream) const
Definition: number_impl.cpp:125
number_impl::do_less
virtual bool do_less(number_impl const &rhs) const =0
number_void::do_multiply
virtual std::shared_ptr< number_impl > do_multiply(number_impl const &rhs)
Definition: number_impl.cpp:156
calc_error
Definition: calc_error.hpp:11
number_long::value
long long value() const
Definition: number_impl.hpp:101
rational::denominator
value_type denominator() const
Return the denominator.
Definition: rational.hpp:52
number_rational::do_multiply
virtual std::shared_ptr< number_impl > do_multiply(number_impl const &rhs)
Definition: number_impl.cpp:289
number_impl::save
void save(std::ostream &stream) const
Definition: number_impl.cpp:12
number_double::do_add
virtual std::shared_ptr< number_impl > do_add(number_impl const &rhs)
Definition: number_impl.cpp:354
rational::numerator
value_type numerator() const
Return the numerator.
Definition: rational.hpp:50
number_impl::promote_to_double
virtual std::shared_ptr< number_impl > promote_to_double()
Definition: number_impl.cpp:112
number_impl::do_subtract
virtual std::shared_ptr< number_impl > do_subtract(number_impl const &rhs)=0
number_void::do_add
virtual std::shared_ptr< number_impl > do_add(number_impl const &rhs)
Definition: number_impl.cpp:146
number_rational::promote_to_void
virtual std::shared_ptr< number_impl > promote_to_void()
Definition: number_impl.cpp:316
number_impl::less
bool less(number_impl const &rhs) const
Definition: number_impl.cpp:68
number_long::value_
long long value_
Definition: number_impl.hpp:116
number_impl::promote
std::shared_ptr< number_impl > promote(number_impl &rhs) const
Definition: number_impl.cpp:56
number_long::do_subtract
virtual std::shared_ptr< number_impl > do_subtract(number_impl const &rhs)
Definition: number_impl.cpp:205
number_double
Definition: number_impl.hpp:147
calc_error.hpp
number_long::do_less
virtual bool do_less(number_impl const &rhs) const
Definition: number_impl.cpp:194
number_impl::~number_impl
virtual ~number_impl()
Definition: number_impl.cpp:9
number_rational::do_add
virtual std::shared_ptr< number_impl > do_add(number_impl const &rhs)
Definition: number_impl.cpp:271
number_rational::do_equals
virtual bool do_equals(number_impl const &rhs) const
Definition: number_impl.cpp:259
number_long::promote_to_double
virtual std::shared_ptr< number_impl > promote_to_double()
Definition: number_impl.cpp:239
number_double::do_subtract
virtual std::shared_ptr< number_impl > do_subtract(number_impl const &rhs)
Definition: number_impl.cpp:359
number_rational::do_divide
virtual std::shared_ptr< number_impl > do_divide(number_impl const &rhs)
Definition: number_impl.cpp:298
number_impl::print
void print(std::ostream &stream) const
Definition: number_impl.cpp:44
number_long::promote_to_rational
virtual std::shared_ptr< number_impl > promote_to_rational()
Definition: number_impl.cpp:234
number_impl::add
std::shared_ptr< number_impl > add(number_impl const &rhs)
Definition: number_impl.cpp:74
number_rational::do_save
virtual void do_save(std::ostream &stream) const
Definition: number_impl.cpp:253
number_impl::do_add
virtual std::shared_ptr< number_impl > do_add(number_impl const &rhs)=0
number_void::do_promote
virtual std::shared_ptr< number_impl > do_promote(number_impl &rhs) const
Definition: number_impl.cpp:166
number_impl::do_save
virtual void do_save(std::ostream &stream) const =0
number_impl::do_promote
virtual std::shared_ptr< number_impl > do_promote(number_impl &rhs) const =0
number_rational
Definition: number_impl.hpp:122
number_void::do_less
virtual bool do_less(number_impl const &rhs) const
Definition: number_impl.cpp:139
number_impl::subtract
std::shared_ptr< number_impl > subtract(number_impl const &rhs)
Definition: number_impl.cpp:79
number_double::do_promote
virtual std::shared_ptr< number_impl > do_promote(number_impl &rhs) const
Definition: number_impl.cpp:377
number_impl.hpp
rational< long long >
number_impl::do_divide
virtual std::shared_ptr< number_impl > do_divide(number_impl const &rhs)=0
number_rational::do_to_string
virtual std::string do_to_string() const
Definition: number_impl.cpp:245
number_void::do_subtract
virtual std::shared_ptr< number_impl > do_subtract(number_impl const &rhs)
Definition: number_impl.cpp:151
number_rational::value
rational< long long > value() const
Definition: number_impl.hpp:127
number_double::value_
double value_
Definition: number_impl.hpp:163
number_long::do_equals
virtual bool do_equals(number_impl const &rhs) const
Definition: number_impl.cpp:188
number_impl::do_to_string
virtual std::string do_to_string() const =0
number_impl::read_library
static std::shared_ptr< number_impl > read_library(std::istream &stream)
Definition: number_impl.cpp:18
number_impl::promote_to_rational
virtual std::shared_ptr< number_impl > promote_to_rational()
Definition: number_impl.cpp:107
number_impl::to_string
std::string to_string() const
Definition: number_impl.cpp:50
number_impl
Definition: number_impl.hpp:10
number_double::do_to_string
virtual std::string do_to_string() const
Definition: number_impl.cpp:328
number_double::do_multiply
virtual std::shared_ptr< number_impl > do_multiply(number_impl const &rhs)
Definition: number_impl.cpp:364
number_impl::do_multiply
virtual std::shared_ptr< number_impl > do_multiply(number_impl const &rhs)=0
number_impl::multiply
std::shared_ptr< number_impl > multiply(number_impl const &rhs)
Definition: number_impl.cpp:84
number_double::do_equals
virtual bool do_equals(number_impl const &rhs) const
Definition: number_impl.cpp:342
number_impl::promote_to_void
virtual std::shared_ptr< number_impl > promote_to_void()
Definition: number_impl.cpp:97
number_long::do_divide
virtual std::shared_ptr< number_impl > do_divide(number_impl const &rhs)
Definition: number_impl.cpp:215
number_rational::do_promote
virtual std::shared_ptr< number_impl > do_promote(number_impl &rhs) const
Definition: number_impl.cpp:310
number_double::promote_to_void
virtual std::shared_ptr< number_impl > promote_to_void()
Definition: number_impl.cpp:383
number_rational::do_subtract
virtual std::shared_ptr< number_impl > do_subtract(number_impl const &rhs)
Definition: number_impl.cpp:280
number_void::do_divide
virtual std::shared_ptr< number_impl > do_divide(number_impl const &rhs)
Definition: number_impl.cpp:161
number_long::do_to_string
virtual std::string do_to_string() const
Definition: number_impl.cpp:174
number_long::do_save
virtual void do_save(std::ostream &stream) const
Definition: number_impl.cpp:182
number_double::do_less
virtual bool do_less(number_impl const &rhs) const
Definition: number_impl.cpp:348
number_long::promote_to_void
virtual std::shared_ptr< number_impl > promote_to_void()
Definition: number_impl.cpp:229
number_impl::promote_to_long
virtual std::shared_ptr< number_impl > promote_to_long()
Definition: number_impl.cpp:102
number_void::do_equals
virtual bool do_equals(number_impl const &rhs) const
Definition: number_impl.cpp:132
number_long
Definition: number_impl.hpp:98
number_impl::do_equals
virtual bool do_equals(number_impl const &rhs) const =0
number_double::value
double value() const
Definition: number_impl.hpp:150
number_long::do_add
virtual std::shared_ptr< number_impl > do_add(number_impl const &rhs)
Definition: number_impl.cpp:200
number_void::do_to_string
virtual std::string do_to_string() const
Definition: number_impl.cpp:119
number_long::do_promote
virtual std::shared_ptr< number_impl > do_promote(number_impl &rhs) const
Definition: number_impl.cpp:223
number_impl::equals
bool equals(number_impl const &rhs) const
Definition: number_impl.cpp:62
number_rational::value_
rational< long long > value_
Definition: number_impl.hpp:141
number_impl::divide
std::shared_ptr< number_impl > divide(number_impl const &rhs)
Definition: number_impl.cpp:89
number_rational::promote_to_double
virtual std::shared_ptr< number_impl > promote_to_double()
Definition: number_impl.cpp:321
number_long::do_multiply
virtual std::shared_ptr< number_impl > do_multiply(number_impl const &rhs)
Definition: number_impl.cpp:210
number_double::do_divide
virtual std::shared_ptr< number_impl > do_divide(number_impl const &rhs)
Definition: number_impl.cpp:369