style: all files refromatted with clang-format

This commit is contained in:
Mateusz Pusz committed 2022-03-17 23:59:48 +01:00
1 parent cc90985958
commit 144f6951c0
143 files changed
+5845 -3563

No files matched your search

@@ -29,11 +29,12 @@
namespace units::detail {
template<Exponent E>
requires (E::den == 1 || E::den == 2) // TODO provide support for any den
requires(E::den == 1 || E::den == 2) // TODO provide support for any den
constexpr ratio exp_ratio()
{
const ratio base_ratio = E::dimension::base_unit::ratio;
const ratio positive_ratio = E::num * E::den < 0 ? ratio(base_ratio.den, base_ratio.num, -base_ratio.exp) : base_ratio;
const ratio positive_ratio =
E::num * E::den < 0 ? ratio(base_ratio.den, base_ratio.num, -base_ratio.exp) : base_ratio;
const std::intmax_t N = E::num * E::den < 0 ? -E::num : E::num;
const ratio ratio_pow = pow<N>(positive_ratio);
return E::den == 2 ? sqrt(ratio_pow) : ratio_pow;
+61 -73
View File
@@ -26,9 +26,9 @@
// IWYU pragma: begin_exports
#include <units/bits/external/fixed_string.h>
#include <units/bits/external/type_traits.h>
#include <units/customization_points.h>
#include <units/ratio.h>
#include <units/bits/external/type_traits.h>
// IWYU pragma: end_exports
#include <cstdint>
@@ -73,7 +73,7 @@ concept Prefix = requires(T* t) { detail::to_prefix_base(t); };
* Satisfied by all ratio values for which `R.num > 0` and `R.den > 0`.
*/
template<ratio R>
concept UnitRatio = R.num > 0 && R.den > 0;
concept UnitRatio = (R.num > 0) && (R.den > 0);
// Unit
template<ratio R, typename U>
@@ -136,10 +136,10 @@ concept Exponent = detail::is_exponent<T>;
namespace detail {
template<Exponent... Es>
requires (BaseDimension<typename Es::dimension> && ...)
requires(BaseDimension<typename Es::dimension> && ...)
struct derived_dimension_base;
} // namespace detail
} // namespace detail
/**
* @brief A concept matching all derived dimensions in the library.
@@ -170,7 +170,7 @@ auto default_unit()
return typename D::coherent_unit{};
}
} // namespace detail
} // namespace detail
/**
* @brief Returns a 'default' unit of the dimension
@@ -200,10 +200,7 @@ using dimension_unit = decltype(detail::default_unit<D>());
* @tparam D Dimension type to use for verification.
*/
template<typename U, typename D>
concept UnitOf =
Unit<U> &&
Dimension<D> &&
std::same_as<typename U::reference, typename dimension_unit<D>::reference>;
concept UnitOf = Unit<U> && Dimension<D> && std::same_as<typename U::reference, typename dimension_unit<D>::reference>;
// PointOrigin
@@ -217,13 +214,13 @@ struct point_origin;
*/
template<typename T>
concept PointOrigin = is_derived_from_specialization_of<T, point_origin> &&
requires {
typename T::dimension;
requires Dimension<typename T::dimension>;
typename T::point_origin;
requires std::same_as<typename T::point_origin, point_origin<typename T::dimension>>;
requires !std::same_as<T, point_origin<typename T::dimension>>;
};
requires {
typename T::dimension;
requires Dimension<typename T::dimension>;
typename T::point_origin;
requires std::same_as<typename T::point_origin, point_origin<typename T::dimension>>;
requires !std::same_as<T, point_origin<typename T::dimension>>;
};
// RebindablePointOriginFor
@@ -247,8 +244,7 @@ using rebind_point_origin_dimension = typename conditional<is_same_v<typename O:
*/
template<typename T, typename D>
concept RebindablePointOriginFor =
requires { typename rebind_point_origin_dimension<T, D>; } &&
PointOrigin<rebind_point_origin_dimension<T, D>> &&
requires { typename rebind_point_origin_dimension<T, D>; } && PointOrigin<rebind_point_origin_dimension<T, D>> &&
std::same_as<D, typename rebind_point_origin_dimension<T, D>::dimension>;
// Kind
@@ -260,13 +256,11 @@ struct _kind_base;
} // namespace detail
template<typename T, template<typename...> typename Base>
concept kind_impl_ =
is_derived_from_specialization_of<T, Base> &&
requires {
typename T::base_kind;
typename T::dimension;
requires Dimension<typename T::dimension>;
};
concept kind_impl_ = is_derived_from_specialization_of<T, Base> && requires {
typename T::base_kind;
typename T::dimension;
requires Dimension<typename T::dimension>;
};
/**
* @brief A concept matching all kind types
@@ -274,10 +268,8 @@ concept kind_impl_ =
* Satisfied by all kind types derived from an specialization of @c kind.
*/
template<typename T>
concept Kind =
kind_impl_<T, detail::_kind_base> &&
kind_impl_<typename T::base_kind, detail::_kind_base> &&
std::same_as<typename T::base_kind, typename T::base_kind::base_kind>;
concept Kind = kind_impl_<T, detail::_kind_base> && kind_impl_<typename T::base_kind, detail::_kind_base> &&
std::same_as<typename T::base_kind, typename T::base_kind::base_kind>;
// PointKind
namespace detail {
@@ -294,9 +286,7 @@ struct _point_kind_base;
*/
template<typename T>
concept PointKind =
kind_impl_<T, detail::_point_kind_base> &&
requires { typename T::origin; } &&
PointOrigin<typename T::origin> &&
kind_impl_<T, detail::_point_kind_base> && requires { typename T::origin; } && PointOrigin<typename T::origin> &&
std::same_as<typename T::dimension, typename T::base_kind::dimension> &&
std::same_as<typename T::dimension, typename T::origin::dimension>;
@@ -394,30 +384,26 @@ concept QuantityPointLike = detail::is_quantity_point_like<T>;
// Representation
template<typename T, typename U>
concept common_type_with_ = // exposition only
std::same_as<std::common_type_t<T, U>, std::common_type_t<U, T>> &&
std::constructible_from<std::common_type_t<T, U>, T> &&
std::constructible_from<std::common_type_t<T, U>, U>;
concept common_type_with_ = // exposition only
(std::same_as<std::common_type_t<T, U>, std::common_type_t<U, T>>) &&
(std::constructible_from<std::common_type_t<T, U>, T>) && (std::constructible_from<std::common_type_t<T, U>, U>);
template<typename T, typename U = T>
concept scalable_number_ = // exposition only
std::regular_invocable<std::multiplies<>, T, U> &&
std::regular_invocable<std::divides<>, T, U>;
concept scalable_number_ = // exposition only
(std::regular_invocable<std::multiplies<>, T, U>) && (std::regular_invocable<std::divides<>, T, U>);
template<typename T>
concept castable_number_ = // exposition only
common_type_with_<T, std::intmax_t> &&
scalable_number_<std::common_type_t<T, std::intmax_t>>;
concept castable_number_ = // exposition only
common_type_with_<T, std::intmax_t> && scalable_number_<std::common_type_t<T, std::intmax_t>>;
template<typename T>
concept scalable_ = // exposition only
castable_number_<T> ||
(requires { typename T::value_type; } && castable_number_<typename T::value_type> && scalable_number_<T, std::common_type_t<typename T::value_type, std::intmax_t>>);
concept scalable_ = // exposition only
castable_number_<T> || (requires { typename T::value_type; } && castable_number_<typename T::value_type> &&
scalable_number_<T, std::common_type_t<typename T::value_type, std::intmax_t>>);
template<typename T, typename U>
concept scalable_with_ = // exposition only
common_type_with_<T, U> &&
scalable_<std::common_type_t<T, U>>;
concept scalable_with_ = // exposition only
common_type_with_<T, U> && scalable_<std::common_type_t<T, U>>;
// WrappedQuantity
namespace detail {
@@ -427,7 +413,9 @@ inline constexpr bool is_wrapped_quantity = false;
template<typename T>
requires requires { typename T::value_type; }
inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::value_type> || QuantityLike<typename T::value_type> || is_wrapped_quantity<typename T::value_type>;
inline constexpr bool is_wrapped_quantity<T> =
Quantity<typename T::value_type> || QuantityLike<typename T::value_type> ||
is_wrapped_quantity<typename T::value_type>;
template<typename T>
requires requires { typename T::quantity_type; }
@@ -442,7 +430,7 @@ inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::quantity_typ
* recursively (i.e. `std::optional<si::length<si::metre>>`).
*/
template<typename T>
concept wrapped_quantity_ = // exposition only
concept wrapped_quantity_ = // exposition only
detail::is_wrapped_quantity<T>;
/**
@@ -451,39 +439,39 @@ concept wrapped_quantity_ = // exposition only
* Satisfied by types that satisfy `(!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>`.
*/
template<typename T>
concept Representation =
(!Quantity<T>) &&
(!QuantityLike<T>) &&
(!wrapped_quantity_<T>) &&
std::regular<T> &&
scalable_<T>;
concept Representation = (!Quantity<T>) && (!QuantityLike<T>) &&
(!wrapped_quantity_<T>) && std::regular<T> && scalable_<T>;
namespace detail {
template<typename T>
requires requires(T q) {
typename quantity_like_traits<T>::dimension;
typename quantity_like_traits<T>::unit;
typename quantity_like_traits<T>::rep;
requires Dimension<typename quantity_like_traits<T>::dimension>;
requires Unit<typename quantity_like_traits<T>::unit>;
requires Representation<typename quantity_like_traits<T>::rep>;
{ quantity_like_traits<T>::number(q) } -> std::convertible_to<typename quantity_like_traits<T>::rep>;
}
typename quantity_like_traits<T>::dimension;
typename quantity_like_traits<T>::unit;
typename quantity_like_traits<T>::rep;
requires Dimension<typename quantity_like_traits<T>::dimension>;
requires Unit<typename quantity_like_traits<T>::unit>;
requires Representation<typename quantity_like_traits<T>::rep>;
{
quantity_like_traits<T>::number(q)
} -> std::convertible_to<typename quantity_like_traits<T>::rep>;
}
inline constexpr bool is_quantity_like<T> = true;
template<typename T>
requires requires(T q) {
typename quantity_point_like_traits<T>::dimension;
typename quantity_point_like_traits<T>::unit;
typename quantity_point_like_traits<T>::rep;
requires Dimension<typename quantity_point_like_traits<T>::dimension>;
requires Unit<typename quantity_point_like_traits<T>::unit>;
requires Representation<typename quantity_point_like_traits<T>::rep>;
{ quantity_point_like_traits<T>::relative(q) } -> QuantityLike;
}
typename quantity_point_like_traits<T>::dimension;
typename quantity_point_like_traits<T>::unit;
typename quantity_point_like_traits<T>::rep;
requires Dimension<typename quantity_point_like_traits<T>::dimension>;
requires Unit<typename quantity_point_like_traits<T>::unit>;
requires Representation<typename quantity_point_like_traits<T>::rep>;
{
quantity_point_like_traits<T>::relative(q)
} -> QuantityLike;
}
inline constexpr bool is_quantity_point_like<T> = true;
} // namespace detail
} // namespace detail
} // namespace units
+18 -14
View File
@@ -59,7 +59,7 @@ struct common_quantity_reference_impl<reference<D, U1>, reference<D, U2>> {
};
template<typename D1, typename U1, typename D2, typename U2>
requires same_unit_reference<dimension_unit<D1>, dimension_unit<D2>>::value
requires(same_unit_reference<dimension_unit<D1>, dimension_unit<D2>>::value)
struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
using type = reference<D1, downcast_unit<D1, common_ratio(U1::ratio, U2::ratio)>>;
};
@@ -77,8 +77,8 @@ struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
using common_quantity_reference =
TYPENAME detail::common_quantity_reference_impl <
std::remove_const_t<decltype(Q1::reference)>, std::remove_const_t<decltype(Q2::reference)>>::type;
TYPENAME detail::common_quantity_reference_impl<std::remove_const_t<decltype(Q1::reference)>,
std::remove_const_t<decltype(Q2::reference)>>::type;
} // namespace detail
} // namespace units
@@ -91,33 +91,37 @@ struct common_type<Q1, Q2> {
private:
using ref = units::detail::common_quantity_reference<Q1, Q2>;
public:
using type = units::quantity<typename ref::dimension, typename ref::unit, common_type_t<typename Q1::rep, typename Q2::rep>>;
using type =
units::quantity<typename ref::dimension, typename ref::unit, common_type_t<typename Q1::rep, typename Q2::rep>>;
};
template<units::QuantityPoint QP1, units::QuantityPointEquivalentTo<QP1> QP2>
requires requires { typename common_type_t<typename QP1::rep, typename QP2::rep>; }
struct common_type<QP1, QP2> {
using type = units::quantity_point<
units::rebind_point_origin_dimension<typename QP1::origin,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::dimension>,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::unit,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::rep>;
using type =
units::quantity_point<units::rebind_point_origin_dimension<
typename QP1::origin, typename common_type_t<typename QP1::quantity_type,
typename QP2::quantity_type>::dimension>,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::unit,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::rep>;
};
template<units::QuantityKind QK1, units::QuantityKindEquivalentTo<QK1> QK2>
requires requires { typename common_type_t<typename QK1::rep, typename QK2::rep>; }
struct common_type<QK1, QK2> {
using type = units::quantity_kind<typename QK1::kind_type,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::unit,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::rep>;
using type =
units::quantity_kind<typename QK1::kind_type,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::unit,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::rep>;
};
template<units::QuantityPointKind QPK1, units::QuantityPointKindEquivalentTo<QPK1> QPK2>
requires requires { typename common_type_t<typename QPK1::rep, typename QPK2::rep>; }
struct common_type<QPK1, QPK2> {
using type = units::quantity_point_kind<typename QPK1::point_kind_type,
using type = units::quantity_point_kind<
typename QPK1::point_kind_type,
typename common_type_t<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>::unit,
typename common_type_t<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>::rep>;
};
}
} // namespace std
+99 -99
View File
@@ -76,105 +76,105 @@ struct decimal_fp {
// >>> for i in range(1, 100):
// ... print(f"/* log({i:>2d}) = */ {math.log(i):.16f},")
constexpr std::array<double, 99> log_table{
/* log( 1) = */ 0.0000000000000000,
/* log( 2) = */ 0.6931471805599453,
/* log( 3) = */ 1.0986122886681098,
/* log( 4) = */ 1.3862943611198906,
/* log( 5) = */ 1.6094379124341003,
/* log( 6) = */ 1.7917594692280550,
/* log( 7) = */ 1.9459101490553132,
/* log( 8) = */ 2.0794415416798357,
/* log( 9) = */ 2.1972245773362196,
/* log(10) = */ 2.3025850929940459,
/* log(11) = */ 2.3978952727983707,
/* log(12) = */ 2.4849066497880004,
/* log(13) = */ 2.5649493574615367,
/* log(14) = */ 2.6390573296152584,
/* log(15) = */ 2.7080502011022101,
/* log(16) = */ 2.7725887222397811,
/* log(17) = */ 2.8332133440562162,
/* log(18) = */ 2.8903717578961645,
/* log(19) = */ 2.9444389791664403,
/* log(20) = */ 2.9957322735539909,
/* log(21) = */ 3.0445224377234230,
/* log(22) = */ 3.0910424533583161,
/* log(23) = */ 3.1354942159291497,
/* log(24) = */ 3.1780538303479458,
/* log(25) = */ 3.2188758248682006,
/* log(26) = */ 3.2580965380214821,
/* log(27) = */ 3.2958368660043291,
/* log(28) = */ 3.3322045101752038,
/* log(29) = */ 3.3672958299864741,
/* log(30) = */ 3.4011973816621555,
/* log(31) = */ 3.4339872044851463,
/* log(32) = */ 3.4657359027997265,
/* log(33) = */ 3.4965075614664802,
/* log(34) = */ 3.5263605246161616,
/* log(35) = */ 3.5553480614894135,
/* log(36) = */ 3.5835189384561099,
/* log(37) = */ 3.6109179126442243,
/* log(38) = */ 3.6375861597263857,
/* log(39) = */ 3.6635616461296463,
/* log(40) = */ 3.6888794541139363,
/* log(41) = */ 3.7135720667043080,
/* log(42) = */ 3.7376696182833684,
/* log(43) = */ 3.7612001156935624,
/* log(44) = */ 3.7841896339182610,
/* log(45) = */ 3.8066624897703196,
/* log(46) = */ 3.8286413964890951,
/* log(47) = */ 3.8501476017100584,
/* log(48) = */ 3.8712010109078911,
/* log(49) = */ 3.8918202981106265,
/* log(50) = */ 3.9120230054281460,
/* log(51) = */ 3.9318256327243257,
/* log(52) = */ 3.9512437185814275,
/* log(53) = */ 3.9702919135521220,
/* log(54) = */ 3.9889840465642745,
/* log(55) = */ 4.0073331852324712,
/* log(56) = */ 4.0253516907351496,
/* log(57) = */ 4.0430512678345503,
/* log(58) = */ 4.0604430105464191,
/* log(59) = */ 4.0775374439057197,
/* log(60) = */ 4.0943445622221004,
/* log(61) = */ 4.1108738641733114,
/* log(62) = */ 4.1271343850450917,
/* log(63) = */ 4.1431347263915326,
/* log(64) = */ 4.1588830833596715,
/* log(65) = */ 4.1743872698956368,
/* log(66) = */ 4.1896547420264252,
/* log(67) = */ 4.2046926193909657,
/* log(68) = */ 4.2195077051761070,
/* log(69) = */ 4.2341065045972597,
/* log(70) = */ 4.2484952420493594,
/* log(71) = */ 4.2626798770413155,
/* log(72) = */ 4.2766661190160553,
/* log(73) = */ 4.2904594411483910,
/* log(74) = */ 4.3040650932041702,
/* log(75) = */ 4.3174881135363101,
/* log(76) = */ 4.3307333402863311,
/* log(77) = */ 4.3438054218536841,
/* log(78) = */ 4.3567088266895917,
/* log(79) = */ 4.3694478524670215,
/* log(80) = */ 4.3820266346738812,
/* log(81) = */ 4.3944491546724391,
/* log(82) = */ 4.4067192472642533,
/* log(83) = */ 4.4188406077965983,
/* log(84) = */ 4.4308167988433134,
/* log(85) = */ 4.4426512564903167,
/* log(86) = */ 4.4543472962535073,
/* log(87) = */ 4.4659081186545837,
/* log(88) = */ 4.4773368144782069,
/* log(89) = */ 4.4886363697321396,
/* log(90) = */ 4.4998096703302650,
/* log(91) = */ 4.5108595065168497,
/* log(92) = */ 4.5217885770490405,
/* log(93) = */ 4.5325994931532563,
/* log(94) = */ 4.5432947822700038,
/* log(95) = */ 4.5538768916005408,
/* log(96) = */ 4.5643481914678361,
/* log(97) = */ 4.5747109785033828,
/* log(98) = */ 4.5849674786705723,
/* log(99) = */ 4.5951198501345898,
/* log( 1) = */ 0.0000000000000000,
/* log( 2) = */ 0.6931471805599453,
/* log( 3) = */ 1.0986122886681098,
/* log( 4) = */ 1.3862943611198906,
/* log( 5) = */ 1.6094379124341003,
/* log( 6) = */ 1.7917594692280550,
/* log( 7) = */ 1.9459101490553132,
/* log( 8) = */ 2.0794415416798357,
/* log( 9) = */ 2.1972245773362196,
/* log(10) = */ 2.3025850929940459,
/* log(11) = */ 2.3978952727983707,
/* log(12) = */ 2.4849066497880004,
/* log(13) = */ 2.5649493574615367,
/* log(14) = */ 2.6390573296152584,
/* log(15) = */ 2.7080502011022101,
/* log(16) = */ 2.7725887222397811,
/* log(17) = */ 2.8332133440562162,
/* log(18) = */ 2.8903717578961645,
/* log(19) = */ 2.9444389791664403,
/* log(20) = */ 2.9957322735539909,
/* log(21) = */ 3.0445224377234230,
/* log(22) = */ 3.0910424533583161,
/* log(23) = */ 3.1354942159291497,
/* log(24) = */ 3.1780538303479458,
/* log(25) = */ 3.2188758248682006,
/* log(26) = */ 3.2580965380214821,
/* log(27) = */ 3.2958368660043291,
/* log(28) = */ 3.3322045101752038,
/* log(29) = */ 3.3672958299864741,
/* log(30) = */ 3.4011973816621555,
/* log(31) = */ 3.4339872044851463,
/* log(32) = */ 3.4657359027997265,
/* log(33) = */ 3.4965075614664802,
/* log(34) = */ 3.5263605246161616,
/* log(35) = */ 3.5553480614894135,
/* log(36) = */ 3.5835189384561099,
/* log(37) = */ 3.6109179126442243,
/* log(38) = */ 3.6375861597263857,
/* log(39) = */ 3.6635616461296463,
/* log(40) = */ 3.6888794541139363,
/* log(41) = */ 3.7135720667043080,
/* log(42) = */ 3.7376696182833684,
/* log(43) = */ 3.7612001156935624,
/* log(44) = */ 3.7841896339182610,
/* log(45) = */ 3.8066624897703196,
/* log(46) = */ 3.8286413964890951,
/* log(47) = */ 3.8501476017100584,
/* log(48) = */ 3.8712010109078911,
/* log(49) = */ 3.8918202981106265,
/* log(50) = */ 3.9120230054281460,
/* log(51) = */ 3.9318256327243257,
/* log(52) = */ 3.9512437185814275,
/* log(53) = */ 3.9702919135521220,
/* log(54) = */ 3.9889840465642745,
/* log(55) = */ 4.0073331852324712,
/* log(56) = */ 4.0253516907351496,
/* log(57) = */ 4.0430512678345503,
/* log(58) = */ 4.0604430105464191,
/* log(59) = */ 4.0775374439057197,
/* log(60) = */ 4.0943445622221004,
/* log(61) = */ 4.1108738641733114,
/* log(62) = */ 4.1271343850450917,
/* log(63) = */ 4.1431347263915326,
/* log(64) = */ 4.1588830833596715,
/* log(65) = */ 4.1743872698956368,
/* log(66) = */ 4.1896547420264252,
/* log(67) = */ 4.2046926193909657,
/* log(68) = */ 4.2195077051761070,
/* log(69) = */ 4.2341065045972597,
/* log(70) = */ 4.2484952420493594,
/* log(71) = */ 4.2626798770413155,
/* log(72) = */ 4.2766661190160553,
/* log(73) = */ 4.2904594411483910,
/* log(74) = */ 4.3040650932041702,
/* log(75) = */ 4.3174881135363101,
/* log(76) = */ 4.3307333402863311,
/* log(77) = */ 4.3438054218536841,
/* log(78) = */ 4.3567088266895917,
/* log(79) = */ 4.3694478524670215,
/* log(80) = */ 4.3820266346738812,
/* log(81) = */ 4.3944491546724391,
/* log(82) = */ 4.4067192472642533,
/* log(83) = */ 4.4188406077965983,
/* log(84) = */ 4.4308167988433134,
/* log(85) = */ 4.4426512564903167,
/* log(86) = */ 4.4543472962535073,
/* log(87) = */ 4.4659081186545837,
/* log(88) = */ 4.4773368144782069,
/* log(89) = */ 4.4886363697321396,
/* log(90) = */ 4.4998096703302650,
/* log(91) = */ 4.5108595065168497,
/* log(92) = */ 4.5217885770490405,
/* log(93) = */ 4.5325994931532563,
/* log(94) = */ 4.5432947822700038,
/* log(95) = */ 4.5538768916005408,
/* log(96) = */ 4.5643481914678361,
/* log(97) = */ 4.5747109785033828,
/* log(98) = */ 4.5849674786705723,
/* log(99) = */ 4.5951198501345898,
};
decimal_fp x = to_decimal(v);
@@ -34,17 +34,17 @@ namespace units::detail {
* Expression of the dependence of a quantity on the base quantities (and their base dimensions) of a system of
* quantities as a product of powers of factors corresponding to the base quantities, omitting any numerical factors.
* A power of a factor is the factor raised to an exponent.
*
* A derived dimension can be formed from multiple exponents (i.e. speed is represented as "exponent<L, 1>, exponent<T, -1>").
* It is also possible to form a derived dimension with only one exponent (i.e. frequency is represented as just
*
* A derived dimension can be formed from multiple exponents (i.e. speed is represented as "exponent<L, 1>, exponent<T,
* -1>"). It is also possible to form a derived dimension with only one exponent (i.e. frequency is represented as just
* "exponent<T, -1>").
*
*
* @note This class template is used by the library engine and should not be directly instantiated by the user.
*
*
* @tparam Es zero or more exponents of a derived dimension
*/
template<Exponent... Es>
requires (BaseDimension<typename Es::dimension> && ...)
requires(BaseDimension<typename Es::dimension> && ...)
struct derived_dimension_base : downcast_base<derived_dimension_base<Es...>> {
using exponents = exponent_list<Es...>;
};
@@ -32,19 +32,16 @@ namespace units::detail {
template<bool Divide, std::size_t NegativeExpCount, std::size_t Idx>
constexpr auto operator_text()
{
if constexpr(Idx == 0) {
if constexpr(Divide && NegativeExpCount == 1) {
if constexpr (Idx == 0) {
if constexpr (Divide && NegativeExpCount == 1) {
return basic_fixed_string("1/");
}
else {
} else {
return basic_fixed_string("");
}
}
else {
if constexpr(Divide && NegativeExpCount == 1) {
} else {
if constexpr (Divide && NegativeExpCount == 1) {
return basic_fixed_string("/");
}
else {
} else {
return basic_symbol_text(" ⋅ ", " ");
}
}
@@ -54,24 +51,21 @@ template<typename E, basic_symbol_text Symbol, std::size_t NegativeExpCount, std
constexpr auto exp_text()
{
// get calculation operator + symbol
const auto txt = operator_text<E::num < 0, NegativeExpCount, Idx>() + Symbol;
if constexpr(E::den != 1) {
const auto txt = operator_text<(E::num < 0), NegativeExpCount, Idx>() + Symbol;
if constexpr (E::den != 1) {
// add root part
return txt + basic_fixed_string("^(") + regular<abs(E::num)>() + basic_fixed_string("/") + regular<E::den>() + basic_fixed_string(")");
}
else if constexpr(E::num != 1) {
return txt + basic_fixed_string("^(") + regular<abs(E::num)>() + basic_fixed_string("/") + regular<E::den>() +
basic_fixed_string(")");
} else if constexpr (E::num != 1) {
// add exponent part
if constexpr(NegativeExpCount > 1) { // no '/' sign here (only negative exponents)
if constexpr (NegativeExpCount > 1) { // no '/' sign here (only negative exponents)
return txt + superscript<E::num>();
}
else if constexpr(E::num != -1) { // -1 is replaced with '/' sign here
} else if constexpr (E::num != -1) { // -1 is replaced with '/' sign here
return txt + superscript<abs(E::num)>();
}
else {
} else {
return txt;
}
}
else {
} else {
return txt;
}
}
+3 -2
View File
@@ -38,7 +38,7 @@ inline constexpr bool same_scaled_units<exponent_list<Es...>, Us...> = (UnitOf<U
template<Exponent E>
constexpr ratio inverse_if_negative(const ratio& r)
{
if constexpr(E::num * E::den > 0)
if constexpr (E::num * E::den > 0)
return r;
else
return inverse(r);
@@ -47,7 +47,8 @@ constexpr ratio inverse_if_negative(const ratio& r)
template<Unit... Us, typename... Es>
constexpr ratio derived_ratio(exponent_list<Es...>)
{
return (... * inverse_if_negative<Es>(pow<detail::abs(Es::num)>(Us::ratio / dimension_unit<typename Es::dimension>::ratio)));
return (... * inverse_if_negative<Es>(
pow<detail::abs(Es::num)>(Us::ratio / dimension_unit<typename Es::dimension>::ratio)));
}
template<DerivedDimension D, Unit... Us>
@@ -54,7 +54,8 @@ struct dim_consolidate<exponent_list<E1, ERest...>> {
using type = type_list_push_front<typename dim_consolidate<exponent_list<ERest...>>::type, E1>;
};
template<BaseDimension Dim, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
template<BaseDimension Dim, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2,
typename... ERest>
struct dim_consolidate<exponent_list<exponent<Dim, Num1, Den1>, exponent<Dim, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;
+2 -2
View File
@@ -30,8 +30,8 @@ namespace units::detail {
/**
* @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions
*
* @tparam Es Exponents of potentially derived dimensions
*
* @tparam Es Exponents of potentially derived dimensions
*/
template<Exponent... Es>
struct dim_unpack;
+11 -9
View File
@@ -34,11 +34,11 @@ namespace units {
/**
* @brief Unknown dimension
*
*
* Sometimes a temporary partial result of a complex calculation may not result in a predefined
* dimension. In such a case an `unknown_dimension` is created with a coherent unit of `unknown_coherent_unit`
* and ratio(1).
*
*
* @tparam Es the list of exponents of ingredient dimensions
*/
template<Exponent... Es>
@@ -70,7 +70,7 @@ struct downcast_dimension_impl<D> {
using type = TYPENAME check_unknown<downcast<D>>::type;
};
} // namespace detail
} // namespace detail
template<Dimension D>
using downcast_dimension = TYPENAME detail::downcast_dimension_impl<D>::type;
@@ -97,8 +97,7 @@ struct dim_invert_impl<derived_dimension_base<Es...>> {
};
template<DerivedDimension D>
struct dim_invert_impl<D> : dim_invert_impl<downcast_base_t<D>> {
};
struct dim_invert_impl<D> : dim_invert_impl<downcast_base_t<D>> {};
} // namespace detail
@@ -123,7 +122,7 @@ struct to_dimension<exponent_list<exponent<D, 1>>> {
/**
* @brief Merges 2 sorted derived dimensions into one units::derived_dimension_base
*
*
* A result of a dimensional calculation may result with many exponents of the same base dimension orginated
* from different parts of the equation. As the exponents lists of both operands it is enough to merge them
* into one list and consolidate duplicates. Also it is possible that final exponents list will contain only
@@ -131,19 +130,22 @@ struct to_dimension<exponent_list<exponent<D, 1>>> {
* dimension itself.
*/
template<Dimension D1, Dimension D2>
using merge_dimension = TYPENAME to_dimension<typename dim_consolidate<type_list_merge_sorted<typename D1::exponents, typename D2::exponents, exponent_less>>::type>::type;
using merge_dimension = TYPENAME to_dimension<typename dim_consolidate<
type_list_merge_sorted<typename D1::exponents, typename D2::exponents, exponent_less>>::type>::type;
template<Dimension D1, Dimension D2>
struct dimension_multiply_impl;
template<BaseDimension D1, BaseDimension D2>
struct dimension_multiply_impl<D1, D2> {
using type = downcast_dimension<merge_dimension<derived_dimension_base<exponent<D1, 1>>, derived_dimension_base<exponent<D2, 1>>>>;
using type = downcast_dimension<
merge_dimension<derived_dimension_base<exponent<D1, 1>>, derived_dimension_base<exponent<D2, 1>>>>;
};
template<BaseDimension D1, DerivedDimension D2>
struct dimension_multiply_impl<D1, D2> {
using type = downcast_dimension<merge_dimension<derived_dimension_base<exponent<D1, 1>>, typename D2::downcast_base_type>>;
using type =
downcast_dimension<merge_dimension<derived_dimension_base<exponent<D1, 1>>, typename D2::downcast_base_type>>;
};
template<DerivedDimension D1, BaseDimension D2>
+33 -34
View File
@@ -30,12 +30,10 @@ namespace units {
namespace detail {
template<typename T, typename U>
struct equivalent_impl : std::false_type {
};
struct equivalent_impl : std::false_type {};
template<typename T>
struct equivalent_impl<T, T> : std::true_type {
};
struct equivalent_impl<T, T> : std::true_type {};
// units
@@ -47,39 +45,35 @@ struct equivalent_impl<U1, U2> : std::disjunction<std::is_base_of<U1, U2>, std::
// dimensions
template<BaseDimension D1, BaseDimension D2>
struct equivalent_impl<D1, D2> : std::conjunction<std::bool_constant<D1::symbol == D2::symbol>,
same_unit_reference<typename D1::base_unit, typename D2::base_unit>> {
};
struct equivalent_impl<D1, D2> :
std::conjunction<std::bool_constant<D1::symbol == D2::symbol>,
same_unit_reference<typename D1::base_unit, typename D2::base_unit>> {};
template<Exponent E1, Exponent E2>
struct equivalent_exp : std::false_type {
};
struct equivalent_exp : std::false_type {};
template<BaseDimension Dim1, std::intmax_t Num, std::intmax_t Den, BaseDimension Dim2>
struct equivalent_exp<exponent<Dim1, Num, Den>, exponent<Dim2, Num, Den>> : equivalent_impl<Dim1, Dim2> {
};
struct equivalent_exp<exponent<Dim1, Num, Den>, exponent<Dim2, Num, Den>> : equivalent_impl<Dim1, Dim2> {};
template<DerivedDimension D1, DerivedDimension D2>
struct equivalent_derived_dim : std::false_type {
};
struct equivalent_derived_dim : std::false_type {};
template<typename... Es1, typename... Es2>
requires(sizeof...(Es1) == sizeof...(Es2))
struct equivalent_derived_dim<derived_dimension_base<Es1...>, derived_dimension_base<Es2...>> :
std::conjunction<equivalent_exp<Es1, Es2>...> {
};
std::conjunction<equivalent_exp<Es1, Es2>...> {};
template<DerivedDimension D1, DerivedDimension D2>
struct equivalent_impl<D1, D2> :
std::disjunction<std::is_base_of<D1, D2>, std::is_base_of<D2, D1>,
equivalent_derived_dim<downcast_base_t<D1>, downcast_base_t<D2>>> {
};
equivalent_derived_dim<downcast_base_t<D1>, downcast_base_t<D2>>> {};
// additionally accounts for unknown dimensions
template<Unit U1, Dimension D1, Unit U2, Dimension D2>
struct equivalent_unit : std::disjunction<equivalent_impl<U1, U2>,
std::bool_constant<U1::ratio / dimension_unit<D1>::ratio == U2::ratio / dimension_unit<D2>::ratio>> {};
struct equivalent_unit :
std::disjunction<equivalent_impl<U1, U2>, std::bool_constant<U1::ratio / dimension_unit<D1>::ratio ==
U2::ratio / dimension_unit<D2>::ratio>> {};
// point origins
@@ -90,41 +84,46 @@ concept EquivalentPointOrigins =
std::same_as<U, rebind_point_origin_dimension<T, typename U::dimension>>;
template<PointOrigin T, PointOrigin U>
struct equivalent_impl<T, U> : std::bool_constant<
EquivalentPointOrigins<T, U> && equivalent_impl<typename T::dimension, typename U::dimension>::value> {};
struct equivalent_impl<T, U> :
std::bool_constant<EquivalentPointOrigins<T, U> &&
equivalent_impl<typename T::dimension, typename U::dimension>::value> {};
// (point) kinds
template<Kind T, Kind U>
struct equivalent_impl<T, U> :
std::conjunction<std::is_same<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::dimension, typename U::dimension>> {};
std::conjunction<std::is_same<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::dimension, typename U::dimension>> {};
template<PointKind T, PointKind U>
struct equivalent_impl<T, U> :
std::conjunction<equivalent_impl<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::origin, typename U::origin>> {};
std::conjunction<equivalent_impl<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::origin, typename U::origin>> {};
// quantities, quantity points, quantity (point) kinds
template<Quantity Q1, Quantity Q2>
struct equivalent_impl<Q1, Q2> : std::conjunction<equivalent_impl<typename Q1::dimension, typename Q2::dimension>,
equivalent_unit<typename Q1::unit, typename Q1::dimension,
typename Q2::unit, typename Q2::dimension>> {};
struct equivalent_impl<Q1, Q2> :
std::conjunction<
equivalent_impl<typename Q1::dimension, typename Q2::dimension>,
equivalent_unit<typename Q1::unit, typename Q1::dimension, typename Q2::unit, typename Q2::dimension>> {};
template<QuantityPoint QP1, QuantityPoint QP2>
struct equivalent_impl<QP1, QP2> : std::conjunction<equivalent_impl<typename QP1::quantity_type, typename QP2::quantity_type>,
equivalent_impl<typename QP1::origin, typename QP2::origin>> {};
struct equivalent_impl<QP1, QP2> :
std::conjunction<equivalent_impl<typename QP1::quantity_type, typename QP2::quantity_type>,
equivalent_impl<typename QP1::origin, typename QP2::origin>> {};
template<QuantityKind QK1, QuantityKind QK2>
struct equivalent_impl<QK1, QK2> : std::conjunction<equivalent_impl<typename QK1::kind_type, typename QK2::kind_type>,
equivalent_impl<typename QK1::quantity_type, typename QK2::quantity_type>> {};
struct equivalent_impl<QK1, QK2> :
std::conjunction<equivalent_impl<typename QK1::kind_type, typename QK2::kind_type>,
equivalent_impl<typename QK1::quantity_type, typename QK2::quantity_type>> {};
template<QuantityPointKind QPK1, QuantityPointKind QPK2>
struct equivalent_impl<QPK1, QPK2> : std::conjunction<equivalent_impl<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>,
equivalent_impl<typename QPK1::origin, typename QPK2::origin>> {};
struct equivalent_impl<QPK1, QPK2> :
std::conjunction<equivalent_impl<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>,
equivalent_impl<typename QPK1::origin, typename QPK2::origin>> {};
} // namespace detail
+17 -17
View File
@@ -38,17 +38,16 @@ namespace units {
template<typename BaseType>
struct downcast_base {
using downcast_base_type = BaseType;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND
friend auto downcast_guide(downcast_base);
friend auto downcast_poison_pill(downcast_base);
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
};
template<typename T>
concept Downcastable =
requires { typename T::downcast_base_type; } &&
std::derived_from<T, downcast_base<typename T::downcast_base_type>>;
requires { typename T::downcast_base_type; } && std::derived_from<T, downcast_base<typename T::downcast_base_type>>;
template<typename T>
concept has_downcast_guide = requires(T t) { downcast_guide(t); };
@@ -58,30 +57,31 @@ concept has_downcast_poison_pill = requires(T t) { downcast_poison_pill(t); };
template<typename Target, Downcastable T>
struct downcast_child : T {
friend auto downcast_guide(typename T::downcast_base)
{ return std::type_identity<Target>(); }
friend auto downcast_guide(typename T::downcast_base) { return std::type_identity<Target>(); }
};
template<Downcastable T>
struct downcast_poison : T {
friend auto downcast_poison_pill(typename T::downcast_base)
{ return true; }
friend auto downcast_poison_pill(typename T::downcast_base) { return true; }
};
enum class downcast_mode {
off = 0, // no downcasting at all
on = 1, // downcasting always forced -> compile-time errors in case of duplicated definitions
automatic = 2 // downcasting automatically enabled if no collisions are present
off = 0, // no downcasting at all
on = 1, // downcasting always forced -> compile-time errors in case of duplicated definitions
automatic = 2 // downcasting automatically enabled if no collisions are present
};
template<typename Target, Downcastable T, downcast_mode mode = static_cast<downcast_mode>(UNITS_DOWNCAST_MODE)>
struct downcast_dispatch : std::conditional_t<mode == downcast_mode::off, T,
struct downcast_dispatch :
std::conditional_t<mode == downcast_mode::off, T,
#ifdef UNITS_COMP_MSVC
downcast_child<Target, T>> {};
downcast_child<Target, T>> {
};
#else
std::conditional_t<mode == downcast_mode::automatic && has_downcast_guide<T>,
downcast_poison<T>, downcast_child<Target, T>>> {};
std::conditional_t<mode == downcast_mode::automatic && has_downcast_guide<T>, downcast_poison<T>,
downcast_child<Target, T>>> {
};
#endif
namespace detail {
@@ -89,7 +89,7 @@ namespace detail {
template<typename T>
constexpr auto downcast_impl()
{
if constexpr(has_downcast_guide<downcast_base<T>> && !has_downcast_poison_pill<downcast_base<T>>)
if constexpr (has_downcast_guide<downcast_base<T>> && !has_downcast_poison_pill<downcast_base<T>>)
return decltype(downcast_guide(std::declval<downcast_base<T>>()))();
else
return std::type_identity<T>();
+17 -16
View File
@@ -22,11 +22,11 @@
#pragma once
#include <units/bits/external/hacks.h> // IWYU pragma: keep
#include <units/bits/external/hacks.h> // IWYU pragma: keep
// IWYU pragma: begin_exports
#include <cstdlib>
#include <compare>
#include <cstdlib>
// IWYU pragma: end_exports
#include <cstddef>
@@ -37,7 +37,7 @@ namespace units {
/**
* @brief A compile-time fixed string
*
*
* @tparam CharT Character type to be used by the string
* @tparam N The size of the string
*/
@@ -70,7 +70,7 @@ struct basic_fixed_string {
template<std::size_t N2>
[[nodiscard]] constexpr friend basic_fixed_string<CharT, N + N2> operator+(
const basic_fixed_string& lhs, const basic_fixed_string<CharT, N2>& rhs) noexcept
const basic_fixed_string& lhs, const basic_fixed_string<CharT, N2>& rhs) noexcept
{
CharT txt[N + N2 + 1] = {};
@@ -82,21 +82,23 @@ struct basic_fixed_string {
[[nodiscard]] constexpr bool operator==(const basic_fixed_string& other) const
{
if (size() != other.size())
return false;
if (size() != other.size()) return false;
for (size_t i = 0; i != size(); ++i) {
if ((*this)[i] != other[i])
return false;
if ((*this)[i] != other[i]) return false;
}
return true;
// return std::ranges::equal(*this, other);
}
template<std::size_t N2>
[[nodiscard]] friend constexpr bool operator==(const basic_fixed_string&, const basic_fixed_string<CharT, N2>&) { return false; }
[[nodiscard]] friend constexpr bool operator==(const basic_fixed_string&, const basic_fixed_string<CharT, N2>&)
{
return false;
}
template<std::size_t N2>
[[nodiscard]] friend constexpr auto operator<=>(const basic_fixed_string& lhs, const basic_fixed_string<CharT, N2>& rhs)
[[nodiscard]] friend constexpr auto operator<=>(const basic_fixed_string& lhs,
const basic_fixed_string<CharT, N2>& rhs)
{
auto first1 = lhs.begin();
const auto last1 = lhs.end();
@@ -105,12 +107,11 @@ struct basic_fixed_string {
auto comp = std::compare_three_way();
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
if (auto cmp = comp(*first1, *first2); cmp != 0)
return cmp;
return first1 != last1 ? std::strong_ordering::greater :
first2 != last2 ? std::strong_ordering::less :
std::strong_ordering::equal;
if (auto cmp = comp(*first1, *first2); cmp != 0) return cmp;
return first1 != last1 ? std::strong_ordering::greater
: first2 != last2 ? std::strong_ordering::less
: std::strong_ordering::equal;
// return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
};
+22 -27
View File
@@ -39,9 +39,9 @@
#define UNITS_DIAGNOSTIC_PUSH UNITS_PRAGMA(GCC diagnostic push)
#define UNITS_DIAGNOSTIC_POP UNITS_PRAGMA(GCC diagnostic pop)
#define UNITS_DIAGNOSTIC_IGNORE_PRAGMAS UNITS_PRAGMA(GCC diagnostic ignored "-Wpragmas")
#define UNITS_DIAGNOSTIC_IGNORE(X) \
UNITS_DIAGNOSTIC_IGNORE_PRAGMAS \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
#define UNITS_DIAGNOSTIC_IGNORE(X) \
UNITS_DIAGNOSTIC_IGNORE_PRAGMAS \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-warning-option") \
UNITS_PRAGMA(GCC diagnostic ignored X)
#define UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF
@@ -87,8 +87,8 @@
#endif
#include <concepts>
#include <compare>
#include <concepts>
#if UNITS_COMP_MSVC || UNITS_COMP_CLANG
@@ -130,14 +130,14 @@ using concepts::totally_ordered;
using ranges::compare_three_way;
using ranges::input_iterator;
using ranges::sentinel_for;
using ranges::iter_value_t;
using ranges::sentinel_for;
namespace ranges {
using ::ranges::begin;
using ::ranges::end;
using ::ranges::distance;
using ::ranges::end;
using ::ranges::input_range;
using ::ranges::range_value_t;
@@ -145,7 +145,7 @@ using ::ranges::range_value_t;
using ::ranges::lower_bound;
using ::ranges::transform;
}
} // namespace ranges
// missing in Range-v3
template<class T>
@@ -153,15 +153,10 @@ concept floating_point = std::is_floating_point_v<T>;
template<class T>
concept default_initializable =
std::constructible_from<T> &&
requires { T{}; } &&
requires { ::new (static_cast<void*>(nullptr)) T; };
std::constructible_from<T> && requires { T{}; } && requires { ::new (static_cast<void*>(nullptr)) T; };
template<class F, class... Args>
concept invocable =
requires(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
};
concept invocable = requires(F&& f, Args&&... args) { std::invoke(std::forward<F>(f), std::forward<Args>(args)...); };
template<class F, class... Args>
concept regular_invocable = invocable<F, Args...>;
@@ -172,44 +167,44 @@ constexpr bool cmp_equal(T t, U u) noexcept
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t == u;
return t == u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? false : UT(t) == u;
return t < 0 ? false : UT(t) == u;
else
return u < 0 ? false : t == UU(u);
return u < 0 ? false : t == UU(u);
}
template<class T, class U>
constexpr bool cmp_not_equal(T t, U u) noexcept
{
return !cmp_equal(t, u);
}
template<class T, class U>
constexpr bool cmp_less(T t, U u) noexcept
{
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t < u;
return t < u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? true : UT(t) < u;
return t < 0 ? true : UT(t) < u;
else
return u < 0 ? false : t < UU(u);
return u < 0 ? false : t < UU(u);
}
template<class T, class U>
constexpr bool cmp_greater(T t, U u) noexcept
{
return cmp_less(u, t);
}
template<class T, class U>
constexpr bool cmp_less_equal(T t, U u) noexcept
{
return !cmp_greater(t, u);
}
template<class T, class U>
constexpr bool cmp_greater_equal(T t, U u) noexcept
{
@@ -220,7 +215,7 @@ template<class R, class T>
constexpr bool in_range(T t) noexcept
{
return std::cmp_greater_equal(t, std::numeric_limits<R>::min()) &&
std::cmp_less_equal(t, std::numeric_limits<R>::max());
std::cmp_less_equal(t, std::numeric_limits<R>::max());
}
#elif UNITS_LIBCXX < 14000
@@ -233,4 +228,4 @@ using ::ranges::compare_three_way;
#endif
} // namespace std
} // namespace std
+23 -13
View File
@@ -28,19 +28,29 @@
namespace units::detail {
template<std::intmax_t Value>
requires (0 <= Value) && (Value < 10)
requires(0 <= Value) && (Value < 10)
inline constexpr basic_fixed_string superscript_number = "";
template<> inline constexpr basic_fixed_string superscript_number<0> = "\u2070";
template<> inline constexpr basic_fixed_string superscript_number<1> = "\u00b9";
template<> inline constexpr basic_fixed_string superscript_number<2> = "\u00b2";
template<> inline constexpr basic_fixed_string superscript_number<3> = "\u00b3";
template<> inline constexpr basic_fixed_string superscript_number<4> = "\u2074";
template<> inline constexpr basic_fixed_string superscript_number<5> = "\u2075";
template<> inline constexpr basic_fixed_string superscript_number<6> = "\u2076";
template<> inline constexpr basic_fixed_string superscript_number<7> = "\u2077";
template<> inline constexpr basic_fixed_string superscript_number<8> = "\u2078";
template<> inline constexpr basic_fixed_string superscript_number<9> = "\u2079";
template<>
inline constexpr basic_fixed_string superscript_number<0> = "\u2070";
template<>
inline constexpr basic_fixed_string superscript_number<1> = "\u00b9";
template<>
inline constexpr basic_fixed_string superscript_number<2> = "\u00b2";
template<>
inline constexpr basic_fixed_string superscript_number<3> = "\u00b3";
template<>
inline constexpr basic_fixed_string superscript_number<4> = "\u2074";
template<>
inline constexpr basic_fixed_string superscript_number<5> = "\u2075";
template<>
inline constexpr basic_fixed_string superscript_number<6> = "\u2076";
template<>
inline constexpr basic_fixed_string superscript_number<7> = "\u2077";
template<>
inline constexpr basic_fixed_string superscript_number<8> = "\u2078";
template<>
inline constexpr basic_fixed_string superscript_number<9> = "\u2079";
inline constexpr basic_symbol_text superscript_minus("\u207b", "-");
@@ -49,9 +59,9 @@ inline constexpr basic_symbol_text superscript_prefix("", "^");
template<std::intmax_t Value>
constexpr auto superscript_helper()
{
if constexpr(Value < 0)
if constexpr (Value < 0)
return superscript_minus + superscript_helper<-Value>();
else if constexpr(Value < 10)
else if constexpr (Value < 10)
return basic_symbol_text(superscript_number<Value>, basic_fixed_string(static_cast<char>('0' + Value)));
else
return superscript_helper<Value / 10>() + superscript_helper<Value % 10>();
+6 -5
View File
@@ -111,7 +111,7 @@ struct split_impl<List, Idx, N> {
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
requires (Idx < N)
requires(Idx < N)
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = TYPENAME type_list_push_front_impl<typename base::first_list, T>::type;
@@ -144,8 +144,7 @@ template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
@@ -174,13 +173,15 @@ template<template<typename...> typename List, typename Lhs1, typename... LhsRest
template<typename, typename> typename Pred>
requires Pred<Lhs1, Rhs1>::value
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = TYPENAME type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type;
using type = TYPENAME type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type;
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = TYPENAME type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type;
using type = TYPENAME type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type;
};
} // namespace detail
+1 -1
View File
@@ -22,8 +22,8 @@
#pragma once
#include <cstdint>
#include <cassert>
#include <cstdint>
namespace units::detail {
+8 -4
View File
@@ -36,12 +36,16 @@ template<typename Dim, template<typename...> typename DimTemplate>
inline constexpr bool same_exponents_of = false;
template<Exponent... Es, template<typename...> typename DimTemplate>
inline constexpr bool same_exponents_of<unknown_dimension<Es...>, DimTemplate> = requires { typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>; } && std::same_as<exponent_list<Es...>, typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>::recipe>;
inline constexpr bool same_exponents_of<unknown_dimension<Es...>, DimTemplate> =
requires { typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>; } &&
std::same_as<exponent_list<Es...>, typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit,
typename Es::dimension...>::recipe>;
} // namespace detail
} // namespace detail
template<typename Dim, template<typename...> typename DimTemplate>
concept EquivalentUnknownDimensionOfT = Dimension<Dim> && is_derived_from_specialization_of<Dim, unknown_dimension> && detail::same_exponents_of<Dim, DimTemplate>;
concept EquivalentUnknownDimensionOfT = Dimension<Dim> && is_derived_from_specialization_of<Dim, unknown_dimension> &&
detail::same_exponents_of<Dim, DimTemplate>;
#endif
@@ -56,7 +60,7 @@ concept DimensionOfT = Dimension<Dim> && (is_derived_from_specialization_of<Dim,
#if UNITS_DOWNCAST_MODE == 0
|| EquivalentUnknownDimensionOfT<Dim, DimTemplate>
#endif
);
);
/**
* @brief A concept matching all quantities with provided dimension class template
+7 -7
View File
@@ -22,6 +22,7 @@
#pragma once
#include <gsl/gsl-lite.hpp>
#include <array>
#include <cassert>
#include <cmath>
@@ -29,7 +30,6 @@
#include <numeric>
#include <tuple>
#include <type_traits>
#include <gsl/gsl-lite.hpp>
namespace units::detail {
@@ -106,9 +106,9 @@ template<typename T>
// (a 10^e) mod b -> [ (a mod b) (10^e mod b) ] mod b
return std::gcd(
b, static_cast<std::intmax_t>(mulmod(static_cast<std::uint64_t>(a % b),
modpow(10, static_cast<std::uint64_t>(e), static_cast<std::uint64_t>(b)),
static_cast<std::uint64_t>(b))));
b, static_cast<std::intmax_t>(mulmod(static_cast<std::uint64_t>(a % b),
modpow(10, static_cast<std::uint64_t>(e), static_cast<std::uint64_t>(b)),
static_cast<std::uint64_t>(b))));
}
constexpr void cwap(std::intmax_t& lhs, std::intmax_t& rhs)
@@ -119,8 +119,8 @@ constexpr void cwap(std::intmax_t& lhs, std::intmax_t& rhs)
}
// Computes the rational gcd of n1/d1 x 10^e1 and n2/d2 x 10^e2
[[nodiscard]] constexpr auto gcd_frac(std::intmax_t n1, std::intmax_t d1, std::intmax_t e1, std::intmax_t n2, std::intmax_t d2,
std::intmax_t e2) noexcept
[[nodiscard]] constexpr auto gcd_frac(std::intmax_t n1, std::intmax_t d1, std::intmax_t e1, std::intmax_t n2,
std::intmax_t d2, std::intmax_t e2) noexcept
{
// Short cut for equal ratios
if (n1 == n2 && d1 == d2 && e1 == e2) {
@@ -153,7 +153,7 @@ constexpr void cwap(std::intmax_t& lhs, std::intmax_t& rhs)
constexpr void normalize(std::intmax_t& num, std::intmax_t& den, std::intmax_t& exp)
{
if(num == 0) {
if (num == 0) {
den = 1;
exp = 0;
return;
+1 -1
View File
@@ -33,7 +33,7 @@ namespace units::detail {
template<std::intmax_t N, typename F>
requires gt_zero<N>
[[nodiscard]] constexpr std::intmax_t iroot_impl(std::intmax_t v, F const& pow_function) noexcept
[[nodiscard]] constexpr std::intmax_t iroot_impl(std::intmax_t v, const F& pow_function) noexcept
{
if constexpr (N == 1) {
return v;
+37 -49
View File
@@ -24,8 +24,8 @@
#include <units/bits/derived_symbol_text.h>
#include <units/bits/external/text_tools.h>
#include <units/prefix.h>
#include <units/derived_dimension.h>
#include <units/prefix.h>
namespace units::detail {
@@ -34,33 +34,25 @@ inline constexpr basic_symbol_text base_multiplier("\u00D7 10", "x 10");
template<ratio R>
constexpr auto ratio_text()
{
if constexpr(R.num == 1 && R.den == 1 && R.exp != 0) {
if constexpr (R.num == 1 && R.den == 1 && R.exp != 0) {
return base_multiplier + superscript<R.exp>();
}
else if constexpr(R.num != 1 || R.den != 1 || R.exp != 0) {
} else if constexpr (R.num != 1 || R.den != 1 || R.exp != 0) {
auto txt = basic_fixed_string("[") + regular<R.num>();
if constexpr(R.den == 1) {
if constexpr(R.exp == 0) {
if constexpr (R.den == 1) {
if constexpr (R.exp == 0) {
return txt + basic_fixed_string("]");
} else {
return txt + " " + base_multiplier + superscript<R.exp>() + basic_fixed_string("]");
}
else {
return txt + " " + base_multiplier + superscript<R.exp>() +
basic_fixed_string("]");
} else {
if constexpr (R.exp == 0) {
return txt + basic_fixed_string("/") + regular<R.den>() + basic_fixed_string("]");
} else {
return txt + basic_fixed_string("/") + regular<R.den>() + " " + base_multiplier + superscript<R.exp>() +
basic_fixed_string("]");
}
}
else {
if constexpr(R.exp == 0) {
return txt + basic_fixed_string("/") + regular<R.den>() +
basic_fixed_string("]");
}
else {
return txt + basic_fixed_string("/") + regular<R.den>() +
" " + base_multiplier + superscript<R.exp>() +
basic_fixed_string("]");
}
}
}
else {
} else {
return basic_fixed_string("");
}
}
@@ -68,32 +60,29 @@ constexpr auto ratio_text()
template<ratio R, typename PrefixFamily, std::size_t SymbolLen>
constexpr auto prefix_or_ratio_text()
{
if constexpr(R.num == 1 && R.den == 1 && R.exp == 0) {
if constexpr (R.num == 1 && R.den == 1 && R.exp == 0) {
// no ratio/prefix
return basic_fixed_string("");
}
else {
} else {
if constexpr (!is_same_v<PrefixFamily, no_prefix>) {
// try to form a prefix
using prefix = downcast<detail::prefix_base<PrefixFamily, R>>;
if constexpr(!is_same_v<prefix, prefix_base<PrefixFamily, R>>) {
if constexpr (!is_same_v<prefix, prefix_base<PrefixFamily, R>>) {
// print as a prefixed unit
return prefix::symbol;
}
else {
} else {
// print as a ratio of the coherent unit
constexpr auto txt = ratio_text<R>();
if constexpr(SymbolLen > 0 && txt.standard().size() > 0)
if constexpr (SymbolLen > 0 && txt.standard().size() > 0)
return txt + basic_fixed_string(" ");
else
return txt;
}
}
else {
} else {
// print as a ratio of the coherent unit
constexpr auto txt = ratio_text<R>();
if constexpr(SymbolLen > 0 && txt.standard().size() > 0)
if constexpr (SymbolLen > 0 && txt.standard().size() > 0)
return txt + basic_fixed_string(" ");
else
return txt;
@@ -104,7 +93,8 @@ constexpr auto prefix_or_ratio_text()
template<typename... Es, std::size_t... Idxs>
constexpr auto derived_dimension_unit_text(exponent_list<Es...>, std::index_sequence<Idxs...>)
{
return (exp_text<Es, dimension_unit<typename Es::dimension>::symbol, negative_exp_count<Es...>, Idxs>() + ... + basic_symbol_text(basic_fixed_string("")));
return (exp_text<Es, dimension_unit<typename Es::dimension>::symbol, negative_exp_count<Es...>, Idxs>() + ... +
basic_symbol_text(basic_fixed_string("")));
}
template<typename... Es>
@@ -120,10 +110,9 @@ template<Exponent Exp>
constexpr auto exponent_list_with_named_units(Exp)
{
using dim = TYPENAME Exp::dimension;
if constexpr(dimension_unit<dim>::is_named) {
if constexpr (dimension_unit<dim>::is_named) {
return exponent_list<Exp>();
}
else {
} else {
using recipe = TYPENAME dim::recipe;
return exponent_list_with_named_units(recipe());
}
@@ -135,10 +124,7 @@ constexpr auto exponent_list_with_named_units(exponent_list<Es...>)
return type_list_join<decltype(exponent_list_with_named_units(Es()))...>();
}
constexpr auto exponent_list_with_named_units(exponent_list<> empty)
{
return empty;
}
constexpr auto exponent_list_with_named_units(exponent_list<> empty) { return empty; }
template<Dimension Dim>
constexpr auto derived_dimension_unit_text()
@@ -149,29 +135,31 @@ constexpr auto derived_dimension_unit_text()
template<typename T>
// TODO replace with `inline constexpr bool has_symbol` when MSVC cathes up
concept has_symbol = requires{ T::symbol; };
concept has_symbol = requires { T::symbol; };
template<Dimension Dim, Unit U>
constexpr auto unit_text()
{
if constexpr(has_symbol<U>) {
if constexpr (has_symbol<U>) {
// already has a symbol so print it
return U::symbol;
}
else {
} else {
// print as a prefix or ratio of a coherent unit
using coherent_unit = dimension_unit<Dim>;
if constexpr(has_symbol<coherent_unit>) {
if constexpr (has_symbol<coherent_unit>) {
// use predefined coherent unit symbol
constexpr auto symbol_text = coherent_unit::symbol;
constexpr auto prefix_txt = prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family, symbol_text.standard().size()>();
constexpr auto prefix_txt =
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family,
symbol_text.standard().size()>();
return prefix_txt + symbol_text;
}
else {
} else {
// use derived dimension ingredients to create a unit symbol
constexpr auto symbol_text = derived_dimension_unit_text<Dim>();
constexpr auto prefix_txt = prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family, symbol_text.standard().size()>();
constexpr auto prefix_txt =
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family,
symbol_text.standard().size()>();
return prefix_txt + symbol_text;
}
}