feat: SymbolicArg applied to expression templates

This commit is contained in:
Mateusz Pusz
2024-11-08 13:30:55 +01:00
parent 1702853893
commit 8423e50777

View File

@@ -58,7 +58,7 @@ concept SymbolicConstant =
* *
* @tparam Ts The list of types * @tparam Ts The list of types
*/ */
template<typename... Ts> template<detail::SymbolicArg... Ts>
struct type_list {}; struct type_list {};
/** /**
@@ -66,7 +66,7 @@ struct type_list {};
* *
* @note Can't be empty * @note Can't be empty
*/ */
template<typename T, typename... Ts> template<detail::SymbolicArg T, detail::SymbolicArg... Ts>
struct per {}; struct per {};
namespace detail { namespace detail {
@@ -113,7 +113,7 @@ constexpr bool ratio_one<N, N> = true;
* *
* @note @p Den is an optional parameter to shorten the types presented to the user in the case when @p Den equals `1`. * @note @p Den is an optional parameter to shorten the types presented to the user in the case when @p Den equals `1`.
*/ */
template<typename F, int Num, int... Den> template<detail::SymbolicArg F, int Num, int... Den>
requires(detail::valid_ratio<Num, Den...> && detail::positive_ratio<Num, Den...> && !detail::ratio_one<Num, Den...>) requires(detail::valid_ratio<Num, Den...> && detail::positive_ratio<Num, Den...> && !detail::ratio_one<Num, Den...>)
struct power { struct power {
using factor = F; using factor = F;
@@ -141,7 +141,7 @@ constexpr bool is_specialization_of_power = false;
template<typename F, int... Ints> template<typename F, int... Ints>
constexpr bool is_specialization_of_power<power<F, Ints...>> = true; constexpr bool is_specialization_of_power<power<F, Ints...>> = true;
template<typename T, ratio R> template<SymbolicArg T, ratio R>
consteval auto power_or_T_impl() consteval auto power_or_T_impl()
{ {
if constexpr (is_specialization_of_power<T>) { if constexpr (is_specialization_of_power<T>) {
@@ -158,7 +158,7 @@ consteval auto power_or_T_impl()
} }
} }
template<typename T, auto R> template<SymbolicArg T, auto R>
// template<typename T, ratio R> // TODO ICE gcc 12 // template<typename T, ratio R> // TODO ICE gcc 12
using power_or_T = decltype(power_or_T_impl<T, R>()); using power_or_T = decltype(power_or_T_impl<T, R>());
@@ -309,7 +309,7 @@ struct expr_fractions_result {
using _den_ = Den; // exposition only using _den_ = Den; // exposition only
}; };
template<typename OneType, typename List> template<SymbolicArg OneType, typename List>
[[nodiscard]] consteval auto expr_fractions_impl() [[nodiscard]] consteval auto expr_fractions_impl()
{ {
constexpr std::size_t size = type_list_size<List>; constexpr std::size_t size = type_list_size<List>;
@@ -337,11 +337,11 @@ template<typename OneType, typename List>
/** /**
* @brief Divides expression template spec to numerator and denominator parts * @brief Divides expression template spec to numerator and denominator parts
*/ */
template<typename OneType, typename... Ts> template<SymbolicArg OneType, typename... Ts>
struct expr_fractions : decltype(expr_fractions_impl<OneType, type_list<Ts...>>()) {}; struct expr_fractions : decltype(expr_fractions_impl<OneType, type_list<Ts...>>()) {};
// expr_make_spec // expr_make_spec
template<typename NumList, typename DenList, typename OneType, template<typename...> typename To> template<typename NumList, typename DenList, SymbolicArg OneType, template<typename...> typename To>
[[nodiscard]] MP_UNITS_CONSTEVAL auto expr_make_spec_impl() [[nodiscard]] MP_UNITS_CONSTEVAL auto expr_make_spec_impl()
{ {
constexpr std::size_t num = type_list_size<NumList>; constexpr std::size_t num = type_list_size<NumList>;
@@ -365,7 +365,7 @@ template<typename NumList, typename DenList, typename OneType, template<typename
/** /**
* @brief Creates an expression template spec based on provided numerator and denominator parts * @brief Creates an expression template spec based on provided numerator and denominator parts
*/ */
template<typename NumList, typename DenList, typename OneType, template<typename, typename> typename Pred, template<typename NumList, typename DenList, SymbolicArg OneType, template<typename, typename> typename Pred,
template<typename...> typename To> template<typename...> typename To>
[[nodiscard]] MP_UNITS_CONSTEVAL auto get_optimized_expression() [[nodiscard]] MP_UNITS_CONSTEVAL auto get_optimized_expression()
{ {
@@ -386,8 +386,8 @@ template<typename NumList, typename DenList, typename OneType, template<typename
* @tparam Lhs lhs of the operation * @tparam Lhs lhs of the operation
* @tparam Rhs rhs of the operation * @tparam Rhs rhs of the operation
*/ */
template<template<typename...> typename To, typename OneType, template<typename, typename> typename Pred, typename Lhs, template<template<typename...> typename To, SymbolicArg OneType, template<typename, typename> typename Pred,
typename Rhs> typename Lhs, typename Rhs>
[[nodiscard]] MP_UNITS_CONSTEVAL auto expr_multiply(Lhs, Rhs) [[nodiscard]] MP_UNITS_CONSTEVAL auto expr_multiply(Lhs, Rhs)
{ {
if constexpr (is_same_v<Lhs, OneType>) { if constexpr (is_same_v<Lhs, OneType>) {
@@ -421,8 +421,8 @@ template<template<typename...> typename To, typename OneType, template<typename,
* @tparam Lhs lhs of the operation * @tparam Lhs lhs of the operation
* @tparam Rhs rhs of the operation * @tparam Rhs rhs of the operation
*/ */
template<template<typename...> typename To, typename OneType, template<typename, typename> typename Pred, typename Lhs, template<template<typename...> typename To, SymbolicArg OneType, template<typename, typename> typename Pred,
typename Rhs> typename Lhs, typename Rhs>
[[nodiscard]] MP_UNITS_CONSTEVAL auto expr_divide(Lhs lhs, Rhs rhs) [[nodiscard]] MP_UNITS_CONSTEVAL auto expr_divide(Lhs lhs, Rhs rhs)
{ {
if constexpr (is_same_v<Lhs, Rhs>) { if constexpr (is_same_v<Lhs, Rhs>) {
@@ -455,7 +455,7 @@ template<template<typename...> typename To, typename OneType, template<typename,
* @tparam OneType type that represents the value `1` * @tparam OneType type that represents the value `1`
* @tparam To destination type list to put the result to * @tparam To destination type list to put the result to
*/ */
template<template<typename...> typename To, typename OneType, typename T> template<template<typename...> typename To, SymbolicArg OneType, typename T>
[[nodiscard]] consteval auto expr_invert(T) [[nodiscard]] consteval auto expr_invert(T)
{ {
if constexpr (is_specialization_of<T, To>) if constexpr (is_specialization_of<T, To>)
@@ -467,7 +467,7 @@ template<template<typename...> typename To, typename OneType, typename T>
} }
template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, typename OneType, template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred, typename... Nums, typename... Dens> template<typename, typename> typename Pred, typename... Nums, typename... Dens>
requires detail::non_zero<Den> requires detail::non_zero<Den>
[[nodiscard]] consteval auto expr_pow_impl(type_list<Nums...>, type_list<Dens...>) [[nodiscard]] consteval auto expr_pow_impl(type_list<Nums...>, type_list<Dens...>)
@@ -487,7 +487,7 @@ template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To
* @tparam Pred binary less then predicate * @tparam Pred binary less then predicate
* @tparam T Expression being the base of the operation * @tparam T Expression being the base of the operation
*/ */
template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, typename OneType, template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred, typename T> template<typename, typename> typename Pred, typename T>
requires detail::non_zero<Den> requires detail::non_zero<Den>
[[nodiscard]] consteval auto expr_pow(T v) [[nodiscard]] consteval auto expr_pow(T v)
@@ -551,7 +551,7 @@ template<typename T, auto... Ints>
return pow<Ints...>(T{}); return pow<Ints...>(T{});
} }
template<template<typename> typename Proj, template<typename...> typename To, typename OneType, template<template<typename> typename Proj, template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred, expr_type_projectable<Proj>... Nums, template<typename, typename> typename Pred, expr_type_projectable<Proj>... Nums,
expr_type_projectable<Proj>... Dens> expr_type_projectable<Proj>... Dens>
[[nodiscard]] consteval auto expr_map_impl(type_list<Nums...>, type_list<Dens...>) [[nodiscard]] consteval auto expr_map_impl(type_list<Nums...>, type_list<Dens...>)
@@ -569,7 +569,7 @@ template<template<typename> typename Proj, template<typename...> typename To, ty
* @tparam Pred binary less then predicate * @tparam Pred binary less then predicate
* @tparam T expression template to map from * @tparam T expression template to map from
*/ */
template<template<typename> typename Proj, template<typename...> typename To, typename OneType, template<template<typename> typename Proj, template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred, expr_projectable<Proj> T> template<typename, typename> typename Pred, expr_projectable<Proj> T>
[[nodiscard]] consteval auto expr_map(T) [[nodiscard]] consteval auto expr_map(T)
{ {