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>
41 #include <cmath>
44 
45 namespace RosMsgParser
46 {
47 
48 namespace details{
49 
50 template <typename T>
51 using Invoke = typename T::type;
52 
53 
54 template <typename BoolCondition>
56 
57 
58 template <typename T>
59 struct is_integer : std::integral_constant<bool, std::is_integral<T>::value
60  && !std::is_same<T, bool>::value
61  && !std::is_same<T, char>::value>
62 {};
63 
64 template <typename From, typename To>
65 struct is_same_real : std::integral_constant<bool,
66  std::is_same<From, To>::value
67  && std::is_floating_point<To>::value >
68 {};
69 
70 
71 template <typename From, typename To>
73  : std::integral_constant<bool, is_integer<From>::value
74  && is_integer<To>::value
75  && sizeof(From) <= sizeof(To)
76  && std::is_signed<From>::value == std::is_signed<To>::value>
77 {};
78 
79 template <typename From, typename To>
80 struct float_conversion
81  : std::integral_constant<bool, std::is_floating_point<From>::value
82  && std::is_floating_point<To>::value
83  && !std::is_same<From,To>::value >
84 {};
85 
86 template <typename From, typename To>
87 struct unsigned_to_smaller_conversion
88  : std::integral_constant<bool, is_integer<From>::value
89  && is_integer<To>::value
90  && (sizeof(From) > sizeof(To))
91  && !std::is_signed<From>::value
92  && !std::is_signed<To>::value >
93 {};
94 
95 template <typename From, typename To>
96 struct signed_to_smaller_conversion
97  : std::integral_constant<bool, is_integer<From>::value
98  && is_integer<To>::value
99  && (sizeof(From) > sizeof(To))
100  && std::is_signed<From>::value
101  && std::is_signed<To>::value >
102 {};
103 
104 //---------------------------
105 template <typename From, typename To>
106 struct signed_to_smaller_unsigned_conversion
107  : std::integral_constant<bool, is_integer<From>::value
108  && is_integer<To>::value
109  && sizeof(From) >= sizeof(To)
110  && std::is_signed<From>::value
111  && !std::is_signed<To>::value >
112 {};
113 
114 template <typename From, typename To>
115 struct signed_to_larger_unsigned_conversion
116  : std::integral_constant<bool, is_integer<From>::value
117  && is_integer<To>::value
118  && sizeof(From) < sizeof(To)
119  && std::is_signed<From>::value
120  && !std::is_signed<To>::value >
121 {};
122 
123 template <typename From, typename To>
124 struct unsigned_to_smaller_signed_conversion
125  : std::integral_constant<bool, is_integer<From>::value
126  && is_integer<To>::value
127  && (sizeof(From) >= sizeof(To))
128  && !std::is_signed<From>::value
129  && std::is_signed<To>::value >
130 {};
131 
132 template <typename From, typename To>
133 struct unsigned_to_larger_signed_conversion
134  : std::integral_constant<bool, is_integer<From>::value
135  && is_integer<To>::value
136  && sizeof(From) < sizeof(To)
137  && !std::is_signed<From>::value
138  && std::is_signed<To>::value >
139 {};
140 
141 template <typename From, typename To>
142 struct floating_to_signed_conversion
143  : std::integral_constant<bool, std::is_floating_point<From>::value
144  && is_integer<To>::value
145  && std::is_signed<To>::value >
146 {};
147 
148 template <typename From, typename To>
149 struct floating_to_unsigned_conversion
150  : std::integral_constant<bool, std::is_floating_point<From>::value
151  && is_integer<To>::value
152  && !std::is_signed<To>::value >
153 {};
154 
155 template <typename From, typename To>
156 struct integer_to_floating_conversion
157  : std::integral_constant<bool, is_integer<From>::value
158  && std::is_floating_point<To>::value >
159 {};
160 
161 template <typename From, typename To>
162 inline void checkUpperLimit(const From& from)
163 {
164  if ((sizeof(To) < sizeof(From)) &&
165  (from > static_cast<From>(std::numeric_limits<To>::max()))) {
166  throw RangeException("Value too large.");
167  }
168  else if (static_cast<To>(from) > std::numeric_limits<To>::max()) {
169  throw RangeException("Value too large.");
170  }
171 }
172 
173 template <typename From, typename To>
174 inline void checkUpperLimitFloat(const From& from)
175 {
176  if (from > std::numeric_limits<To>::max()){
177  throw RangeException("Value too large.");
178  }
179 }
180 
181 template <typename From, typename To>
182 inline void checkLowerLimitFloat(const From& from)
183 {
184  if (from < -std::numeric_limits<To>::max()){
185  throw RangeException("Value too small.");
186  }
187 }
188 
189 template <typename From, typename To>
190 inline void checkLowerLimit(const From& from)
191 {
192  if (from < std::numeric_limits<To>::min()){
193  throw RangeException("Value too small.");
194  }
195 }
196 
197 template <typename From, typename To>
198 inline void checkTruncation(const From& from)
199 {
200  if(from != static_cast<From>(static_cast<To>( from))){
201  throw RangeException("Floating point truncated");
202  }
203 }
204 
205 
206 //----------------------- Implementation ----------------------------------------------
207 
208 template<typename SRC,typename DST,
210 inline void convert_impl( const SRC& from, DST& target )
211 {
212  target = from;
213 }
214 
215 
216 template<typename SRC,typename DST,
218 inline void convert_impl( const SRC& from, DST& target )
219 {
220  target = static_cast<DST>( from);
221 }
222 
223 template<typename SRC,typename DST,
225 inline void convert_impl( const SRC& from, DST& target )
226 {
227  if(!std::isnan(from)) {
228  checkTruncation<SRC,DST>(from);
229  }
230  target = static_cast<DST>( from );
231 }
232 
233 
234 template<typename SRC,typename DST,
236 inline void convert_impl( const SRC& from, DST& target )
237 {
238  checkUpperLimit<SRC,DST>(from);
239  target = static_cast<DST>(from);
240 }
241 
242 template<typename SRC,typename DST,
244 inline void convert_impl( const SRC& from, DST& target )
245 {
246  checkLowerLimit<SRC,DST>(from);
247  checkUpperLimit<SRC,DST>(from);
248  target = static_cast<DST>( from);
249 }
250 
251 
252 template<typename SRC,typename DST,
254 inline void convert_impl( const SRC& from, DST& target )
255 {
256  if (from < 0){
257  throw RangeException("Value is negative and can't be converted to signed");
258  }
259 
260  checkUpperLimit<SRC,DST>(from);
261  target = static_cast<DST>( from);
262 }
263 
264 
265 template<typename SRC,typename DST,
267 inline void convert_impl( const SRC& from, DST& target )
268 {
269  if (from < 0){
270  throw RangeException("Value is negative and can't be converted to signed");
271  }
272 
273  target = static_cast<DST>( from);
274 }
275 
276 template<typename SRC,typename DST,
278 inline void convert_impl( const SRC& from, DST& target )
279 {
280  target = static_cast<DST>( from);
281 }
282 
283 template<typename SRC,typename DST,
285 inline void convert_impl( const SRC& from, DST& target )
286 {
287  checkUpperLimit<SRC,DST>(from);
288  target = static_cast<DST>( from);
289 }
290 
291 template<typename SRC,typename DST,
293 inline void convert_impl( const SRC& from, DST& target )
294 {
295  checkLowerLimitFloat<SRC,DST>(from);
296  checkUpperLimitFloat<SRC,DST>(from);
297 
298  if( from != static_cast<SRC>(static_cast<DST>( from))){
299  throw RangeException("Floating point truncated");
300  }
301 
302  target = static_cast<DST>( from);
303 }
304 
305 template<typename SRC,typename DST,
307 inline void convert_impl( const SRC& from, DST& target )
308 {
309  if (from < 0 ){
310  throw RangeException("Value is negative and can't be converted to signed");
311  }
312 
313  checkLowerLimitFloat<SRC,DST>(from);
314 
315  if( from != static_cast<SRC>(static_cast<DST>( from))){
316  throw RangeException("Floating point truncated");
317  }
318 
319  target = static_cast<DST>( from);
320 }
321 
322 template<typename SRC,typename DST,
324 inline void convert_impl( const SRC& from, DST& target )
325 {
326  checkTruncation<SRC,DST>(from);
327  target = static_cast<DST>( from);
328 }
329 
330 } //end namespace details
331 
332 } //end namespace
333 
334 #endif // VARIANT_H
335 
bool isnan(T)
Definition: chrono.h:787
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
Definition: format.h:821
type
Definition: core.h:1059
Invoke< std::enable_if< BoolCondition::value > > EnableIf
typename T::type Invoke
Definition: core.h:1131


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:01:01