Wed, 15 Jun 2022 12:17:29 +0300
Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
#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