OnixS C++ ICE Binary Order Entry Handler 1.0.0
API Documentation
Loading...
Searching...
No Matches
SbeOptional.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/ICE/BOE/ABI.h>
28
29#ifdef ONIXS_ICEBOE_CXX17
30# include <optional>
31#endif
32
34
36
37#ifdef ONIXS_ICEBOE_CXX17
38 using NullOpt = std::nullopt_t;
39 constexpr auto nullOpt = std::nullopt;
40#else
41 struct NullOpt
42 {
43 enum class _Construct { _Token };
44 explicit constexpr NullOpt(_Construct) noexcept {}
45 };
46 constexpr NullOpt nullOpt { NullOpt::_Construct::_Token };
47#endif
48
49inline std::string toStr(NullOpt)
50{
51 return "[]";
52}
53
54
55template <typename Derived>
57{
58public:
59 template <typename D = Derived>
60 ONIXS_ICEBOE_FORCEINLINE
61 auto value() const -> decltype(*std::declval<const D&>())
62 {
63 if (!this_().hasValue())
65
66 return *this_();
67 }
68
69 ONIXS_ICEBOE_FORCEINLINE
70 static constexpr Derived null() noexcept
71 {
72 return {};
73 }
74
75 explicit operator bool() const noexcept
76 {
77 return this_().hasValue();
78 }
79
80#ifdef ONIXS_ICEBOE_CXX17
81 template <typename D = Derived>
82 using Native = std::optional<std::decay_t<decltype(*std::declval<const D&>())>>;
83
84 template <typename D = Derived>
85 auto asNative() const noexcept
86 {
87 return this_().hasValue() ? Native<D>(*this_()) : std::nullopt;
88 }
89
90 template <typename D = Derived>
91 operator Native<D>() const noexcept(noexcept(asNative<D>()))
92 {
93 return asNative();
94 }
95#endif
96
97protected:
98 ~SbeOptionalField() = default;
99
100private:
101 ONIXS_ICEBOE_FORCEINLINE
102 const Derived& this_() const noexcept
103 {
104 return *static_cast<const Derived*>(this);
105 }
106};
107
108template <typename T, typename Null, typename Enable = void> class SbeOptional;
109
110template<class T, typename Null>
112 <
113 T
114 , Null
115 , typename std::enable_if
116 <
117 std::is_same<T, typename Null::Value>::value
118 && isConstant<Null>::value
119 && !isScopedEnum<T>::value
120 >::type
121 >
122 : public SbeOptionalField<SbeOptional<T, Null>>
123{
124public:
125 using HeldType = T;
126
127 template<typename U
128 , typename std::enable_if<std::is_constructible<T, U&&>::value, void*>::type = nullptr>
129 SbeOptional(U&& u) noexcept(noexcept(T(std::forward<U>(u))))
130 : value_(std::forward<U>(u))
131 {
132 }
133
134 template<class U, class V, class... Rest
135 , typename std::enable_if<std::is_constructible<T, U&&, V&&, Rest&&...>::value, void*>::type = nullptr>
136 explicit SbeOptional(U&& u, V&& v, Rest&&... rest) noexcept(noexcept(T(std::forward<U>(u), std::forward<V>(v), std::forward<Rest>(rest)...)))
137 : value_(std::forward<U>(u), std::forward<V>(v), std::forward<Rest>(rest)...)
138 {
139 }
140
141 constexpr SbeOptional() noexcept
142 : value_(Null::value())
143 {
144 }
145
146 constexpr SbeOptional(NullOpt) noexcept
147 : value_(Null::value())
148 {
149 }
150
151 ChooseValueKind<T> raw() const noexcept
152 {
153 return value_;
154 }
155
156 bool hasValue() const noexcept
157 {
158 return value_ != Null::value();
159 }
160
161 ChooseValueKind<T> operator*() const noexcept
162 {
163 assert(hasValue());
164 return value_;
165 }
166
167 const T* operator->() const noexcept
168 {
169 assert(hasValue());
170 return &value_;
171 }
172
173private:
174 T value_;
175};
176
178template<class T, typename Null>
181{
182 static_assert(isScopedEnum<T>::value, "");
183 static_assert(std::is_same<typename underlyingType<T>::type, typename Null::Value>::value, "");
184
185public:
186 using HeldType = T;
187
189 : value_(v)
190 {
191 }
192
193 constexpr SbeOptionalEnumeration() noexcept
194 : value_(static_cast<T>(Null::value()))
195 {
196 }
197
198 constexpr SbeOptionalEnumeration(NullOpt) noexcept
199 : value_(static_cast<T>(Null::value()))
200 {
201 }
202
203 T raw() const noexcept
204 {
205 return value_;
206 }
207
208 bool hasValue() const noexcept
209 {
210 return toUnderlying(value_) != Null::value();
211 }
212
213 T operator*() const noexcept
214 {
215 assert(hasValue());
216 return value_;
217 }
218
219private:
220 T value_;
221};
222
223
226 : public SbeOptionalField<SbeOptionalStr>
227{
228public:
230
231 constexpr SbeOptionalStr(StrRef v) noexcept
232 : value_(v)
233 {
234 }
235
236 constexpr SbeOptionalStr() noexcept
237 : value_(StrRef{})
238 {
239 }
240
241 constexpr SbeOptionalStr(NullOpt) noexcept
242 : value_(StrRef{})
243 {
244 }
245
246 StrRef raw() const noexcept
247 {
248 return value_;
249 }
250
251 bool hasValue() const noexcept
252 {
253 return !value_.empty();
254 }
255
256 StrRef operator*() const noexcept
257 {
258 assert(hasValue());
259 return value_;
260 }
261
262 const StrRef* operator->() const noexcept
263 {
264 return &value_;
265 }
266
267private:
268 StrRef value_;
269};
270
272template<class T>
274 : public SbeOptionalField<SbeOptionalConverted<T>>
275{
276public:
277 using HeldType = T;
278
280 : valid_(true)
281 {
282 new (static_cast<void*>(storage_)) T(std::forward<T&&>(value));
283 }
284
285 constexpr SbeOptionalConverted() noexcept
286 : valid_(false)
287 {
288 }
289
290 constexpr SbeOptionalConverted(NullOpt) noexcept
291 : valid_(false)
292 {
293 }
294
295 static_assert(std::is_trivially_destructible<T>::value, "");
297
298 bool hasValue() const noexcept
299 {
300 return valid_;
301 }
302
303 ChooseValueKind<T> operator*() const noexcept
304 {
305 assert(hasValue());
306 return *ptr();
307 }
308
309 const T* operator->() const noexcept
310 {
311 assert(hasValue());
312 return ptr();
313 }
314
315
316private:
317 const T* ptr() const noexcept
318 {
319 return reinterpret_cast<const T*>(storage_);
320 }
321
322 alignas(T) uint8_t storage_[sizeof(T)];
323 bool valid_;
324};
325
327
328class OptionalTag {};
330
331template<typename T> struct isOptional
332 : std::integral_constant
333 <
334 bool,
335 std::is_base_of<SbeOptionalField<cleanType<T>>, cleanType<T>>::value
336 >
337 {};
338
339
340template <typename T>
341typename std::enable_if<isOptional<T>::value, bool>::type
342 operator==(const T& t, NullOpt) noexcept
343{
344 return !t;
345}
346
347template <typename T>
348typename std::enable_if<isOptional<T>::value, bool>::type
349 operator==(NullOpt, const T& t) noexcept
350{
351 return !t;
352}
353
354template <typename T>
355typename std::enable_if<isOptional<T>::value, bool>::type
356 operator!=(const T& t, NullOpt) noexcept
357{
358 return !!t;
359}
360
361template <typename T>
362typename std::enable_if<isOptional<T>::value, bool>::type
363 operator!=(NullOpt, const T& t) noexcept
364{
365 return !!t;
366}
367
368template <typename T>
369std::string toStr(const T& value, typename std::enable_if<isOptional<T>::value, void*>::type = nullptr)
370{
371 return value == nullOpt ? toStr(nullOpt) : toStr(*value);
372}
373
374template <typename T>
375typename std::enable_if<isOptional<T>::value, std::ostream&>::type
376 operator<<(std::ostream& stream, const T& value)
377{
378 stream << toStr(value);
379 return stream;
380}
381
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE_BEGIN
Definition ABI.h:102
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE_END
Definition ABI.h:106
#define ONIXS_ICEBOE_EXPORTED
Definition Compiler.h:153
constexpr SbeOptionalConverted(NullOpt) noexcept
ChooseValueKind< T > operator*() const noexcept
constexpr SbeOptionalEnumeration(NullOpt) noexcept
std::optional< std::decay_t< decltype(*std::declval< const D & >())> > Native
Definition SbeOptional.h:82
static ONIXS_ICEBOE_FORCEINLINE constexpr Derived null() noexcept
Definition SbeOptional.h:70
ONIXS_ICEBOE_FORCEINLINE auto value() const -> decltype(*std::declval< const D & >())
Definition SbeOptional.h:61
const StrRef * operator->() const noexcept
constexpr SbeOptionalStr(StrRef v) noexcept
constexpr SbeOptionalStr(NullOpt) noexcept
SbeOptional(U &&u, V &&v, Rest &&... rest) noexcept(noexcept(T(std::forward< U >(u), std::forward< V >(v), std::forward< Rest >(rest)...)))
std::ostream & operator<<(std::ostream &stream, const FloatingPointDecimal< Mantissa, Exponent > &value)
Serializes into a stream.
bool operator!=(const Decimal &left, const Decimal &right)
SbeOptional< typename T::Value, T > SbeOptionalT
std::string toStr(const FixedPointDecimal< Mantissa, Exponent > &)
Serializes a fixed-point decimal into a string.
@ D
Other, including other-provided screen.
Definition Fields.h:183
std::basic_string_view< Char > StrRef
Definition StrRef.h:46
bool operator==(const Decimal &left, const Decimal &right) noexcept
constexpr OptionalTag optional