feat: new quantity creation syntax support added

This commit is contained in:
Mateusz Pusz
2022-12-22 17:50:41 +01:00
parent be58a6e03a
commit 0a1ee606f3
3 changed files with 69 additions and 39 deletions

View File

@@ -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;

View File

@@ -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
};

View File

@@ -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>