| |
1 #ifndef TYPECONVERSIONS_H |
| |
2 #define TYPECONVERSIONS_H |
| |
3 #include <type_traits> |
| |
4 #include <QtGlobal> |
| |
5 |
| |
6 template<typename T, typename R> |
| |
7 struct transfer_cvref |
| |
8 { |
| |
9 using type = std::remove_reference_t<R>; |
| |
10 }; |
| |
11 |
| |
12 template<typename T, typename R> |
| |
13 struct transfer_cvref<T&, R> |
| |
14 { |
| |
15 using type = std::remove_reference_t<R>&; |
| |
16 }; |
| |
17 |
| |
18 template<typename T, typename R> |
| |
19 struct transfer_cvref<const T&, R> |
| |
20 { |
| |
21 using type = const std::remove_reference_t<R>&; |
| |
22 }; |
| |
23 |
| |
24 template<typename T, typename R> |
| |
25 struct transfer_cvref<T&&, R> |
| |
26 { |
| |
27 using type = std::remove_reference_t<R>&&; |
| |
28 }; |
| |
29 |
| |
30 //! \brief transfer l-value reference, r-value reference and const l-value |
| |
31 //! reference from T onto R |
| |
32 template<typename T, typename R> |
| |
33 using transfer_cvref_t = typename transfer_cvref<T, R>::type; |
| |
34 static_assert(std::is_same_v<transfer_cvref_t<int, char>, char>); |
| |
35 static_assert(std::is_same_v<transfer_cvref_t<int&, char>, char&>); |
| |
36 static_assert(std::is_same_v<transfer_cvref_t<int&&, char>, char&&>); |
| |
37 |
| |
38 //! \brief casts @c x to a suitable unsigned integer |
| |
39 template<typename T> |
| |
40 constexpr auto unsigned_cast(T x) |
| |
41 -> std::enable_if_t<std::is_integral_v<T>, std::make_unsigned_t<T>> |
| |
42 { |
| |
43 return static_cast<std::make_unsigned_t<T>>(x); |
| |
44 } |
| |
45 |
| |
46 //! \brief casts @c x to a suitable signed integer |
| |
47 template<typename T> |
| |
48 constexpr auto signed_cast(T x) |
| |
49 -> std::enable_if_t<std::is_integral_v<T>, std::make_signed_t<T>> |
| |
50 { |
| |
51 return static_cast<std::make_signed_t<T>>(x); |
| |
52 } |
| |
53 |
| |
54 //! \brief casts floating point values to float |
| |
55 template<typename T> |
| |
56 constexpr auto float_cast(T x) |
| |
57 -> std::enable_if_t<std::is_floating_point_v<T>, float> |
| |
58 { |
| |
59 return static_cast<float>(x); |
| |
60 } |
| |
61 |
| |
62 //! \brief casts floating point values to double |
| |
63 template<typename T> |
| |
64 constexpr auto double_cast(T x) |
| |
65 -> std::enable_if_t<std::is_floating_point_v<T>, double> |
| |
66 { |
| |
67 return static_cast<double>(x); |
| |
68 } |
| |
69 |
| |
70 //! \brief casts floating point values to qreal |
| |
71 template<typename T> |
| |
72 constexpr auto qreal_cast(T x) |
| |
73 -> std::enable_if_t<std::is_floating_point_v<T>, qreal> |
| |
74 { |
| |
75 return static_cast<qreal>(x); |
| |
76 } |
| |
77 |
| |
78 //! \brief convert an enum value to its corresponding integer value (including |
| |
79 //! references) |
| |
80 template<typename T> |
| |
81 constexpr auto&& enum_value_cast(T&& enu) |
| |
82 { |
| |
83 using valuetype = std::underlying_type_t<std::remove_cvref_t<T>>; |
| |
84 using reftype = transfer_cvref_t<T&&, valuetype>; |
| |
85 return reinterpret_cast<reftype>(enu); |
| |
86 } |
| |
87 |
| |
88 #endif // TYPECONVERSIONS_H |