OnixS C++ CME MDP Premium Market Data Handler 5.11.1
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
123Decimal quantize(const Decimal& operand, Int32 exponent);
124
130template <class MantissaType>
131ONIXS_CMEMDH_NODISCARD MantissaType quantizedMantissa(const Decimal& operand, Int32 exponent)
132{
133 const auto res = quantize(operand, exponent).mantissa();
134
135 if ONIXS_CMEMDH_UNLIKELY(!details::isMantissaInRange<MantissaType>(res))
136 throwCannotQuantizeOrConvert();
137
138 return static_cast<MantissaType>(res);
139}
140
141template <class MantissaType, class ExponentType>
146
147template <class MantissaType, class ExponentType>
149{
150 if ONIXS_CMEMDH_UNLIKELY(!details::isMantissaInRange<MantissaType>(number.mantissa()) ||
152 throwCannotQuantizeOrConvert();
153
155 static_cast<MantissaType>(number.mantissa()),
156 static_cast<ExponentType>(number.exponent()));
157}
158
164template <class DecimalT>
165ONIXS_CMEMDH_NODISCARD typename std::enable_if<details::IsDecimal<DecimalT>::value, DecimalT>::type
166convert(const Decimal& number)
167{
168 DecimalT res;
169 convert(res, number);
170 return res;
171}
172
176bool decimalEqual(const Decimal& left, const Decimal& right) noexcept;
177
179inline bool operator==(const Decimal& left, const Decimal& right) noexcept
180{
181 return ((left.exponent() == right.exponent()) ? (left.mantissa() == right.mantissa()) : decimalEqual(left, right));
182}
183
185inline bool operator!=(const Decimal& left, const Decimal& right)
186{
187 return ((left.exponent() == right.exponent()) ? (left.mantissa() != right.mantissa()) : !decimalEqual(left, right));
188}
189
193bool decimalLess(const Decimal& left, const Decimal& right) noexcept;
194
196inline bool operator<(const Decimal& left, const Decimal& right) noexcept
197{
198 return ((left.exponent() == right.exponent()) ? (left.mantissa() < right.mantissa()) : decimalLess(left, right));
199}
200
202inline bool operator<=(const Decimal& left, const Decimal& right)
203{
204 return !(right < left);
205}
206
208inline bool operator>(const Decimal& left, const Decimal& right)
209{
210 return (right < left);
211}
212
214inline bool operator>=(const Decimal& left, const Decimal& right)
215{
216 return (right <= left);
217}
218
221void decimalToStr(std::string&, Int64, Int32);
222
225size_t toStr(const Decimal&, Char* buf, size_t size);
226
230bool fromStr(Decimal&, const Char*, size_t);
231
234inline bool fromStr(Decimal& value, const std::string& str)
235{
236 return fromStr(value, str.c_str(), str.size());
237}
238
240inline void toStr(std::string& str, const Decimal& number)
241{
242 decimalToStr(str, number.mantissa(), number.exponent());
243}
244
246template <class Mantissa, class Exponent>
247inline void toStr(std::string& str, const FloatingPointDecimal<Mantissa, Exponent>& number)
248{
249 if (isNull(number))
250 {
251 str += "[]";
252 return;
253 }
254
255 toStr(str, Decimal(number));
256}
257
259template <class Mantissa, class Exponent>
260inline void toStr(std::string& str, const FixedPointDecimal<Mantissa, Exponent>& number)
261{
262 if (isNull(number))
263 {
264 str += "[]";
265 return;
266 }
267
268 toStr(str, Decimal(number));
269}
270
272template <class Mantissa, class Exponent>
274{
275 std::string str;
276
277 toStr(str, number);
278
279 return str;
280}
281
283template <class Mantissa, class Exponent>
285{
286 std::string str;
287
288 toStr(str, number);
289
290 return str;
291}
292
294template <class Decimal1, class Decimal2>
295void checkAgsValid(const Decimal1& arg1, const Decimal2& arg2)
296{
297 if (isNull(arg1) || isNull(arg2))
298 throw std::invalid_argument("Provided argument is Null.");
299}
300
302template <class Mantissa, class Exponent>
305{
306 if (isNull(left) && isNull(right))
307 return true;
308
309 return left.mantissa() == right.mantissa();
310}
311
313template <class Mantissa, class Exponent>
316{
317 return !(left == right);
318}
319
321template <class Mantissa, class Exponent>
324{
325 checkAgsValid(left, right);
326
327 return left.mantissa() < right.mantissa();
328}
329
331template <class Mantissa, class Exponent>
334{
335 checkAgsValid(left, right);
336
337 return left.mantissa() > right.mantissa();
338}
339
341template <class Mantissa, class Exponent>
344{
345 checkAgsValid(left, right);
346
347 return left.mantissa() <= right.mantissa();
348}
349
351template <class Mantissa, class Exponent>
354{
355 checkAgsValid(left, right);
356
357 return left.mantissa() >= right.mantissa();
358}
359
361template <class Decimal1, class Decimal2>
363 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
364 operator==(const Decimal1& left, const Decimal2& right)
365{
366 if (isNull(left) && isNull(right))
367 return true;
368
369 return Decimal(left) == Decimal(right);
370}
371
373template <class Decimal1, class Decimal2>
375 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
376 operator!=(const Decimal1& left, const Decimal2& right)
377{
378 return !(left == right);
379}
380
382template <class Decimal1, class Decimal2>
384 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
385 operator>(const Decimal1& left, const Decimal2& right)
386{
387 checkAgsValid(left, right);
388
389 return Decimal(left) > Decimal(right);
390}
391
393template <class Decimal1, class Decimal2>
395 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
396 operator>=(const Decimal1& left, const Decimal2& right)
397{
398 checkAgsValid(left, right);
399
400 return Decimal(left) >= Decimal(right);
401}
402
404template <class Decimal1, class Decimal2>
406 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
407 operator<(const Decimal1& left, const Decimal2& right)
408{
409 checkAgsValid(left, right);
410
411 return Decimal(left) < Decimal(right);
412}
413
415template <class Decimal1, class Decimal2>
417 typename std::enable_if<details::AreBothDecimals<Decimal1, Decimal2>::value, bool>::type
418 operator<=(const Decimal1& left, const Decimal2& right)
419{
420 checkAgsValid(left, right);
421
422 return Decimal(left) <= Decimal(right);
423}
424
426template <class Mantissa, class Exponent>
427std::ostream& operator<<(std::ostream& stream, const FixedPointDecimal<Mantissa, Exponent>& value)
428{
429 std::string str;
430
431 toStr(str, value);
432
433 return stream << str;
434}
435
437template <class Mantissa, class Exponent>
438std::ostream& operator<<(std::ostream& stream, const FloatingPointDecimal<Mantissa, Exponent>& value)
439{
440 std::string str;
441
442 toStr(str, value);
443
444 return stream << str;
445}
446
#define ONIXS_CMEMDH_MESSAGING_NAMESPACE_BEGIN
Definition Bootstrap.h:77
#define ONIXS_CMEMDH_MESSAGING_NAMESPACE_END
Definition Bootstrap.h:78
#define ONIXS_CMEMDH_COLDPATH
Definition Compiler.h:168
#define ONIXS_CMEMDH_EXPORTED
Definition Compiler.h:163
#define ONIXS_CMEMDH_NORETURN
Definition Compiler.h:164
#define ONIXS_CMEMDH_PURE
Definition Compiler.h:169
#define ONIXS_CMEMDH_NODISCARD
Definition Compiler.h:165
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:695
Int32 DecimalExponent
Aliases exponent component type for the decimal type.
bool operator<=(const Timestamp &left, const Timestamp &right) noexcept
Compares instances.
Definition Time.h:683
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:340
char Char
Character type alias.
Definition String.h:30
bool operator==(const TimeSpan &left, const TimeSpan &right) noexcept
Compares Timespans.
Definition Time.h:334
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:346
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:352
void toStr(std::string &, Int8)
Serializes given integer into a string.
std::ostream & operator<<(std::ostream &os, const Timestamp &value)
Definition Time.h:761
bool operator==(const MemoryPoolAllocator< Object > &left, const MemoryPoolAllocator< OtherObject > &right) noexcept
Tests whether two allocators use the same pool.
Definition MemoryPool.h:302
void toStr(std::string &str, BookState::Enum bookState)
Appends a string representation of a book state.