Lely core libraries  2.3.4
type_traits.hpp
Go to the documentation of this file.
1 
22 #ifndef LELY_COAPP_TYPE_TRAITS_HPP_
23 #define LELY_COAPP_TYPE_TRAITS_HPP_
24 
25 #include <lely/features.h>
26 
27 #include <string>
28 #include <system_error>
29 #include <type_traits>
30 #include <vector>
31 
32 #include <cstdint>
33 
34 namespace lely {
35 
36 namespace canopen {
37 
38 namespace detail {
39 
40 template <class, uint16_t, bool = false>
42 
43 template <class T, uint16_t N>
44 struct canopen_traits<T, N, false> {
45  using type = T;
46 
47  static constexpr uint16_t index = N;
48 
49  static constexpr bool is_basic = false;
50 };
51 
52 template <class T, uint16_t N>
53 struct canopen_traits<T, N, true> {
54  using type = T;
55 
56  using c_type = T;
57 
58  static constexpr uint16_t index = N;
59 
60  static constexpr bool is_basic = true;
61 
62  static c_type construct(const void* p, ::std::size_t n,
63  ::std::error_code& ec) noexcept;
64 
65  static void
66  destroy(c_type& /*val*/) noexcept {}
67 
68  static constexpr type
69  from_c_type(c_type val) noexcept {
70  return val;
71  }
72 
73  static constexpr c_type
74  to_c_type(type value, ::std::error_code& /*ec*/) noexcept {
75  return value;
76  }
77 
78  static constexpr void*
79  address(c_type& val) noexcept {
80  return &val;
81  }
82 
83  static constexpr const void*
84  address(const c_type& val) noexcept {
85  return &val;
86  }
87 
88  static constexpr ::std::size_t
89  size(const c_type& /*val*/) noexcept {
90  return sizeof(c_type);
91  }
92 };
93 
94 } // namespace detail
95 
97 template <class>
99 
104 template <>
105 struct canopen_traits<bool> : detail::canopen_traits<bool, 0x0001, true> {};
106 
111 template <>
112 struct canopen_traits<int8_t> : detail::canopen_traits<int8_t, 0x0002, true> {};
113 
118 template <>
119 struct canopen_traits<int16_t> : detail::canopen_traits<int16_t, 0x0003, true> {
120 };
121 
126 template <>
127 struct canopen_traits<int32_t> : detail::canopen_traits<int32_t, 0x0004, true> {
128 };
129 
134 template <>
135 struct canopen_traits<uint8_t> : detail::canopen_traits<uint8_t, 0x0005, true> {
136 };
137 
142 template <>
143 struct canopen_traits<uint16_t>
144  : detail::canopen_traits<uint16_t, 0x0006, true> {};
145 
150 template <>
151 struct canopen_traits<uint32_t>
152  : detail::canopen_traits<uint32_t, 0x0007, true> {};
153 
158 template <>
159 struct canopen_traits<float> : detail::canopen_traits<float, 0x0008, true> {};
160 
165 template <>
166 struct canopen_traits<::std::string>
167  : detail::canopen_traits<::std::string, 0x0009> {
168  using c_type = char*;
169 
170  static char* construct(const void* p, ::std::size_t n,
171  ::std::error_code& ec) noexcept;
172 
173  static void destroy(char*& val) noexcept;
174 
175  static ::std::string
176  from_c_type(const char* val) {
177  return val ? ::std::string{val} : ::std::string{};
178  }
179 
180  static char*
181  to_c_type(const type& vs, ::std::error_code& ec) noexcept {
182  return to_c_type(vs.c_str(), ec);
183  }
184 
185  static char* to_c_type(const char* vs, ::std::error_code& ec) noexcept;
186 
187  static constexpr void*
188  address(char* val) noexcept {
189  return val;
190  }
191 
192  static constexpr const void*
193  address(const char* val) noexcept {
194  return val;
195  }
196 
197  static ::std::size_t
198  size(const char* val) noexcept {
199  return val ? ::std::char_traits<char>::length(val) : 0;
200  }
201 };
202 
207 template <>
208 struct canopen_traits<::std::vector<uint8_t>>
209  : detail::canopen_traits<::std::vector<uint8_t>, 0x000a> {
210  using c_type = uint8_t*;
211 
212  static uint8_t* construct(const void* p, ::std::size_t n,
213  ::std::error_code& ec) noexcept;
214 
215  static void destroy(uint8_t*& val) noexcept;
216 
217  static ::std::vector<uint8_t>
218  from_c_type(const uint8_t* val) {
219  return {val, val + size(val)};
220  }
221 
222  static uint8_t*
223  to_c_type(const ::std::vector<uint8_t>& os, ::std::error_code& ec) noexcept {
224  return to_c_type(os.data(), os.size(), ec);
225  }
226 
227  static uint8_t* to_c_type(const uint8_t* os, ::std::size_t n,
228  ::std::error_code& ec) noexcept;
229 
230  static constexpr void*
231  address(uint8_t* val) noexcept {
232  return val;
233  }
234 
235  static constexpr const void*
236  address(const uint8_t* val) noexcept {
237  return val;
238  }
239 
240  static ::std::size_t size(const uint8_t* val) noexcept;
241 };
242 
247 template <>
248 struct canopen_traits<::std::basic_string<char16_t>>
249  : detail::canopen_traits<::std::basic_string<char16_t>, 0x000b> {
250  using c_type = char16_t*;
251 
252  static char16_t* construct(const void* p, ::std::size_t n,
253  ::std::error_code& ec) noexcept;
254 
255  static void destroy(char16_t*& val) noexcept;
256 
257  static ::std::basic_string<char16_t>
258  from_c_type(const char16_t* val) {
259  return val ? ::std::basic_string<char16_t>{val}
260  : ::std::basic_string<char16_t>{};
261  }
262 
263  static char16_t*
264  to_c_type(const ::std::basic_string<char16_t>& us,
265  ::std::error_code& ec) noexcept {
266  return to_c_type(us.c_str(), ec);
267  }
268 
269  static char16_t* to_c_type(const char16_t* us,
270  ::std::error_code& ec) noexcept;
271 
272  static constexpr void*
273  address(char16_t* val) noexcept {
274  return val;
275  }
276 
277  static constexpr const void*
278  address(const char16_t* val) noexcept {
279  return val;
280  }
281 
282  static ::std::size_t
283  size(const char16_t* val) noexcept {
284  return val ? ::std::char_traits<char16_t>::length(val) : 0;
285  }
286 };
287 
288 // TIME_OF_DAY
289 // TIME_DIFFERENCE.
290 // DOMAIN
291 // INTEGER24
292 
297 template <>
298 struct canopen_traits<double> : detail::canopen_traits<double, 0x0011, true> {};
299 
300 // INTEGER40
301 // INTEGER48
302 // INTEGER56
303 
308 template <>
309 struct canopen_traits<int64_t> : detail::canopen_traits<int64_t, 0x0015, true> {
310 };
311 
312 // UNSIGNED24
313 // UNSIGNED40
314 // UNSIGNED48
315 // UNSIGNED56
316 
321 template <>
322 struct canopen_traits<uint64_t>
323  : detail::canopen_traits<uint64_t, 0x001b, true> {};
324 
329 template <class T, class = T>
330 struct is_canopen : ::std::false_type {};
331 
332 template <class T>
333 struct is_canopen<T, typename canopen_traits<T>::type> : ::std::true_type {};
334 
339 template <class T, class = T>
340 struct is_canopen_basic : ::std::false_type {};
341 
342 template <class T>
343 struct is_canopen_basic<T, typename canopen_traits<T>::type>
344  : ::std::integral_constant<bool, canopen_traits<T>::is_basic> {};
345 
350 inline constexpr bool
351 is_canopen_same(uint16_t t1, uint16_t t2) noexcept {
352  // OCTET_STRING and DOMAIN are both byte arrays.
353  return t1 == t2 || (t1 == 0x000a && t2 == 0x000f) ||
354  (t1 == 0x000f && t2 == 0x000a);
355 }
356 
357 } // namespace canopen
358 
359 } // namespace lely
360 
361 #endif // LELY_COAPP_TYPE_TRAITS_HPP_
This header file is part of the Lely libraries; it contains the compiler feature definitions.
constexpr bool is_canopen_same(uint16_t t1, uint16_t t2) noexcept
Returns true if the CANopen data types t1 and t2 map to the same C++ type, and false if not.
A class template mapping CANopen types to C and C++ types.
Definition: type_traits.hpp:98
If T is one of the CANopen basic types, provides the member constant value equal to true.
If T is one of the CANopen basic or array types, provides the member constant value equal to true.