|
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 |