src/typeconversions.h

Wed, 22 Jun 2022 16:12:28 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Wed, 22 Jun 2022 16:12:28 +0300
changeset 247
07ad61423c3c
parent 218
63125c36de73
child 250
2837b549e616
permissions
-rw-r--r--

fix cylinders being possibly rendered inside out

#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