Qpid Proton C++ API 0.39.0
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
Loading...
Searching...
No Matches
type_traits.hpp
1#ifndef PROTON_INTERNAL_TYPE_TRAITS_HPP
2#define PROTON_INTERNAL_TYPE_TRAITS_HPP
3
4/*
5 *
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 *
23 */
24
25// Type traits for mapping between AMQP and C++ types.
26//
27// Also provides workarounds for missing type_traits classes on older
28// C++ compilers.
29
30#include "../types_fwd.hpp"
31#include "../type_id.hpp"
32
33#include <proton/type_compat.h>
34
35#include <limits>
36#include <type_traits>
37
38namespace proton {
39namespace internal {
40
41class decoder;
42class encoder;
43
44struct type_id_unknown {
45 static constexpr bool has_id = false;
46};
47
48template <type_id ID, class T> struct type_id_constant {
49 typedef T type;
50 static constexpr type_id value = ID;
51 static constexpr bool has_id = true;
52};
53
56template <class T> struct type_id_of : public type_id_unknown {};
57template<> struct type_id_of<null> : public type_id_constant<NULL_TYPE, null> {};
58template<> struct type_id_of<decltype(nullptr)> : public type_id_constant<NULL_TYPE, null> {};
59template<> struct type_id_of<bool> : public type_id_constant<BOOLEAN, bool> {};
60template<> struct type_id_of<uint8_t> : public type_id_constant<UBYTE, uint8_t> {};
61template<> struct type_id_of<int8_t> : public type_id_constant<BYTE, int8_t> {};
62template<> struct type_id_of<uint16_t> : public type_id_constant<USHORT, uint16_t> {};
63template<> struct type_id_of<int16_t> : public type_id_constant<SHORT, int16_t> {};
64template<> struct type_id_of<uint32_t> : public type_id_constant<UINT, uint32_t> {};
65template<> struct type_id_of<int32_t> : public type_id_constant<INT, int32_t> {};
66template<> struct type_id_of<uint64_t> : public type_id_constant<ULONG, uint64_t> {};
67template<> struct type_id_of<int64_t> : public type_id_constant<LONG, int64_t> {};
68template<> struct type_id_of<wchar_t> : public type_id_constant<CHAR, wchar_t> {};
69template<> struct type_id_of<float> : public type_id_constant<FLOAT, float> {};
70template<> struct type_id_of<double> : public type_id_constant<DOUBLE, double> {};
71template<> struct type_id_of<timestamp> : public type_id_constant<TIMESTAMP, timestamp> {};
72template<> struct type_id_of<decimal32> : public type_id_constant<DECIMAL32, decimal32> {};
73template<> struct type_id_of<decimal64> : public type_id_constant<DECIMAL64, decimal64> {};
74template<> struct type_id_of<decimal128> : public type_id_constant<DECIMAL128, decimal128> {};
75template<> struct type_id_of<uuid> : public type_id_constant<UUID, uuid> {};
76template<> struct type_id_of<std::string> : public type_id_constant<STRING, std::string> {};
77template<> struct type_id_of<symbol> : public type_id_constant<SYMBOL, symbol> {};
78template<> struct type_id_of<binary> : public type_id_constant<BINARY, binary> {};
80
82template <class T> struct has_type_id {
83 static constexpr bool value = type_id_of<T>::has_id;
84};
85
86// The known/unknown integer type magic is required because the C++ standard is
87// vague a about the equivalence of integral types for overloading. E.g. char is
88// sometimes equivalent to signed char, sometimes unsigned char, sometimes
89// neither. int8_t or uint8_t may or may not be equivalent to a char type.
90// int64_t may or may not be equivalent to long long etc. C++ compilers are also
91// allowed to add their own non-standard integer types like __int64, which may
92// or may not be equivalent to any of the standard integer types.
93//
94// The solution is to use a fixed, standard set of integer types that are
95// guaranteed to be distinct for overloading (see type_id_of) and to use template
96// specialization to convert other integer types to a known integer type with the
97// same sizeof and is_signed.
98
99// Map arbitrary integral types to known integral types.
100template<size_t SIZE, bool IS_SIGNED> struct integer_type;
101template<> struct integer_type<1, true> { typedef int8_t type; };
102template<> struct integer_type<2, true> { typedef int16_t type; };
103template<> struct integer_type<4, true> { typedef int32_t type; };
104template<> struct integer_type<8, true> { typedef int64_t type; };
105template<> struct integer_type<1, false> { typedef uint8_t type; };
106template<> struct integer_type<2, false> { typedef uint16_t type; };
107template<> struct integer_type<4, false> { typedef uint32_t type; };
108template<> struct integer_type<8, false> { typedef uint64_t type; };
109
110// True if T is an integer type that does not have an explicit type_id.
111template <class T> struct is_unknown_integer {
112 static constexpr bool value = !has_type_id<T>::value && std::is_integral<T>::value;
113};
114
115template<class T, class = typename std::enable_if<is_unknown_integer<T>::value>::type>
116struct known_integer : public integer_type<sizeof(T), std::is_signed<T>::value> {};
117
118// Helper base for SFINAE templates.
119struct sfinae {
120 typedef char yes;
121 typedef double no;
122 struct any_t {
123 template < typename T > any_t(T const&);
124 };
125};
126
127} // internal
128} // proton
129
130#endif // PROTON_INTERNAL_TYPE_TRAITS_HPP
The main Proton namespace.
Definition: annotation_key.hpp:33
type_id
An identifier for AMQP types.
Definition: type_id.hpp:37