conversion_impl.hpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright 2016-2017 Davide Faconti
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage, Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 * *******************************************************************/
34 
35 #ifndef VARIANT_IMPL_H
36 #define VARIANT_IMPL_H
37 
38 #include <type_traits>
39 #include <limits>
40 #include <iostream>
43 
44 namespace RosIntrospection
45 {
46 
47 namespace details{
48 
49 template <typename T>
50 using Invoke = typename T::type;
51 
52 
53 template <typename BoolCondition>
55 
56 
57 template <typename T>
58 struct is_integer : std::integral_constant<bool, std::is_integral<T>::value
59  && !std::is_same<T, bool>::value
60  && !std::is_same<T, char>::value>
61 {};
62 
63 template <typename From, typename To>
64 struct is_same_real : std::integral_constant<bool,
65  std::is_same<From, To>::value
66  && std::is_floating_point<To>::value >
67 {};
68 
69 
70 template <typename From, typename To>
72  : std::integral_constant<bool, is_integer<From>::value
73  && is_integer<To>::value
74  && sizeof(From) <= sizeof(To)
75  && std::is_signed<From>::value == std::is_signed<To>::value>
76 {};
77 
78 template <typename From, typename To>
79 struct float_conversion
80  : std::integral_constant<bool, std::is_floating_point<From>::value
81  && std::is_floating_point<To>::value
82  && !std::is_same<From,To>::value >
83 {};
84 
85 template <typename From, typename To>
86 struct unsigned_to_smaller_conversion
87  : std::integral_constant<bool, is_integer<From>::value
88  && is_integer<To>::value
89  && (sizeof(From) > sizeof(To))
90  && !std::is_signed<From>::value
91  && !std::is_signed<To>::value >
92 {};
93 
94 template <typename From, typename To>
95 struct signed_to_smaller_conversion
96  : std::integral_constant<bool, is_integer<From>::value
97  && is_integer<To>::value
98  && (sizeof(From) > sizeof(To))
99 && std::is_signed<From>::value
100 && std::is_signed<To>::value >
101 {};
102 
103 //---------------------------
104 template <typename From, typename To>
105 struct signed_to_smaller_unsigned_conversion
106  : std::integral_constant<bool, is_integer<From>::value
107  && is_integer<To>::value
108  && sizeof(From) >= sizeof(To)
109  && std::is_signed<From>::value
110  && !std::is_signed<To>::value >
111 {};
112 
113 template <typename From, typename To>
114 struct signed_to_larger_unsigned_conversion
115  : std::integral_constant<bool, is_integer<From>::value
116  && is_integer<To>::value
117  && sizeof(From) < sizeof(To)
118  && std::is_signed<From>::value
119  && !std::is_signed<To>::value >
120 {};
121 
122 template <typename From, typename To>
123 struct unsigned_to_smaller_signed_conversion
124  : std::integral_constant<bool, is_integer<From>::value
125  && is_integer<To>::value
126  && (sizeof(From) >= sizeof(To))
127  && !std::is_signed<From>::value
128  && std::is_signed<To>::value >
129 {};
130 
131 template <typename From, typename To>
132 struct unsigned_to_larger_signed_conversion
133  : std::integral_constant<bool, is_integer<From>::value
134  && is_integer<To>::value
135  && sizeof(From) < sizeof(To)
136  && !std::is_signed<From>::value
137  && std::is_signed<To>::value >
138 {};
139 
140 template <typename From, typename To>
141 struct floating_to_signed_conversion
142  : std::integral_constant<bool, std::is_floating_point<From>::value
143  && is_integer<To>::value
144  && std::is_signed<To>::value >
145 {};
146 
147 template <typename From, typename To>
148 struct floating_to_unsigned_conversion
149  : std::integral_constant<bool, std::is_floating_point<From>::value
150  && is_integer<To>::value
151  && !std::is_signed<To>::value >
152 {};
153 
154 template <typename From, typename To>
155 struct integer_to_floating_conversion
156  : std::integral_constant<bool, is_integer<From>::value
157  && std::is_floating_point<To>::value >
158 {};
159 
160 template <typename From, typename To>
161 inline void checkUpperLimit(const From& from)
162 {
163  if ((sizeof(To) < sizeof(From)) &&
164  (from > static_cast<From>(std::numeric_limits<To>::max()))) {
165  throw RangeException("Value too large.");
166  }
167  else if (static_cast<To>(from) > std::numeric_limits<To>::max()) {
168  throw RangeException("Value too large.");
169  }
170 }
171 
172 template <typename From, typename To>
173 inline void checkUpperLimitFloat(const From& from)
174 {
175  if (from > std::numeric_limits<To>::max()){
176  throw RangeException("Value too large.");
177  }
178 }
179 
180 template <typename From, typename To>
181 inline void checkLowerLimitFloat(const From& from)
182 {
183  if (from < -std::numeric_limits<To>::max()){
184  throw RangeException("Value too small.");
185  }
186 }
187 
188 template <typename From, typename To>
189 inline void checkLowerLimit(const From& from)
190 {
191  if (from < std::numeric_limits<To>::min()){
192  throw RangeException("Value too small.");
193  }
194 }
195 
196 template <typename From, typename To>
197 inline void checkTruncation(const From& from)
198 {
199  if( from != static_cast<From>(static_cast<To>( from))){
200  throw RangeException("Floating point truncated");
201  }
202 }
203 
204 
205 //----------------------- Implementation ----------------------------------------------
206 
207 template<typename SRC,typename DST,
209 inline void convert_impl( const SRC& from, DST& target )
210 {
211  target = from;
212 }
213 
214 
215 template<typename SRC,typename DST,
217 inline void convert_impl( const SRC& from, DST& target )
218 {
219  target = static_cast<DST>( from);
220 }
221 
222 template<typename SRC,typename DST,
224 inline void convert_impl( const SRC& from, DST& target )
225 {
226  if( std::isnan(from) ){
227  target = std::numeric_limits<DST>::quiet_NaN();
228  }
229  else if( std::isinf(from) ){
230  target = std::numeric_limits<DST>::infinity();
231  }
232  else{
233  checkTruncation<SRC,DST>(from);
234  target = static_cast<DST>( from );
235  }
236 }
237 
238 
239 template<typename SRC,typename DST,
241 inline void convert_impl( const SRC& from, DST& target )
242 {
243  //std::cout << "unsigned_to_smaller_conversion" << std::endl;
244 
245  checkUpperLimit<SRC,DST>(from);
246  target = static_cast<DST>( from);
247 }
248 
249 template<typename SRC,typename DST,
251 inline void convert_impl( const SRC& from, DST& target )
252 {
253  //std::cout << "signed_to_smaller_conversion" << std::endl;
254  checkLowerLimit<SRC,DST>(from);
255  checkUpperLimit<SRC,DST>(from);
256  target = static_cast<DST>( from);
257 }
258 
259 
260 template<typename SRC,typename DST,
262 inline void convert_impl( const SRC& from, DST& target )
263 {
264  //std::cout << "signed_to_smaller_unsigned_conversion" << std::endl;
265  if (from < 0 )
266  throw RangeException("Value is negative and can't be converted to signed");
267 
268  checkUpperLimit<SRC,DST>(from);
269 
270  target = static_cast<DST>( from);
271 }
272 
273 
274 template<typename SRC,typename DST,
276 inline void convert_impl( const SRC& from, DST& target )
277 {
278  //std::cout << "signed_to_larger_unsigned_conversion" << std::endl;
279 
280  if ( from < 0 )
281  throw RangeException("Value is negative and can't be converted to signed");
282 
283  target = static_cast<DST>( from);
284 }
285 
286 template<typename SRC,typename DST,
288 inline void convert_impl( const SRC& from, DST& target )
289 {
290  //std::cout << "unsigned_to_larger_signed_conversion" << std::endl;
291  target = static_cast<DST>( from);
292 }
293 
294 template<typename SRC,typename DST,
296 inline void convert_impl( const SRC& from, DST& target )
297 {
298  checkUpperLimit<SRC,DST>(from);
299  target = static_cast<DST>( from);
300 }
301 
302 template<typename SRC,typename DST,
304 inline void convert_impl( const SRC& from, DST& target )
305 {
306  checkLowerLimitFloat<SRC,DST>(from);
307  checkLowerLimitFloat<SRC,DST>(from);
308 
309  if( from != static_cast<SRC>(static_cast<DST>( from))){
310  throw RangeException("Floating point truncated");
311  }
312 
313  target = static_cast<DST>( from);
314 }
315 
316 template<typename SRC,typename DST,
318 inline void convert_impl( const SRC& from, DST& target )
319 {
320  if ( from < 0 ){
321  throw RangeException("Value is negative and can't be converted to signed");
322  }
323 
324  checkLowerLimitFloat<SRC,DST>(from);
325 
326  if( from != static_cast<SRC>(static_cast<DST>( from)))
327  throw RangeException("Floating point truncated");
328 
329  target = static_cast<DST>( from);
330 }
331 
332 template<typename SRC,typename DST,
334 inline void convert_impl( const SRC& from, DST& target )
335 {
336  checkTruncation<SRC,DST>(from);
337  target = static_cast<DST>( from);
338 }
339 
340 } //end namespace details
341 
342 } //end namespace
343 
344 #endif // VARIANT_H
345 
Invoke< std::enable_if< BoolCondition::value > > EnableIf


ros_type_introspection
Author(s): Davide Faconti
autogenerated on Sun Sep 6 2020 03:19:54