mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 04:14:27 +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/bits/external/type_traits.h>
|
||||||
#include <units/customization_points.h>
|
#include <units/customization_points.h>
|
||||||
#include <units/dimension.h>
|
#include <units/dimension.h>
|
||||||
#include <units/quantity_spec.h>
|
|
||||||
#include <units/unit.h>
|
#include <units/unit.h>
|
||||||
|
|
||||||
namespace units {
|
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>
|
template<QuantitySpec auto Q, Unit auto U>
|
||||||
struct reference;
|
struct reference;
|
||||||
|
|
||||||
|
@@ -26,32 +26,13 @@
|
|||||||
#include <units/bits/expression_template.h>
|
#include <units/bits/expression_template.h>
|
||||||
#include <units/bits/external/type_name.h>
|
#include <units/bits/external/type_name.h>
|
||||||
#include <units/bits/external/type_traits.h>
|
#include <units/bits/external/type_traits.h>
|
||||||
|
#include <units/bits/quantity_concepts.h>
|
||||||
#include <units/dimension.h>
|
#include <units/dimension.h>
|
||||||
#include <units/unit.h>
|
#include <units/unit.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
namespace units {
|
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 {
|
namespace detail {
|
||||||
|
|
||||||
// TODO revise the note in the below comment
|
// TODO revise the note in the below comment
|
||||||
@@ -90,9 +71,6 @@ template<auto... Args>
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline constexpr bool is_specialization_of_derived_quantity_spec = false;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_dimensionless = false;
|
inline constexpr bool is_dimensionless = false;
|
||||||
|
|
||||||
@@ -111,17 +89,6 @@ inline constexpr bool is_per_of_quantity_specs<per<Ts...>> =
|
|||||||
|
|
||||||
} // namespace detail
|
} // 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>
|
template<typename T>
|
||||||
concept DerivedQuantitySpecExpr = NamedQuantitySpec<T> || detail::is_dimensionless<T> ||
|
concept DerivedQuantitySpecExpr = NamedQuantitySpec<T> || detail::is_dimensionless<T> ||
|
||||||
detail::is_power_of_quantity_spec<T> || detail::is_per_of_quantity_specs<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
|
} // namespace detail
|
||||||
|
|
||||||
template<QuantitySpec auto Q, Unit auto U>
|
|
||||||
struct reference;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A specification of a derived quantity
|
* @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>{};
|
return reference<derived_quantity_spec{}, u>{};
|
||||||
}
|
}
|
||||||
#endif
|
#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 {
|
namespace detail {
|
||||||
@@ -329,6 +300,13 @@ struct quantity_spec<Self, Dim, Args...> {
|
|||||||
{
|
{
|
||||||
return reference<Self{}, u>{};
|
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>{};
|
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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -23,7 +23,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <units/bits/quantity_concepts.h>
|
#include <units/bits/quantity_concepts.h>
|
||||||
#include <units/quantity_spec.h>
|
|
||||||
#include <units/unit.h>
|
#include <units/unit.h>
|
||||||
|
|
||||||
namespace units {
|
namespace units {
|
||||||
@@ -51,6 +50,13 @@ struct reference {
|
|||||||
static constexpr QuantitySpec auto quantity_spec = Q;
|
static constexpr QuantitySpec auto quantity_spec = Q;
|
||||||
static constexpr Dimension auto dimension = Q.dimension;
|
static constexpr Dimension auto dimension = Q.dimension;
|
||||||
static constexpr Unit auto unit = U;
|
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
|
// Reference
|
||||||
@@ -67,12 +73,14 @@ template<Reference R1, Reference R2>
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO remove when all code is refactored to a new syntax
|
||||||
template<Representation Rep, Reference R>
|
template<Representation Rep, Reference R>
|
||||||
[[nodiscard]] constexpr quantity<R{}, Rep> operator*(const Rep& lhs, R)
|
[[nodiscard]] constexpr quantity<R{}, Rep> operator*(const Rep& lhs, R)
|
||||||
{
|
{
|
||||||
return quantity<R{}, Rep>(lhs);
|
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;
|
void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete;
|
||||||
|
|
||||||
template<Reference R1, Reference R2>
|
template<Reference R1, Reference R2>
|
||||||
|
Reference in New Issue
Block a user