OnixS C++ CME MDP Conflated TCP Handler  1.3.1
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 
24 
27 
28 #include <limits>
29 
31 
32 /// \private
36 void throwCannotQuantizeOrConvert();
37 
38 /// Universal decimal type.
40 //
41 
42 /// \private
44 inline bool isNull(const Decimal&) ONIXS_CONFLATEDTCP_NOTHROW
45 {
46  return false;
47 }
48 
49 /// Quantize so its exponent is the same as that of provided value.
50 ///
51 /// \return `false` if the value cannot be quantized.
53 bool
54 quantize(
55  const Decimal& operand,
56  Int32 exponent,
57  Decimal& quantized);
58 
59 /// Quantize so its exponent is the same as that of provided value.
60 ///
61 /// \throw std::exception if the value cannot be quantized.
62 ///
63 /// \return resulting decimal.
67 Decimal quantize(const Decimal& operand, Int32 exponent);
68 
69 /// Quantize so its exponent is the same as that of provided value.
70 ///
71 /// \throw std::exception if the value cannot be quantized
72 ///
73 /// \return resulting decimal mantissa
74 template <class MantissaType>
76 MantissaType quantizedMantissa(const Decimal& operand, Int32 exponent)
77 {
78  const Decimal::Mantissa res =
79  quantize(
80  operand, exponent)
81  .mantissa();
82 
83  if(static_cast<MantissaType>(
84  (std::numeric_limits<MantissaType>::max)()) >= res)
85  {
86  return static_cast<MantissaType>(res);
87  }
88 
89  throwCannotQuantizeOrConvert();
90 }
91 
92 template
93 <
94  class MantissaType,
95  class ExponentType
96 >
97 void convert(
99  const Decimal& number)
100 {
101  res =
103  quantizedMantissa<MantissaType>(number, ExponentType()));
104 }
105 
106 template
107  <
108  class MantissaType,
109  class ExponentType
110  >
111 void convert(
113  const Decimal& number)
114 {
115  if(static_cast<MantissaType>(
116  (std::numeric_limits<MantissaType>::max)()) < number.mantissa())
117  {
118  throwCannotQuantizeOrConvert();
119  }
120 
121  res =
123  static_cast<MantissaType>(number.mantissa()),
124  number.exponent());
125 }
126 
127 /// Convert the decimal in to a different one.
128 ///
129 /// \throw std::exception if the value cannot be converted
130 ///
131 /// \return resulting decimal
132 template
133 <
134  class DecimalT
135 >
138 typename EnableIf<details::IsDecimal<DecimalT>::value, DecimalT>::type
139  convert(const Decimal& number)
140 {
141  DecimalT res;
142  convert(res, number);
143  return res;
144 }
145 
146 /// \private
149 bool
151  const Decimal& left,
152  const Decimal& right) ONIXS_CONFLATEDTCP_NOTHROW;
153 
154 /// \private
157 bool
158 operator <(
159  const Decimal& left,
160  const Decimal& right);
161 
162 /// \private
165 bool
167  const Decimal& left,
168  const Decimal& right);
169 
170 /// \private
171 inline
173 bool
174 operator >(
175  const Decimal& left,
176  const Decimal& right)
177 {
178  return (right < left);
179 }
180 
181 /// \private
182 inline
184 bool
186  const Decimal& left,
187  const Decimal& right)
188 {
189  return (right <= left);
190 }
191 
192 /// \private.
194 void
195 decimalToStr(
196  std::string&,
197  Int64,
198  Int32);
199 
200 /// \private.
202 size_t
203 toStr(
204  const Decimal&,
205  Char* buf,
206  size_t size);
207 
208 /// Deserializes a decimal number
209 /// from the given text presentation.
211 bool
212 fromStr(
213  Decimal&,
214  const Char*,
216 
217 
218 /// Deserializes a decimal number
219 /// from the given text presentation.
220 inline
221 bool
223  Decimal& value,
224  const std::string& str) ONIXS_CONFLATEDTCP_NOTHROW
225 {
226  return
227  fromStr(
228  value,
229  str.c_str(),
230  str.size());
231 }
232 
233 /// \private
234 inline
235 void
236 toStr(
237  std::string& str,
238  const Decimal& number)
239 {
240  decimalToStr
241  (
242  str,
243  number.mantissa(),
244  number.exponent()
245  );
246 }
247 
248 /// Serializes floating-point decimal into a string.
249 template
250 <
251  class Mantissa,
252  class Exponent
253 >
254 inline
255 void
257  std::string& str,
258  const
260  <Mantissa, Exponent>& number)
261 {
262  if(isNull(number))
263  {
264  str += "[]";
265  return;
266  }
267 
268  toStr(str, Decimal(number));
269 }
270 
271 /// Serializes into a stream.
272 template
273 <
274  class Mantissa,
275  class Exponent
276 >
277 inline
278 std::ostream&
280  std::ostream& stream,
281  const
283  <Mantissa, Exponent>& value)
284 {
285  std::string str;
286 
287  toStr(str, value);
288 
289  return stream << str;
290 }
291 
292 /// Serializes a fixed-point decimal into a string.
293 template
294 <
295  class Mantissa,
296  class Exponent
297 >
298 inline
299 void
301  std::string& str,
302  const
304  <Mantissa, Exponent>& number)
305 {
306  if(isNull(Decimal(number)))
307  {
308  str += "[]";
309  return;
310  }
311 
312  toStr(str, Decimal(number));
313 }
314 
315 /// Serializes a floating-point decimal into a string.
316 template
317 <
318  class Mantissa,
319  class Exponent
320 >
323 {
324  std::string str;
325 
326  toStr(str, number);
327 
328  return str;
329 }
330 
331 /// Serializes a fixed-point decimal into a string.
332 template
333 <
334  class Mantissa,
335  class Exponent
336 >
337 inline
339 std::string
341  const
343  <
344  Mantissa,
345  Exponent
346  >& number)
347 {
348  std::string str;
349 
350  toStr(str, number);
351 
352  return str;
353 }
354 
355 /// Serializes into a stream.
356 inline
357 std::ostream& operator << (std::ostream& stream, const Decimal& value)
358 {
359  std::string str;
360 
361  toStr(str, value);
362 
363  return stream << str;
364 }
365 
366 /// Serializes into a stream.
367 template
368  <
369  class Mantissa,
370  class Exponent
371  >
372 inline
373 std::ostream&
375  std::ostream& stream,
376  const
378  <Mantissa, Exponent>& value)
379 {
380  std::string str;
381 
382  toStr(str, value);
383 
384  return stream << str;
385 }
386 
387 ///\private
388 template
389 <
390  class Decimal1,
391  class Decimal2
392 >
393 void checkAgsValid(
394  const Decimal1& arg1, const Decimal2& arg2)
395 {
396  if(isNull(arg1) || isNull(arg2))
397  throw std::invalid_argument("Provided argument is Null.");
398 }
399 
400 /// Compares two fixed-point decimals.
401 template
402 <
403  class Mantissa,
404  class Exponent
405 >
408 bool
410  const
412  <Mantissa, Exponent>& left,
413  const
415  <Mantissa, Exponent>& right)
416 {
417  if(isNull(left) && isNull(right))
418  return true;
419 
420  return left.mantissa() == right.mantissa();
421 }
422 
423 /// Compares two fixed-point decimals.
424 template
425 <
426  class Mantissa,
427  class Exponent
428 >
431 bool
433  const
435  <Mantissa, Exponent>& left,
436  const
438  <Mantissa, Exponent>& right)
439 {
440  return !(left == right);
441 }
442 
443 /// Compares two fixed-point decimals.
444 template
445 <
446  class Mantissa,
447  class Exponent
448 >
451 bool
453  const
455  <Mantissa, Exponent>& left,
456  const
458  <Mantissa, Exponent>& right)
459 {
460  checkAgsValid(left, right);
461 
462  return left.mantissa() < right.mantissa();
463 }
464 
465 /// Compares two fixed-point decimals.
466 template
467 <
468  class Mantissa,
469  class Exponent
470 >
473 bool
475  const
477  <Mantissa, Exponent>& left,
478  const
480  <Mantissa, Exponent>& right)
481 {
482  checkAgsValid(left, right);
483 
484  return left.mantissa() > right.mantissa();
485 }
486 
487 /// Compares two fixed-point decimals.
488 template
489 <
490  class Mantissa,
491  class Exponent
492 >
495 bool
497  const
499  <Mantissa, Exponent>& left,
500  const
502  <Mantissa, Exponent>& right)
503 {
504  checkAgsValid(left, right);
505 
506  return left.mantissa() <= right.mantissa();
507 }
508 
509 /// Compares two fixed-point decimals.
510 template
511 <
512  class Mantissa,
513  class Exponent
514 >
517 bool
519  const
521  <Mantissa, Exponent>& left,
522  const
524  <Mantissa, Exponent>& right)
525 {
526  checkAgsValid(left, right);
527 
528  return left.mantissa() >= right.mantissa();
529 }
530 
531 /// Compares two decimals.
532 template
533 <
534  class Decimal1,
535  class Decimal2
536 >
539 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
541  const Decimal1& left, const Decimal2& right)
542 {
543  bool isNullLeft = isNull(left);
544  bool isNullRight = isNull(right);
545 
546  if (isNullLeft && isNullRight)
547  return true;
548 
549  return Decimal(left) == Decimal(right);
550 }
551 
552 /// Compares two decimals.
553 template
554 <
555  class Decimal1,
556  class Decimal2
557 >
560 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
562  const Decimal1& left, const Decimal2& right)
563 {
564  return !(left == right);
565 }
566 
567 /// Compares two decimals.
568 template
569 <
570  class Decimal1,
571  class Decimal2
572 >
575 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
577  const Decimal1& left, const Decimal2& right)
578 {
579  checkAgsValid(left, right);
580 
581  return Decimal(left) > Decimal(right);
582 }
583 
584 /// Compares two decimals.
585 template
586 <
587  class Decimal1,
588  class Decimal2
589 >
592 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
594  const Decimal1& left, const Decimal2& right)
595 {
596  checkAgsValid(left, right);
597 
598  return Decimal(left) >= Decimal(right);
599 }
600 
601 /// Compares two decimals.
602 template
603 <
604  class Decimal1,
605  class Decimal2
606 >
609 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
611  const Decimal1& left, const Decimal2& right)
612 {
613  checkAgsValid(left, right);
614 
615  return Decimal(left) < Decimal(right);
616 }
617 
618 /// Compares two decimals.
619 template
620 <
621  class Decimal1,
622  class Decimal2
623 >
626 typename EnableIf<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
628  const Decimal1& left, const Decimal2& right)
629 {
630  checkAgsValid(left, right);
631 
632  return Decimal(left) <= Decimal(right);
633 }
634 
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator>=(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator<=(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
A real number with a floating exponent.
Definition: Decimal.h:32
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator==(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
#define ONIXS_CONFLATEDTCP_NOTHROW
Definition: Compiler.h:189
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) noexcept
Deserializes a decimal number from the given text presentation.
FloatingPointDecimal< Int64, Int32 > Decimal
Universal decimal type.
#define ONIXS_CONFLATEDTCP_EXPORTED
Definition: Compiler.h:187
void toStr(std::string &str, const FixedPointDecimal< Mantissa, Exponent > &number)
Serializes a fixed-point decimal into a string.
EnableIf< details::IsDecimal< DecimalT >::value, DecimalT >::type convert(const Decimal &number)
Convert the decimal in to a different one.
#define ONIXS_CONFLATEDTCP_MESSAGING_MDP_NAMESPACE_BEGIN
Definition: ABI.h:148
std::ostream & operator<<(std::ostream &stream, const FixedPointDecimal< Mantissa, Exponent > &value)
Serializes into a stream.
#define ONIXS_CONFLATEDTCP_MESSAGING_MDP_NAMESPACE_END
Definition: ABI.h:152
#define ONIXS_CONFLATEDTCP_NORETURN
Definition: Compiler.h:197
#define ONIXS_CONFLATEDTCP_PURE
Definition: Compiler.h:202
#define ONIXS_CONFLATEDTCP_CONSTEXPR
Definition: Compiler.h:192
#define ONIXS_CONFLATEDTCP_NODISCARD
Definition: Compiler.h:198
#define ONIXS_CONFLATEDTCP_COLDPATH
Definition: Compiler.h:201
EnableIf< details::AreBothDecimals< Decimal1, Decimal2 >::value, bool >::type operator<(const Decimal1 &left, const Decimal2 &right)
Compares two decimals.
MantissaType Mantissa
Mantissa component type.
Definition: Decimal.h:56
MantissaType quantizedMantissa(const Decimal &operand, Int32 exponent)
Quantize so its exponent is the same as that of provided value.
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
bool isNull(const PRICE9 &value) noexcept
Definition: Composites.h:767
Decimal quantize(const Decimal &operand, Int32 exponent)
Quantize so its exponent is the same as that of provided value.