Qpid Proton C++  0.13.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
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 
29 
30 #include "./config.hpp"
31 #include "../types_fwd.hpp"
32 #include "../type_id.hpp"
33 
34 namespace proton {
35 namespace internal {
36 
37 class decoder;
38 class encoder;
39 
40 template <bool, class T=void> struct enable_if {};
41 template <class T> struct enable_if<true, T> { typedef T type; };
42 
43 struct true_type { static const bool value = true; };
44 struct false_type { static const bool value = false; };
45 
46 template <class T> struct is_integral : public false_type {};
47 template <class T> struct is_signed : public false_type {};
48 
49 template <> struct is_integral<char> : public true_type {};
50 template <> struct is_signed<char> : public false_type {};
51 
52 template <> struct is_integral<unsigned char> : public true_type {};
53 template <> struct is_integral<unsigned short> : public true_type {};
54 template <> struct is_integral<unsigned int> : public true_type {};
55 template <> struct is_integral<unsigned long> : public true_type {};
56 
57 template <> struct is_integral<signed char> : public true_type {};
58 template <> struct is_integral<signed short> : public true_type {};
59 template <> struct is_integral<signed int> : public true_type {};
60 template <> struct is_integral<signed long> : public true_type {};
61 
62 template <> struct is_signed<unsigned short> : public false_type {};
63 template <> struct is_signed<unsigned int> : public false_type {};
64 template <> struct is_signed<unsigned long> : public false_type {};
65 
66 template <> struct is_signed<signed char> : public true_type {};
67 template <> struct is_signed<signed short> : public true_type {};
68 template <> struct is_signed<signed int> : public true_type {};
69 template <> struct is_signed<signed long> : public true_type {};
70 
71 #if PN_CPP_HAS_LONG_LONG
72 template <> struct is_integral<unsigned long long> : public true_type {};
73 template <> struct is_integral<signed long long> : public true_type {};
74 template <> struct is_signed<unsigned long long> : public false_type {};
75 template <> struct is_signed<signed long long> : public true_type {};
76 #endif
77 
78 template <class T, class U> struct is_same { static const bool value=false; };
79 template <class T> struct is_same<T,T> { static const bool value=true; };
80 
81 template< class T > struct remove_const { typedef T type; };
82 template< class T > struct remove_const<const T> { typedef T type; };
83 
84 template <type_id ID, class T> struct type_id_constant {
85  typedef T type;
86  static const type_id value = ID;
87 };
88 
91 template <class T> struct type_id_of;
92 template<> struct type_id_of<bool> : public type_id_constant<BOOLEAN, bool> {};
93 template<> struct type_id_of<uint8_t> : public type_id_constant<UBYTE, uint8_t> {};
94 template<> struct type_id_of<int8_t> : public type_id_constant<BYTE, int8_t> {};
95 template<> struct type_id_of<uint16_t> : public type_id_constant<USHORT, uint16_t> {};
96 template<> struct type_id_of<int16_t> : public type_id_constant<SHORT, int16_t> {};
97 template<> struct type_id_of<uint32_t> : public type_id_constant<UINT, uint32_t> {};
98 template<> struct type_id_of<int32_t> : public type_id_constant<INT, int32_t> {};
99 template<> struct type_id_of<uint64_t> : public type_id_constant<ULONG, uint64_t> {};
100 template<> struct type_id_of<int64_t> : public type_id_constant<LONG, int64_t> {};
101 template<> struct type_id_of<wchar_t> : public type_id_constant<CHAR, wchar_t> {};
102 template<> struct type_id_of<float> : public type_id_constant<FLOAT, float> {};
103 template<> struct type_id_of<double> : public type_id_constant<DOUBLE, double> {};
104 template<> struct type_id_of<timestamp> : public type_id_constant<TIMESTAMP, timestamp> {};
105 template<> struct type_id_of<decimal32> : public type_id_constant<DECIMAL32, decimal32> {};
106 template<> struct type_id_of<decimal64> : public type_id_constant<DECIMAL64, decimal64> {};
107 template<> struct type_id_of<decimal128> : public type_id_constant<DECIMAL128, decimal128> {};
108 template<> struct type_id_of<uuid> : public type_id_constant<UUID, uuid> {};
109 template<> struct type_id_of<std::string> : public type_id_constant<STRING, std::string> {};
110 template<> struct type_id_of<symbol> : public type_id_constant<SYMBOL, symbol> {};
111 template<> struct type_id_of<binary> : public type_id_constant<BINARY, binary> {};
113 
115 template <class T, class Enable=void> struct has_type_id : public false_type {};
116 template <class T> struct has_type_id<T, typename type_id_of<T>::type> : public true_type {};
117 
118 // The known/unknown integer type magic is required because the C++ standard is
119 // vague a about the equivalence of integral types for overloading. E.g. char is
120 // sometimes equivalent to signed char, sometimes unsigned char, sometimes
121 // neither. int8_t or uint8_t may or may not be equivalent to a char type.
122 // int64_t may or may not be equivalent to long long etc. C++ compilers are also
123 // allowed to add their own non-standard integer types like __int64, which may
124 // or may not be equivalent to any of the standard integer types.
125 //
126 // The solution is to use a fixed, standard set of integer types that are
127 // guaranteed to be distinct for overloading (see type_id_of) and to use template
128 // specialization to convert other integer types to a known integer type with the
129 // same sizeof and is_signed.
130 
131 // Map arbitrary integral types to known integral types.
132 template<size_t SIZE, bool IS_SIGNED> struct integer_type;
133 template<> struct integer_type<1, true> { typedef int8_t type; };
134 template<> struct integer_type<2, true> { typedef int16_t type; };
135 template<> struct integer_type<4, true> { typedef int32_t type; };
136 template<> struct integer_type<8, true> { typedef int64_t type; };
137 template<> struct integer_type<1, false> { typedef uint8_t type; };
138 template<> struct integer_type<2, false> { typedef uint16_t type; };
139 template<> struct integer_type<4, false> { typedef uint32_t type; };
140 template<> struct integer_type<8, false> { typedef uint64_t type; };
141 
142 // True if T is an integer type that does not have an explicit type_id.
143 template <class T> struct is_unknown_integer {
144  static const bool value = !has_type_id<T>::value && is_integral<T>::value;
145 };
146 
147 template<class T, class = typename enable_if<is_unknown_integer<T>::value>::type>
148 struct known_integer : public integer_type<sizeof(T), is_signed<T>::value> {};
149 
150 
151 // Helper base for SFINAE templates.
152 struct sfinae {
153  typedef char yes;
154  typedef double no;
155  struct wildcard { wildcard(...); };
156 };
157 
158 template <class From, class To> struct is_convertible : public sfinae {
159  static yes test(const To&);
160  static no test(...);
161  static const From& from;
162  // Windows compilers warn about data-loss caused by legal conversions. We
163  // can't use static_cast because that will cause a hard error instead of
164  // letting SFINAE overload resolution select the test(...) overload.
165 #ifdef _WIN32
166 #pragma warning( push )
167 #pragma warning( disable : 4244 )
168 #endif
169  static bool const value = sizeof(test(from)) == sizeof(yes);
170 #ifdef _WIN32
171 #pragma warning( pop )
172 #endif
173 };
174 
175 } // internal
176 } // proton
177 
178 #endif // PROTON_INTERNAL_TYPE_TRAITS_HPP
type_id
An identifier for AMQP types.
Definition: type_id.hpp:38