refactor: scalar and complex renamed to real_scalar and complex_scalar respectively + concepts refactoring + electromagnetism fixes

This commit is contained in:
Mateusz Pusz
2025-02-11 17:26:19 +01:00
parent 9fb08e3c95
commit 47a82f466c
21 changed files with 569 additions and 579 deletions

View File

@ -1704,7 +1704,7 @@ and is equal to
\item \item
\tcode{Ch} if specified, \tcode{Ch} if specified,
\item \item
otherwise, \tcode{quantity_character::scalar} for the first signature, and otherwise, \tcode{quantity_character::real_scalar} for the first signature, and
\item \item
otherwise, \tcode{(BC).character}, otherwise, \tcode{(BC).character},
where \tcode{BC} is the argument preceding \tcode{Ch} in the signatures above. where \tcode{BC} is the argument preceding \tcode{Ch} in the signatures above.
@ -1788,7 +1788,7 @@ be packs denoting the template arguments of
\item \item
\tcode{\placeholdernc{QUANTITY-CHARACTER-OF}(Pack)} be \tcode{\placeholdernc{QUANTITY-CHARACTER-OF}(Pack)} be
\begin{codeblock} \begin{codeblock}
std::max({quantity_character::scalar, @\exposidnc{expr-type}@<Pack>::character...}) std::max({quantity_character::real_scalar, @\exposidnc{expr-type}@<Pack>::character...})
\end{codeblock} \end{codeblock}
and and
\item \item
@ -1796,7 +1796,7 @@ and
\tcode{den_char} be \tcode{\placeholdernc{QUANTITY-CHARACTER-OF}(Dens)}. \tcode{den_char} be \tcode{\placeholdernc{QUANTITY-CHARACTER-OF}(Dens)}.
\end{itemize} \end{itemize}
The member \tcode{character} is equal to The member \tcode{character} is equal to
\tcode{quantity_character::scalar} if \tcode{num_char == den_char} is \tcode{true}, and \tcode{quantity_character::real_scalar} if \tcode{num_char == den_char} is \tcode{true}, and
\tcode{std::max(num_char, den_char)} otherwise. \tcode{std::max(num_char, den_char)} otherwise.
\rSec4[dimless.qty]{Base quantity of dimension one} \rSec4[dimless.qty]{Base quantity of dimension one}
@ -4033,8 +4033,8 @@ it represents the numerical value of a quantity\irefiev{112-01-29}.
\begin{itemdecl} \begin{itemdecl}
template<typename T, quantity_character Ch> template<typename T, quantity_character Ch>
concept @\defexposconceptnc{IsOfCharacter}@ = (Ch == quantity_character::scalar && @\exposconceptnc{Scalar}@<T>) || // \expos concept @\defexposconceptnc{IsOfCharacter}@ = (Ch == quantity_character::real_scalar && @\exposconceptnc{Scalar}@<T>) || // \expos
(Ch == quantity_character::complex && @\exposconceptnc{Complex}@<T>) || (Ch == quantity_character::complex_scalar && @\exposconceptnc{Complex}@<T>) ||
(Ch == quantity_character::vector && @\exposconceptnc{Vector}@<T>); (Ch == quantity_character::vector && @\exposconceptnc{Vector}@<T>);
template<typename T, auto V> template<typename T, auto V>

View File

@ -34,8 +34,8 @@ A quantity character determines the properties and operations that can be perfor
Quantities defined by the ISQ may be of the following characters: Quantities defined by the ISQ may be of the following characters:
- scalar (e.g., _time_, _width_, _speed_, _apparent power_), - real scalar (e.g., _time_, _width_, _speed_, _apparent power_),
- complex (e.g., _complex power_, _voltage phasor_, _electric current phasor_), - complex scalar (e.g., _voltage phasor_, _complex power_, _impedance_),
- vector (e.g., _displacement_, _velocity_, _force_), - vector (e.g., _displacement_, _velocity_, _force_),
- tensor (e.g., _moment of inertia_, _stress_, _strain_). - tensor (e.g., _moment of inertia_, _stress_, _strain_).

View File

@ -90,7 +90,7 @@ in one line of code. In the above code:
!!! note !!! note
Some quantities may be specified to have complex, vector, or tensor character Some quantities may be specified to have complex scalar, vector, or tensor character
(e.g., `displacement`). The quantity character can be set with the last parameter of (e.g., `displacement`). The quantity character can be set with the last parameter of
`quantity_spec`. `quantity_spec`.

View File

@ -395,11 +395,11 @@ the same kind.
Some quantities are more complicated than others. For example, _power_ has: Some quantities are more complicated than others. For example, _power_ has:
- scalar quantities expressed in: - real scalar quantities expressed in:
- W (watts) (e.g., _mechanical power_, _active power_), - W (watts) (e.g., _mechanical power_, _active power_),
- VA (volt-ampere) (e.g., _apparent power_), - VA (volt-ampere) (e.g., _apparent power_),
- var (e.g., _reactive power_), - var (e.g., _reactive power_),
- complex quantities expressed in VA (volt-ampere) (e.g., _complex power_). - complex scalar quantities expressed in VA (volt-ampere) (e.g., _complex power_).
How should we model this? Maybe those should be two or three independent trees of quantities, each How should we model this? Maybe those should be two or three independent trees of quantities, each
having its own unit? having its own unit?

View File

@ -119,15 +119,15 @@ results in the `derived_dimension<isq::dim_length, per<isq::dim_time>>` type.
[ISO 80000](../../appendix/references.md#ISO80000) explicitly states that quantities (even of the same kind) may have [ISO 80000](../../appendix/references.md#ISO80000) explicitly states that quantities (even of the same kind) may have
different [characters](../../appendix/glossary.md#character): different [characters](../../appendix/glossary.md#character):
- scalar, - real scalar (e.g., _time_, _width_, _speed_, _apparent power_),
- complex, - complex scalar (e.g., _voltage phasor_, _complex power_, _impedance_),
- vector, - vector (e.g., _displacement_, _velocity_, _force_),
- tensor. - tensor (e.g., _moment of inertia_, _stress_, _strain_).
The quantity character in the **mp-units** library is implemented with the `quantity_character` enumeration: The quantity character in the **mp-units** library is implemented with the `quantity_character` enumeration:
```cpp ```cpp
enum class quantity_character { scalar, complex, vector, tensor }; enum class quantity_character { real_scalar, complex_scalar, vector, tensor };
``` ```
!!! info !!! info

View File

@ -138,7 +138,7 @@ private:
} // namespace } // namespace
static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::scalar>); static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::real_scalar>);
static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::vector>); static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::vector>);
namespace { namespace {

View File

@ -93,7 +93,6 @@ if(NOT ${projectPrefix}API_FREESTANDING)
include/mp-units/bits/requires_hosted.h include/mp-units/bits/requires_hosted.h
include/mp-units/ext/format.h include/mp-units/ext/format.h
include/mp-units/cartesian_vector.h include/mp-units/cartesian_vector.h
include/mp-units/complex.h
include/mp-units/format.h include/mp-units/format.h
include/mp-units/math.h include/mp-units/math.h
include/mp-units/ostream.h include/mp-units/ostream.h

View File

@ -26,6 +26,7 @@
// //
#include <mp-units/bits/module_macros.h> #include <mp-units/bits/module_macros.h>
#include <mp-units/framework/customization_points.h> #include <mp-units/framework/customization_points.h>
#include <mp-units/framework/representation_concepts.h>
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
#include <mp-units/bits/fmt.h> #include <mp-units/bits/fmt.h>
@ -46,7 +47,7 @@ import std;
namespace mp_units { namespace mp_units {
MP_UNITS_EXPORT template<typename T = double> MP_UNITS_EXPORT template<detail::Scalar T = double>
class cartesian_vector { class cartesian_vector {
public: public:
// public members required to satisfy structural type requirements :-( // public members required to satisfy structural type requirements :-(
@ -101,7 +102,12 @@ public:
[[nodiscard]] constexpr T magnitude() const [[nodiscard]] constexpr T magnitude() const
requires treat_as_floating_point<T> requires treat_as_floating_point<T>
{ {
return std::hypot(_coordinates_[0], _coordinates_[1], _coordinates_[2]); using namespace std;
if constexpr (detail::ComplexScalar<T>)
return hypot(mp_units::modulus(_coordinates_[0]), mp_units::modulus(_coordinates_[1]),
mp_units::modulus(_coordinates_[2]));
else
return hypot(_coordinates_[0], _coordinates_[1], _coordinates_[2]);
} }
[[nodiscard]] constexpr cartesian_vector unit() const [[nodiscard]] constexpr cartesian_vector unit() const

View File

@ -1,43 +0,0 @@
// The MIT License (MIT)
//
// Copyright (c) 2018 Mateusz Pusz
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include <mp-units/bits/requires_hosted.h>
//
#include <mp-units/bits/module_macros.h>
#include <mp-units/framework/representation_concepts.h>
#ifndef MP_UNITS_IN_MODULE_INTERFACE
#ifdef MP_UNITS_IMPORT_STD
import std;
#else
#include <complex>
#endif
#endif
namespace mp_units {
template<typename T>
constexpr bool disable_scalar<std::complex<T>> = true;
} // namespace mp_units

View File

@ -29,7 +29,6 @@
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
#include <mp-units/cartesian_vector.h> #include <mp-units/cartesian_vector.h>
#include <mp-units/complex.h>
#include <mp-units/format.h> #include <mp-units/format.h>
#include <mp-units/math.h> #include <mp-units/math.h>
#include <mp-units/ostream.h> #include <mp-units/ostream.h>

View File

@ -116,12 +116,6 @@ template<QuantitySpec QS, detail::WeakUnitOf<QS{}> U>
return reference<QS, U>{}; return reference<QS, U>{};
} }
// TODO revise the note in the below comment
/**
* @brief Returns the most restrictive character from the list
*
* @note `vector * vector` returns vector (not tensor)
*/
template<std::same_as<quantity_character>... Ts> template<std::same_as<quantity_character>... Ts>
[[nodiscard]] consteval quantity_character common_quantity_character(Ts... args) [[nodiscard]] consteval quantity_character common_quantity_character(Ts... args)
{ {
@ -133,13 +127,10 @@ template<typename... Qs1, typename... Qs2>
const type_list<Qs2...>&) const type_list<Qs2...>&)
{ {
constexpr quantity_character num = constexpr quantity_character num =
detail::common_quantity_character(quantity_character::scalar, expr_type<Qs1>::character...); detail::common_quantity_character(quantity_character::real_scalar, expr_type<Qs1>::character...);
constexpr quantity_character den = constexpr quantity_character den =
detail::common_quantity_character(quantity_character::scalar, expr_type<Qs2>::character...); detail::common_quantity_character(quantity_character::real_scalar, expr_type<Qs2>::character...);
if constexpr (num == den) return detail::max(num, den);
return quantity_character::scalar;
else
return detail::common_quantity_character(num, den);
} }
/** /**
@ -291,7 +282,7 @@ MP_UNITS_EXPORT_END
* *
* This quantity serves as a root/kind for a new hierarchy of quantities of the same kind. * This quantity serves as a root/kind for a new hierarchy of quantities of the same kind.
* *
* Base quantities have scalar character by default. * Base quantities have real scalar character by default.
* *
* User should derive a strong type from this class template rather than use it directly in the source code. * User should derive a strong type from this class template rather than use it directly in the source code.
* For example: * For example:
@ -312,7 +303,7 @@ MP_UNITS_EXPORT_END
* errors. Having them of the same names improves user experience and somehow blurs those separate domains. * errors. Having them of the same names improves user experience and somehow blurs those separate domains.
* *
* @tparam BaseDimension base dimension for which a base quantity is being defined * @tparam BaseDimension base dimension for which a base quantity is being defined
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be real scalar
*/ */
#if MP_UNITS_API_NO_CRTP #if MP_UNITS_API_NO_CRTP
template<detail::BaseDimension auto Dim, detail::QSProperty auto... Args> template<detail::BaseDimension auto Dim, detail::QSProperty auto... Args>
@ -323,7 +314,8 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
#endif #endif
using _base_type_ = quantity_spec; using _base_type_ = quantity_spec;
static constexpr detail::BaseDimension auto dimension = Dim; static constexpr detail::BaseDimension auto dimension = Dim;
static constexpr quantity_character character = detail::quantity_character_init<Args...>(quantity_character::scalar); static constexpr quantity_character character =
detail::quantity_character_init<Args...>(quantity_character::real_scalar);
}; };
/** /**
@ -334,7 +326,7 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
* *
* This quantity serves as a root/kind for a new hierarchy of quantities of the same kind. * This quantity serves as a root/kind for a new hierarchy of quantities of the same kind.
* *
* Such quantities by default derive the character from the derived quantity definition. * Such quantities obtain the character from the derived quantity equation.
* *
* User should derive a strong type from this class template rather than use it directly in the source code. * User should derive a strong type from this class template rather than use it directly in the source code.
* For example: * For example:
@ -342,10 +334,8 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
* @code{.cpp} * @code{.cpp}
* inline constexpr struct area final : quantity_spec<pow<2>(length)> {} area; * inline constexpr struct area final : quantity_spec<pow<2>(length)> {} area;
* inline constexpr struct volume final : quantity_spec<pow<3>(length)> {} volume; * inline constexpr struct volume final : quantity_spec<pow<3>(length)> {} volume;
* inline constexpr struct velocity final : quantity_spec<displacement / duration> {} velocity; * inline constexpr struct velocity final : quantity_spec<displacement / duration> {} velocity; // vector
* inline constexpr struct speed final : quantity_spec<length / time> {} speed; * inline constexpr struct force final : quantity_spec<mass * acceleration> {} force; // vector
* inline constexpr struct force final : quantity_spec<mass * acceleration, quantity_character::vector> {} force;
* inline constexpr struct power final : quantity_spec<force * velocity, quantity_character::scalar> {} power;
* @endcode * @endcode
* *
* @note A common convention in this library is to assign the same name for a type and an object of this type. * @note A common convention in this library is to assign the same name for a type and an object of this type.
@ -354,7 +344,7 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
* errors. Having them of the same names improves user experience and somehow blurs those separate domains. * errors. Having them of the same names improves user experience and somehow blurs those separate domains.
* *
* @tparam Eq quantity equation specification of a derived quantity * @tparam Eq quantity equation specification of a derived quantity
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be real scalar
*/ */
#if MP_UNITS_API_NO_CRTP #if MP_UNITS_API_NO_CRTP
template<detail::DerivedQuantitySpec auto Eq, detail::QSProperty auto... Args> template<detail::DerivedQuantitySpec auto Eq, detail::QSProperty auto... Args>
@ -366,6 +356,9 @@ struct quantity_spec<Self, Eq, Args...> : detail::quantity_spec_interface<Self>
using _base_type_ = quantity_spec; using _base_type_ = quantity_spec;
static constexpr auto _equation_ = Eq; static constexpr auto _equation_ = Eq;
static constexpr Dimension auto dimension = Eq.dimension; static constexpr Dimension auto dimension = Eq.dimension;
// TODO static_assert that character property is not passed in Args
static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character); static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character);
}; };
@ -387,7 +380,8 @@ struct propagate_equation<Q, true> {
* Quantities of the same kind form a hierarchy. This specialization adds new leaf to such a tree which * Quantities of the same kind form a hierarchy. This specialization adds new leaf to such a tree which
* can later be used as a parent by other quantities. * can later be used as a parent by other quantities.
* *
* The character of those quantities by default is derived from the parent quantity. * The character of those quantities by default is derived from the parent quantity but can be overriden
* by explicitly passing a property.
* *
* User should derive a strong type from this class template rather than use it directly in the source code. * User should derive a strong type from this class template rather than use it directly in the source code.
* For example: * For example:
@ -397,6 +391,8 @@ struct propagate_equation<Q, true> {
* inline constexpr struct height final : quantity_spec<length> {} height; * inline constexpr struct height final : quantity_spec<length> {} height;
* inline constexpr struct diameter final : quantity_spec<width> {} diameter; * inline constexpr struct diameter final : quantity_spec<width> {} diameter;
* inline constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement; * inline constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement;
* inline constexpr struct voltage_phasor final : quantity_spec<voltage, quantity_character::complex_scalar) {}
* voltage_phasor;
* @endcode * @endcode
* *
* @note A common convention in this library is to assign the same name for a type and an object of this type. * @note A common convention in this library is to assign the same name for a type and an object of this type.
@ -405,7 +401,7 @@ struct propagate_equation<Q, true> {
* errors. Having them of the same names improves user experience and somehow blurs those separate domains. * errors. Having them of the same names improves user experience and somehow blurs those separate domains.
* *
* @tparam Q quantity specification of a parent quantity * @tparam Q quantity specification of a parent quantity
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be real scalar
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind * or `is_kind` in case the quantity starts a new hierarchy tree of a kind
*/ */
#if MP_UNITS_API_NO_CRTP #if MP_UNITS_API_NO_CRTP
@ -445,7 +441,7 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
* can later be used as a parent by other quantities. Additionally, this defintion adds additional * can later be used as a parent by other quantities. Additionally, this defintion adds additional
* constraints on the derived quantity's equation. * constraints on the derived quantity's equation.
* *
* The character of those quantities by default is derived from the parent quantity. * Such quantities obtain the character from the derived quantity equation.
* *
* User should derive a strong type from this class template rather than use it directly in the source code. * User should derive a strong type from this class template rather than use it directly in the source code.
* For example: * For example:
@ -463,8 +459,8 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
* errors. Having them of the same names improves user experience and somehow blurs those separate domains. * errors. Having them of the same names improves user experience and somehow blurs those separate domains.
* *
* @tparam Q quantity specification of a parent quantity * @tparam Q quantity specification of a parent quantity
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar * @tparam Args optionally a value of `quantity_character` in case the base quantity should not
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind * be real scalar or `is_kind` in case the quantity starts a new hierarchy tree of a kind
*/ */
// clang-format on // clang-format on
#if MP_UNITS_API_NO_CRTP #if MP_UNITS_API_NO_CRTP
@ -481,6 +477,9 @@ struct quantity_spec<Self, QS, Eq, Args...> : detail::quantity_spec_interface<Se
static constexpr auto _parent_ = QS; static constexpr auto _parent_ = QS;
static constexpr auto _equation_ = Eq; static constexpr auto _equation_ = Eq;
static constexpr Dimension auto dimension = _parent_.dimension; static constexpr Dimension auto dimension = _parent_.dimension;
// TODO static_assert that character property is not passed in Args
static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character); static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character);
}; };

View File

@ -41,34 +41,6 @@ import std;
namespace mp_units { namespace mp_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.
*
* A complex is a physical quantity that is represented with a complex number.
*
* 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.
*/
MP_UNITS_EXPORT enum class quantity_character : std::int8_t { scalar, complex, vector, tensor };
MP_UNITS_EXPORT template<typename T>
constexpr bool disable_scalar = false;
template<>
MP_UNITS_INLINE constexpr bool disable_scalar<bool> = true;
namespace detail { namespace detail {
template<typename T> template<typename T>
@ -82,23 +54,44 @@ concept ScalableWith = requires(const T v, const S s) {
}; };
template<typename T> template<typename T>
concept Scalar = (!disable_scalar<T>) && concept Addable = requires(const T a, const T b) {
requires(const T a, const T b) { { -a } -> std::common_with<T>;
{ -a } -> std::common_with<T>; { a + b } -> std::common_with<T>;
{ a + b } -> std::common_with<T>; { a - b } -> std::common_with<T>;
{ a - b } -> std::common_with<T>; };
} && ScalableWith<T, T>
#if MP_UNITS_COMP_GCC != 12 && !defined(MP_UNITS_XCODE15_HACKS)
&& WeaklyRegular<T>
#endif
;
namespace real_impl { } // namespace detail
/**
* @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. It might
* be a real or complex number which affects which operations are allowed on a quantity.
*
* 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.
*/
MP_UNITS_EXPORT enum class quantity_character : std::int8_t { real_scalar, complex_scalar, vector, tensor };
/////////////// COMPLEX SCALAR ///////////////
namespace detail::real_impl {
void real() = delete; // poison pill void real() = delete; // poison pill
struct real_t { struct real_t {
[[nodiscard]] constexpr Scalar auto operator()(const WeaklyRegular auto& clx) const // TODO how to constrain the return with RealScalar?
[[nodiscard]] constexpr auto operator()(const WeaklyRegular auto& clx) const
requires requires { clx.real(); } || requires { real(clx); } requires requires { clx.real(); } || requires { real(clx); }
{ {
if constexpr (requires { clx.real(); }) if constexpr (requires { clx.real(); })
@ -108,9 +101,7 @@ struct real_t {
} }
}; };
} // namespace real_impl } // namespace detail::real_impl
} // namespace detail
inline namespace cpo { inline namespace cpo {
@ -123,7 +114,8 @@ namespace detail::imag_impl {
void imag() = delete; // poison pill void imag() = delete; // poison pill
struct imag_t { struct imag_t {
[[nodiscard]] constexpr Scalar auto operator()(const WeaklyRegular auto& clx) const // TODO how to constrain the return with RealScalar?
[[nodiscard]] constexpr auto operator()(const WeaklyRegular auto& clx) const
requires requires { clx.imag(); } || requires { imag(clx); } requires requires { clx.imag(); } || requires { imag(clx); }
{ {
if constexpr (requires { clx.imag(); }) if constexpr (requires { clx.imag(); })
@ -147,7 +139,8 @@ void modulus() = delete; // poison pill
void abs() = delete; // poison pill void abs() = delete; // poison pill
struct modulus_t { struct modulus_t {
[[nodiscard]] constexpr Scalar auto operator()(const WeaklyRegular auto& clx) const // TODO how to constrain the return with RealScalar?
[[nodiscard]] constexpr auto operator()(const WeaklyRegular auto& clx) const
requires requires { clx.modulus(); } || requires { modulus(clx); } || requires { clx.abs(); } || requires requires { clx.modulus(); } || requires { modulus(clx); } || requires { clx.abs(); } ||
requires { abs(clx); } requires { abs(clx); }
{ {
@ -155,7 +148,7 @@ struct modulus_t {
return clx.modulus(); return clx.modulus();
else if constexpr (requires { modulus(clx); }) else if constexpr (requires { modulus(clx); })
return modulus(clx); return modulus(clx);
// `std` made a precedence of using `abs` for modulo on `std::complex` // `std` made a precedence of using `abs` for modulus on `std::complex`
else if constexpr (requires { clx.abs(); }) else if constexpr (requires { clx.abs(); })
return clx.abs(); return clx.abs();
else if constexpr (requires { abs(clx); }) else if constexpr (requires { abs(clx); })
@ -171,30 +164,55 @@ MP_UNITS_EXPORT inline constexpr ::mp_units::detail::modulus_impl::modulus_t mod
} }
namespace detail {
template<typename T>
concept ComplexScalar =
// TODO should the below be provided?
// (!disable_complex<T>) &&
Addable<T> && ScalableWith<T, T> &&
requires(const T v, const T& ref) {
::mp_units::real(v);
::mp_units::imag(v);
::mp_units::modulus(v);
requires ScalableWith<T, decltype(::mp_units::modulus(v))>;
requires std::constructible_from<T, decltype(::mp_units::real(ref)), decltype(::mp_units::imag(ref))>;
}
#ifndef MP_UNITS_XCODE15_HACKS
&& WeaklyRegular<T>
#endif
;
} // namespace detail
/////////////// REAL SCALAR ///////////////
MP_UNITS_EXPORT template<typename T> MP_UNITS_EXPORT template<typename T>
constexpr bool disable_complex = false; constexpr bool disable_real = false;
template<>
MP_UNITS_INLINE constexpr bool disable_real<bool> = true;
namespace detail { namespace detail {
template<typename T> template<typename T>
concept Complex = (!disable_complex<T>) && concept RealScalar =
requires(const T a, const T b, const T& c) { (!disable_real<T>) && Addable<T> && ScalableWith<T, T> && std::totally_ordered<T> && (!ComplexScalar<T>)
{ -a } -> std::common_with<T>; #if MP_UNITS_COMP_GCC != 12 && !defined(MP_UNITS_XCODE15_HACKS)
{ a + b } -> std::common_with<T>; && WeaklyRegular<T>
{ a - b } -> std::common_with<T>;
{ a* b } -> std::common_with<T>;
{ a / b } -> std::common_with<T>;
::mp_units::real(a);
::mp_units::imag(a);
::mp_units::modulus(a);
requires ScalableWith<T, decltype(::mp_units::modulus(a))>;
requires std::constructible_from<T, decltype(::mp_units::real(c)), decltype(::mp_units::imag(c))>;
}
#ifndef MP_UNITS_XCODE15_HACKS
&& WeaklyRegular<T>
#endif #endif
; ;
namespace magnitude_impl {
template<typename T>
concept Scalar = RealScalar<T> || ComplexScalar<T>;
} // namespace detail
/////////////// VECTOR ///////////////
namespace detail::magnitude_impl {
void magnitude() = delete; // poison pill void magnitude() = delete; // poison pill
void abs() = delete; // poison pill void abs() = delete; // poison pill
@ -203,32 +221,29 @@ struct magnitude_t {
template<WeaklyRegular T> template<WeaklyRegular T>
[[nodiscard]] constexpr Scalar auto operator()(const T& vec) const [[nodiscard]] constexpr Scalar auto operator()(const T& vec) const
requires requires { vec.magnitude(); } || requires { magnitude(vec); } || requires requires { vec.magnitude(); } || requires { magnitude(vec); } ||
(Scalar<T> && (RealScalar<T> && (std::is_arithmetic_v<T> || requires { vec.abs(); } || requires { abs(vec); }))
(requires { vec.abs(); } || requires { abs(vec); } || (std::is_arithmetic_v<T> && (!is_same_v<T, bool>))))
{ {
if constexpr (requires { vec.magnitude(); }) if constexpr (requires { vec.magnitude(); })
return vec.magnitude(); return vec.magnitude();
else if constexpr (requires { magnitude(vec); }) else if constexpr (requires { magnitude(vec); })
return magnitude(vec); return magnitude(vec);
// allow scalar types to represent one dimensional vector quantities // allow real types to represent one dimensional vector quantities
if constexpr (Scalar<T>) { if constexpr (RealScalar<T>) {
if constexpr (requires { vec.abs(); }) if constexpr (std::is_arithmetic_v<T>)
return vec.abs();
else if constexpr (requires { abs(vec); })
return abs(vec);
else if constexpr (std::is_arithmetic_v<T> && (!is_same_v<T, bool>))
#if MP_UNITS_HOSTED || __cpp_lib_freestanding_cstdlib >= 202306L #if MP_UNITS_HOSTED || __cpp_lib_freestanding_cstdlib >= 202306L
return std::abs(vec); return std::abs(vec);
#else #else
return vec >= 0 ? vec : -vec; return vec >= 0 ? vec : -vec;
#endif #endif
else if constexpr (requires { vec.abs(); })
return vec.abs();
else if constexpr (requires { abs(vec); })
return abs(vec);
} }
} }
}; };
} // namespace magnitude_impl } // namespace detail::magnitude_impl
} // namespace detail
inline namespace cpo { inline namespace cpo {
@ -236,22 +251,15 @@ MP_UNITS_EXPORT inline constexpr ::mp_units::detail::magnitude_impl::magnitude_t
} }
MP_UNITS_EXPORT template<typename T>
constexpr bool disable_vector = false;
namespace detail { namespace detail {
template<typename T> template<typename T>
concept Vector = (!disable_vector<T>) && concept Vector = Addable<T> &&
requires(const T a, const T b) { requires(const T v) {
{ -a } -> std::common_with<T>; ::mp_units::magnitude(v);
{ a + b } -> std::common_with<T>; requires ScalableWith<T, decltype(::mp_units::magnitude(v))>;
{ a - b } -> std::common_with<T>;
::mp_units::magnitude(a);
requires ScalableWith<T, decltype(::mp_units::magnitude(a))>;
// TODO should we also check for the below (e.g., when `size() > 1` or `2`) // TODO should we also check for the below (e.g., when `size() > 1` or `2`)
// ::mp_units::zero_vector<T>(); // ::mp_units::zero_vector<T>();
// ::mp_units::unit_vector(a);
// ::mp_units::scalar_product(a, b); // ::mp_units::scalar_product(a, b);
// ::mp_units::vector_product(a, b); // ::mp_units::vector_product(a, b);
// ::mp_units::tensor_product(a, b); // ::mp_units::tensor_product(a, b);
@ -263,11 +271,11 @@ concept Vector = (!disable_vector<T>) &&
} // namespace detail } // namespace detail
/////////////// TENSOR ///////////////
// MP_UNITS_EXPORT template<typename T> // MP_UNITS_EXPORT template<typename T>
// constexpr bool disable_tensor = false; // constexpr bool disable_tensor = false;
namespace detail {
// TODO provide when some actual operations will be required // TODO provide when some actual operations will be required
// template<typename T> // template<typename T>
// concept Tensor = (!disable_tensor<T>) && WeaklyRegular<T> && requires(const T a, const T b) { // concept Tensor = (!disable_tensor<T>) && WeaklyRegular<T> && requires(const T a, const T b) {
@ -276,25 +284,33 @@ namespace detail {
// ::mp_units::scalar_product(a, b); // ::mp_units::scalar_product(a, b);
// }; // };
namespace detail {
template<typename T> template<typename T>
constexpr bool is_quantity = false; constexpr bool is_quantity = false;
template<typename T> template<typename T>
using scaling_factor_type_t = conditional<treat_as_floating_point<T>, long double, std::intmax_t>; using scaling_factor_type_t = conditional<treat_as_floating_point<T>, long double, std::intmax_t>;
// TODO how can we use `(!Quantity<T>)` below? // TODO replace the below and above with the logic from #615 when available
template<typename T> template<typename T>
concept ScalarRepresentation = (!is_quantity<T>) && Scalar<T> && requires(const T v, const scaling_factor_type_t<T> f) { concept ScalableByFactor = requires(const T v, const scaling_factor_type_t<T> f) {
// scaling
{ v* f } -> std::common_with<T>; { v* f } -> std::common_with<T>;
{ f* v } -> std::common_with<T>; { f* v } -> std::common_with<T>;
{ v / f } -> std::common_with<T>; { v / f } -> std::common_with<T>;
}; };
// TODO how can we use `(!Quantity<T>)` below?
template<typename T> template<typename T>
concept ComplexRepresentation = concept NotQuantity = (!is_quantity<T>);
(!is_quantity<T>) && Complex<T> && requires(const T v, const scaling_factor_type_t<T> f) {
// scaling template<typename T>
concept RealScalarRepresentation = NotQuantity<T> && RealScalar<T> && ScalableByFactor<T>;
template<typename T>
concept ComplexScalarRepresentation =
NotQuantity<T> && ComplexScalar<T> && requires(const T v, const scaling_factor_type_t<T> f) {
// TODO The below conversion to `T` is an exception compared to other representation types // TODO The below conversion to `T` is an exception compared to other representation types
// `std::complex<T>` * `U` do not work, but `std::complex<T>` is convertible from `U` // `std::complex<T>` * `U` do not work, but `std::complex<T>` is convertible from `U`
// Maybe expose this as a customization point? // Maybe expose this as a customization point?
@ -304,30 +320,29 @@ concept ComplexRepresentation =
}; };
template<typename T> template<typename T>
concept VectorRepresentation = (!is_quantity<T>) && Vector<T> && requires(const T v, const scaling_factor_type_t<T> f) { concept ScalarRepresentation = RealScalarRepresentation<T> || ComplexScalarRepresentation<T>;
// scaling
{ v* f } -> std::common_with<T>; template<typename T>
{ f* v } -> std::common_with<T>; concept VectorRepresentation = NotQuantity<T> && Vector<T> && ScalableByFactor<T>;
{ v / f } -> std::common_with<T>;
};
// template<typename T> // template<typename T>
// concept TensorRepresentation = (!is_quantity<T>) && Tensor<T>; // concept TensorRepresentation = NotQuantity<T> && Tensor<T>;
} // namespace detail } // namespace detail
MP_UNITS_EXPORT template<typename T> MP_UNITS_EXPORT template<typename T>
concept Representation = detail::ScalarRepresentation<T> || detail::ComplexRepresentation<T> || concept Representation =
detail::VectorRepresentation<T>; // || detail::TensorRepresentation<T>; detail::ScalarRepresentation<T> || detail::VectorRepresentation<T>; // || detail::TensorRepresentation<T>;
namespace detail { namespace detail {
template<typename T, quantity_character Ch> template<typename T, quantity_character Ch>
concept IsOfCharacter = concept IsOfCharacter =
(Ch == quantity_character::scalar && Scalar<T>) || (Ch == quantity_character::complex && Complex<T>) || (Ch == quantity_character::real_scalar && RealScalar<T>) ||
(Ch == quantity_character::complex_scalar && ComplexScalar<T>) ||
(Ch == quantity_character::vector && Vector<T>); // || (Ch == quantity_character::tensor && Tensor<T>); (Ch == quantity_character::vector && Vector<T>); // || (Ch == quantity_character::tensor && Tensor<T>);
} } // namespace detail
MP_UNITS_EXPORT template<typename T, auto V> MP_UNITS_EXPORT template<typename T, auto V>
concept RepresentationOf = concept RepresentationOf =

View File

@ -54,8 +54,8 @@ QUANTITY_SPEC(electric_current_density, electric_charge_density* velocity);
QUANTITY_SPEC(linear_electric_current_density, surface_density_of_electric_charge* velocity); // vector QUANTITY_SPEC(linear_electric_current_density, surface_density_of_electric_charge* velocity); // vector
QUANTITY_SPEC(electric_field_strength, force / electric_charge); // vector QUANTITY_SPEC(electric_field_strength, force / electric_charge); // vector
QUANTITY_SPEC(electric_potential, electric_field_strength* length, QUANTITY_SPEC(electric_potential, electric_field_strength* length,
quantity_character::scalar); // TODO what is a correct equation here? quantity_character::real_scalar); // TODO what is a correct equation here?
QUANTITY_SPEC(electric_potential_difference, electric_potential, quantity_character::scalar); QUANTITY_SPEC(electric_potential_difference, electric_potential, quantity_character::real_scalar);
QUANTITY_SPEC(voltage, electric_potential); QUANTITY_SPEC(voltage, electric_potential);
inline constexpr auto electric_tension = voltage; inline constexpr auto electric_tension = voltage;
QUANTITY_SPEC(induced_voltage, voltage); // TODO what is a correct equation here? QUANTITY_SPEC(induced_voltage, voltage); // TODO what is a correct equation here?
@ -73,19 +73,20 @@ inline constexpr auto light_speed_in_vacuum = speed_of_light_in_vacuum;
inline constexpr auto luminal_speed = speed_of_light_in_vacuum; inline constexpr auto luminal_speed = speed_of_light_in_vacuum;
QUANTITY_SPEC(electric_constant, inverse(magnetic_constant* pow<2>(speed_of_light_in_vacuum))); QUANTITY_SPEC(electric_constant, inverse(magnetic_constant* pow<2>(speed_of_light_in_vacuum)));
inline constexpr auto permittivity_of_vacuum = electric_constant; inline constexpr auto permittivity_of_vacuum = electric_constant;
QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::scalar); QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::real_scalar);
QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant); QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant);
QUANTITY_SPEC(electric_susceptibility, dimensionless, QUANTITY_SPEC(electric_susceptibility, dimensionless,
electric_polarization / electric_constant / electric_field_strength, quantity_character::scalar); electric_polarization / electric_constant / electric_field_strength, quantity_character::real_scalar);
QUANTITY_SPEC(electric_flux, electric_flux_density* area, quantity_character::scalar); QUANTITY_SPEC(electric_flux, electric_flux_density* area, quantity_character::real_scalar);
QUANTITY_SPEC(displacement_current_density, electric_flux_density / time); // vector QUANTITY_SPEC(displacement_current_density, electric_flux_density / time); // vector
QUANTITY_SPEC(displacement_current, electric_current, displacement_current_density* area, quantity_character::scalar); QUANTITY_SPEC(displacement_current, electric_current, displacement_current_density* area,
quantity_character::real_scalar);
QUANTITY_SPEC(total_current, electric_current); QUANTITY_SPEC(total_current, electric_current);
QUANTITY_SPEC(total_current_density, electric_current_density); // vector QUANTITY_SPEC(total_current_density, electric_current_density); // vector
QUANTITY_SPEC(magnetic_flux, magnetic_flux_density* area, quantity_character::scalar); QUANTITY_SPEC(magnetic_flux, magnetic_flux_density* area, quantity_character::real_scalar);
QUANTITY_SPEC(magnetic_vector_potential, QUANTITY_SPEC(magnetic_vector_potential,
magnetic_flux_density* length); // vector // TODO what is a correct equation here? magnetic_flux_density* length); // vector // TODO what is a correct equation here?
QUANTITY_SPEC(protoflux, magnetic_vector_potential* displacement, quantity_character::scalar); QUANTITY_SPEC(protoflux, magnetic_vector_potential* displacement, quantity_character::real_scalar);
QUANTITY_SPEC(linked_magnetic_flux, magnetic_flux); QUANTITY_SPEC(linked_magnetic_flux, magnetic_flux);
QUANTITY_SPEC(total_magnetic_flux, magnetic_flux); QUANTITY_SPEC(total_magnetic_flux, magnetic_flux);
QUANTITY_SPEC(magnetic_moment, electric_current* area, quantity_character::vector); QUANTITY_SPEC(magnetic_moment, electric_current* area, quantity_character::vector);
@ -93,23 +94,24 @@ inline constexpr auto magnetic_area_moment = magnetic_moment;
QUANTITY_SPEC(magnetization, magnetic_moment / volume); // vector QUANTITY_SPEC(magnetization, magnetic_moment / volume); // vector
QUANTITY_SPEC(magnetic_field_strength, magnetization); // vector QUANTITY_SPEC(magnetic_field_strength, magnetization); // vector
inline constexpr auto magnetizing_field = magnetic_field_strength; inline constexpr auto magnetizing_field = magnetic_field_strength;
QUANTITY_SPEC(permeability, magnetic_flux_density / magnetic_field_strength, quantity_character::scalar); QUANTITY_SPEC(permeability, magnetic_flux_density / magnetic_field_strength, quantity_character::real_scalar);
QUANTITY_SPEC(relative_permeability, dimensionless, permeability / magnetic_constant); QUANTITY_SPEC(relative_permeability, dimensionless, permeability / magnetic_constant);
QUANTITY_SPEC(magnetic_susceptibility, dimensionless, magnetization / magnetic_field_strength, QUANTITY_SPEC(magnetic_susceptibility, dimensionless, magnetization / magnetic_field_strength,
quantity_character::scalar); quantity_character::real_scalar);
QUANTITY_SPEC(magnetic_polarization, magnetic_constant* magnetization); // vector QUANTITY_SPEC(magnetic_polarization, magnetic_constant* magnetization); // vector
QUANTITY_SPEC(magnetic_dipole_moment, magnetic_constant* magnetic_moment); // vector QUANTITY_SPEC(magnetic_dipole_moment, magnetic_constant* magnetic_moment); // vector
QUANTITY_SPEC(coercivity, magnetic_field_strength, quantity_character::scalar); QUANTITY_SPEC(coercivity, magnetic_field_strength, quantity_character::real_scalar);
inline constexpr auto coercive_field_strength = coercivity; inline constexpr auto coercive_field_strength = coercivity;
QUANTITY_SPEC(electromagnetic_energy_density, electric_field_strength* electric_flux_density, QUANTITY_SPEC(electromagnetic_energy_density, electric_field_strength* electric_flux_density,
quantity_character::scalar); quantity_character::real_scalar);
QUANTITY_SPEC(Poynting_vector, electric_field_strength* magnetic_field_strength); // vector QUANTITY_SPEC(Poynting_vector, electric_field_strength* magnetic_field_strength); // vector
QUANTITY_SPEC(source_voltage, voltage); QUANTITY_SPEC(source_voltage, voltage);
inline constexpr auto source_tension = source_voltage; inline constexpr auto source_tension = source_voltage;
QUANTITY_SPEC(magnetic_potential, electric_current); // TODO what is a correct equation here? QUANTITY_SPEC(magnetic_potential, electric_current); // TODO what is a correct equation here?
QUANTITY_SPEC(magnetic_tension, electric_current, magnetic_field_strength* position_vector, quantity_character::scalar); QUANTITY_SPEC(magnetic_tension, electric_current, magnetic_field_strength* position_vector,
quantity_character::real_scalar);
QUANTITY_SPEC(magnetomotive_force, electric_current, magnetic_field_strength* position_vector, QUANTITY_SPEC(magnetomotive_force, electric_current, magnetic_field_strength* position_vector,
quantity_character::scalar); quantity_character::real_scalar);
QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless); QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless);
QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux); QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux);
QUANTITY_SPEC(permeance, inverse(reluctance)); QUANTITY_SPEC(permeance, inverse(reluctance));
@ -118,15 +120,15 @@ inline constexpr auto self_inductance = inductance;
QUANTITY_SPEC(mutual_inductance, protoflux / electric_current); QUANTITY_SPEC(mutual_inductance, protoflux / electric_current);
QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance))); QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance)));
QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor)); QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor));
QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::scalar); QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::real_scalar);
QUANTITY_SPEC(resistivity, inverse(conductivity)); QUANTITY_SPEC(resistivity, inverse(conductivity));
QUANTITY_SPEC(electromagnetism_power, power, voltage* electric_current); // different name than in ISQ QUANTITY_SPEC(electromagnetism_power, power, voltage* electric_current); // different name than in ISQ
inline constexpr auto instantaneous_power = electromagnetism_power; inline constexpr auto instantaneous_power = electromagnetism_power;
QUANTITY_SPEC(resistance, voltage / electric_current); QUANTITY_SPEC(resistance, voltage / electric_current);
QUANTITY_SPEC(conductance, inverse(resistance)); QUANTITY_SPEC(conductance, inverse(resistance));
QUANTITY_SPEC(phase_difference, phase_angle); QUANTITY_SPEC(phase_difference, phase_angle);
QUANTITY_SPEC(electric_current_phasor, electric_current, quantity_character::complex); QUANTITY_SPEC(electric_current_phasor, electric_current, quantity_character::complex_scalar);
QUANTITY_SPEC(voltage_phasor, voltage, quantity_character::complex); QUANTITY_SPEC(voltage_phasor, voltage, quantity_character::complex_scalar);
inline constexpr auto electric_tension_phasor = voltage_phasor; inline constexpr auto electric_tension_phasor = voltage_phasor;
QUANTITY_SPEC(impedance, voltage_phasor / electric_current_phasor); // complex QUANTITY_SPEC(impedance, voltage_phasor / electric_current_phasor); // complex
inline constexpr auto complex_impedance = impedance; // complex inline constexpr auto complex_impedance = impedance; // complex
@ -134,23 +136,23 @@ QUANTITY_SPEC(impedance_of_vacuum, impedance); // comple
inline constexpr auto wave_impedance_in_vacuum = impedance_of_vacuum; // complex inline constexpr auto wave_impedance_in_vacuum = impedance_of_vacuum; // complex
QUANTITY_SPEC( QUANTITY_SPEC(
resistance_to_alternating_current, impedance, resistance_to_alternating_current, impedance,
quantity_character::scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity) quantity_character::real_scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity)
QUANTITY_SPEC(reactance, impedance, quantity_character::scalar); QUANTITY_SPEC(reactance, impedance, quantity_character::real_scalar);
QUANTITY_SPEC(apparent_impedance, impedance, quantity_character::scalar); QUANTITY_SPEC(apparent_impedance, impedance, quantity_character::real_scalar);
QUANTITY_SPEC(admittance, inverse(impedance)); // complex QUANTITY_SPEC(admittance, inverse(impedance)); // complex
inline constexpr auto complex_admittance = admittance; // complex inline constexpr auto complex_admittance = admittance; // complex
QUANTITY_SPEC(admittance_of_vacuum, admittance, inverse(impedance_of_vacuum)); // complex QUANTITY_SPEC(admittance_of_vacuum, admittance, inverse(impedance_of_vacuum)); // complex
QUANTITY_SPEC( QUANTITY_SPEC(
conductance_for_alternating_current, conductance, conductance_for_alternating_current, conductance,
quantity_character::scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity) quantity_character::real_scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity)
QUANTITY_SPEC(susceptance, admittance); QUANTITY_SPEC(susceptance, admittance, quantity_character::real_scalar);
QUANTITY_SPEC(apparent_admittance, admittance, quantity_character::scalar); QUANTITY_SPEC(apparent_admittance, admittance, quantity_character::real_scalar);
QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance); QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance);
QUANTITY_SPEC(loss_factor, dimensionless, inverse(quality_factor)); QUANTITY_SPEC(loss_factor, dimensionless, inverse(quality_factor));
QUANTITY_SPEC(loss_angle, angular_measure); QUANTITY_SPEC(loss_angle, angular_measure);
QUANTITY_SPEC(active_power, isq::power, inverse(period) * (instantaneous_power * time)); QUANTITY_SPEC(active_power, isq::power, inverse(period) * (instantaneous_power * time));
QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); // complex // separate kind QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); // complex // separate kind
QUANTITY_SPEC(apparent_power, complex_power, quantity_character::scalar); QUANTITY_SPEC(apparent_power, complex_power, quantity_character::real_scalar);
QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power); QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power);
QUANTITY_SPEC(reactive_power, isq::mass* pow<2>(isq::length) / pow<3>(isq::time)); // separate kind QUANTITY_SPEC(reactive_power, isq::mass* pow<2>(isq::length) / pow<3>(isq::time)); // separate kind
QUANTITY_SPEC(non_active_power, pow<1, 2>(pow<2>(apparent_power))); // separate kind QUANTITY_SPEC(non_active_power, pow<1, 2>(pow<2>(apparent_power))); // separate kind

View File

@ -60,16 +60,16 @@ QUANTITY_SPEC(impulse, force* time); // vector
QUANTITY_SPEC(angular_momentum, position_vector* momentum); // vector QUANTITY_SPEC(angular_momentum, position_vector* momentum); // vector
QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor); QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor);
QUANTITY_SPEC(moment_of_force, position_vector* force); // vector QUANTITY_SPEC(moment_of_force, position_vector* force); // vector
QUANTITY_SPEC(torque, moment_of_force, quantity_character::scalar); QUANTITY_SPEC(torque, moment_of_force, quantity_character::real_scalar);
QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector
QUANTITY_SPEC(pressure, force / area, quantity_character::scalar); QUANTITY_SPEC(pressure, force / area, quantity_character::real_scalar);
QUANTITY_SPEC(gauge_pressure, pressure); QUANTITY_SPEC(gauge_pressure, pressure);
QUANTITY_SPEC(stress, pressure, quantity_character::tensor); QUANTITY_SPEC(stress, pressure, quantity_character::tensor);
QUANTITY_SPEC(normal_stress, pressure, quantity_character::scalar); QUANTITY_SPEC(normal_stress, pressure, quantity_character::real_scalar);
QUANTITY_SPEC(shear_stress, pressure, quantity_character::scalar); QUANTITY_SPEC(shear_stress, pressure, quantity_character::real_scalar);
QUANTITY_SPEC(strain, dimensionless, quantity_character::tensor); QUANTITY_SPEC(strain, dimensionless, quantity_character::tensor);
QUANTITY_SPEC(relative_linear_strain, length / length); QUANTITY_SPEC(relative_linear_strain, length / length);
QUANTITY_SPEC(shear_strain, dimensionless, displacement / thickness, quantity_character::scalar); QUANTITY_SPEC(shear_strain, dimensionless, displacement / thickness, quantity_character::real_scalar);
QUANTITY_SPEC(relative_volume_strain, volume / volume); QUANTITY_SPEC(relative_volume_strain, volume / volume);
QUANTITY_SPEC(Poisson_number, dimensionless, width / length); QUANTITY_SPEC(Poisson_number, dimensionless, width / length);
QUANTITY_SPEC(modulus_of_elasticity, normal_stress / relative_linear_strain); QUANTITY_SPEC(modulus_of_elasticity, normal_stress / relative_linear_strain);
@ -82,30 +82,32 @@ QUANTITY_SPEC(compressibility, inverse(volume) * (volume / pressure));
QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area); QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area);
QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area); QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area);
QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance); QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance);
QUANTITY_SPEC(static_friction_coefficient, dimensionless, static_friction_force / force, quantity_character::scalar); QUANTITY_SPEC(static_friction_coefficient, dimensionless, static_friction_force / force,
quantity_character::real_scalar);
inline constexpr auto static_friction_factor = static_friction_coefficient; inline constexpr auto static_friction_factor = static_friction_coefficient;
inline constexpr auto coefficient_of_static_friction = static_friction_coefficient; inline constexpr auto coefficient_of_static_friction = static_friction_coefficient;
QUANTITY_SPEC(kinetic_friction_factor, dimensionless, kinetic_friction_force / force, quantity_character::scalar); QUANTITY_SPEC(kinetic_friction_factor, dimensionless, kinetic_friction_force / force, quantity_character::real_scalar);
inline constexpr auto dynamic_friction_factor = kinetic_friction_factor; inline constexpr auto dynamic_friction_factor = kinetic_friction_factor;
QUANTITY_SPEC(rolling_resistance_factor, force / force, quantity_character::scalar); QUANTITY_SPEC(rolling_resistance_factor, force / force, quantity_character::real_scalar);
QUANTITY_SPEC(drag_coefficient, dimensionless, drag_force / (mass_density * pow<2>(speed) * area), QUANTITY_SPEC(drag_coefficient, dimensionless, drag_force / (mass_density * pow<2>(speed) * area),
quantity_character::scalar); quantity_character::real_scalar);
inline constexpr auto drag_factor = drag_coefficient; inline constexpr auto drag_factor = drag_coefficient;
QUANTITY_SPEC(dynamic_viscosity, shear_stress* length / velocity, quantity_character::scalar); QUANTITY_SPEC(dynamic_viscosity, shear_stress* length / velocity, quantity_character::real_scalar);
QUANTITY_SPEC(kinematic_viscosity, dynamic_viscosity / mass_density); QUANTITY_SPEC(kinematic_viscosity, dynamic_viscosity / mass_density);
QUANTITY_SPEC(surface_tension, force / length, quantity_character::scalar); // TODO what is a correct equation here? QUANTITY_SPEC(surface_tension, force / length,
QUANTITY_SPEC(power, mass* pow<2>(length) / pow<3>(time)); // not in ISO 80000 quantity_character::real_scalar); // TODO what is a correct equation here?
QUANTITY_SPEC(mechanical_power, power, force* velocity, quantity_character::scalar); QUANTITY_SPEC(power, mass* pow<2>(length) / pow<3>(time)); // not in ISO 80000
QUANTITY_SPEC(mechanical_power, power, force* velocity, quantity_character::real_scalar);
QUANTITY_SPEC(mechanical_energy, energy); // differs from ISO 80000 QUANTITY_SPEC(mechanical_energy, energy); // differs from ISO 80000
QUANTITY_SPEC(potential_energy, mechanical_energy); // differs from ISO 80000 QUANTITY_SPEC(potential_energy, mechanical_energy); // differs from ISO 80000
QUANTITY_SPEC(kinetic_energy, mechanical_energy, mass* pow<2>(speed)); // differs from ISO 80000 QUANTITY_SPEC(kinetic_energy, mechanical_energy, mass* pow<2>(speed)); // differs from ISO 80000
QUANTITY_SPEC(mechanical_work, force* displacement, quantity_character::scalar); QUANTITY_SPEC(mechanical_work, force* displacement, quantity_character::real_scalar);
inline constexpr auto work = mechanical_work; inline constexpr auto work = mechanical_work;
QUANTITY_SPEC(mechanical_efficiency, mechanical_power / mechanical_power); QUANTITY_SPEC(mechanical_efficiency, mechanical_power / mechanical_power);
QUANTITY_SPEC(mass_flow, mass_density* velocity); // vector QUANTITY_SPEC(mass_flow, mass_density* velocity); // vector
QUANTITY_SPEC(mass_flow_rate, mass_flow* area, quantity_character::scalar); QUANTITY_SPEC(mass_flow_rate, mass_flow* area, quantity_character::real_scalar);
QUANTITY_SPEC(mass_change_rate, mass / time); QUANTITY_SPEC(mass_change_rate, mass / time);
QUANTITY_SPEC(volume_flow_rate, velocity* area, quantity_character::scalar); QUANTITY_SPEC(volume_flow_rate, velocity* area, quantity_character::real_scalar);
QUANTITY_SPEC(action, energy* time); QUANTITY_SPEC(action, energy* time);
} // namespace mp_units::isq } // namespace mp_units::isq

View File

@ -57,7 +57,7 @@ QUANTITY_SPEC(propagation_coefficient, cotes_angle_constant / length);
QUANTITY_SPEC(angular_momentum, position_vector* momentum / cotes_angle_constant); // vector QUANTITY_SPEC(angular_momentum, position_vector* momentum / cotes_angle_constant); // vector
QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor); QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor);
QUANTITY_SPEC(moment_of_force, position_vector* force / cotes_angle_constant); // vector QUANTITY_SPEC(moment_of_force, position_vector* force / cotes_angle_constant); // vector
QUANTITY_SPEC(torque, moment_of_force, quantity_character::scalar); QUANTITY_SPEC(torque, moment_of_force, quantity_character::real_scalar);
QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector
QUANTITY_SPEC(loss_angle, angular_measure); QUANTITY_SPEC(loss_angle, angular_measure);

View File

@ -60,7 +60,8 @@ using namespace mp_units;
using namespace mp_units::si::unit_symbols; using namespace mp_units::si::unit_symbols;
template<QuantitySpec auto QS, QuantityOf<QS> Q> template<QuantitySpec auto QS, QuantityOf<QS> Q>
requires(Q::quantity_spec.character == quantity_character::vector) && (QS.character == quantity_character::scalar) requires(Q::quantity_spec.character == quantity_character::vector) &&
(QS.character == quantity_character::real_scalar)
[[nodiscard]] constexpr QuantityOf<QS> auto get_magnitude(const Q& q) [[nodiscard]] constexpr QuantityOf<QS> auto get_magnitude(const Q& q)
{ {
const auto& v = q.numerical_value_ref_in(q.unit); const auto& v = q.numerical_value_ref_in(q.unit);
@ -68,7 +69,8 @@ template<QuantitySpec auto QS, QuantityOf<QS> Q>
} }
template<QuantitySpec auto QS, QuantityOf<QS> T> template<QuantitySpec auto QS, QuantityOf<QS> T>
requires(T::quantity_spec.character == quantity_character::vector) && (QS.character == quantity_character::scalar) requires(T::quantity_spec.character == quantity_character::vector) &&
(QS.character == quantity_character::real_scalar)
[[nodiscard]] constexpr QuantityOf<QS> auto get_magnitude(const vector<T>& v) [[nodiscard]] constexpr QuantityOf<QS> auto get_magnitude(const vector<T>& v)
{ {
return hypot(QS(v(0)), QS(v(1)), QS(v(2))); return hypot(QS(v(0)), QS(v(1)), QS(v(2)));

View File

@ -25,7 +25,6 @@
#include <mp-units/systems/si.h> #include <mp-units/systems/si.h>
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
#include <mp-units/cartesian_vector.h> #include <mp-units/cartesian_vector.h>
#include <mp-units/complex.h>
#endif #endif
#ifdef MP_UNITS_IMPORT_STD #ifdef MP_UNITS_IMPORT_STD
import std; import std;
@ -331,30 +330,46 @@ static_assert(!Representation<std::chrono::seconds>);
#endif #endif
// RepresentationOf // RepresentationOf
static_assert(RepresentationOf<int, quantity_character::scalar>); static_assert(RepresentationOf<int, quantity_character::real_scalar>);
static_assert(!RepresentationOf<int, quantity_character::complex>); static_assert(!RepresentationOf<int, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<int, quantity_character::complex_scalar>);
static_assert(RepresentationOf<int, quantity_character::vector>); static_assert(RepresentationOf<int, quantity_character::vector>);
static_assert(!RepresentationOf<int, quantity_character::tensor>); static_assert(!RepresentationOf<int, quantity_character::tensor>);
static_assert(RepresentationOf<double, quantity_character::scalar>);
static_assert(!RepresentationOf<double, quantity_character::complex>); static_assert(RepresentationOf<double, quantity_character::real_scalar>);
static_assert(!RepresentationOf<double, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<double, quantity_character::complex_scalar>);
static_assert(RepresentationOf<double, quantity_character::vector>); static_assert(RepresentationOf<double, quantity_character::vector>);
static_assert(!RepresentationOf<double, quantity_character::tensor>); static_assert(!RepresentationOf<double, quantity_character::tensor>);
static_assert(!RepresentationOf<bool, quantity_character::scalar>);
static_assert(!RepresentationOf<bool, quantity_character::complex>); static_assert(!RepresentationOf<bool, quantity_character::real_scalar>);
static_assert(!RepresentationOf<bool, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<bool, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<bool, quantity_character::vector>); static_assert(!RepresentationOf<bool, quantity_character::vector>);
static_assert(!RepresentationOf<bool, quantity_character::tensor>); static_assert(!RepresentationOf<bool, quantity_character::tensor>);
static_assert(!RepresentationOf<std::optional<int>, quantity_character::scalar>);
static_assert(!RepresentationOf<std::optional<int>, quantity_character::real_scalar>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
static_assert(RepresentationOf<std::complex<double>, quantity_character::complex>); static_assert(!RepresentationOf<std::complex<double>, quantity_character::real_scalar>);
static_assert(!RepresentationOf<std::complex<double>, quantity_character::scalar>); static_assert(RepresentationOf<std::complex<double>, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<std::complex<double>, quantity_character::vector>); static_assert(!RepresentationOf<std::complex<double>, quantity_character::vector>);
static_assert(!RepresentationOf<std::complex<double>, quantity_character::tensor>); static_assert(!RepresentationOf<std::complex<double>, quantity_character::tensor>);
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::real_scalar>);
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::complex_scalar>);
static_assert(RepresentationOf<cartesian_vector<double>, quantity_character::vector>); static_assert(RepresentationOf<cartesian_vector<double>, quantity_character::vector>);
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::scalar>); static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::complex>);
static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::tensor>); static_assert(!RepresentationOf<cartesian_vector<double>, quantity_character::tensor>);
static_assert(!RepresentationOf<std::chrono::seconds, quantity_character::scalar>);
static_assert(!RepresentationOf<std::string, quantity_character::scalar>); static_assert(!RepresentationOf<cartesian_vector<std::complex<double>>, quantity_character::real_scalar>);
static_assert(!RepresentationOf<cartesian_vector<std::complex<double>>, quantity_character::complex_scalar>);
static_assert(RepresentationOf<cartesian_vector<std::complex<double>>, quantity_character::vector>);
static_assert(!RepresentationOf<cartesian_vector<std::complex<double>>, quantity_character::complex_scalar>);
static_assert(!RepresentationOf<cartesian_vector<std::complex<double>>, quantity_character::tensor>);
static_assert(!RepresentationOf<std::chrono::seconds, quantity_character::real_scalar>);
static_assert(!RepresentationOf<std::string, quantity_character::real_scalar>);
#endif #endif
// Quantity // Quantity

View File

@ -37,24 +37,24 @@ using enum mp_units::quantity_character;
return q.character == ch && (... && requires { q[units]; }); return q.character == ch && (... && requires { q[units]; });
} }
static_assert(verify(isq_angle::cotes_angle_constant, scalar, rad)); static_assert(verify(isq_angle::cotes_angle_constant, real_scalar, rad));
static_assert(verify(isq_angle::angular_measure, scalar, rad)); static_assert(verify(isq_angle::angular_measure, real_scalar, rad));
static_assert(verify(isq_angle::rotational_displacement, scalar, rad)); static_assert(verify(isq_angle::rotational_displacement, real_scalar, rad));
static_assert(verify(isq_angle::angular_displacement, scalar, rad)); static_assert(verify(isq_angle::angular_displacement, real_scalar, rad));
static_assert(verify(isq_angle::solid_angular_measure, scalar, sr)); static_assert(verify(isq_angle::solid_angular_measure, real_scalar, sr));
static_assert(verify(isq_angle::angular_velocity, vector, rad / s)); static_assert(verify(isq_angle::angular_velocity, vector, rad / s));
static_assert(verify(isq_angle::angular_acceleration, vector, rad / s2)); static_assert(verify(isq_angle::angular_acceleration, vector, rad / s2));
static_assert(verify(isq_angle::rotation, scalar, rad)); static_assert(verify(isq_angle::rotation, real_scalar, rad));
static_assert(verify(isq_angle::angular_frequency, scalar, rad / s)); static_assert(verify(isq_angle::angular_frequency, real_scalar, rad / s));
static_assert(verify(isq_angle::angular_repetency, scalar, rad / m)); static_assert(verify(isq_angle::angular_repetency, real_scalar, rad / m));
static_assert(verify(isq_angle::angular_wavenumber, scalar, rad / m)); static_assert(verify(isq_angle::angular_wavenumber, real_scalar, rad / m));
static_assert(verify(isq_angle::phase_coefficient, scalar, rad / m)); static_assert(verify(isq_angle::phase_coefficient, real_scalar, rad / m));
static_assert(verify(isq_angle::propagation_coefficient, scalar, rad / m)); static_assert(verify(isq_angle::propagation_coefficient, real_scalar, rad / m));
static_assert(verify(isq_angle::moment_of_inertia, tensor, kg* m2 / rad2)); static_assert(verify(isq_angle::moment_of_inertia, tensor, kg* m2 / rad2));
static_assert(verify(isq_angle::angular_momentum, vector, J* s / rad)); static_assert(verify(isq_angle::angular_momentum, vector, J* s / rad));
static_assert(verify(isq_angle::moment_of_force, vector, J / rad)); static_assert(verify(isq_angle::moment_of_force, vector, J / rad));
static_assert(verify(isq_angle::torque, scalar, J / rad)); static_assert(verify(isq_angle::torque, real_scalar, J / rad));
static_assert(verify(isq_angle::angular_impulse, vector, J* s / rad)); static_assert(verify(isq_angle::angular_impulse, vector, J* s / rad));
static_assert(verify(isq_angle::loss_angle, scalar, rad)); static_assert(verify(isq_angle::loss_angle, real_scalar, rad));
} // namespace } // namespace

View File

@ -38,69 +38,69 @@ using enum mp_units::quantity_character;
} }
// space and time // space and time
static_assert(verify(isq::length, scalar, m)); static_assert(verify(isq::length, real_scalar, m));
static_assert(verify(isq::width, scalar, m)); static_assert(verify(isq::width, real_scalar, m));
static_assert(verify(isq::breadth, scalar, m)); static_assert(verify(isq::breadth, real_scalar, m));
static_assert(verify(isq::height, scalar, m)); static_assert(verify(isq::height, real_scalar, m));
static_assert(verify(isq::depth, scalar, m)); static_assert(verify(isq::depth, real_scalar, m));
static_assert(verify(isq::altitude, scalar, m)); static_assert(verify(isq::altitude, real_scalar, m));
static_assert(verify(isq::thickness, scalar, m)); static_assert(verify(isq::thickness, real_scalar, m));
static_assert(verify(isq::diameter, scalar, m)); static_assert(verify(isq::diameter, real_scalar, m));
static_assert(verify(isq::radius, scalar, m)); static_assert(verify(isq::radius, real_scalar, m));
static_assert(verify(isq::path_length, scalar, m)); static_assert(verify(isq::path_length, real_scalar, m));
static_assert(verify(isq::arc_length, scalar, m)); static_assert(verify(isq::arc_length, real_scalar, m));
static_assert(verify(isq::distance, scalar, m)); static_assert(verify(isq::distance, real_scalar, m));
static_assert(verify(isq::radial_distance, scalar, m)); static_assert(verify(isq::radial_distance, real_scalar, m));
static_assert(verify(isq::position_vector, vector, m)); static_assert(verify(isq::position_vector, vector, m));
static_assert(verify(isq::displacement, vector, m)); static_assert(verify(isq::displacement, vector, m));
static_assert(verify(isq::radius_of_curvature, scalar, m)); static_assert(verify(isq::radius_of_curvature, real_scalar, m));
static_assert(verify(isq::curvature, scalar, one / m)); static_assert(verify(isq::curvature, real_scalar, one / m));
static_assert(verify(isq::area, scalar, m2)); static_assert(verify(isq::area, real_scalar, m2));
static_assert(verify(isq::volume, scalar, m3)); static_assert(verify(isq::volume, real_scalar, m3));
static_assert(verify(isq::angular_measure, scalar, rad, one)); static_assert(verify(isq::angular_measure, real_scalar, rad, one));
static_assert(verify(isq::rotational_displacement, scalar, rad, one)); static_assert(verify(isq::rotational_displacement, real_scalar, rad, one));
static_assert(verify(isq::angular_displacement, scalar, rad, one)); static_assert(verify(isq::angular_displacement, real_scalar, rad, one));
static_assert(verify(isq::phase_angle, scalar, rad, one)); static_assert(verify(isq::phase_angle, real_scalar, rad, one));
static_assert(verify(isq::solid_angular_measure, scalar, sr, one)); static_assert(verify(isq::solid_angular_measure, real_scalar, sr, one));
static_assert(verify(isq::duration, scalar, s)); static_assert(verify(isq::duration, real_scalar, s));
static_assert(verify(isq::velocity, vector, m / s)); static_assert(verify(isq::velocity, vector, m / s));
static_assert(verify(isq::speed, scalar, m / s)); static_assert(verify(isq::speed, real_scalar, m / s));
static_assert(verify(isq::acceleration, vector, m / s2)); static_assert(verify(isq::acceleration, vector, m / s2));
static_assert(verify(isq::angular_velocity, vector, rad / s, one / s)); static_assert(verify(isq::angular_velocity, vector, rad / s, one / s));
static_assert(verify(isq::angular_acceleration, vector, rad / s2, one / s2)); static_assert(verify(isq::angular_acceleration, vector, rad / s2, one / s2));
static_assert(verify(isq::period_duration, scalar, s)); static_assert(verify(isq::period_duration, real_scalar, s));
static_assert(verify(isq::duration, scalar, s)); static_assert(verify(isq::duration, real_scalar, s));
static_assert(verify(isq::time_constant, scalar, s)); static_assert(verify(isq::time_constant, real_scalar, s));
static_assert(verify(isq::rotation, scalar, one)); static_assert(verify(isq::rotation, real_scalar, one));
static_assert(verify(isq::frequency, scalar, Hz, one / s)); static_assert(verify(isq::frequency, real_scalar, Hz, one / s));
static_assert(verify(isq::rotational_frequency, scalar, one / s)); static_assert(verify(isq::rotational_frequency, real_scalar, one / s));
static_assert(verify(isq::angular_frequency, scalar, rad / s, one / s)); static_assert(verify(isq::angular_frequency, real_scalar, rad / s, one / s));
static_assert(verify(isq::wavelength, scalar, m)); static_assert(verify(isq::wavelength, real_scalar, m));
static_assert(verify(isq::repetency, scalar, one / m)); static_assert(verify(isq::repetency, real_scalar, one / m));
static_assert(verify(isq::wavenumber, scalar, one / m)); static_assert(verify(isq::wavenumber, real_scalar, one / m));
static_assert(verify(isq::wave_vector, vector, one / m)); static_assert(verify(isq::wave_vector, vector, one / m));
static_assert(verify(isq::angular_repetency, scalar, one / m)); static_assert(verify(isq::angular_repetency, real_scalar, one / m));
static_assert(verify(isq::angular_wavenumber, scalar, one / m)); static_assert(verify(isq::angular_wavenumber, real_scalar, one / m));
static_assert(verify(isq::phase_speed, scalar, m / s)); static_assert(verify(isq::phase_speed, real_scalar, m / s));
static_assert(verify(isq::group_speed, scalar, m / s)); static_assert(verify(isq::group_speed, real_scalar, m / s));
static_assert(verify(isq::damping_coefficient, scalar, one / s)); static_assert(verify(isq::damping_coefficient, real_scalar, one / s));
static_assert(verify(isq::logarithmic_decrement, scalar, one)); static_assert(verify(isq::logarithmic_decrement, real_scalar, one));
static_assert(verify(isq::attenuation, scalar, one / m)); static_assert(verify(isq::attenuation, real_scalar, one / m));
static_assert(verify(isq::extinction, scalar, one / m)); static_assert(verify(isq::extinction, real_scalar, one / m));
static_assert(verify(isq::phase_coefficient, scalar, rad / m, one / m)); static_assert(verify(isq::phase_coefficient, real_scalar, rad / m, one / m));
static_assert(verify(isq::propagation_coefficient, scalar, one / m)); static_assert(verify(isq::propagation_coefficient, real_scalar, one / m));
// mechanics // mechanics
static_assert(verify(isq::mass, scalar, kg)); static_assert(verify(isq::mass, real_scalar, kg));
static_assert(verify(isq::mass_density, scalar, kg / m3)); static_assert(verify(isq::mass_density, real_scalar, kg / m3));
static_assert(verify(isq::density, scalar, kg / m3)); static_assert(verify(isq::density, real_scalar, kg / m3));
static_assert(verify(isq::specific_volume, scalar, m3 / kg)); static_assert(verify(isq::specific_volume, real_scalar, m3 / kg));
static_assert(verify(isq::relative_mass_density, scalar, one)); static_assert(verify(isq::relative_mass_density, real_scalar, one));
static_assert(verify(isq::relative_density, scalar, one)); static_assert(verify(isq::relative_density, real_scalar, one));
static_assert(verify(isq::surface_mass_density, scalar, kg / m2)); static_assert(verify(isq::surface_mass_density, real_scalar, kg / m2));
static_assert(verify(isq::surface_density, scalar, kg / m2)); static_assert(verify(isq::surface_density, real_scalar, kg / m2));
static_assert(verify(isq::linear_mass_density, scalar, kg / m)); static_assert(verify(isq::linear_mass_density, real_scalar, kg / m));
static_assert(verify(isq::linear_density, scalar, kg / m)); static_assert(verify(isq::linear_density, real_scalar, kg / m));
static_assert(verify(isq::moment_of_inertia, tensor, kg* m2)); static_assert(verify(isq::moment_of_inertia, tensor, kg* m2));
static_assert(verify(isq::momentum, vector, kg* m / s)); static_assert(verify(isq::momentum, vector, kg* m / s));
static_assert(verify(isq::force, vector, N, kg* m / s2)); static_assert(verify(isq::force, vector, N, kg* m / s2));
@ -116,285 +116,286 @@ static_assert(verify(isq::drag_force, vector, N, kg* m / s2));
static_assert(verify(isq::impulse, vector, N* s, kg* m / s)); static_assert(verify(isq::impulse, vector, N* s, kg* m / s));
static_assert(verify(isq::angular_momentum, vector, kg* m2 / s)); static_assert(verify(isq::angular_momentum, vector, kg* m2 / s));
static_assert(verify(isq::moment_of_force, vector, N* m, kg* m2 / s2)); static_assert(verify(isq::moment_of_force, vector, N* m, kg* m2 / s2));
static_assert(verify(isq::torque, scalar, N* m, kg* m2 / s2)); static_assert(verify(isq::torque, real_scalar, N* m, kg* m2 / s2));
static_assert(verify(isq::angular_impulse, vector, N* m* s, kg* m2 / s)); static_assert(verify(isq::angular_impulse, vector, N* m* s, kg* m2 / s));
static_assert(verify(isq::pressure, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::pressure, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::gauge_pressure, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::gauge_pressure, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::stress, tensor, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::stress, tensor, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::normal_stress, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::normal_stress, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::shear_stress, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::shear_stress, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::strain, tensor, one)); static_assert(verify(isq::strain, tensor, one));
static_assert(verify(isq::relative_linear_strain, scalar, one)); static_assert(verify(isq::relative_linear_strain, real_scalar, one));
static_assert(verify(isq::shear_strain, scalar, one)); static_assert(verify(isq::shear_strain, real_scalar, one));
static_assert(verify(isq::relative_volume_strain, scalar, one)); static_assert(verify(isq::relative_volume_strain, real_scalar, one));
static_assert(verify(isq::Poisson_number, scalar, one)); static_assert(verify(isq::Poisson_number, real_scalar, one));
static_assert(verify(isq::modulus_of_elasticity, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::modulus_of_elasticity, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::Young_modulus, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::Young_modulus, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::modulus_of_rigidity, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::modulus_of_rigidity, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::shear_modulus, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::shear_modulus, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::modulus_of_compression, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::modulus_of_compression, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::bulk_modulus, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::bulk_modulus, real_scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::compressibility, scalar, one / Pa, m* s2 / kg)); static_assert(verify(isq::compressibility, real_scalar, one / Pa, m* s2 / kg));
static_assert(verify(isq::second_axial_moment_of_area, scalar, m4)); static_assert(verify(isq::second_axial_moment_of_area, real_scalar, m4));
static_assert(verify(isq::second_polar_moment_of_area, scalar, m4)); static_assert(verify(isq::second_polar_moment_of_area, real_scalar, m4));
static_assert(verify(isq::section_modulus, scalar, m3)); static_assert(verify(isq::section_modulus, real_scalar, m3));
static_assert(verify(isq::static_friction_coefficient, scalar, one)); static_assert(verify(isq::static_friction_coefficient, real_scalar, one));
static_assert(verify(isq::static_friction_factor, scalar, one)); static_assert(verify(isq::static_friction_factor, real_scalar, one));
static_assert(verify(isq::coefficient_of_static_friction, scalar, one)); static_assert(verify(isq::coefficient_of_static_friction, real_scalar, one));
static_assert(verify(isq::kinetic_friction_factor, scalar, one)); static_assert(verify(isq::kinetic_friction_factor, real_scalar, one));
static_assert(verify(isq::dynamic_friction_factor, scalar, one)); static_assert(verify(isq::dynamic_friction_factor, real_scalar, one));
static_assert(verify(isq::rolling_resistance_factor, scalar, one)); static_assert(verify(isq::rolling_resistance_factor, real_scalar, one));
static_assert(verify(isq::drag_coefficient, scalar, one)); static_assert(verify(isq::drag_coefficient, real_scalar, one));
static_assert(verify(isq::drag_factor, scalar, one)); static_assert(verify(isq::drag_factor, real_scalar, one));
static_assert(verify(isq::dynamic_viscosity, scalar, Pa* s, kg / m / s)); static_assert(verify(isq::dynamic_viscosity, real_scalar, Pa* s, kg / m / s));
static_assert(verify(isq::kinematic_viscosity, scalar, m2 / s)); static_assert(verify(isq::kinematic_viscosity, real_scalar, m2 / s));
static_assert(verify(isq::surface_tension, scalar, N / m, kg / s2)); static_assert(verify(isq::surface_tension, real_scalar, N / m, kg / s2));
static_assert(verify(isq::power, scalar, W, N* m / s, kg* m2 / s3)); static_assert(verify(isq::power, real_scalar, W, N* m / s, kg* m2 / s3));
static_assert(verify(isq::potential_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::potential_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::kinetic_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::kinetic_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::mechanical_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::mechanical_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::mechanical_work, scalar, J, kg* m2 / s2)); static_assert(verify(isq::mechanical_work, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::work, scalar, J, kg* m2 / s2)); static_assert(verify(isq::work, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::mechanical_efficiency, scalar, one)); static_assert(verify(isq::mechanical_efficiency, real_scalar, one));
static_assert(verify(isq::mass_flow, vector, kg / m2 / s)); static_assert(verify(isq::mass_flow, vector, kg / m2 / s));
static_assert(verify(isq::mass_flow_rate, scalar, kg / s)); static_assert(verify(isq::mass_flow_rate, real_scalar, kg / s));
static_assert(verify(isq::mass_change_rate, scalar, kg / s)); static_assert(verify(isq::mass_change_rate, real_scalar, kg / s));
static_assert(verify(isq::volume_flow_rate, scalar, m3 / s)); static_assert(verify(isq::volume_flow_rate, real_scalar, m3 / s));
static_assert(verify(isq::action, scalar, J* s, kg* m2 / s)); static_assert(verify(isq::action, real_scalar, J* s, kg* m2 / s));
// thermodynamics // thermodynamics
static_assert(verify(isq::thermodynamic_temperature, scalar, K)); static_assert(verify(isq::thermodynamic_temperature, real_scalar, K));
static_assert(verify(isq::Celsius_temperature, scalar, deg_C)); static_assert(verify(isq::Celsius_temperature, real_scalar, deg_C));
static_assert(verify(isq::linear_expansion_coefficient, scalar, one / K)); static_assert(verify(isq::linear_expansion_coefficient, real_scalar, one / K));
static_assert(verify(isq::cubic_expansion_coefficient, scalar, one / K)); static_assert(verify(isq::cubic_expansion_coefficient, real_scalar, one / K));
static_assert(verify(isq::relative_pressure_coefficient, scalar, one / K)); static_assert(verify(isq::relative_pressure_coefficient, real_scalar, one / K));
static_assert(verify(isq::pressure_coefficient, scalar, Pa / K, kg / m / s2 / K)); static_assert(verify(isq::pressure_coefficient, real_scalar, Pa / K, kg / m / s2 / K));
static_assert(verify(isq::isothermal_compressibility, scalar, one / Pa, m* s2 / kg)); static_assert(verify(isq::isothermal_compressibility, real_scalar, one / Pa, m* s2 / kg));
static_assert(verify(isq::isentropic_compressibility, scalar, one / Pa, m* s2 / kg)); static_assert(verify(isq::isentropic_compressibility, real_scalar, one / Pa, m* s2 / kg));
static_assert(verify(isq::heat, scalar, J, kg* m2 / s2)); static_assert(verify(isq::heat, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::amount_of_heat, scalar, J, kg* m2 / s2)); static_assert(verify(isq::amount_of_heat, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::latent_heat, scalar, J, kg* m2 / s2)); static_assert(verify(isq::latent_heat, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::heat_flow_rate, scalar, W, J / s, kg* m2 / s3)); static_assert(verify(isq::heat_flow_rate, real_scalar, W, J / s, kg* m2 / s3));
static_assert(verify(isq::density_of_heat_flow_rate, scalar, W / m2, kg / s3)); static_assert(verify(isq::density_of_heat_flow_rate, real_scalar, W / m2, kg / s3));
static_assert(verify(isq::thermal_conductivity, scalar, W / (m * K), kg* m / s3 / K)); static_assert(verify(isq::thermal_conductivity, real_scalar, W / (m * K), kg* m / s3 / K));
static_assert(verify(isq::coefficient_of_heat_transfer, scalar, W / (m2 * K), kg / s3 / K)); static_assert(verify(isq::coefficient_of_heat_transfer, real_scalar, W / (m2 * K), kg / s3 / K));
static_assert(verify(isq::surface_coefficient_of_heat_transfer, scalar, W / (m2 * K), kg / s3 / K)); static_assert(verify(isq::surface_coefficient_of_heat_transfer, real_scalar, W / (m2 * K), kg / s3 / K));
static_assert(verify(isq::thermal_insulance, scalar, m2* K / W, s3* K / kg)); static_assert(verify(isq::thermal_insulance, real_scalar, m2* K / W, s3* K / kg));
static_assert(verify(isq::thermal_resistance, scalar, K / W, s3* K / kg / m2)); static_assert(verify(isq::thermal_resistance, real_scalar, K / W, s3* K / kg / m2));
static_assert(verify(isq::thermal_conductance, scalar, W / K, kg* m2 / s3 / K)); static_assert(verify(isq::thermal_conductance, real_scalar, W / K, kg* m2 / s3 / K));
static_assert(verify(isq::thermal_diffusivity, scalar, m2 / s)); static_assert(verify(isq::thermal_diffusivity, real_scalar, m2 / s));
static_assert(verify(isq::heat_capacity, scalar, J / K, kg* m2 / s2 / K)); static_assert(verify(isq::heat_capacity, real_scalar, J / K, kg* m2 / s2 / K));
static_assert(verify(isq::specific_heat_capacity, scalar, J / (kg * K), m2 / s2 / K)); static_assert(verify(isq::specific_heat_capacity, real_scalar, J / (kg * K), m2 / s2 / K));
static_assert(verify(isq::specific_heat_capacity_at_constant_pressure, scalar, J / (kg * K), m2 / s2 / K)); static_assert(verify(isq::specific_heat_capacity_at_constant_pressure, real_scalar, J / (kg * K), m2 / s2 / K));
static_assert(verify(isq::specific_heat_capacity_at_constant_volume, scalar, J / (kg * K), m2 / s2 / K)); static_assert(verify(isq::specific_heat_capacity_at_constant_volume, real_scalar, J / (kg * K), m2 / s2 / K));
static_assert(verify(isq::specific_heat_capacity_at_saturated_vapour_pressure, scalar, J / (kg * K), m2 / s2 / K)); static_assert(verify(isq::specific_heat_capacity_at_saturated_vapour_pressure, real_scalar, J / (kg * K), m2 / s2 / K));
static_assert(verify(isq::ratio_of_specific_heat_capacities, scalar, one)); static_assert(verify(isq::ratio_of_specific_heat_capacities, real_scalar, one));
static_assert(verify(isq::isentropic_exponent, scalar, one)); static_assert(verify(isq::isentropic_exponent, real_scalar, one));
static_assert(verify(isq::isentropic_expansion_factor, scalar, one)); static_assert(verify(isq::isentropic_expansion_factor, real_scalar, one));
static_assert(verify(isq::entropy, scalar, J / K, kg* m2 / s2 / K)); static_assert(verify(isq::entropy, real_scalar, J / K, kg* m2 / s2 / K));
static_assert(verify(isq::specific_entropy, scalar, J / (kg * K), m2 / s2 / K)); static_assert(verify(isq::specific_entropy, real_scalar, J / (kg * K), m2 / s2 / K));
static_assert(verify(isq::energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::internal_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::internal_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::thermodynamic_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::thermodynamic_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::enthalpy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::enthalpy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::Helmholtz_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::Helmholtz_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::Helmholtz_function, scalar, J, kg* m2 / s2)); static_assert(verify(isq::Helmholtz_function, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::Gibbs_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::Gibbs_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::Gibbs_function, scalar, J, kg* m2 / s2)); static_assert(verify(isq::Gibbs_function, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::specific_energy, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_energy, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_internal_energy, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_internal_energy, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_thermodynamic_energy, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_thermodynamic_energy, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_enthalpy, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_enthalpy, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_Helmholtz_energy, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_Helmholtz_energy, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_Helmholtz_function, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_Helmholtz_function, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_Gibbs_energy, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_Gibbs_energy, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::specific_Gibbs_function, scalar, J / kg, m2 / s2)); static_assert(verify(isq::specific_Gibbs_function, real_scalar, J / kg, m2 / s2));
static_assert(verify(isq::Massieu_function, scalar, J / K, kg* m2 / s2 / K)); static_assert(verify(isq::Massieu_function, real_scalar, J / K, kg* m2 / s2 / K));
static_assert(verify(isq::Planck_function, scalar, J / K, kg* m2 / s2 / K)); static_assert(verify(isq::Planck_function, real_scalar, J / K, kg* m2 / s2 / K));
static_assert(verify(isq::Joule_Thomson_coefficient, scalar, K / Pa, m* s2* K / kg)); static_assert(verify(isq::Joule_Thomson_coefficient, real_scalar, K / Pa, m* s2* K / kg));
static_assert(verify(isq::thermodynamic_efficiency, scalar, one)); static_assert(verify(isq::thermodynamic_efficiency, real_scalar, one));
static_assert(verify(isq::maximum_efficiency, scalar, one)); static_assert(verify(isq::maximum_efficiency, real_scalar, one));
static_assert(verify(isq::specific_gas_constant, scalar, J / (kg * K), m2 / s2 / K)); static_assert(verify(isq::specific_gas_constant, real_scalar, J / (kg * K), m2 / s2 / K));
static_assert(verify(isq::mass_concentration_of_water, scalar, kg / m3)); static_assert(verify(isq::mass_concentration_of_water, real_scalar, kg / m3));
static_assert(verify(isq::mass_concentration_of_water_vapour, scalar, kg / m3)); static_assert(verify(isq::mass_concentration_of_water_vapour, real_scalar, kg / m3));
static_assert(verify(isq::mass_ratio_of_water_to_dry_matter, scalar, one)); static_assert(verify(isq::mass_ratio_of_water_to_dry_matter, real_scalar, one));
static_assert(verify(isq::mass_ratio_of_water_vapour_to_dry_gas, scalar, one)); static_assert(verify(isq::mass_ratio_of_water_vapour_to_dry_gas, real_scalar, one));
static_assert(verify(isq::mass_fraction_of_water, scalar, one)); static_assert(verify(isq::mass_fraction_of_water, real_scalar, one));
static_assert(verify(isq::mass_fraction_of_dry_matter, scalar, one)); static_assert(verify(isq::mass_fraction_of_dry_matter, real_scalar, one));
static_assert(verify(isq::relative_humidity, scalar, one)); static_assert(verify(isq::relative_humidity, real_scalar, one));
static_assert(verify(isq::relative_mass_concentration_of_vapour, scalar, one)); static_assert(verify(isq::relative_mass_concentration_of_vapour, real_scalar, one));
static_assert(verify(isq::relative_mass_ratio_of_vapour, scalar, one)); static_assert(verify(isq::relative_mass_ratio_of_vapour, real_scalar, one));
static_assert(verify(isq::dew_point_temperature, scalar, K)); static_assert(verify(isq::dew_point_temperature, real_scalar, K));
// electromagnetism // electromagnetism
static_assert(verify(isq::electric_current, scalar, A)); static_assert(verify(isq::electric_current, real_scalar, A));
static_assert(verify(isq::electric_charge, scalar, C, A* s)); static_assert(verify(isq::electric_charge, real_scalar, C, A* s));
static_assert(verify(isq::elementary_charge, scalar, C, A* s)); static_assert(verify(isq::elementary_charge, real_scalar, C, A* s));
static_assert(verify(isq::electric_charge_density, scalar, C / m3, s* A / m3)); static_assert(verify(isq::electric_charge_density, real_scalar, C / m3, s* A / m3));
static_assert(verify(isq::volume_electric_charge, scalar, C / m3, s* A / m3)); static_assert(verify(isq::volume_electric_charge, real_scalar, C / m3, s* A / m3));
static_assert(verify(isq::volumic_charge, scalar, C / m3, s* A / m3)); static_assert(verify(isq::volumic_charge, real_scalar, C / m3, s* A / m3));
static_assert(verify(isq::surface_density_of_electric_charge, scalar, C / m2, s* A / m2)); static_assert(verify(isq::surface_density_of_electric_charge, real_scalar, C / m2, s* A / m2));
static_assert(verify(isq::areic_electric_charge, scalar, C / m2, s* A / m2)); static_assert(verify(isq::areic_electric_charge, real_scalar, C / m2, s* A / m2));
static_assert(verify(isq::areic_charge, scalar, C / m2, s* A / m2)); static_assert(verify(isq::areic_charge, real_scalar, C / m2, s* A / m2));
static_assert(verify(isq::linear_density_of_electric_charge, scalar, C / m, s* A / m)); static_assert(verify(isq::linear_density_of_electric_charge, real_scalar, C / m, s* A / m));
static_assert(verify(isq::lineic_electric_charge, scalar, C / m, s* A / m)); static_assert(verify(isq::lineic_electric_charge, real_scalar, C / m, s* A / m));
static_assert(verify(isq::lineic_charge, scalar, C / m, s* A / m)); static_assert(verify(isq::lineic_charge, real_scalar, C / m, s* A / m));
static_assert(verify(isq::electric_dipole_moment, vector, C* m, m* s* A)); static_assert(verify(isq::electric_dipole_moment, vector, C* m, m* s* A));
static_assert(verify(isq::electric_polarization, vector, C / m2, s* A / m2)); static_assert(verify(isq::electric_polarization, vector, C / m2, s* A / m2));
static_assert(verify(isq::electric_current_density, vector, A / m2)); static_assert(verify(isq::electric_current_density, vector, A / m2));
static_assert(verify(isq::linear_electric_current_density, vector, A / m)); static_assert(verify(isq::linear_electric_current_density, vector, A / m));
static_assert(verify(isq::electric_field_strength, vector, V / m, kg* m / (s3 * A))); static_assert(verify(isq::electric_field_strength, vector, V / m, kg* m / (s3 * A)));
static_assert(verify(isq::electric_potential, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::electric_potential, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::electric_potential_difference, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::electric_potential_difference, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::voltage, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::voltage, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::electric_tension, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::electric_tension, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::induced_voltage, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::induced_voltage, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::electric_flux_density, vector, C / m2, s* A / m2)); static_assert(verify(isq::electric_flux_density, vector, C / m2, s* A / m2));
static_assert(verify(isq::electric_displacement, vector, C / m2, s* A / m2)); static_assert(verify(isq::electric_displacement, vector, C / m2, s* A / m2));
static_assert(verify(isq::capacitance, scalar, F, pow<4>(s) * square(A) / (kg * m2))); static_assert(verify(isq::capacitance, real_scalar, F, pow<4>(s) * square(A) / (kg * m2)));
static_assert(verify(isq::electric_constant, scalar, F / m, pow<4>(s) * square(A) / (kg * m3))); static_assert(verify(isq::electric_constant, real_scalar, F / m, pow<4>(s) * square(A) / (kg * m3)));
static_assert(verify(isq::permittivity_of_vacuum, scalar, F / m, pow<4>(s) * square(A) / (kg * m3))); static_assert(verify(isq::permittivity_of_vacuum, real_scalar, F / m, pow<4>(s) * square(A) / (kg * m3)));
static_assert(verify(isq::permittivity, scalar, F / m, pow<4>(s) * square(A) / (kg * m3))); static_assert(verify(isq::permittivity, real_scalar, F / m, pow<4>(s) * square(A) / (kg * m3)));
static_assert(verify(isq::relative_permittivity, scalar, one)); static_assert(verify(isq::relative_permittivity, real_scalar, one));
static_assert(verify(isq::electric_susceptibility, scalar, one)); static_assert(verify(isq::electric_susceptibility, real_scalar, one));
static_assert(verify(isq::electric_flux, scalar, C, s* A)); static_assert(verify(isq::electric_flux, real_scalar, C, s* A));
static_assert(verify(isq::displacement_current_density, vector, A / m2)); static_assert(verify(isq::displacement_current_density, vector, A / m2));
static_assert(verify(isq::displacement_current, scalar, A)); static_assert(verify(isq::displacement_current, real_scalar, A));
static_assert(verify(isq::total_current, scalar, A)); static_assert(verify(isq::total_current, real_scalar, A));
static_assert(verify(isq::total_current_density, vector, A / m2)); static_assert(verify(isq::total_current_density, vector, A / m2));
static_assert(verify(isq::magnetic_flux_density, vector, T, kg / (s2 * A))); static_assert(verify(isq::magnetic_flux_density, vector, T, kg / (s2 * A)));
static_assert(verify(isq::magnetic_flux, scalar, Wb, kg* m2 / (s2 * A))); static_assert(verify(isq::magnetic_flux, real_scalar, Wb, kg* m2 / (s2 * A)));
static_assert(verify(isq::protoflux, scalar, Wb, kg* m2 / (s2 * A))); static_assert(verify(isq::protoflux, real_scalar, Wb, kg* m2 / (s2 * A)));
static_assert(verify(isq::linked_magnetic_flux, scalar, Wb, kg* m2 / (s2 * A))); static_assert(verify(isq::linked_magnetic_flux, real_scalar, Wb, kg* m2 / (s2 * A)));
static_assert(verify(isq::total_magnetic_flux, scalar, Wb, kg* m2 / (s2 * A))); static_assert(verify(isq::total_magnetic_flux, real_scalar, Wb, kg* m2 / (s2 * A)));
static_assert(verify(isq::magnetic_moment, vector, A* m2)); static_assert(verify(isq::magnetic_moment, vector, A* m2));
static_assert(verify(isq::magnetic_area_moment, vector, A* m2)); static_assert(verify(isq::magnetic_area_moment, vector, A* m2));
static_assert(verify(isq::magnetization, vector, A / m)); static_assert(verify(isq::magnetization, vector, A / m));
static_assert(verify(isq::magnetic_field_strength, vector, A / m)); static_assert(verify(isq::magnetic_field_strength, vector, A / m));
static_assert(verify(isq::magnetizing_field, vector, A / m)); static_assert(verify(isq::magnetizing_field, vector, A / m));
static_assert(verify(isq::magnetic_constant, scalar, H / m, kg* m / (s2 * square(A)))); static_assert(verify(isq::magnetic_constant, real_scalar, H / m, kg* m / (s2 * square(A))));
static_assert(verify(isq::permeability_of_vacuum, scalar, H / m, kg* m / (s2 * square(A)))); static_assert(verify(isq::permeability_of_vacuum, real_scalar, H / m, kg* m / (s2 * square(A))));
static_assert(verify(isq::permeability, scalar, H / m, kg* m / (s2 * square(A)))); static_assert(verify(isq::permeability, real_scalar, H / m, kg* m / (s2 * square(A))));
static_assert(verify(isq::relative_permeability, scalar, one)); static_assert(verify(isq::relative_permeability, real_scalar, one));
static_assert(verify(isq::magnetic_susceptibility, scalar, one)); static_assert(verify(isq::magnetic_susceptibility, real_scalar, one));
static_assert(verify(isq::magnetic_polarization, vector, T, Wb / m2, kg / (s2 * A))); static_assert(verify(isq::magnetic_polarization, vector, T, Wb / m2, kg / (s2 * A)));
static_assert(verify(isq::magnetic_dipole_moment, vector, Wb* m, kg* m3 / (s2 * A))); static_assert(verify(isq::magnetic_dipole_moment, vector, Wb* m, kg* m3 / (s2 * A)));
static_assert(verify(isq::coercivity, scalar, A / m)); static_assert(verify(isq::coercivity, real_scalar, A / m));
static_assert(verify(isq::coercive_field_strength, scalar, A / m)); static_assert(verify(isq::coercive_field_strength, real_scalar, A / m));
static_assert(verify(isq::magnetic_vector_potential, vector, J / (A * m), kg* m / (s2 * A))); static_assert(verify(isq::magnetic_vector_potential, vector, J / (A * m), kg* m / (s2 * A)));
static_assert(verify(isq::electromagnetic_energy_density, scalar, J / m3, kg / (m * s2))); static_assert(verify(isq::electromagnetic_energy_density, real_scalar, J / m3, kg / (m * s2)));
static_assert(verify(isq::Poynting_vector, vector, W / m2, kg / s3)); static_assert(verify(isq::Poynting_vector, vector, W / m2, kg / s3));
static_assert(verify(isq::phase_speed_of_electromagnetic_waves, scalar, m / s)); static_assert(verify(isq::phase_speed_of_electromagnetic_waves, real_scalar, m / s));
static_assert(verify(isq::speed_of_light_in_vacuum, scalar, m / s)); static_assert(verify(isq::speed_of_light_in_vacuum, real_scalar, m / s));
static_assert(verify(isq::light_speed_in_vacuum, scalar, m / s)); static_assert(verify(isq::light_speed_in_vacuum, real_scalar, m / s));
static_assert(verify(isq::luminal_speed, scalar, m / s)); static_assert(verify(isq::luminal_speed, real_scalar, m / s));
static_assert(verify(isq::source_voltage, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::source_voltage, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::source_tension, scalar, V, kg* m2 / (s3 * A))); static_assert(verify(isq::source_tension, real_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::magnetic_potential, scalar, A)); static_assert(verify(isq::magnetic_potential, real_scalar, A));
static_assert(verify(isq::magnetic_tension, scalar, A)); static_assert(verify(isq::magnetic_tension, real_scalar, A));
static_assert(verify(isq::magnetomotive_force, scalar, A)); static_assert(verify(isq::magnetomotive_force, real_scalar, A));
static_assert(verify(isq::number_of_turns_in_a_winding, scalar, one)); static_assert(verify(isq::number_of_turns_in_a_winding, real_scalar, one));
static_assert(verify(isq::reluctance, scalar, one / H, s2* square(A) / (kg * m2))); static_assert(verify(isq::reluctance, real_scalar, one / H, s2* square(A) / (kg * m2)));
static_assert(verify(isq::permeance, scalar, H, kg* m2 / (s2 * square(A)))); static_assert(verify(isq::permeance, real_scalar, H, kg* m2 / (s2 * square(A))));
static_assert(verify(isq::inductance, scalar, H, kg* m2 / (s2 * square(A)))); static_assert(verify(isq::inductance, real_scalar, H, kg* m2 / (s2 * square(A))));
static_assert(verify(isq::self_inductance, scalar, H, kg* m2 / (s2 * square(A)))); static_assert(verify(isq::self_inductance, real_scalar, H, kg* m2 / (s2 * square(A))));
static_assert(verify(isq::mutual_inductance, scalar, H, kg* m2 / (s2 * square(A)))); static_assert(verify(isq::mutual_inductance, real_scalar, H, kg* m2 / (s2 * square(A))));
static_assert(verify(isq::coupling_factor, scalar, one)); static_assert(verify(isq::coupling_factor, real_scalar, one));
static_assert(verify(isq::leakage_factor, scalar, one)); static_assert(verify(isq::leakage_factor, real_scalar, one));
static_assert(verify(isq::conductivity, scalar, S / m, s3* square(A) / (kg * m3))); static_assert(verify(isq::conductivity, real_scalar, S / m, s3* square(A) / (kg * m3)));
static_assert(verify(isq::resistivity, scalar, Ω* m, kg* m3 / (s3 * square(A)))); static_assert(verify(isq::resistivity, real_scalar, Ω* m, kg* m3 / (s3 * square(A))));
static_assert(verify(isq::electromagnetism_power, scalar, W, kg* m2 / s3)); static_assert(verify(isq::electromagnetism_power, real_scalar, W, kg* m2 / s3));
static_assert(verify(isq::instantaneous_power, scalar, W, kg* m2 / s3)); static_assert(verify(isq::instantaneous_power, real_scalar, W, kg* m2 / s3));
static_assert(verify(isq::resistance, scalar, Ω, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::resistance, real_scalar, Ω, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::conductance, scalar, S, s3* square(A) / (kg * m2))); static_assert(verify(isq::conductance, real_scalar, S, s3* square(A) / (kg * m2)));
static_assert(verify(isq::phase_difference, scalar, rad, one)); static_assert(verify(isq::phase_difference, real_scalar, rad, one));
static_assert(verify(isq::electric_current_phasor, complex, A)); static_assert(verify(isq::electric_current_phasor, complex_scalar, A));
static_assert(verify(isq::voltage_phasor, complex, V, kg* m2 / (s3 * A))); static_assert(verify(isq::voltage_phasor, complex_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::electric_tension_phasor, complex, V, kg* m2 / (s3 * A))); static_assert(verify(isq::electric_tension_phasor, complex_scalar, V, kg* m2 / (s3 * A)));
static_assert(verify(isq::impedance, scalar, Ω, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::impedance, complex_scalar, Ω, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::complex_impedance, scalar, Ω, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::complex_impedance, complex_scalar, Ω, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::impedance_of_vacuum, scalar, V / A, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::impedance_of_vacuum, complex_scalar, V / A, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::wave_impedance_in_vacuum, scalar, V / A, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::wave_impedance_in_vacuum, complex_scalar, V / A, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::resistance_to_alternating_current, scalar, Ω, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::resistance_to_alternating_current, real_scalar, Ω, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::reactance, scalar, Ω, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::reactance, real_scalar, Ω, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::apparent_impedance, scalar, Ω, kg* m2 / (s3 * square(A)))); static_assert(verify(isq::apparent_impedance, real_scalar, Ω, kg* m2 / (s3 * square(A))));
static_assert(verify(isq::admittance, scalar, S, s3* square(A) / (kg * m2))); static_assert(verify(isq::admittance, complex_scalar, S, s3* square(A) / (kg * m2)));
static_assert(verify(isq::complex_admittance, scalar, S, s3* square(A) / (kg * m2))); static_assert(verify(isq::complex_admittance, complex_scalar, S, s3* square(A) / (kg * m2)));
static_assert(verify(isq::admittance_of_vacuum, scalar, A / V, s3* square(A) / (kg * m2))); static_assert(verify(isq::admittance_of_vacuum, complex_scalar, A / V, s3* square(A) / (kg * m2)));
static_assert(verify(isq::conductance_for_alternating_current, scalar, S, s3* square(A) / (kg * m2))); static_assert(verify(isq::conductance_for_alternating_current, real_scalar, S, s3* square(A) / (kg * m2)));
static_assert(verify(isq::susceptance, scalar, S, s3* square(A) / (kg * m2))); static_assert(verify(isq::susceptance, real_scalar, S, s3* square(A) / (kg * m2)));
static_assert(verify(isq::apparent_admittance, scalar, S, s3* square(A) / (kg * m2))); static_assert(verify(isq::apparent_admittance, real_scalar, S, s3* square(A) / (kg * m2)));
static_assert(verify(isq::quality_factor, scalar, one)); static_assert(verify(isq::quality_factor, real_scalar, one));
static_assert(verify(isq::loss_factor, scalar, one)); static_assert(verify(isq::loss_factor, real_scalar, one));
static_assert(verify(isq::loss_angle, scalar, rad, one)); static_assert(verify(isq::loss_angle, real_scalar, rad, one));
static_assert(verify(isq::active_power, scalar, W, kg* m2 / s3)); static_assert(verify(isq::active_power, real_scalar, W, kg* m2 / s3));
static_assert(verify(isq::apparent_power, scalar, V* A, kg* m2 / s3)); static_assert(verify(isq::apparent_power, real_scalar, V* A, kg* m2 / s3));
static_assert(verify(isq::power_factor, scalar, one)); static_assert(verify(isq::power_factor, real_scalar, one));
static_assert(verify(isq::complex_power, complex, V* A, kg* m2 / s3)); static_assert(verify(isq::complex_power, complex_scalar, V* A, kg* m2 / s3));
static_assert(verify(isq::reactive_power, scalar, var, V* A, kg* m2 / s3)); static_assert(verify(isq::reactive_power, real_scalar, var, V* A, kg* m2 / s3));
static_assert(verify(isq::non_active_power, scalar, V* A, kg* m2 / s3)); static_assert(verify(isq::non_active_power, real_scalar, V* A, kg* m2 / s3));
static_assert(verify(isq::active_energy, scalar, J, W* s, kg* m2 / s2)); static_assert(verify(isq::active_energy, real_scalar, J, W* s, kg* m2 / s2));
// light and radiation // light and radiation
static_assert(verify(isq::speed_of_light_in_a_medium, scalar, m / s)); static_assert(verify(isq::speed_of_light_in_a_medium, real_scalar, m / s));
static_assert(verify(isq::refractive_index, scalar, one)); static_assert(verify(isq::refractive_index, real_scalar, one));
static_assert(verify(isq::radiant_energy, scalar, J, kg* m2 / s2)); static_assert(verify(isq::radiant_energy, real_scalar, J, kg* m2 / s2));
static_assert(verify(isq::spectral_radiant_energy, scalar, J / nm, kg* m / s2)); static_assert(verify(isq::spectral_radiant_energy, real_scalar, J / nm, kg* m / s2));
static_assert(verify(isq::radiant_energy_density, scalar, J / m3, kg / m / s2)); static_assert(verify(isq::radiant_energy_density, real_scalar, J / m3, kg / m / s2));
static_assert(verify(isq::spectral_radiant_energy_density_in_terms_of_wavelength, scalar, J / (m3 * nm), kg / m2 / s2)); static_assert(verify(isq::spectral_radiant_energy_density_in_terms_of_wavelength, real_scalar, J / (m3 * nm),
static_assert(verify(isq::spectral_radiant_energy_density_in_terms_of_wavenumber, scalar, J / m2, kg / s2)); kg / m2 / s2));
static_assert(verify(isq::radiant_flux, scalar, W, kg* m2 / s3)); static_assert(verify(isq::spectral_radiant_energy_density_in_terms_of_wavenumber, real_scalar, J / m2, kg / s2));
static_assert(verify(isq::radiant_power, scalar, W, kg* m2 / s3)); static_assert(verify(isq::radiant_flux, real_scalar, W, kg* m2 / s3));
static_assert(verify(isq::spectral_radiant_flux, scalar, W / nm, kg* m / s3)); static_assert(verify(isq::radiant_power, real_scalar, W, kg* m2 / s3));
static_assert(verify(isq::spectral_radiant_power, scalar, W / nm, kg* m / s3)); static_assert(verify(isq::spectral_radiant_flux, real_scalar, W / nm, kg* m / s3));
static_assert(verify(isq::radiant_intensity, scalar, W / sr, kg* m2 / s3 / sr)); static_assert(verify(isq::spectral_radiant_power, real_scalar, W / nm, kg* m / s3));
static_assert(verify(isq::spectral_radiant_intensity, scalar, W / (sr * nm), kg* m / s3 / sr)); static_assert(verify(isq::radiant_intensity, real_scalar, W / sr, kg* m2 / s3 / sr));
static_assert(verify(isq::radiance, scalar, W / (sr * m2), kg / s3 / sr)); static_assert(verify(isq::spectral_radiant_intensity, real_scalar, W / (sr * nm), kg* m / s3 / sr));
static_assert(verify(isq::spectral_radiance, scalar, W / (sr * m2 * nm), kg / m / s3 / sr)); static_assert(verify(isq::radiance, real_scalar, W / (sr * m2), kg / s3 / sr));
static_assert(verify(isq::irradiance, scalar, W / m2, kg / s3)); static_assert(verify(isq::spectral_radiance, real_scalar, W / (sr * m2 * nm), kg / m / s3 / sr));
static_assert(verify(isq::spectral_irradiance, scalar, W / (m2 * nm), kg / m / s3)); static_assert(verify(isq::irradiance, real_scalar, W / m2, kg / s3));
static_assert(verify(isq::radiant_exitance, scalar, W / m2, kg / s3)); static_assert(verify(isq::spectral_irradiance, real_scalar, W / (m2 * nm), kg / m / s3));
static_assert(verify(isq::spectral_radiant_exitance, scalar, W / (m2 * nm), kg / m / s3)); static_assert(verify(isq::radiant_exitance, real_scalar, W / m2, kg / s3));
static_assert(verify(isq::radiant_exposure, scalar, J / m2, kg / s2)); static_assert(verify(isq::spectral_radiant_exitance, real_scalar, W / (m2 * nm), kg / m / s3));
static_assert(verify(isq::spectral_radiant_exposure, scalar, J / (m2 * nm), kg / m / s2)); static_assert(verify(isq::radiant_exposure, real_scalar, J / m2, kg / s2));
static_assert(verify(isq::spectral_radiant_exposure, real_scalar, J / (m2 * nm), kg / m / s2));
// atomic and nuclear physics // atomic and nuclear physics
static_assert(verify(isq::activity, scalar, Bq, one / s)); static_assert(verify(isq::activity, real_scalar, Bq, one / s));
static_assert(verify(isq::absorbed_dose, scalar, Gy, J / kg, m2 / s2)); static_assert(verify(isq::absorbed_dose, real_scalar, Gy, J / kg, m2 / s2));
static_assert(verify(isq::quality_factor, scalar, one)); static_assert(verify(isq::quality_factor, real_scalar, one));
static_assert(verify(isq::dose_equivalent, scalar, Sv, J / kg, m2 / s2)); static_assert(verify(isq::dose_equivalent, real_scalar, Sv, J / kg, m2 / s2));
// information science and technology // information science and technology
static_assert(verify(isq::traffic_intensity, scalar, E)); static_assert(verify(isq::traffic_intensity, real_scalar, E));
static_assert(verify(isq::traffic_offered_intensity, scalar, E)); static_assert(verify(isq::traffic_offered_intensity, real_scalar, E));
static_assert(verify(isq::traffic_carried_intensity, scalar, E)); static_assert(verify(isq::traffic_carried_intensity, real_scalar, E));
static_assert(verify(isq::traffic_load, scalar, E)); static_assert(verify(isq::traffic_load, real_scalar, E));
static_assert(verify(isq::mean_queue_length, scalar, one)); static_assert(verify(isq::mean_queue_length, real_scalar, one));
static_assert(verify(isq::loss_probability, scalar, one)); static_assert(verify(isq::loss_probability, real_scalar, one));
static_assert(verify(isq::waiting_probability, scalar, one)); static_assert(verify(isq::waiting_probability, real_scalar, one));
static_assert(verify(isq::call_intensity, scalar, one / s)); static_assert(verify(isq::call_intensity, real_scalar, one / s));
static_assert(verify(isq::calling_rate, scalar, one / s)); static_assert(verify(isq::calling_rate, real_scalar, one / s));
static_assert(verify(isq::completed_call_intensity, scalar, one / s)); static_assert(verify(isq::completed_call_intensity, real_scalar, one / s));
static_assert(verify(isq::storage_capacity, scalar, one, bit, o, B)); static_assert(verify(isq::storage_capacity, real_scalar, one, bit, o, B));
static_assert(verify(isq::storage_size, scalar, one, bit, o, B)); static_assert(verify(isq::storage_size, real_scalar, one, bit, o, B));
static_assert(verify(isq::equivalent_binary_storage_capacity, scalar, one, bit)); static_assert(verify(isq::equivalent_binary_storage_capacity, real_scalar, one, bit));
static_assert(verify(isq::transfer_rate, scalar, one / s, o / s, B / s)); static_assert(verify(isq::transfer_rate, real_scalar, one / s, o / s, B / s));
static_assert(verify(isq::period_of_data_elements, scalar, s)); static_assert(verify(isq::period_of_data_elements, real_scalar, s));
static_assert(verify(isq::binary_digit_rate, scalar, one / s, bit / s)); static_assert(verify(isq::binary_digit_rate, real_scalar, one / s, bit / s));
static_assert(verify(isq::bit_rate, scalar, one / s, bit / s)); static_assert(verify(isq::bit_rate, real_scalar, one / s, bit / s));
static_assert(verify(isq::period_of_binary_digits, scalar, s)); static_assert(verify(isq::period_of_binary_digits, real_scalar, s));
static_assert(verify(isq::bit_period, scalar, s)); static_assert(verify(isq::bit_period, real_scalar, s));
static_assert(verify(isq::equivalent_binary_digit_rate, scalar, one / s, bit / s)); static_assert(verify(isq::equivalent_binary_digit_rate, real_scalar, one / s, bit / s));
static_assert(verify(isq::equivalent_bit_rate, scalar, one / s, bit / s)); static_assert(verify(isq::equivalent_bit_rate, real_scalar, one / s, bit / s));
static_assert(verify(isq::modulation_rate, scalar, one / s, Bd)); static_assert(verify(isq::modulation_rate, real_scalar, one / s, Bd));
static_assert(verify(isq::line_digit_rate, scalar, one / s, Bd)); static_assert(verify(isq::line_digit_rate, real_scalar, one / s, Bd));
static_assert(verify(isq::quantizing_distortion_power, scalar, W)); static_assert(verify(isq::quantizing_distortion_power, real_scalar, W));
static_assert(verify(isq::carrier_power, scalar, W)); static_assert(verify(isq::carrier_power, real_scalar, W));
static_assert(verify(isq::signal_energy_per_binary_digit, scalar, J)); static_assert(verify(isq::signal_energy_per_binary_digit, real_scalar, J));
static_assert(verify(isq::error_probability, scalar, one)); static_assert(verify(isq::error_probability, real_scalar, one));
static_assert(verify(isq::Hamming_distance, scalar, one)); static_assert(verify(isq::Hamming_distance, real_scalar, one));
static_assert(verify(isq::clock_frequency, scalar, Hz)); static_assert(verify(isq::clock_frequency, real_scalar, Hz));
static_assert(verify(isq::clock_rate, scalar, Hz)); static_assert(verify(isq::clock_rate, real_scalar, Hz));
static_assert(verify(isq::decision_content, scalar, one)); static_assert(verify(isq::decision_content, real_scalar, one));
} // namespace } // namespace

View File

@ -86,11 +86,11 @@ QUANTITY_SPEC_(mass_density, mass / volume);
QUANTITY_SPEC_(force, mass * acceleration); QUANTITY_SPEC_(force, mass * acceleration);
QUANTITY_SPEC_(weight, force, mass * acceleration_of_free_fall); QUANTITY_SPEC_(weight, force, mass * acceleration_of_free_fall);
QUANTITY_SPEC_(moment_of_force, position_vector* force); QUANTITY_SPEC_(moment_of_force, position_vector* force);
QUANTITY_SPEC_(torque, moment_of_force, quantity_character::scalar); QUANTITY_SPEC_(torque, moment_of_force, quantity_character::real_scalar);
QUANTITY_SPEC_(pressure, force / area, quantity_character::scalar); QUANTITY_SPEC_(pressure, force / area, quantity_character::real_scalar);
QUANTITY_SPEC_(stress, pressure, quantity_character::tensor); QUANTITY_SPEC_(stress, pressure, quantity_character::tensor);
QUANTITY_SPEC_(strain, dimensionless, quantity_character::tensor); QUANTITY_SPEC_(strain, dimensionless, quantity_character::tensor);
QUANTITY_SPEC_(power, force* velocity, quantity_character::scalar); QUANTITY_SPEC_(power, force* velocity, quantity_character::real_scalar);
QUANTITY_SPEC_(efficiency, power / power); QUANTITY_SPEC_(efficiency, power / power);
QUANTITY_SPEC_(energy, mass * pow<2>(length) / pow<2>(time)); QUANTITY_SPEC_(energy, mass * pow<2>(length) / pow<2>(time));
QUANTITY_SPEC_(mechanical_energy, energy); QUANTITY_SPEC_(mechanical_energy, energy);
@ -100,14 +100,14 @@ QUANTITY_SPEC_(kinetic_energy, mechanical_energy, mass* pow<2>(speed));
QUANTITY_SPEC_(electric_current, dim_electric_current); QUANTITY_SPEC_(electric_current, dim_electric_current);
QUANTITY_SPEC_(electric_charge, electric_current* time); QUANTITY_SPEC_(electric_charge, electric_current* time);
QUANTITY_SPEC_(electric_field_strength, force / electric_charge); // vector QUANTITY_SPEC_(electric_field_strength, force / electric_charge); // vector
QUANTITY_SPEC_(electric_potential, electric_field_strength* length, quantity_character::scalar); QUANTITY_SPEC_(electric_potential, electric_field_strength* length, quantity_character::real_scalar);
QUANTITY_SPEC_(voltage, electric_potential); QUANTITY_SPEC_(voltage, electric_potential);
QUANTITY_SPEC_(electromagnetism_power, power, voltage* electric_current); QUANTITY_SPEC_(electromagnetism_power, power, voltage* electric_current);
QUANTITY_SPEC_(electric_current_phasor, electric_current, quantity_character::complex); QUANTITY_SPEC_(electric_current_phasor, electric_current, quantity_character::complex_scalar);
QUANTITY_SPEC_(voltage_phasor, voltage, quantity_character::complex); QUANTITY_SPEC_(voltage_phasor, voltage, quantity_character::complex_scalar);
QUANTITY_SPEC_(active_power, power, inverse(period_duration) * (electromagnetism_power * time)); QUANTITY_SPEC_(active_power, power, inverse(period_duration) * (electromagnetism_power * time));
QUANTITY_SPEC_(complex_power, voltage_phasor* electric_current_phasor); // separate kind QUANTITY_SPEC_(complex_power, voltage_phasor* electric_current_phasor); // separate kind
QUANTITY_SPEC_(apparent_power, complex_power, quantity_character::scalar); QUANTITY_SPEC_(apparent_power, complex_power, quantity_character::real_scalar);
// clang-format on // clang-format on
@ -1012,12 +1012,6 @@ static_assert(convertible(kind_of<dimensionless / time>, solid_angular_measure_r
static_assert(convertible(kind_of<dimensionless / time>, kind_of<angular_measure_rate>) == yes); static_assert(convertible(kind_of<dimensionless / time>, kind_of<angular_measure_rate>) == yes);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<solid_angular_measure_rate>) == yes); static_assert(convertible(kind_of<dimensionless / time>, kind_of<solid_angular_measure_rate>) == yes);
// quantity character checks
static_assert((displacement / time).character == quantity_character::vector);
static_assert((position_vector / position_vector * time).character == quantity_character::scalar);
static_assert((velocity / acceleration).character == quantity_character::scalar);
// get_common_quantity_spec // get_common_quantity_spec
static_assert(get_common_quantity_spec(length, length) == length); static_assert(get_common_quantity_spec(length, length) == length);
static_assert(get_common_quantity_spec(kind_of<length>, kind_of<length>) == kind_of<length>); static_assert(get_common_quantity_spec(kind_of<length>, kind_of<length>) == kind_of<length>);

View File

@ -30,7 +30,6 @@
#include <mp-units/systems/si.h> #include <mp-units/systems/si.h>
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
#include <mp-units/cartesian_vector.h> #include <mp-units/cartesian_vector.h>
#include <mp-units/complex.h>
#include <mp-units/math.h> #include <mp-units/math.h>
#endif #endif
#ifdef MP_UNITS_IMPORT_STD #ifdef MP_UNITS_IMPORT_STD