Skip to content

Commit

Permalink
Merge branch 'master' into ref_docs
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP authored Oct 26, 2024
2 parents 0248136 + 76057ea commit 04eab10
Show file tree
Hide file tree
Showing 11 changed files with 49 additions and 94 deletions.
4 changes: 0 additions & 4 deletions example/include/ranged_representation.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ class ranged_representation : public validated_type<T, is_in_range_t<T, Min, Max
template<typename T, auto Min, auto Max>
constexpr bool mp_units::is_scalar<ranged_representation<T, Min, Max>> = mp_units::is_scalar<T>;

template<typename T, auto Min, auto Max>
constexpr bool mp_units::treat_as_floating_point<ranged_representation<T, Min, Max>> =
mp_units::treat_as_floating_point<T>;

template<typename T, auto Min, auto Max, typename Char>
struct MP_UNITS_STD_FMT::formatter<ranged_representation<T, Min, Max>, Char> : formatter<T, Char> {
template<typename FormatContext>
Expand Down
3 changes: 0 additions & 3 deletions example/include/validated_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ class validated_type {
template<typename T, typename Validator>
constexpr bool mp_units::is_scalar<validated_type<T, Validator>> = mp_units::is_scalar<T>;

template<typename T, typename Validator>
constexpr bool mp_units::treat_as_floating_point<validated_type<T, Validator>> = mp_units::treat_as_floating_point<T>;


template<typename CharT, typename Traits, typename T, typename Validator>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
Expand Down
7 changes: 2 additions & 5 deletions example/measurement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,9 @@ class measurement {

} // namespace

template<class T>
constexpr bool mp_units::treat_as_floating_point<measurement<T>> = mp_units::treat_as_floating_point<T>;

template<class T>
template<typename T>
constexpr bool mp_units::is_scalar<measurement<T>> = true;
template<class T>
template<typename T>
constexpr bool mp_units::is_vector<measurement<T>> = true;

static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::scalar>);
Expand Down
1 change: 1 addition & 0 deletions src/core/include/mp-units/bits/core_gmf.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#if MP_UNITS_HOSTED
#include <mp-units/ext/format.h>
#ifndef MP_UNITS_IMPORT_STD
#include <chrono>
#include <cmath>
#include <locale>
#include <ostream>
Expand Down
36 changes: 11 additions & 25 deletions src/core/include/mp-units/ext/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#ifdef MP_UNITS_IMPORT_STD
import std;
#else
#include <iterator>
#include <type_traits>
#include <utility>
#endif
Expand Down Expand Up @@ -100,44 +101,29 @@ constexpr bool is_derived_from_specialization_of = requires(T* t) { detail::to_b
template<typename T, template<auto...> typename Type>
constexpr bool is_derived_from_specialization_of_v = requires(T* t) { detail::to_base_specialization_of_v<Type>(t); };

namespace detail {

template<typename T>
struct get_value_type {
using type = T::value_type;
};

template<typename T>
struct get_element_type {
using type = std::remove_reference_t<typename T::element_type>;
};

} // namespace detail
requires(!std::is_pointer_v<T> && !std::is_array_v<T>) &&
requires { typename std::indirectly_readable_traits<T>::value_type; }
using wrapped_type_t = std::indirectly_readable_traits<T>::value_type;

template<typename T>
requires requires { typename T::value_type; } || requires { typename T::element_type; }
struct wrapped_type {
using type =
conditional<requires { typename T::value_type; }, detail::get_value_type<T>, detail::get_element_type<T>>::type;
};

template<typename T>
requires requires { typename T::value_type; } || requires { typename T::element_type; }
using wrapped_type_t = wrapped_type<T>::type;
namespace detail {

template<typename T>
struct value_type {
struct value_type_impl {
using type = T;
};

template<typename T>
requires requires { typename wrapped_type_t<T>; }
struct value_type<T> {
struct value_type_impl<T> {
using type = wrapped_type_t<T>;
};

} // namespace detail

template<typename T>
using value_type_t = value_type<T>::type;
requires std::is_object_v<T>
using value_type_t = detail::value_type_impl<T>::type;

template<typename T, typename... Ts>
concept one_of = (false || ... || std::same_as<T, Ts>);
Expand Down
14 changes: 9 additions & 5 deletions src/core/include/mp-units/framework/customization_points.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import std;
#include <concepts>
#include <limits>
#include <type_traits>
#if MP_UNITS_HOSTED
#include <chrono>
#endif
#endif
#endif

Expand All @@ -50,11 +53,12 @@ MP_UNITS_EXPORT_BEGIN
* @tparam Rep a representation type for which a type trait is defined
*/
template<typename Rep>
constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>;

template<typename Rep>
requires requires { typename wrapped_type_t<Rep>; }
constexpr bool treat_as_floating_point<Rep> = treat_as_floating_point<wrapped_type_t<Rep>>;
constexpr bool treat_as_floating_point =
#if MP_UNITS_HOSTED
std::chrono::treat_as_floating_point_v<value_type_t<Rep>>;
#else
std::is_floating_point_v<value_type_t<Rep>>;
#endif

/**
* @brief Specifies a type to have a scalar character
Expand Down
13 changes: 8 additions & 5 deletions src/core/include/mp-units/framework/dimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,23 @@ import std;

namespace mp_units {

template<detail::DerivedDimensionExpr... Expr>
template<typename... Expr>
struct derived_dimension;

MP_UNITS_EXPORT struct dimension_one;

namespace detail {

template<typename T>
struct is_dimension_one : std::false_type {};

template<typename Lhs, typename Rhs>
struct base_dimension_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};

template<typename T1, typename T2>
using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;

template<DerivedDimensionExpr... Expr>
template<typename... Expr>
struct derived_dimension_impl : expr_fractions<is_dimension_one, Expr...> {};

struct dimension_interface {
Expand Down Expand Up @@ -165,7 +168,7 @@ struct base_dimension : detail::dimension_interface {
* @note User should not instantiate this type! It is not exported from the C++ module. The library will
* instantiate this type automatically based on the dimensional arithmetic equation provided by the user.
*/
template<detail::DerivedDimensionExpr... Expr>
template<typename... Expr>
struct derived_dimension final : detail::dimension_interface, detail::derived_dimension_impl<Expr...> {};

/**
Expand Down Expand Up @@ -250,14 +253,14 @@ constexpr auto dimension_symbol_impl(Out out, const power<F, Num, Den...>&, cons
return copy_symbol_exponent<CharT, Num, Den...>(fmt.encoding, negative_power, out);
}

template<typename CharT, std::output_iterator<CharT> Out, DerivedDimensionExpr... Ms>
template<typename CharT, std::output_iterator<CharT> Out, typename... Ms>
constexpr Out dimension_symbol_impl(Out out, const type_list<Ms...>&, const dimension_symbol_formatting& fmt,
bool negative_power)
{
return (..., (out = dimension_symbol_impl<CharT>(out, Ms{}, fmt, negative_power)));
}

template<typename CharT, std::output_iterator<CharT> Out, DerivedDimensionExpr... Nums, DerivedDimensionExpr... Dens>
template<typename CharT, std::output_iterator<CharT> Out, typename... Nums, typename... Dens>
constexpr Out dimension_symbol_impl(Out out, const type_list<Nums...>& nums, const type_list<Dens...>& dens,
const dimension_symbol_formatting& fmt)
{
Expand Down
17 changes: 0 additions & 17 deletions src/core/include/mp-units/framework/dimension_concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,6 @@ namespace detail {
template<typename T>
concept BaseDimension = Dimension<T> && is_derived_from_specialization_of_v<T, base_dimension>;

template<typename T>
struct is_dimension_one : std::false_type {};

template<typename T>
concept IsPowerOfDim =
is_specialization_of_power<T> && (BaseDimension<typename T::factor> || is_dimension_one<typename T::factor>::value);

template<typename T>
constexpr bool is_per_of_dims = false;

template<typename... Ts>
constexpr bool is_per_of_dims<per<Ts...>> =
(... && (BaseDimension<Ts> || is_dimension_one<Ts>::value || IsPowerOfDim<Ts>));

template<typename T>
concept DerivedDimensionExpr = BaseDimension<T> || is_dimension_one<T>::value || IsPowerOfDim<T> || is_per_of_dims<T>;

} // namespace detail

/**
Expand Down
16 changes: 8 additions & 8 deletions src/core/include/mp-units/framework/magnitude.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,22 +428,22 @@ constexpr Out magnitude_symbol_impl(Out out, const unit_symbol_formatting& fmt)
template<auto... Ms>
struct magnitude : detail::magnitude_base<magnitude<Ms...>> {
template<Magnitude M>
[[nodiscard]] friend consteval Magnitude auto operator*(magnitude m1, M m2)
[[nodiscard]] friend consteval Magnitude auto operator*(magnitude lhs, M rhs)
{
if constexpr (sizeof...(Ms) == 0)
return m2;
return rhs;
else if constexpr (is_same_v<M, magnitude<>>)
return m1;
return lhs;
else
return _multiply_impl(m1, m2);
return _multiply_impl(lhs, rhs);
}

[[nodiscard]] friend consteval auto operator/(magnitude l, Magnitude auto r) { return l * _pow<-1>(r); }
[[nodiscard]] friend consteval auto operator/(magnitude lhs, Magnitude auto rhs) { return lhs * _pow<-1>(rhs); }

template<Magnitude M2>
[[nodiscard]] friend consteval bool operator==(magnitude, M2)
template<Magnitude Rhs>
[[nodiscard]] friend consteval bool operator==(magnitude, Rhs)
{
return is_same_v<magnitude, M2>;
return is_same_v<magnitude, Rhs>;
}

private:
Expand Down
8 changes: 5 additions & 3 deletions src/core/include/mp-units/framework/quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ template<typename T>
concept IsFloatingPoint = treat_as_floating_point<T>;

template<typename FromRep, typename ToRep, auto FromUnit = one, auto ToUnit = one>
concept ValuePreservingTo = requires(FromRep&& from, ToRep to) {
{ to = std::forward<FromRep>(from) } -> std::same_as<ToRep&>;
} && (IsFloatingPoint<ToRep> || (!IsFloatingPoint<FromRep> && (integral_conversion_factor(FromUnit, ToUnit))));
concept ValuePreservingTo =
requires(FromRep&& from, ToRep to) {
{ to = std::forward<FromRep>(from) } -> std::same_as<ToRep&>;
} && (IsFloatingPoint<ToRep> ||
(!IsFloatingPoint<std::remove_cvref_t<FromRep>> && (integral_conversion_factor(FromUnit, ToUnit))));

template<typename QFrom, typename QTo>
concept QuantityConvertibleTo =
Expand Down
24 changes: 5 additions & 19 deletions src/core/include/mp-units/framework/quantity_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,38 +520,24 @@ struct is_dimensionless<struct dimensionless> : std::true_type {};
*/
namespace detail {

template<typename T>
concept QuantitySpecWithNoSpecifiers = detail::NamedQuantitySpec<T> || detail::DerivedQuantitySpec<T>;

template<QuantitySpec Q>
[[nodiscard]] consteval QuantitySpec auto get_kind_tree_root(Q q);

} // namespace detail

#if MP_UNITS_API_NO_CRTP
template<typename Q>
requires detail::QuantitySpecWithNoSpecifiers<Q> && detail::SameQuantitySpec<detail::get_kind_tree_root(Q{}), Q{}>
requires(!detail::QuantityKindSpec<Q>) && detail::SameQuantitySpec<detail::get_kind_tree_root(Q{}), Q{}>
#if MP_UNITS_API_NO_CRTP
struct kind_of_<Q> final : Q::_base_type_ {
using _base_type_ = kind_of_;
static constexpr auto _quantity_spec_ = Q{};
};
#else

#if MP_UNITS_COMP_CLANG
template<typename Q>
requires detail::QuantitySpecWithNoSpecifiers<Q> && detail::SameQuantitySpec<detail::get_kind_tree_root(Q{}), Q{}>
#else
template<detail::QuantitySpecWithNoSpecifiers Q>
requires detail::SameQuantitySpec<detail::get_kind_tree_root(Q{}), Q{}>
#endif
struct kind_of_<Q> final : quantity_spec<kind_of_<Q>, Q{}>::_base_type_ {
#endif
using _base_type_ = kind_of_;
static constexpr auto _quantity_spec_ = Q{};
};
#endif

MP_UNITS_EXPORT template<detail::QuantitySpecWithNoSpecifiers auto Q>
requires detail::SameQuantitySpec<detail::get_kind_tree_root(Q), Q>
MP_UNITS_EXPORT template<auto Q>
requires requires { typename kind_of_<decltype(Q)>; }
constexpr kind_of_<MP_UNITS_REMOVE_CONST(decltype(Q))> kind_of;

namespace detail {
Expand Down

0 comments on commit 04eab10

Please sign in to comment.