mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-01 03:14:29 +02:00
feat: new quantity creation syntax support added
This commit is contained in:
@@ -25,11 +25,48 @@
|
||||
#include <units/bits/external/type_traits.h>
|
||||
#include <units/customization_points.h>
|
||||
#include <units/dimension.h>
|
||||
#include <units/quantity_spec.h>
|
||||
#include <units/unit.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
/**
|
||||
* @brief Quantity character
|
||||
*
|
||||
* Scalars, vectors and tensors are mathematical objects that can be used to
|
||||
* denote certain physical quantities and their values. They are as such
|
||||
* independent of the particular choice of a coordinate system, whereas
|
||||
* each scalar component of a vector or a tensor and each component vector and
|
||||
* component tensor depend on that choice.
|
||||
*
|
||||
* A scalar is a physical quantity that has magnitude but no direction.
|
||||
*
|
||||
* Vectors are physical quantities that possess both magnitude and direction
|
||||
* and whose operations obey the axioms of a vector space.
|
||||
*
|
||||
* Tensors can be used to describe more general physical quantities.
|
||||
* For example, the Cauchy stress tensor possess magnitude, direction,
|
||||
* and orientation qualities.
|
||||
*/
|
||||
enum class quantity_character { scalar, vector, tensor };
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_derived_quantity_spec = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Concept matching quantity specification types
|
||||
*
|
||||
* Satisfied by all `derived_quantity_spec` specializations.
|
||||
*/
|
||||
template<typename T>
|
||||
concept DerivedQuantitySpec = detail::is_specialization_of_derived_quantity_spec<T>;
|
||||
|
||||
template<typename T>
|
||||
concept QuantitySpec = NamedQuantitySpec<T> || DerivedQuantitySpec<T>;
|
||||
|
||||
template<QuantitySpec auto Q, Unit auto U>
|
||||
struct reference;
|
||||
|
||||
|
@@ -26,32 +26,13 @@
|
||||
#include <units/bits/expression_template.h>
|
||||
#include <units/bits/external/type_name.h>
|
||||
#include <units/bits/external/type_traits.h>
|
||||
#include <units/bits/quantity_concepts.h>
|
||||
#include <units/dimension.h>
|
||||
#include <units/unit.h>
|
||||
#include <tuple>
|
||||
|
||||
namespace units {
|
||||
|
||||
/**
|
||||
* @brief Quantity character
|
||||
*
|
||||
* Scalars, vectors and tensors are mathematical objects that can be used to
|
||||
* denote certain physical quantities and their values. They are as such
|
||||
* independent of the particular choice of a coordinate system, whereas
|
||||
* each scalar component of a vector or a tensor and each component vector and
|
||||
* component tensor depend on that choice.
|
||||
*
|
||||
* A scalar is a physical quantity that has magnitude but no direction.
|
||||
*
|
||||
* Vectors are physical quantities that possess both magnitude and direction
|
||||
* and whose operations obey the axioms of a vector space.
|
||||
*
|
||||
* Tensors can be used to describe more general physical quantities.
|
||||
* For example, the Cauchy stress tensor possess magnitude, direction,
|
||||
* and orientation qualities.
|
||||
*/
|
||||
enum class quantity_character { scalar, vector, tensor };
|
||||
|
||||
namespace detail {
|
||||
|
||||
// TODO revise the note in the below comment
|
||||
@@ -90,9 +71,6 @@ template<auto... Args>
|
||||
return ch;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_derived_quantity_spec = false;
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_dimensionless = false;
|
||||
|
||||
@@ -111,17 +89,6 @@ inline constexpr bool is_per_of_quantity_specs<per<Ts...>> =
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Concept matching quantity specification types
|
||||
*
|
||||
* Satisfied by all `derived_quantity_spec` specializations.
|
||||
*/
|
||||
template<typename T>
|
||||
concept DerivedQuantitySpec = detail::is_specialization_of_derived_quantity_spec<T>;
|
||||
|
||||
template<typename T>
|
||||
concept QuantitySpec = NamedQuantitySpec<T> || DerivedQuantitySpec<T>;
|
||||
|
||||
template<typename T>
|
||||
concept DerivedQuantitySpecExpr = NamedQuantitySpec<T> || detail::is_dimensionless<T> ||
|
||||
detail::is_power_of_quantity_spec<T> || detail::is_per_of_quantity_specs<T>;
|
||||
@@ -167,9 +134,6 @@ concept associated_unit = Unit<U> && requires(U u) { get_dimension_for_impl(get_
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<QuantitySpec auto Q, Unit auto U>
|
||||
struct reference;
|
||||
|
||||
/**
|
||||
* @brief A specification of a derived quantity
|
||||
*
|
||||
@@ -247,6 +211,13 @@ struct derived_quantity_spec : detail::expr_fractions<derived_quantity_spec<>, Q
|
||||
return reference<derived_quantity_spec{}, u>{};
|
||||
}
|
||||
#endif
|
||||
|
||||
template<RepresentationOf<character> Rep, Unit U>
|
||||
[[nodiscard]] consteval Quantity auto operator()(Rep&& v, U u) const
|
||||
requires(dimension == detail::get_dimension_for(u))
|
||||
{
|
||||
return (*this)[u](std::forward<Rep>(v));
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
@@ -329,6 +300,13 @@ struct quantity_spec<Self, Dim, Args...> {
|
||||
{
|
||||
return reference<Self{}, u>{};
|
||||
}
|
||||
|
||||
template<RepresentationOf<character> Rep, Unit U>
|
||||
[[nodiscard]] consteval Quantity auto operator()(Rep&& v, U u) const
|
||||
requires(dimension == detail::get_dimension_for(u))
|
||||
{
|
||||
return (*this)[u](std::forward<Rep>(v));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -391,6 +369,13 @@ struct quantity_spec<Self, Q, Args...> : std::remove_const_t<decltype(Q)> {
|
||||
{
|
||||
return reference<Self{}, u>{};
|
||||
}
|
||||
|
||||
template<RepresentationOf<character> Rep, Unit U>
|
||||
[[nodiscard]] consteval Quantity auto operator()(Rep&& v, U u) const
|
||||
requires(this->dimension == detail::get_dimension_for(u))
|
||||
{
|
||||
return (*this)[u](std::forward<Rep>(v));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -23,7 +23,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <units/bits/quantity_concepts.h>
|
||||
#include <units/quantity_spec.h>
|
||||
#include <units/unit.h>
|
||||
|
||||
namespace units {
|
||||
@@ -51,6 +50,13 @@ struct reference {
|
||||
static constexpr QuantitySpec auto quantity_spec = Q;
|
||||
static constexpr Dimension auto dimension = Q.dimension;
|
||||
static constexpr Unit auto unit = U;
|
||||
|
||||
template<RepresentationOf<Q.character> Rep>
|
||||
// TODO can we somehow return an explicit quantity type here?
|
||||
[[nodiscard]] constexpr Quantity auto operator()(Rep&& value) const
|
||||
{
|
||||
return quantity<reference{}, Rep>(std::forward<Rep>(value));
|
||||
}
|
||||
};
|
||||
|
||||
// Reference
|
||||
@@ -67,12 +73,14 @@ template<Reference R1, Reference R2>
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO remove when all code is refactored to a new syntax
|
||||
template<Representation Rep, Reference R>
|
||||
[[nodiscard]] constexpr quantity<R{}, Rep> operator*(const Rep& lhs, R)
|
||||
{
|
||||
return quantity<R{}, Rep>(lhs);
|
||||
}
|
||||
|
||||
// TODO remove when all code is refactored to a new syntax
|
||||
void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete;
|
||||
|
||||
template<Reference R1, Reference R2>
|
||||
|
Reference in New Issue
Block a user