src/typeconversions.h

changeset 218
63125c36de73
child 250
2837b549e616
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/typeconversions.h	Tue Jun 14 19:50:31 2022 +0300
@@ -0,0 +1,88 @@
+#ifndef TYPECONVERSIONS_H
+#define TYPECONVERSIONS_H
+#include <type_traits>
+#include <QtGlobal>
+
+template<typename T, typename R>
+struct transfer_cvref
+{
+	using type = std::remove_reference_t<R>;
+};
+
+template<typename T, typename R>
+struct transfer_cvref<T&, R>
+{
+	using type = std::remove_reference_t<R>&;
+};
+
+template<typename T, typename R>
+struct transfer_cvref<const T&, R>
+{
+	using type = const std::remove_reference_t<R>&;
+};
+
+template<typename T, typename R>
+struct transfer_cvref<T&&, R>
+{
+	using type = std::remove_reference_t<R>&&;
+};
+
+//! \brief transfer l-value reference, r-value reference and const l-value
+//! reference from T onto R
+template<typename T, typename R>
+using transfer_cvref_t = typename transfer_cvref<T, R>::type;
+static_assert(std::is_same_v<transfer_cvref_t<int, char>, char>);
+static_assert(std::is_same_v<transfer_cvref_t<int&, char>, char&>);
+static_assert(std::is_same_v<transfer_cvref_t<int&&, char>, char&&>);
+
+//! \brief casts @c x to a suitable unsigned integer
+template<typename T>
+constexpr auto unsigned_cast(T x)
+	-> std::enable_if_t<std::is_integral_v<T>, std::make_unsigned_t<T>>
+{
+	return static_cast<std::make_unsigned_t<T>>(x);
+}
+
+//! \brief casts @c x to a suitable signed integer
+template<typename T>
+constexpr auto signed_cast(T x)
+	-> std::enable_if_t<std::is_integral_v<T>, std::make_signed_t<T>>
+{
+	return static_cast<std::make_signed_t<T>>(x);
+}
+
+//! \brief casts floating point values to float
+template<typename T>
+constexpr auto float_cast(T x)
+	-> std::enable_if_t<std::is_floating_point_v<T>, float>
+{
+	return static_cast<float>(x);
+}
+
+//! \brief casts floating point values to double
+template<typename T>
+constexpr auto double_cast(T x)
+	-> std::enable_if_t<std::is_floating_point_v<T>, double>
+{
+	return static_cast<double>(x);
+}
+
+//! \brief casts floating point values to qreal
+template<typename T>
+constexpr auto qreal_cast(T x)
+	-> std::enable_if_t<std::is_floating_point_v<T>, qreal>
+{
+	return static_cast<qreal>(x);
+}
+
+//! \brief convert an enum value to its corresponding integer value (including
+//! references)
+template<typename T>
+constexpr auto&& enum_value_cast(T&& enu)
+{
+	using valuetype = std::underlying_type_t<std::remove_cvref_t<T>>;
+	using reftype = transfer_cvref_t<T&&, valuetype>;
+	return reinterpret_cast<reftype>(enu);
+}
+
+#endif // TYPECONVERSIONS_H

mercurial