29#if !(defined(ONIXS_ICEBOE_DOXYGEN) && ONIXS_ICEBOE_DOXYGEN)
32#define CHECK_TYPE_INTEGRAL(Type) \
34 std::is_integral<Type>::value, \
35 #Type " must be an integral type, consider adding MemberTraits" \
40 template <
class T,
class U>
41 struct IsSameSignedness
43 enum { value = (
static_cast<bool>(std::is_signed<T>::value) ==
static_cast<bool>(std::is_signed<U>::value)) };
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) };
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) };
67 enum { value = HasMantissa<T>::value && HasExponent<T>::value };
75 struct AreBothDecimals
77 enum { value = IsDecimal<Decimal1>::value && IsDecimal<Decimal2>::value };
81 struct HasMemberTraits
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) };
90 struct HasValueStaticMember
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) };
99 struct HasSerializeMember
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) };
108template <
class To,
class From>
111typename std::enable_if<details::IsSameSignedness<To, From>::value, To>::type
112 numericCast(From from)
noexcept
114 const To to =
static_cast<To
>(from);
115 assert(
static_cast<From
>(to) == from);
119template <
class To,
class From>
122typename std::enable_if<!details::IsSameSignedness<To, From>::value, To>::type
123 numericCast(From from)
noexcept
125 const To to =
static_cast<To
>(from);
127 assert(
static_cast<From
>(to) == from);
130 assert((to >
static_cast<To
>(0)) == (from >
static_cast<From
>(0)));
137 template <
typename...>
struct make_void {
typedef void type; };
140template<
class T>
using cleanType =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
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>{};
148template <
typename T>
struct isScopedEnum :
public details::isScopedEnumImpl<cleanType<T>> {};
149template <
typename T>
struct isEnum :
public std::is_enum<cleanType<T>> {};
152 template <
typename T>
153 struct underlyingTypeImpl
155 static_assert(isScopedEnum<T>::value,
"");
156 using type =
typename std::underlying_type<T>::type;
157 static_assert(std::is_integral<type>::value,
"");
161template <
typename T>
struct underlyingType :
public details::underlyingTypeImpl<cleanType<T>> {};
164template <
class T>
constexpr ONIXS_ICEBOE_FORCEINLINE
typename underlyingType<T>::type toUnderlying(T t)
noexcept
166 return static_cast<typename underlyingType<T>::type
>(t);
170 template<
typename T,
typename =
void>
struct isCompositeImpl : std::false_type {};
172 struct isCompositeImpl
177 typename T::MemberTraits, decltype(T::Size), decltype(T::MemberTraits::Count), decltype(std::declval<const T&>().serialize(nullptr))
180 : std::integral_constant
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
190template <
typename T>
struct isComposite :
public details::isCompositeImpl<cleanType<T>> {};
194template <
typename T,
typename =
void>
struct hasCallReturningValue : std::false_type {};
196struct hasCallReturningValue
199 typename make_void<decltype(std::declval<const T&>()())>::type
201 : std::integral_constant
206 decltype(std::declval<const T&>()()),
212template <
typename T,
typename =
void>
213struct hasStaticValueReturningValue : std::false_type {};
216struct hasStaticValueReturningValue
219 typename make_void<decltype(T::value())>::type
221 : std::integral_constant
226 decltype(T::value()),
233template <
typename T,
typename =
void>
struct isConstant : std::false_type {};
239 typename details::make_void<typename T::Value>::type
241 : std::integral_constant
244 std::is_convertible<const T&, typename T::Value>::value
245 && details::hasCallReturningValue<T>::value
246 && details::hasStaticValueReturningValue<T>::value
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;
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)
261 return T{std::get<I>(std::forward<Tuple>(t))...};
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>())))
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>());
273template <
typename>
struct ArgType;
275template <
typename T,
typename A,
typename V>
276struct ArgType<T(A::*)(V) const>
278 using type = cleanType<V>;
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)>{};
286template <
typename T,
typename A,
typename V>
287struct ArgType<T(A::*)(V)>
289 using type = cleanType<V>;
292template <
typename T,
typename V>
293struct ArgType<T(*)(V)>
295 using type = cleanType<V>;
298template <
typename Func, Func F>
struct FuncWrapper;
299template <
typename R,
typename V, R(*F)(V)>
struct FuncWrapper<R(*)(V), F>
302 using ReturnType = R;
304 static_assert(!std::is_convertible<ArgType, ReturnType>::value,
"Direct conversion can be done.");
306 static constexpr bool Nothrow =
noexcept(F(std::declval<ArgType>()));
308 ONIXS_ICEBOE_FORCEINLINE ReturnType operator()(ArgType x)
const noexcept(Nothrow) {
return F(x); }
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>{};
317template <
typename R,
typename V, R(*F)(V)>
318struct ArgType<FuncWrapper<R(*)(V), F>>
320 using type = cleanType<
typename FuncWrapper<R(*)(V), F>::ArgType>;
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>>{};
328#define ONIXS_ICEBOE_WRAP_F(F) FuncWrapper<decltype(&F), &F>
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
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__)
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...)>{};
350#define ONIXS_ICEBOE_FIELD_TYPE_C(...) typename RetType<decltype(&__VA_ARGS__)>::type
358 static constexpr bool value = (
sizeof(T) <= 2 *
sizeof(
void*));
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>&;};
366template<
class T>
using ChooseValueKind =
typename details::ChooseValueKindImpl<T>::type;
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE_BEGIN
#define ONIXS_ICEBOE_MESSAGING_NAMESPACE_END
#define ONIXS_ICEBOE_PURE