OnixS C++ CME iLink 3 Binary Order Entry Handler  1.9.0
API Documentation
Decimal.Operations.h
Go to the documentation of this file.
1 // Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2 //
3 // This software owned by Onix Solutions Limited [OnixS] and is
4 // protected by copyright law and international copyright treaties.
5 //
6 // Access to and use of the software is governed by the terms of the applicable
7 // OnixS Software Services Agreement (the Agreement) and Customer end user license
8 // agreements granting a non-assignable, non-transferable and non-exclusive license
9 // to use the software for it's own data processing purposes under the terms defined
10 // in the Agreement.
11 //
12 // Except as otherwise granted within the terms of the Agreement, copying or
13 // reproduction of any part of this source code or associated reference material
14 // to any other location for further reproduction or redistribution, and any
15 // amendments to this copyright notice, are expressly prohibited.
16 //
17 // Any reproduction or redistribution for sale or hiring of the Software not in
18 // accordance with the terms of the Agreement is a violation of copyright law.
19 //
20 
21 #pragma once
22 
23 #include <OnixS/CME/iLink3/ABI.h>
24 
27 
29 
30 /// \private
34 void throwCannotQuantizeOrConvert();
35 
36 /// Universal decimal type.
38 //
39 
40 /// \private
41 inline bool isNull(const Decimal&) ONIXS_ILINK3_NOEXCEPT
42 {
43  return false;
44 }
45 
46 /// Quantize so its exponent is the same as that of provided value.
47 ///
48 /// \return `false` if the value cannot be quantized.
50 bool
51 quantize(
52  const Decimal& operand,
53  Int32 exponent,
54  Decimal& quantized);
55 
56 /// Quantize so its exponent is the same as that of provided value.
57 ///
58 /// \throw std::exception if the value cannot be quantized.
59 ///
60 /// \return resulting decimal.
63 Decimal quantize(const Decimal& operand, Int32 exponent);
64 
65 /// Quantize so its exponent is the same as that of provided value.
66 ///
67 /// \throw std::exception if the value cannot be quantized
68 ///
69 /// \return resulting decimal mantissa
70 template <class MantissaType>
72 MantissaType quantizedMantissa(const Decimal& operand, Int32 exponent)
73 {
74  const Decimal::Mantissa res =
75  quantize(
76  operand, exponent)
77  .mantissa();
78 
79  if(static_cast<MantissaType>(
80  (std::numeric_limits<MantissaType>::max)()) >= res)
81  {
82  return static_cast<MantissaType>(res);
83  }
84 
85  throwCannotQuantizeOrConvert();
86 }
87 
88 template
89 <
90  class MantissaType,
91  class ExponentType
92 >
93 void convert(
95  const Decimal& number)
96 {
97  res =
99  quantizedMantissa<MantissaType>(number, ExponentType()));
100 }
101 
102 template
103  <
104  class MantissaType,
105  class ExponentType
106  >
107 void convert(
109  const Decimal& number)
110 {
111  if(static_cast<MantissaType>(
112  (std::numeric_limits<MantissaType>::max)()) < number.mantissa())
113  {
114  throwCannotQuantizeOrConvert();
115  }
116 
117  res =
119  static_cast<MantissaType>(number.mantissa()),
120  number.exponent());
121 }
122 
123 /// Convert the decimal in to a different one.
124 ///
125 /// \throw std::exception if the value cannot be converted
126 ///
127 /// \return resulting decimal
128 template
129 <
130  class DecimalT
131 >
133 typename EnableIf<details::IsDecimal<DecimalT>::value, DecimalT>::type
134  convert(const Decimal& number)
135 {
136  DecimalT res;
137  convert(res, number);
138  return res;
139 }
140 
141 /// \private
143 bool
145  const Decimal& left,
146  const Decimal& right);
147 
148 /// \private
150 bool
151 operator <(
152  const Decimal& left,
153  const Decimal& right);
154 
155 /// \private
157 bool
159  const Decimal& left,
160  const Decimal& right);
161 
162 /// \private
163 inline
164 bool
165 operator >(
166  const Decimal& left,
167  const Decimal& right)
168 {
169  return (right < left);
170 }
171 
172 /// \private
173 inline
174 bool
176  const Decimal& left,
177  const Decimal& right)
178 {
179  return (right <= left);
180 }
181 
182 /// \private.
184 void
185 decimalToStr(
186  std::string&,
187  Int64,
188  Int32);
189 
190 /// \private.
192 size_t
193 toStr(
194  const Decimal&,
195  Char* buf,
196  size_t size);
197 
198 /// Deserializes a decimal number
199 /// from the given text presentation.
201 bool
202 fromStr(
203  Decimal&,
204  const Char*,
205  size_t);
206 
207 
208 /// Deserializes a decimal number
209 /// from the given text presentation.
210 inline
211 bool
213  Decimal& value,
214  const std::string& str)
215 {
216  return
217  fromStr(
218  value,
219  str.c_str(),
220  str.size());
221 }
222 
223 /// \private
224 inline
225 void
226 toStr(
227  std::string& str,
228  const Decimal& number)
229 {
230  decimalToStr
231  (
232  str,
233  number.mantissa(),
234  number.exponent()
235  );
236 }
237 
238 /// Serializes floating-point decimal into a string.
239 template
240 <
241  class Mantissa,
242  class Exponent
243 >
244 inline
245 void
247  std::string& str,
248  const
250  <Mantissa, Exponent>& number)
251 {
252  if(isNull(number))
253  {
254  str += "[]";
255  return;
256  }
257 
258  toStr(str, Decimal(number));
259 }
260 
261 /// Serializes into a stream.
262 template
263 <
264  class Mantissa,
265  class Exponent
266 >
267 inline
268 std::ostream&
270  std::ostream& stream,
271  const
273  <Mantissa, Exponent>& value)
274 {
275  std::string str;
276 
277  toStr(str, value);
278 
279  return stream << str;
280 }
281 
282 /// Serializes a fixed-point decimal into a string.
283 template
284 <
285  class Mantissa,
286  class Exponent
287 >
288 inline
289 void
291  std::string& str,
292  const
294  <Mantissa, Exponent>& number)
295 {
296  if(isNull(number))
297  {
298  str += "[]";
299  return;
300  }
301 
302  toStr(str, Decimal(number));
303 }
304 
305 /// Serializes a floating-point decimal into a string.
306 template
307 <
308  class Mantissa,
309  class Exponent
310 >
313 {
314  std::string str;
315 
316  toStr(str, number);
317 
318  return str;
319 }
320 
321 /// Serializes a fixed-point decimal into a string.
322 template
323 <
324  class Mantissa,
325  class Exponent
326 >
327 inline
329 std::string
331  const
333  <
334  Mantissa,
335  Exponent
336  >& number)
337 {
338  std::string str;
339 
340  toStr(str, number);
341 
342  return str;
343 }
344 
345 /// Serializes into a stream.
346 inline
347 std::ostream& operator << (std::ostream& stream, const Decimal& value)
348 {
349  std::string str;
350 
351  toStr(str, value);
352 
353  return stream << str;
354 }
355 
356 /// Serializes into a stream.
357 template
358  <
359  class Mantissa,
360  class Exponent
361  >
362 inline
363 std::ostream&
365  std::ostream& stream,
366  const
368  <Mantissa, Exponent>& value)
369 {
370  std::string str;
371 
372  toStr(str, value);
373 
374  return stream << str;
375 }
376 
377 ///\private
378 template
379 <
380  class Decimal1,
381  class Decimal2
382 >
383 void checkAgsValid(
384  const Decimal1& arg1, const Decimal2& arg2)
385 {
386  if(isNull(arg1) || isNull(arg2))
387  throw std::invalid_argument("Provided argument is Null.");
388 }
389 
390 /// Compares two fixed-point decimals.
391 template
392 <
393  class Mantissa,
394  class Exponent
395 >
397 bool
399  const
401  <Mantissa, Exponent>& left,
402  const
404  <Mantissa, Exponent>& right)
405 {
406  if(isNull(left) && isNull(right))
407  return true;
408 
409  return left.mantissa() == right.mantissa();
410 }
411 
412 /// Compares two fixed-point decimals.
413 template
414 <
415  class Mantissa,
416  class Exponent
417 >
419 bool
421  const
423  <Mantissa, Exponent>& left,
424  const
426  <Mantissa, Exponent>& right)
427 {
428  return !(left == right);
429 }
430 
431 /// Compares two fixed-point decimals.
432 template
433 <
434  class Mantissa,
435  class Exponent
436 >
438 bool
440  const
442  <Mantissa, Exponent>& left,
443  const
445  <Mantissa, Exponent>& right)
446 {
447  checkAgsValid(left, right);
448 
449  return left.mantissa() < right.mantissa();
450 }
451 
452 /// Compares two fixed-point decimals.
453 template
454 <
455  class Mantissa,
456  class Exponent
457 >
459 bool
461  const
463  <Mantissa, Exponent>& left,
464  const
466  <Mantissa, Exponent>& right)
467 {
468  checkAgsValid(left, right);
469 
470  return left.mantissa() > right.mantissa();
471 }
472 
473 /// Compares two fixed-point decimals.
474 template
475 <
476  class Mantissa,
477  class Exponent
478 >
480 bool
482  const
484  <Mantissa, Exponent>& left,
485  const
487  <Mantissa, Exponent>& right)
488 {
489  checkAgsValid(left, right);
490 
491  return left.mantissa() <= right.mantissa();
492 }
493 
494 /// Compares two fixed-point decimals.
495 template
496 <
497  class Mantissa,
498  class Exponent
499 >
501 bool
503  const
505  <Mantissa, Exponent>& left,
506  const
508  <Mantissa, Exponent>& right)
509 {
510  checkAgsValid(left, right);
511 
512  return left.mantissa() >= right.mantissa();
513 }
514 
515 /// Compares two decimals.
516 template
517 <
518  class Decimal1,
519  class Decimal2
520 >
522 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
524  const Decimal1& left, const Decimal2& right)
525 {
526  if(isNull(left) && isNull(right))
527  return true;
528 
529  return Decimal(left) == Decimal(right);
530 }
531 
532 /// Compares two decimals.
533 template
534 <
535  class Decimal1,
536  class Decimal2
537 >
539 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
541  const Decimal1& left, const Decimal2& right)
542 {
543  return !(left == right);
544 }
545 
546 /// Compares two decimals.
547 template
548 <
549  class Decimal1,
550  class Decimal2
551 >
553 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
555  const Decimal1& left, const Decimal2& right)
556 {
557  checkAgsValid(left, right);
558 
559  return Decimal(left) > Decimal(right);
560 }
561 
562 /// Compares two decimals.
563 template
564 <
565  class Decimal1,
566  class Decimal2
567 >
569 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
571  const Decimal1& left, const Decimal2& right)
572 {
573  checkAgsValid(left, right);
574 
575  return Decimal(left) >= Decimal(right);
576 }
577 
578 /// Compares two decimals.
579 template
580 <
581  class Decimal1,
582  class Decimal2
583 >
585 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
587  const Decimal1& left, const Decimal2& right)
588 {
589  checkAgsValid(left, right);
590 
591  return Decimal(left) < Decimal(right);
592 }
593 
594 /// Compares two decimals.
595 template
596 <
597  class Decimal1,
598  class Decimal2
599 >
601 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
603  const Decimal1& left, const Decimal2& right)
604 {
605  checkAgsValid(left, right);
606 
607  return Decimal(left) <= Decimal(right);
608 }
609 
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator>=(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
bool isNull(const Decimal32NULL &value)
Definition: Composites.h:400
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator!=(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
char Char
Character type alias.
Definition: String.h:30
FloatingPointDecimal< Int64, Int32 > Decimal
Universal decimal type.
MantissaType quantizedMantissa(const Decimal &operand, Int32 exponent)
Quantize so its exponent is the same as that of provided value.
A real number with a floating exponent.
Definition: Decimal.h:32
#define ONIXS_ILINK3_NORETURN
Definition: Compiler.h:172
std::ostream & operator<<(std::ostream &stream, const FixedPointDecimal< Mantissa, Exponent > &value)
Serializes into a stream.
MantissaType Mantissa
Mantissa component type.
Definition: Decimal.h:56
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator==(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
bool fromStr(Decimal &value, const std::string &str)
Deserializes a decimal number from the given text presentation.
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator<(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
Decimal quantize(const Decimal &operand, Int32 exponent)
Quantize so its exponent is the same as that of provided value.
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_END
Definition: ABI.h:144
#define ONIXS_ILINK3_EXPORTED
Definition: Compiler.h:162
#define ONIXS_ILINK3_COLDPATH
Definition: Compiler.h:176
EnableIf< details::IsDecimal< DecimalT >::value, DecimalT >::type convert(const Decimal &number)
Convert the decimal in to a different one.
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_BEGIN
Definition: ABI.h:140
void toStr(std::string &str, const FixedPointDecimal< Mantissa, Exponent > &number)
Serializes a fixed-point decimal into a string.
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator<=(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
#define ONIXS_ILINK3_NODISCARD
Definition: Compiler.h:173
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator>(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.