forked from mpusz/mp-units
Type traits changed to variable templates
This commit is contained in:
@@ -77,17 +77,15 @@ namespace units {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_ratio : std::false_type {
|
inline constexpr bool is_ratio = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<intmax_t Num, intmax_t Den>
|
template<intmax_t Num, intmax_t Den>
|
||||||
struct is_ratio<std::ratio<Num, Den>> : std::true_type {
|
inline constexpr bool is_ratio<std::ratio<Num, Den>> = true;
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Ratio = detail::is_ratio<T>::value;
|
concept bool Ratio = detail::is_ratio<T>;
|
||||||
|
|
||||||
// common_ratio
|
// common_ratio
|
||||||
|
|
||||||
|
@@ -30,17 +30,15 @@ namespace mp {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_type_list : std::false_type {
|
inline constexpr bool is_type_list = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<template<typename...> typename T, typename... Types>
|
template<template<typename...> typename T, typename... Types>
|
||||||
struct is_type_list<T<Types...>> : std::true_type {
|
inline constexpr bool is_type_list<T<Types...>> = true;
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool TypeList = detail::is_type_list<T>::value;
|
concept bool TypeList = detail::is_type_list<T>;
|
||||||
|
|
||||||
// push_front
|
// push_front
|
||||||
|
|
||||||
|
@@ -50,16 +50,14 @@ namespace units {
|
|||||||
// is_exp
|
// is_exp
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_exp : std::false_type {
|
inline constexpr bool is_exp = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<typename BaseDim, int Value>
|
template<typename BaseDim, int Value>
|
||||||
struct is_exp<exp<BaseDim, Value>> : std::true_type {
|
inline constexpr bool is_exp<exp<BaseDim, Value>> = true;
|
||||||
};
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Exponent = detail::is_exp<T>::value;
|
concept bool Exponent = detail::is_exp<T>;
|
||||||
|
|
||||||
// exp_less
|
// exp_less
|
||||||
|
|
||||||
@@ -88,16 +86,14 @@ namespace units {
|
|||||||
// is_dimension
|
// is_dimension
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_dimension : std::false_type {
|
inline constexpr bool is_dimension = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<Exponent... Es>
|
template<Exponent... Es>
|
||||||
struct is_dimension<dimension<Es...>> : std::bool_constant<(is_exp<Es>::value && ...)> {
|
inline constexpr bool is_dimension<dimension<Es...>> = true;
|
||||||
};
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Dimension = detail::is_dimension<T>::value;
|
concept bool Dimension = detail::is_dimension<T>;
|
||||||
|
|
||||||
// make_dimension
|
// make_dimension
|
||||||
|
|
||||||
|
@@ -36,26 +36,20 @@ namespace units {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_quantity : std::false_type {
|
inline constexpr bool is_quantity = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<Dimension D, Unit U, Number Rep>
|
template<Dimension D, Unit U, Number Rep>
|
||||||
struct is_quantity<quantity<D, U, Rep>> : std::true_type {
|
inline constexpr bool is_quantity<quantity<D, U, Rep>> = true;
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Quantity = detail::is_quantity<T>::value;
|
concept bool Quantity = detail::is_quantity<T>;
|
||||||
|
|
||||||
// treat_as_floating_point
|
// treat_as_floating_point
|
||||||
|
|
||||||
template<class Rep>
|
template<class Rep>
|
||||||
struct treat_as_floating_point : std::is_floating_point<Rep> {
|
inline constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>;
|
||||||
};
|
|
||||||
|
|
||||||
template<class Rep>
|
|
||||||
inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<Rep>::value;
|
|
||||||
|
|
||||||
// quantity_cast
|
// quantity_cast
|
||||||
|
|
||||||
@@ -131,23 +125,22 @@ namespace units {
|
|||||||
using unit = U;
|
using unit = U;
|
||||||
using rep = Rep;
|
using rep = Rep;
|
||||||
|
|
||||||
static_assert(!detail::is_quantity<Rep>::value, "rep cannot be a quantity");
|
static_assert(!Quantity<Rep>, "rep cannot be a quantity");
|
||||||
|
|
||||||
quantity() = default;
|
quantity() = default;
|
||||||
quantity(const quantity&) = default;
|
quantity(const quantity&) = default;
|
||||||
|
|
||||||
template<class Rep2>
|
template<ConvertibleTo<rep> Rep2>
|
||||||
requires ConvertibleTo<Rep2, rep> &&
|
requires (treat_as_floating_point<rep> || !treat_as_floating_point<Rep2>)
|
||||||
(treat_as_floating_point_v<rep> || !treat_as_floating_point_v<Rep2>)
|
|
||||||
constexpr explicit quantity(const Rep2& r) : value_{static_cast<rep>(r)}
|
constexpr explicit quantity(const Rep2& r) : value_{static_cast<rep>(r)}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Quantity Q2>
|
template<Quantity Q2>
|
||||||
requires Same<dimension, typename Q2::dimension> && ConvertibleTo<typename Q2::rep, rep> &&
|
requires Same<dimension, typename Q2::dimension> && ConvertibleTo<typename Q2::rep, rep> &&
|
||||||
(treat_as_floating_point_v<rep> ||
|
(treat_as_floating_point<rep> ||
|
||||||
(std::ratio_divide<typename Q2::unit::ratio, typename unit::ratio>::den == 1 &&
|
(std::ratio_divide<typename Q2::unit::ratio, typename unit::ratio>::den == 1 &&
|
||||||
!treat_as_floating_point_v<typename Q2::rep>))
|
!treat_as_floating_point<typename Q2::rep>))
|
||||||
constexpr quantity(const Q2& q) : value_{quantity_cast<quantity>(q).count()}
|
constexpr quantity(const Q2& q) : value_{quantity_cast<quantity>(q).count()}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -251,7 +244,7 @@ namespace units {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
|
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
|
||||||
requires treat_as_floating_point_v<std::common_type_t<Rep1, Rep2>> || std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1
|
requires treat_as_floating_point<std::common_type_t<Rep1, Rep2>> || std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1
|
||||||
quantity<dimension_multiply_t<D1, D2>, unit<dimension_multiply_t<D1, D2>, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>, std::common_type_t<Rep1, Rep2>>
|
quantity<dimension_multiply_t<D1, D2>, unit<dimension_multiply_t<D1, D2>, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>, std::common_type_t<Rep1, Rep2>>
|
||||||
constexpr operator*(const quantity<D1, U1, Rep1>& lhs,
|
constexpr operator*(const quantity<D1, U1, Rep1>& lhs,
|
||||||
const quantity<D2, U2, Rep2>& rhs)
|
const quantity<D2, U2, Rep2>& rhs)
|
||||||
@@ -291,7 +284,7 @@ namespace units {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
|
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
|
||||||
requires treat_as_floating_point_v<std::common_type_t<Rep1, Rep2>> || std::ratio_divide<typename U1::ratio, typename U2::ratio>::den == 1
|
requires treat_as_floating_point<std::common_type_t<Rep1, Rep2>> || std::ratio_divide<typename U1::ratio, typename U2::ratio>::den == 1
|
||||||
quantity<dimension_divide_t<D1, D2>, unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename U2::ratio>>, std::common_type_t<Rep1, Rep2>>
|
quantity<dimension_divide_t<D1, D2>, unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename U2::ratio>>, std::common_type_t<Rep1, Rep2>>
|
||||||
constexpr operator/(const quantity<D1, U1, Rep1>& lhs,
|
constexpr operator/(const quantity<D1, U1, Rep1>& lhs,
|
||||||
const quantity<D2, U2, Rep2>& rhs)
|
const quantity<D2, U2, Rep2>& rhs)
|
||||||
|
@@ -39,17 +39,15 @@ namespace units {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_unit : std::false_type {
|
inline constexpr bool is_unit = false;
|
||||||
};
|
|
||||||
|
|
||||||
template<Dimension D, Ratio R>
|
template<Dimension D, Ratio R>
|
||||||
struct is_unit<unit<D, R>> : std::true_type {
|
inline constexpr bool is_unit<unit<D, R>> = true;
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept bool Unit = detail::is_unit<T>::value;
|
concept bool Unit = detail::is_unit<T>;
|
||||||
|
|
||||||
// template<Unit U1, Unit U2>
|
// template<Unit U1, Unit U2>
|
||||||
// auto operator/(U1, U2)
|
// auto operator/(U1, U2)
|
||||||
|
@@ -49,8 +49,7 @@ namespace {
|
|||||||
namespace units {
|
namespace units {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct treat_as_floating_point<my_value<T>> : std::is_floating_point<T> {
|
inline constexpr bool treat_as_floating_point<my_value<T>> = std::is_floating_point_v<T>;
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct quantity_values<my_value<T>> {
|
struct quantity_values<my_value<T>> {
|
||||||
@@ -250,7 +249,7 @@ namespace {
|
|||||||
|
|
||||||
// is_quantity
|
// is_quantity
|
||||||
|
|
||||||
static_assert(units::detail::is_quantity<length<millimeter, int>>::value);
|
static_assert(Quantity<length<millimeter, int>>);
|
||||||
|
|
||||||
// common_type
|
// common_type
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user