OnixS C++ CME MDP Premium Market Data Handler 5.10.2
Users' manual and API documentation
Loading...
Searching...
No Matches
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/MDH/ABI.h>
24
27
28#include <limits>
29#include <type_traits>
30
32
37void throwCannotQuantizeOrConvert();
38
39//
40
47
48namespace details
49{
50 template <class MantissaType>
51 typename std::enable_if<std::numeric_limits<MantissaType>::is_signed, bool>::type
53 {
54 return static_cast<Decimal::Mantissa>((std::numeric_limits<MantissaType>::min)()) <= value &&
55 value <= static_cast<Decimal::Mantissa>((std::numeric_limits<MantissaType>::max)());
56 }
57
58 template <class MantissaType>
59 typename std::enable_if<!std::numeric_limits<MantissaType>::is_signed && (sizeof(MantissaType) < sizeof(Decimal::Mantissa)), bool>::type
61 {
62 return Decimal::Mantissa() <= value &&
63 value <= static_cast<Decimal::Mantissa>((std::numeric_limits<MantissaType>::max)());
64 }
65
66 template <class MantissaType>
67 typename std::enable_if<!std::numeric_limits<MantissaType>::is_signed && (sizeof(MantissaType) >= sizeof(Decimal::Mantissa)), bool>::type
69 {
70 return Decimal::Mantissa() <= value;
71 }
72
73 template <class ExponentType>
74 typename std::enable_if<std::numeric_limits<ExponentType>::is_signed && (sizeof(ExponentType) < sizeof(Decimal::Exponent)), bool>::type
76 {
77 return static_cast<Decimal::Exponent>((std::numeric_limits<ExponentType>::min)()) <= value &&
78 value <= static_cast<Decimal::Exponent>((std::numeric_limits<ExponentType>::max)());
79 }
80
81 template <class ExponentType>
82 typename std::enable_if<std::numeric_limits<ExponentType>::is_signed && (sizeof(ExponentType) >= sizeof(Decimal::Exponent)), bool>::type
84 {
85 return true;
86 }
87
88 template <class ExponentType>
89 typename std::enable_if<!std::numeric_limits<ExponentType>::is_signed && (sizeof(ExponentType) < sizeof(Decimal::Exponent)), bool>::type
91 {
92 return Decimal::Exponent() <= value &&
93 value <= static_cast<Decimal::Exponent>((std::numeric_limits<ExponentType>::max)());
94 }
95
96 template <class ExponentType>
97 typename std::enable_if<!std::numeric_limits<ExponentType>::is_signed && (sizeof(ExponentType) >= sizeof(Decimal::Exponent)), bool>::type
99 {
100 return Decimal::Exponent() <= value;
101 }
102}
103
105inline constexpr bool isNull(const Decimal&) noexcept
106{
107 return false;
108}
109
114bool quantize(const Decimal& operand, Int32 exponent, Decimal& quantized);
115
124Decimal quantize(const Decimal& operand, Int32 exponent);
125
131template <class MantissaType>
132ONIXS_CMEMDH_NODISCARD MantissaType quantizedMantissa(const Decimal& operand, Int32 exponent)
133{
134 const auto res = quantize(operand, exponent).mantissa();
135
136 if ONIXS_CMEMDH_UNLIKELY(!details::isMantissaInRange<MantissaType>(res))
137 throwCannotQuantizeOrConvert();
138
139 return static_cast<MantissaType>(res);
140}
141
142template <class MantissaType, class ExponentType>
147
148template <class MantissaType, class ExponentType>
150{
151 if ONIXS_CMEMDH_UNLIKELY(!details::isMantissaInRange<MantissaType>(number.mantissa()) ||
153 throwCannotQuantizeOrConvert();
154
156 static_cast<MantissaType>(number.mantissa()),
157 static_cast<ExponentType>(number.exponent()));
158}
159
165template <class DecimalT>
166ONIXS_CMEMDH_NODISCARD ONIXS_CMEMDH_PURE typename std::enable_if<details::IsDecimal<DecimalT>::value, DecimalT>::type
167convert(const Decimal& number)
168{
169 DecimalT res;
170 convert(res, number);
171 return res;
172}
173
177bool decimalEqual(const Decimal& left, const Decimal& right) noexcept;
178
180inline bool operator==(const Decimal& left, const Decimal& right) noexcept
181{
182 return ((left.exponent() == right.exponent()) ? (left.mantissa() == right.mantissa()) : decimalEqual(left, right));
183}
184
186inline bool operator!=(const Decimal& left, const Decimal& right)
187{
188 return ((left.exponent() == right.exponent()) ? (left.mantissa() != right.mantissa()) : !decimalEqual(left, right));
189}
190
194bool decimalLess(const Decimal& left, const Decimal& right) noexcept;
195
197inline bool operator<(const Decimal& left, const Decimal& right) noexcept
198{
199 return ((left.exponent() == right.exponent()) ? (left.mantissa() < right.mantissa()) : decimalLess(left, right));
200}
201
203inline bool operator<=(const Decimal& left, const Decimal& right)
204{
205 return !(right < left);
206}
207
209inline ONIXS_CMEMDH_PURE bool operator>(const Decimal& left, const Decimal& right)
210{
211 return (right < left);
212}
213
215inline ONIXS_CMEMDH_PURE bool operator>=(const Decimal& left, const Decimal& right)
216{
217 return (right <= left);
218}
219
222void decimalToStr(std::string&, Int64, Int32);
223
226size_t toStr(const Decimal&, Char* buf, size_t size);
227
231bool fromStr(Decimal&, const Char*, size_t);
232
235inline bool fromStr(Decimal& value, const std::string& str)
236{
237 return fromStr(value, str.c_str(), str.size());
238}
239
241inline void toStr(std::string& str, const Decimal& number)
242{
243 decimalToStr(str, number.mantissa(), number.exponent());
244}
245
247template <class Mantissa, class Exponent>
248inline void toStr(std::string& str, const FloatingPointDecimal<Mantissa, Exponent>& number)
249{
250 if (isNull(number))
251 {
252 str += "[]";
253 return;
254 }
255
256 toStr(str, Decimal(number));
257}
258
260template <class Mantissa, class Exponent>
261inline void toStr(std::string& str, const FixedPointDecimal<Mantissa, Exponent>& number)
262{
263 if (isNull(number))
264 {
265 str += "[]";
266 return;
267 }
268
269 toStr(str, Decimal(number));
270}
271
273template <class Mantissa, class Exponent>
275{
276 std::string str;
277
278 toStr(str, number);
279
280 return str;
281}
282
284template <class Mantissa, class Exponent>
286{
287 std::string str;
288
289 toStr(str, number);
290
291 return str;
292}
293
295template <class Decimal1, class Decimal2>
296void checkAgsValid(const Decimal1& arg1, const Decimal2& arg2)
297{
298 if (isNull(arg1) || isNull(arg2))
299 throw std::invalid_argument("Provided argument is Null.");
300}
301
303template <class Mantissa, class Exponent>
306{
307 if (isNull(left) && isNull(right))
308 return true;
309
310 return left.mantissa() == right.mantissa();
311}
312
314template <class Mantissa, class Exponent>
317{
318 return !(left == right);
319}
320
322template <class Mantissa, class Exponent>
325{
326 checkAgsValid(left, right);
327
328 return left.mantissa() < right.mantissa();
329}
330
332template <class Mantissa, class Exponent>
335{
336 checkAgsValid(left, right);
337
338 return left.mantissa() > right.mantissa();
339}
340
342template <class Mantissa, class Exponent>
345{
346 checkAgsValid(left, right);
347
348 return left.mantissa() <= right.mantissa();
349}
350
352template <class Mantissa, class Exponent>
355{
356 checkAgsValid(left, right);
357
358 return left.mantissa() >= right.mantissa();
359}
360
362template <class Decimal1, class Decimal2>
364 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
365 operator==(const Decimal1& left, const Decimal2& right)
366{
367 if (isNull(left) && isNull(right))
368 return true;
369
370 return Decimal(left) == Decimal(right);
371}
372
374template <class Decimal1, class Decimal2>
376 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
377 operator!=(const Decimal1& left, const Decimal2& right)
378{
379 return !(left == right);
380}
381
383template <class Decimal1, class Decimal2>
385 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
386 operator>(const Decimal1& left, const Decimal2& right)
387{
388 checkAgsValid(left, right);
389
390 return Decimal(left) > Decimal(right);
391}
392
394template <class Decimal1, class Decimal2>
396 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
397 operator>=(const Decimal1& left, const Decimal2& right)
398{
399 checkAgsValid(left, right);
400
401 return Decimal(left) >= Decimal(right);
402}
403
405template <class Decimal1, class Decimal2>
407 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
408 operator<(const Decimal1& left, const Decimal2& right)
409{
410 checkAgsValid(left, right);
411
412 return Decimal(left) < Decimal(right);
413}
414
416template <class Decimal1, class Decimal2>
418 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
419 operator<=(const Decimal1& left, const Decimal2& right)
420{
421 checkAgsValid(left, right);
422
423 return Decimal(left) <= Decimal(right);
424}
425
427template <class Mantissa, class Exponent>
428std::ostream& operator<<(std::ostream& stream, const FixedPointDecimal<Mantissa, Exponent>& value)
429{
430 std::string str;
431
432 toStr(str, value);
433
434 return stream << str;
435}
436
438template <class Mantissa, class Exponent>
439std::ostream& operator<<(std::ostream& stream, const FloatingPointDecimal<Mantissa, Exponent>& value)
440{
441 std::string str;
442
443 toStr(str, value);
444
445 return stream << str;
446}
447
#define ONIXS_CMEMDH_MESSAGING_NAMESPACE_BEGIN
Definition Bootstrap.h:57
#define ONIXS_CMEMDH_MESSAGING_NAMESPACE_END
Definition Bootstrap.h:58
#define ONIXS_CMEMDH_COLDPATH
Definition Compiler.h:153
#define ONIXS_CMEMDH_EXPORTED
Definition Compiler.h:148
#define ONIXS_CMEMDH_NORETURN
Definition Compiler.h:149
#define ONIXS_CMEMDH_PURE
Definition Compiler.h:154
#define ONIXS_CMEMDH_NODISCARD
Definition Compiler.h:150
A real number with a floating exponent.
Definition Decimal.h:39
std::enable_if< std::numeric_limits< MantissaType >::is_signed, bool >::type isMantissaInRange(Decimal::Mantissa value) noexcept
std::enable_if< std::numeric_limits< ExponentType >::is_signed &&(sizeof(ExponentType)< sizeof(Decimal::Exponent)), bool >::type isExponentInRange(Decimal::Exponent value) noexcept
bool operator>=(const Timestamp &left, const Timestamp &right) noexcept
Compares instances.
Definition Time.h:677
Int32 DecimalExponent
Aliases exponent component type for the decimal type.
bool operator<=(const Timestamp &left, const Timestamp &right) noexcept
Compares instances.
Definition Time.h:663
Int64 DecimalMantissa
Aliases mantissa component type for the decimal type.
MantissaType quantizedMantissa(const Decimal &operand, Int32 exponent)
bool fromStr(Int8 &, const Char *, size_t)
bool operator!=(const TimeSpan &left, const TimeSpan &right) noexcept
Compares Timespans.
Definition Time.h:312
char Char
Character type alias.
Definition String.h:30
bool operator==(const TimeSpan &left, const TimeSpan &right) noexcept
Compares Timespans.
Definition Time.h:305
std::int32_t Int32
int32.
Definition Integral.h:34
bool quantize(const Decimal &operand, Int32 exponent, Decimal &quantized)
bool operator<(const TimeSpan &left, const TimeSpan &right) noexcept
Compares Timespans.
Definition Time.h:319
FloatingPointDecimal< DecimalMantissa, DecimalExponent > Decimal
Universal decimal type.
void convert(FixedPointDecimal< MantissaType, ExponentType > &res, const Decimal &number)
bool operator>(const TimeSpan &left, const TimeSpan &right) noexcept
Compares Timespans.
Definition Time.h:326
void toStr(std::string &, Int8)
Serializes given integer into a string.
std::ostream & operator<<(std::ostream &os, const Timestamp &value)
Definition Time.h:746
void toStr(std::string &, BookState::Enum)
Serializes book state value into a string.
bool operator==(const MemoryPoolAllocator< Object > &left, const MemoryPoolAllocator< OtherObject > &right)
Definition MemoryPool.h:181