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
34namespace lely {
35
36namespace canopen {
37
38namespace detail {
39
40template <class, uint16_t, bool = false>
42
43template <class T, uint16_t N>
44struct 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
52template <class T, uint16_t N>
53struct 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
97template <class>
99
104template <>
105struct canopen_traits<bool> : detail::canopen_traits<bool, 0x0001, true> {};
106
111template <>
112struct canopen_traits<int8_t> : detail::canopen_traits<int8_t, 0x0002, true> {};
113
118template <>
119struct canopen_traits<int16_t> : detail::canopen_traits<int16_t, 0x0003, true> {
120};
121
126template <>
127struct canopen_traits<int32_t> : detail::canopen_traits<int32_t, 0x0004, true> {
128};
129
134template <>
135struct canopen_traits<uint8_t> : detail::canopen_traits<uint8_t, 0x0005, true> {
136};
137
142template <>
143struct canopen_traits<uint16_t>
144 : detail::canopen_traits<uint16_t, 0x0006, true> {};
145
150template <>
151struct canopen_traits<uint32_t>
152 : detail::canopen_traits<uint32_t, 0x0007, true> {};
153
158template <>
159struct canopen_traits<float> : detail::canopen_traits<float, 0x0008, true> {};
160
165template <>
166struct 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
207template <>
208struct 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
247template <>
248struct 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
297template <>
298struct canopen_traits<double> : detail::canopen_traits<double, 0x0011, true> {};
299
300// INTEGER40
301// INTEGER48
302// INTEGER56
303
308template <>
309struct canopen_traits<int64_t> : detail::canopen_traits<int64_t, 0x0015, true> {
310};
311
312// UNSIGNED24
313// UNSIGNED40
314// UNSIGNED48
315// UNSIGNED56
316
321template <>
322struct canopen_traits<uint64_t>
323 : detail::canopen_traits<uint64_t, 0x001b, true> {};
324
329template <class T, class = T>
330struct is_canopen : ::std::false_type {};
331
332template <class T>
333struct is_canopen<T, typename canopen_traits<T>::type> : ::std::true_type {};
334
339template <class T, class = T>
340struct is_canopen_basic : ::std::false_type {};
341
342template <class T>
343struct is_canopen_basic<T, typename canopen_traits<T>::type>
344 : ::std::integral_constant<bool, canopen_traits<T>::is_basic> {};
345
350inline constexpr bool
351is_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.