OnixS C++ ICE Binary Order Entry Handler 1.0.0
API Documentation
Loading...
Searching...
No Matches
Utils.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 <cassert>
24#include <tuple>
25#include <type_traits>
26
27#include <OnixS/ICE/BOE/ABI.h>
28
29#if !(defined(ONIXS_ICEBOE_DOXYGEN) && ONIXS_ICEBOE_DOXYGEN)
31
32#define CHECK_TYPE_INTEGRAL(Type) \
33 static_assert( \
34 std::is_integral<Type>::value, \
35 #Type " must be an integral type, consider adding MemberTraits" \
36 );
37
38namespace details {
39
40 template <class T, class U>
41 struct IsSameSignedness
42 {
43 enum { value = (static_cast<bool>(std::is_signed<T>::value) == static_cast<bool>(std::is_signed<U>::value)) };
44 };
45
46 template<typename T>
47 struct HasMantissa
48 {
49 template<typename U> struct SFINAE {};
50 template<typename U> static char test(SFINAE<typename U::Mantissa>*);
51 template<typename U> static int test(...);
52 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
53 };
54
55 template<typename T>
56 struct HasExponent
57 {
58 template<typename U> struct SFINAE {};
59 template<typename U> static char test(SFINAE<typename U::Exponent>*);
60 template<typename U> static int test(...);
61 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
62 };
63
64 template<typename T>
65 struct IsDecimal
66 {
67 enum { value = HasMantissa<T>::value && HasExponent<T>::value };
68 };
69
70 template
71 <
72 class Decimal1,
73 class Decimal2
74 >
75 struct AreBothDecimals
76 {
77 enum { value = IsDecimal<Decimal1>::value && IsDecimal<Decimal2>::value };
78 };
79
80 template<typename T>
81 struct HasMemberTraits
82 {
83 template<typename U> struct SFINAE {};
84 template<typename U> static char test(SFINAE<struct U::MemberTraits>*);
85 template<typename U> static int test(...);
86 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
87 };
88
89 template<typename T>
90 struct HasValueStaticMember
91 {
92 template<typename U, typename U::Value (*)()> struct SFINAE {};
93 template<typename U> static char test(SFINAE<U, &U::value>*);
94 template<typename U> static int test(...);
95 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
96 };
97
98 template<typename T>
99 struct HasSerializeMember
100 {
101 template<typename U, void (U::*)(void*) const noexcept> struct SFINAE {};
102 template<typename U> static char test(SFINAE<U, &U::serialize>*);
103 template<typename U> static int test(...);
104 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) };
105 };
106}
107
108template <class To, class From>
110inline
111typename std::enable_if<details::IsSameSignedness<To, From>::value, To>::type
112 numericCast(From from) noexcept
113{
114 const To to = static_cast<To>(from);
115 assert(static_cast<From>(to) == from);
116 return to;
117}
118
119template <class To, class From>
121inline
122typename std::enable_if<!details::IsSameSignedness<To, From>::value, To>::type
123 numericCast(From from) noexcept
124{
125 const To to = static_cast<To>(from);
126
127 assert(static_cast<From>(to) == from);
128
129 // The sign is lost during the conversion
130 assert((to > static_cast<To>(0)) == (from > static_cast<From>(0)));
131
132 return to;
133}
134
135
136namespace details {
137 template <typename...> struct make_void { typedef void type; };
138}
139
140template<class T> using cleanType = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
141
142
143namespace details {
144 template <typename T, bool = std::is_enum<T>::value> struct isScopedEnumImpl : std::false_type{};
145 template <typename T> struct isScopedEnumImpl<T, true> : std::integral_constant<bool, !std::is_convertible<T, typename std::underlying_type<T>::type>::value>{};
146}
147
148template <typename T> struct isScopedEnum : public details::isScopedEnumImpl<cleanType<T>> {};
149template <typename T> struct isEnum : public std::is_enum<cleanType<T>> {};
150
151namespace details {
152 template <typename T>
153 struct underlyingTypeImpl
154 {
155 static_assert(isScopedEnum<T>::value, "");
156 using type = typename std::underlying_type<T>::type;
157 static_assert(std::is_integral<type>::value, "");
158 };
159}
160
161template <typename T> struct underlyingType : public details::underlyingTypeImpl<cleanType<T>> {};
162
163
164template <class T> constexpr ONIXS_ICEBOE_FORCEINLINE typename underlyingType<T>::type toUnderlying(T t) noexcept
165{
166 return static_cast<typename underlyingType<T>::type>(t);
167}
168
169namespace details {
170 template<typename T, typename = void> struct isCompositeImpl : std::false_type {};
171 template<typename T>
172 struct isCompositeImpl
173 <
174 T,
175 typename make_void
176 <
177 typename T::MemberTraits, decltype(T::Size), decltype(T::MemberTraits::Count), decltype(std::declval<const T&>().serialize(nullptr))
178 >::type
179 >
180 : std::integral_constant
181 <
182 bool,
183 std::is_same<void, decltype(std::declval<const T&>().serialize(nullptr))>::value
184 && std::is_enum<decltype(T::Size)>::value
185 && std::is_enum<decltype(T::MemberTraits::Count)>::value
186 >
187 {};
188}
189
190template <typename T> struct isComposite : public details::isCompositeImpl<cleanType<T>> {};
191
192namespace details {
193
194template <typename T, typename = void> struct hasCallReturningValue : std::false_type {};
195template <typename T>
196struct hasCallReturningValue
197 <
198 T,
199 typename make_void<decltype(std::declval<const T&>()())>::type
200 >
201 : std::integral_constant
202 <
203 bool,
204 std::is_convertible
205 <
206 decltype(std::declval<const T&>()()),
207 typename T::Value
208 >::value
209 >
210{};
211
212template <typename T, typename = void>
213struct hasStaticValueReturningValue : std::false_type {};
214
215template <typename T>
216struct hasStaticValueReturningValue
217 <
218 T,
219 typename make_void<decltype(T::value())>::type
220 >
221 : std::integral_constant
222 <
223 bool,
224 std::is_convertible
225 <
226 decltype(T::value()),
227 typename T::Value
228 >::value
229 >
230{};
231}
232
233template <typename T, typename = void> struct isConstant : std::false_type {};
234
235template <typename T>
236struct isConstant
237 <
238 T,
239 typename details::make_void<typename T::Value>::type
240 >
241 : std::integral_constant
242 <
243 bool,
244 std::is_convertible<const T&, typename T::Value>::value
245 && details::hasCallReturningValue<T>::value
246 && details::hasStaticValueReturningValue<T>::value
247 >
248{};
249
250
251
252namespace details {
253template<std::size_t...> struct indexSequence{};
254template<std::size_t N, std::size_t... I> struct makeIndexSequenceImpl : makeIndexSequenceImpl<N - 1, N - 1, I...> {};
255template<std::size_t... I> struct makeIndexSequenceImpl<0, I...> {typedef indexSequence<I...> type;};
256template<std::size_t N> using makeIndexSequence = typename makeIndexSequenceImpl<N>::type;
257
258template<class T, class Tuple, std::size_t... I>
259T makeFromTupleImpl(Tuple&& t, indexSequence<I...>) noexcept(std::is_nothrow_constructible<T, decltype(std::get<I>(std::forward<Tuple>(t)))...>::value)
260{
261 return T{std::get<I>(std::forward<Tuple>(t))...};
262}
263
264}
265
266template <class T, class Tuple>
267T makeFromTuple(Tuple&& t) noexcept(noexcept(details::makeFromTupleImpl<T>(std::forward<Tuple>(t), details::makeIndexSequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>())))
268{
269 using Tup = typename std::remove_reference<Tuple>::type ;
270 return details::makeFromTupleImpl<T>(std::forward<Tuple>(t), details::makeIndexSequence<std::tuple_size<Tup>::value>());
271}
272
273template <typename> struct ArgType;
274
275template <typename T, typename A, typename V>
276struct ArgType<T(A::*)(V) const>
277{
278 using type = cleanType<V>;
279};
280
281#if ONIXS_ICEBOE_CXX17_NOEXCEPT
282template <typename T, typename A, typename V> struct ArgType<T(A::*)(V) const noexcept> : public ArgType<T(A::*)(V) const>{};
283template <typename T, typename A, typename V> struct ArgType<T(A::*)(V) noexcept> : public ArgType<T(A::*)(V)>{};
284#endif
285
286template <typename T, typename A, typename V>
287struct ArgType<T(A::*)(V)>
288{
289 using type = cleanType<V>;
290};
291
292template <typename T, typename V>
293struct ArgType<T(*)(V)>
294{
295 using type = cleanType<V>;
296};
297
298template <typename Func, Func F> struct FuncWrapper;
299template <typename R, typename V, R(*F)(V)> struct FuncWrapper<R(*)(V), F>
300{
301 using ArgType = V;
302 using ReturnType = R;
303
304 static_assert(!std::is_convertible<ArgType, ReturnType>::value, "Direct conversion can be done.");
305
306 static constexpr bool Nothrow = noexcept(F(std::declval<ArgType>()));
307
308 ONIXS_ICEBOE_FORCEINLINE ReturnType operator()(ArgType x) const noexcept(Nothrow) { return F(x); }
309};
310
311#if ONIXS_ICEBOE_CXX17_NOEXCEPT
312template <typename R, typename V, R(*F)(V) noexcept>
313struct FuncWrapper<R(*)(V) noexcept, F> : public FuncWrapper<R(*)(V), F>{};
314#endif
315
316
317template <typename R, typename V, R(*F)(V)>
318struct ArgType<FuncWrapper<R(*)(V), F>>
319{
320 using type = cleanType<typename FuncWrapper<R(*)(V), F>::ArgType>;
321};
322
323#if ONIXS_ICEBOE_CXX17_NOEXCEPT
324template <typename R, typename V, R(*F)(V) noexcept>
325struct ArgType<FuncWrapper<R(*)(V) noexcept, F>> : public ArgType<FuncWrapper<R(*)(V), F>>{};
326#endif
327
328#define ONIXS_ICEBOE_WRAP_F(F) FuncWrapper<decltype(&F), &F>
329
330
331#if defined ONIXS_NO_RETURN_TYPE_DEDUCTION
332#if defined(ONIXS_ICEBOE_CXX14)
333# define ONIXS_ICEBOE_FIELD_TYPE(...) ONIXS_ICEBOE_NODISCARD auto
334# define ONIXS_ICEBOE_FIELD_TYPE_C(...) ONIXS_ICEBOE_NODISCARD auto
335#else
336namespace details {struct DummyLength {enum {length};};}
337#define __ONIXS_ICEBOE_FIELD_TYPE_IMPL(Name, ...) \
338struct Name : public details::DummyLength { \
339 template<typename T = ThisType> \
340 using type = decltype(std::declval<const T&>().template __VA_ARGS__(std::declval<BlockLength>(), std::declval<OptionalTag>())); \
341}; typename Name::type<ThisType>
342#define ONIXS_ICEBOE_FIELD_TYPE(...) __ONIXS_ICEBOE_FIELD_TYPE_IMPL(ONIXS_ICEBOE_MAKE_UNIQUE_NAME(Dummy), __VA_ARGS__)
343
344template <typename T> struct RetType;
345template <typename T> struct RetType : RetType<typename std::remove_pointer<T>::type> {};
346template <typename R, typename... A> struct RetType<R(A...)> { using type = R; };
347#if ONIXS_ICEBOE_CXX17_NOEXCEPT
348template <typename R, typename... A> struct RetType<R(A...) noexcept> : public RetType<R(A...)>{};
349#endif
350#define ONIXS_ICEBOE_FIELD_TYPE_C(...) typename RetType<decltype(&__VA_ARGS__)>::type
351#endif
352#endif
353
354namespace details {
355template<class T>
356struct smallType
357{
358 static constexpr bool value = (sizeof(T) <= 2 * sizeof(void*));
359};
360
361template<class T, typename = void> struct ChooseValueKindImpl;
362template<class T> struct ChooseValueKindImpl<T, typename std::enable_if<smallType<T>::value>::type> {using type = cleanType<T>;};
363template<class T> struct ChooseValueKindImpl<T, typename std::enable_if<!smallType<T>::value>::type> {using type = const cleanType<T>&;};
364}
365
366template<class T> using ChooseValueKind = typename details::ChooseValueKindImpl<T>::type;
367
369#endif
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE_BEGIN
Definition ABI.h:102
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE_END
Definition ABI.h:106
#define ONIXS_ICEBOE_PURE
Definition Compiler.h:157