OnixS C++ ICE Binary Order Entry Handler 1.1.1
API Documentation
Loading...
Searching...
No Matches
Utils.h
Go to the documentation of this file.
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable OnixS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#pragma once
20
21#include <OnixS/ICE/BOE/ABI.h>
24
25#include "Order.h"
26
27#include <istream>
28#include <sstream>
29
30#ifdef ONIXS_ICEBOE_CXX17
31# include <optional>
32#endif
33
34namespace Samples {
35
36using namespace ONIXS_ICEBOE_NAMESPACE;
38
39namespace details {
40
41template<typename T>
43{
44 template<typename U, Timestamp (U::*)() const> struct SFINAE {};
45 template<typename U> static char test(SFINAE<U, &U::transactTime>*);
46
47#if ONIXS_ICEBOE_CXX17_NOEXCEPT
48 template<typename U, Timestamp (U::*)() const noexcept> struct SFINAE_1 {};
49 template<typename U> static char test(SFINAE_1<U, &U::transactTime>*);
50#endif
51
52 template<typename U> static int test(...);
53 static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(char);
54};
55
56template<typename T>
58{
59 template<typename U, OrderExecID (U::*)() const noexcept> struct SFINAE {};
60 template<typename U> static char test(SFINAE<U, &U::execId>*);
61 template<typename U> static int test(...);
62 static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(char);
63};
64
65template<typename T>
67{
68 template<typename U, typename V, V (U::*)() const noexcept> struct SFINAE {};
69 template<typename U> static char test(SFINAE<U, decltype(std::declval<const U&>().execType()), &U::execType>*);
70 template<typename U> static int test(...);
71 static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(char);
72};
73
74
75template<typename T>
77{
78 template<typename U, typename V, V (U::*)() const noexcept> struct SFINAE {};
79 template<typename U> static char test(SFINAE<U, decltype(std::declval<const U&>().leavesQty()), &U::leavesQty>*);
80 template<typename U> static int test(...);
81 static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(char);
82};
83
84}
85
87template<class T> using hasExecId = typename details::hasExecIdImpl<cleanType<T>>;
88template<class T> using hasExecType = typename details::hasExecTypeImpl<cleanType<T>>;
89template<class T> using hasLeavesQty = typename details::hasLeavesQtyImpl<cleanType<T>>;
90
91template <typename MsgType>
92Timestamp getTransactTime(MsgType&& msg, typename std::enable_if<hasTransactTime<MsgType>::value, void*>::type = nullptr)
93{
94 return msg.transactTime();
95}
96
97template <typename MsgType>
98Timestamp getTransactTime(MsgType&& msg, typename std::enable_if<!hasTransactTime<MsgType>::value && hasExecId<MsgType>::value, void*>::type = nullptr)
99{
100 return msg.execId().transactTime();
101}
102
103template <typename MsgType>
104Timestamp getTransactTime(MsgType&&, typename std::enable_if<!hasTransactTime<MsgType>::value && !hasExecId<MsgType>::value, void*>::type = nullptr)
105{
106 return Timestamp{};
107}
108
109template <typename MsgType>
110ExecTypeEnum getOrdStatus(MsgType&& msg, ExecTypeEnum, typename std::enable_if<hasExecType<MsgType>::value, void*>::type=nullptr)
111{
112 return msg.execType();
113}
114
115template <typename MsgType>
116ExecTypeEnum getOrdStatus(MsgType&&, ExecTypeEnum defaultValue, typename std::enable_if<!hasExecType<MsgType>::value, void*>::type=nullptr)
117{
118 return defaultValue;
119}
120
121template <typename MsgType>
122void setOrdStatus(Order& order, MsgType&& msg, ExecTypeEnum defaultValue)
123{
124 order.orderStatus_ = getOrdStatus(msg, defaultValue);
125}
126
127template <typename MsgType>
128void setLeavesQty(Order& order, MsgType&& msg, typename std::enable_if<hasLeavesQty<MsgType>::value, void*>::type=nullptr)
129{
130 order.leavesQty_ = msg.leavesQty();
131}
132
133template <typename MsgType>
134void setLeavesQty(Order&, MsgType&&, typename std::enable_if<!hasLeavesQty<MsgType>::value, void*>::type=nullptr) {}
135
137{
138 return quantize(value, -9).mantissa();
139}
140
141template <typename T>
142T parseUserInput(const std::string& userInput, typename std::enable_if<std::is_integral<T>::value, void*>::type = nullptr)
143{
144 std::istringstream ss{userInput};
145 ss >> std::ws;
146
147 using Wide = typename std::conditional<std::is_signed<T>::value, long long, unsigned long long>::type;
148 Wide converted{};
149
150 if (!(ss >> converted))
151 throw std::invalid_argument("Invalid user input: '" + userInput + "'");
152
153 return static_cast<T>(converted);
154}
155
156template <typename T>
157T parseUserInput(const std::string& userInput, typename std::enable_if<isScopedEnum<T>::value, void*>::type = nullptr)
158{
159 std::istringstream ss{userInput};
160 ss >> std::ws;
161
162 using Wide =
163 typename std::conditional<
164 std::is_same<typename underlyingType<T>::type, char>::value,
165 char,
166 typename std::conditional<std::is_signed<T>::value,
167 long long,
168 unsigned long long>::type>::type;
169
170 Wide converted{};
171
172 if (!(ss >> converted))
173 throw std::invalid_argument("Invalid user input: '" + userInput + "'");
174
175 const auto enumerated = static_cast<T>(static_cast<typename underlyingType<T>::type>(converted));
176
177 if(ONIXS_ICEBOE_MESSAGING_NAMESPACE::toStr(enumerated).find("UNKNOWN_VALUE") != std::string::npos)
178 throw std::invalid_argument("Invalid user input: '" + userInput + "'");
179
180 return enumerated;
181}
182
183template <typename T>
184Decimal parseUserInput(const std::string& userInput, typename std::enable_if<std::is_floating_point<T>::value, void*>::type = nullptr)
185{
186 Decimal value;
187
188 if(fromStr(value, userInput))
189 return value;
190
191 throw std::invalid_argument("Invalid user input: '" + userInput + "'");
192}
193
194template <typename T>
195T parseUserInput(const std::string& userInput, typename std::enable_if<std::is_same<T, std::string>::value, void*>::type = nullptr)
196{
197 return userInput;
198}
199
200
201template <typename T>
202auto toValueNamePair(T v, typename std::enable_if<isScopedEnum<T>::value, void*>::type=nullptr)
203{
204 return toStr(toUnderlying(v)) + "-" + toStr(v);
205}
206
207template <typename It>
208inline auto join(It first, It last, char delim, typename std::enable_if<isScopedEnum<typename It::value_type>::value, void*>::type=nullptr)
209{
210 if (first == last)
211 return std::string{};
212
213 std::ostringstream oss;
214 oss << toValueNamePair(*first);
215 ++first;
216 for (; first != last; ++first)
217 oss << delim << toValueNamePair(*first);
218
219 return oss.str();
220}
221
223#ifdef ONIXS_ICEBOE_CXX17
224template<typename T> using OptionalRef = std::optional<std::shared_ptr<T>>;
225#else
226template <typename T>
227class OptionalRef
228{
229 using Ref = std::shared_ptr<T>;
230
231public:
232 OptionalRef() noexcept : has_(false) {}
233
234 explicit OptionalRef(std::shared_ptr<T> t)
235 : has_(true)
236 {
237 ::new (&storage_) Ref(t);
238 }
239
240 OptionalRef(const OptionalRef& o)
241 : has_(o.has_)
242 {
243 if (has_) ::new (&storage_) Ref(*o.refptr());
244 }
245
246 OptionalRef(OptionalRef&& o) noexcept
247 : has_(o.has_)
248 {
249 if (has_) ::new (&storage_) Ref(std::move(*o.refptr()));
250 }
251
252 ~OptionalRef() { if (has_) { refptr()->~Ref(); } }
253
254 explicit operator bool() const noexcept { return has_; }
255
256 Ref& operator*() { return value(); }
257 const Ref& operator*() const { return value(); }
258
259 Ref* operator->() { return &value(); }
260 const Ref* operator->() const { return &value(); }
261
262private:
263 Ref* refptr() { return reinterpret_cast<Ref*>(&storage_); }
264 const Ref* refptr() const { return reinterpret_cast<const Ref*>(&storage_); }
265 Ref& value() { if (!has_) throwBadOptionalAccess(); return *refptr(); }
266 const Ref& value() const { if (!has_) throwBadOptionalAccess(); return *refptr(); }
267
268 using Storage = typename std::aligned_storage<sizeof(Ref), alignof(Ref)>::type;
269
270 bool has_;
271 Storage storage_;
272};
273#endif
274
275}
#define ONIXS_ICEBOE_NAMESPACE
Definition ABI.h:113
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE
Definition ABI.h:114
The time point without the time-zone information.
Definition Time.h:470
FloatingPointDecimal< Int64, Int32 > Decimal
Universal decimal type.
ExecTypeEnum
ExecTypeEnum type.
Definition Fields.h:337
Int64 Decimal9
Quantity, Price with constant exponent -9.
Definition Fields.h:32
bool quantize(const Decimal &operand, Int32 exponent, Decimal &quantized)
Quantize so its exponent is the same as that of provided value.
void setOrdStatus(Order &order, MsgType &&msg, ExecTypeEnum defaultValue)
Definition Utils.h:122
typename details::hasTransactTimeImpl< cleanType< T > > hasTransactTime
Definition Utils.h:86
ExecTypeEnum getOrdStatus(MsgType &&msg, ExecTypeEnum, typename std::enable_if< hasExecType< MsgType >::value, void * >::type=nullptr)
Definition Utils.h:110
T parseUserInput(const std::string &userInput, typename std::enable_if< std::is_integral< T >::value, void * >::type=nullptr)
Definition Utils.h:142
auto join(It first, It last, char delim, typename std::enable_if< isScopedEnum< typename It::value_type >::value, void * >::type=nullptr)
Definition Utils.h:208
std::optional< std::shared_ptr< T > > OptionalRef
Manages an optional contained reference.
Definition Utils.h:224
auto toValueNamePair(T v, typename std::enable_if< isScopedEnum< T >::value, void * >::type=nullptr)
Definition Utils.h:202
typename details::hasExecIdImpl< cleanType< T > > hasExecId
Definition Utils.h:87
std::string toStr(Order::PriceOptional value)
Definition Order.cpp:34
Timestamp getTransactTime(MsgType &&msg, typename std::enable_if< hasTransactTime< MsgType >::value, void * >::type=nullptr)
Definition Utils.h:92
typename details::hasExecTypeImpl< cleanType< T > > hasExecType
Definition Utils.h:88
typename details::hasLeavesQtyImpl< cleanType< T > > hasLeavesQty
Definition Utils.h:89
void setLeavesQty(Order &order, MsgType &&msg, typename std::enable_if< hasLeavesQty< MsgType >::value, void * >::type=nullptr)
Definition Utils.h:128
Decimal9 toPriceMantissa(Decimal value)
Definition Utils.h:136
T fromStr(const std::string &s)
Definition Helpers.h:142
ExecTypeEnum orderStatus_
Definition Order.h:70
Qty leavesQty_
Definition Order.h:61
static constexpr bool value
Definition Utils.h:62
static char test(SFINAE< U, &U::execId > *)
static constexpr bool value
Definition Utils.h:71
static char test(SFINAE< U, decltype(std::declval< const U & >().execType()), &U::execType > *)
static char test(SFINAE< U, decltype(std::declval< const U & >().leavesQty()), &U::leavesQty > *)
static constexpr bool value
Definition Utils.h:81
static constexpr bool value
Definition Utils.h:53
static char test(SFINAE< U, &U::transactTime > *)