xo-unit: docs extension

This commit is contained in:
Roland Conybeare 2024-05-07 21:48:48 -04:00
commit d767675dd9
11 changed files with 130 additions and 39 deletions

View file

@ -5,6 +5,6 @@ xo_docdir_doxygen_config()
xo_docdir_sphinx_config(
index.rst examples.rst glossary.rst install.rst implementation.rst
quantity-reference.rst quantity-class.rst quantity-factoryfunctions.rst quantity-unitvars.rst
unit-reference.rst unit-concept.rst unit-quantities.rst dimension-enum.rst
unit-reference.rst unit-concept.rst unit-quantities.rst basis-unit-class.rst dimension-enum.rst
)
#xo_utest_coverage_config2()

39
docs/basis-unit-class.rst Normal file
View file

@ -0,0 +1,39 @@
.. _basis-unit-class:
Basis Unit
==========
.. code-block:: cpp
#include <xo/unit/basis_unit.hpp>
A :code:`basis_unit` represents a unit belonging to a single native dimension.
For example :code:`bu::meter` representing a distance of 1 meter.
.. doxygenclass:: xo::qty::basis_unit
Constants
---------
.. doxygengroup:: basis-unit-mass-units
.. doxygengroup:: basis-unit-distance-units
Member Variables
----------------
.. doxygengroup:: basis-unit-instance-vars
Constructors
------------
.. doxygengroup:: basis-unit-constructors
Access Methods
--------------
.. doxygengroup:: basis-unit-access-methods
Comparison
----------
.. doxygengroup:: basis-unit-comparison-support

View file

@ -47,12 +47,15 @@ Abstraction tower for *xo-unit* components.
(for example consider :code:`xo::qty::qty::foot * xo::qty::qty::meter`)
- bpu:
a power of a basis unit. Has a single dimension.
- basis_unit:
a unit with a single dimension and scale.
A power of a basis unit. Has a single dimension.
- basis_unit: see :doc:`basis-unit-class`.
A unit with a single dimension and scale.
- dimension: see :doc:`dimension-enum`.
identifies a dimension, such as mass or time.
Representation

View file

@ -36,6 +36,7 @@ runtime (since we can't construct new c++ types at runtime).
unit-quantities
quantity-reference
unit-reference
basis-unit-class
dimension-enum
Indices and Tables

View file

@ -17,6 +17,12 @@ Type Traits
.. doxygengroup:: quantity-type-traits
Member Variables
----------------
.. doxygengroup:: quantity-static-vars
.. doxygengroup:: quantity-instance-vars
Constructors
------------
@ -61,13 +67,11 @@ Arithmetic
Support methods for arithmetic operations
.. doxygengroup:: quantity-arithmeticsupport
:content-only:
.. doxygengroup:: quantity-arithmetic-support
Comparison
----------
Support methods for comparison operators
.. doxygengroup:: quantity-comparisonsupport
:content-only:
.. doxygengroup:: quantity-comparison-support

View file

@ -8,37 +8,46 @@
namespace xo {
namespace qty {
/** @class basis_unit2
/** @class basis_unit
* @brief A dimensionless multiple of a single natively-specified basis dimension
*
* For example "3600 minutes" or "1e-6 grams"
**/
struct basis_unit {
public:
/** @defgroup basis-unit-constructors basis_unit constructors **/
///@{
constexpr basis_unit() = default;
constexpr basis_unit(dimension native_dim,
const scalefactor_ratio_type & scalefactor)
: native_dim_{native_dim},
scalefactor_{scalefactor}
{}
///@}
/** @defgroup basis-unit-access-methods basis_unit access methods **/
///@{
constexpr dimension native_dim() const { return native_dim_; }
constexpr const scalefactor_ratio_type & scalefactor() const { return scalefactor_; }
///@}
constexpr basis_unit2_abbrev_type abbrev() const {
return abbrev::basis_unit2_abbrev(native_dim_,
scalefactor_);
}
constexpr basis_unit & operator=(const basis_unit & x) = default;
public: /* need public members so that a basis_unit instance can be a non-type template parameter (a structural type) */
/** @defgroup basis-unit-instance-vars **/
///@{
/** @brief identifies a native unit, e.g. time (in seconds) **/
dimension native_dim_ = dimension::invalid;
/** @brief this unit defined as multiple scalefactor times native unit **/
scalefactor_ratio_type scalefactor_;
///@}
};
/** @defgroup basis-unit-comparison-support basis_unit comparisons **/
///@{
inline constexpr bool
operator==(const basis_unit & x, const basis_unit & y)
{
@ -52,10 +61,13 @@ namespace xo {
return ((x.native_dim_ != y.native_dim_)
|| (x.scalefactor_ != y.scalefactor_));
}
///@}
namespace bu {
// ----- mass -----
/** @defgroup basis-unit-mass-units **/
///@{
constexpr basis_unit picogram = basis_unit(dim::mass, scalefactor_ratio_type( 1, 1000000000000));
constexpr basis_unit nanogram = basis_unit(dim::mass, scalefactor_ratio_type( 1, 1000000000));
constexpr basis_unit microgram = basis_unit(dim::mass, scalefactor_ratio_type( 1, 1000000));
@ -66,9 +78,12 @@ namespace xo {
constexpr basis_unit kilotonne = basis_unit(dim::mass, scalefactor_ratio_type( 1000000000, 1));
constexpr basis_unit megatonne = basis_unit(dim::mass, scalefactor_ratio_type( 1000000000000, 1));
constexpr basis_unit gigatonne = basis_unit(dim::mass, scalefactor_ratio_type(1000000000000000, 1));
///@}
// ----- distance -----
/** @defgroup basis-unit-distance-units **/
///@{
/* International spelling */
constexpr basis_unit picometre = basis_unit(dim::distance, scalefactor_ratio_type( 1, 1000000000000));
constexpr basis_unit nanometre = basis_unit(dim::distance, scalefactor_ratio_type( 1, 1000000000));
@ -100,9 +115,12 @@ namespace xo {
constexpr basis_unit yard = basis_unit(dim::distance, scalefactor_ratio_type( 3*3048, 10000));
/** @brief basis-unit representing 1 mile; defined as exactly 1760 yards = 5280 feet **/
constexpr basis_unit mile = basis_unit(dim::distance, scalefactor_ratio_type( 5280*3048, 10000));
///@}
// ----- time -----
/** @defgroup basis-unit-time-units **/
///@{
constexpr basis_unit picosecond = basis_unit(dim::time, scalefactor_ratio_type( 1, 1000000000000));
constexpr basis_unit nanosecond = basis_unit(dim::time, scalefactor_ratio_type( 1, 1000000000));
constexpr basis_unit microsecond = basis_unit(dim::time, scalefactor_ratio_type( 1, 1000000));
@ -120,9 +138,13 @@ namespace xo {
constexpr basis_unit year360 = basis_unit(dim::time, scalefactor_ratio_type( 360*24*3600, 1));
/* 250 = approx number of trading days in a calendar year */
constexpr basis_unit year250 = basis_unit(dim::time, scalefactor_ratio_type( 250*24*3600, 1));
///@}
// ----- currency -----
/** @defgroup basis-unit-misc-units **/
///@{
/* pseudounit -- placeholder for any actual currency amount */
constexpr basis_unit currency = basis_unit(dim::currency, scalefactor_ratio_type( 1, 1));
@ -130,6 +152,7 @@ namespace xo {
/* psuedounit -- context-dependent interpretation */
constexpr basis_unit price = basis_unit(dim::price, scalefactor_ratio_type( 1, 1));
///@}
}
namespace units {
@ -145,10 +168,7 @@ namespace xo {
// ----- scaled_native_unit_abbrev_helper -----
/* Require: InnerScale is ratio type; InnerScale >= 1
*
* NOTE: clang 18 doesn't accept that scalefactor_ratio_type is a 'structural type'
*/
/* Require: InnerScale is ratio type; InnerScale >= 1 */
template <dim BasisDim, std::int64_t InnerScaleNum = 1, std::int64_t InnerScaleDen = 1>
struct scaled_native_unit2_abbrev;

View file

@ -5,9 +5,7 @@
#pragma once
//#include "xo/indentlog/print/tag.hpp"
#include "basis_unit.hpp"
//#include "dim_iostream.hpp"
namespace xo {
namespace qty {
@ -50,15 +48,12 @@ namespace xo {
}
}
/** @class native_bpu2
/** @class bpu
*
* @brief represent product of a compile-time scale-factor with a rational power of a native unit
*
* Example:
* native_bpu<universal::time, ratio<1>, ratio<-1,2>> represents unit of 1/sqrt(t)
**/
template<typename Int>
struct bpu : basis_unit {
struct bpu {
public:
using ratio_int_type = Int;
@ -66,13 +61,13 @@ namespace xo {
constexpr bpu() = default;
constexpr bpu(const basis_unit & bu,
const power_ratio_type & power)
: basis_unit{bu},
: bu_{bu},
power_{power}
{}
constexpr bpu(dim native_dim,
const scalefactor_ratio_type & scalefactor,
const power_ratio_type & power)
: basis_unit(native_dim, scalefactor),
: bu_(native_dim, scalefactor),
power_{power}
{}
@ -80,6 +75,8 @@ namespace xo {
return bpu<Int>(bu, power_ratio_type(1,1));
}
constexpr dimension native_dim() const { return bu_.native_dim(); }
constexpr const scalefactor_ratio_type & scalefactor() const { return bu_.scalefactor(); }
constexpr const power_ratio_type & power() const { return power_; }
/** @brief abbreviation for this dimension
@ -92,14 +89,14 @@ namespace xo {
**/
constexpr bpu_abbrev_type abbrev() const
{
return abbrev::bpu_abbrev(native_dim_,
scalefactor_,
power_);
return abbrev::bpu_abbrev(bu_.native_dim_,
bu_.scalefactor_,
power_);
}
/* for bpu x, x.reciprocal() represents dimension of 1/x */
constexpr bpu<Int> reciprocal() const {
return bpu<Int>(native_dim(), scalefactor(), power_.negate());
return bpu<Int>(bu_.native_dim(), bu_.scalefactor(), power_.negate());
}
template <typename Int2>
@ -110,6 +107,8 @@ namespace xo {
}
public: /* need public members so that a basis_unit instance can be a non-type template parameter (a structural type) */
/** @brief this bpu represent a power of this basis unit **/
basis_unit bu_;
/** @brief this unit represents basis dimension (bu) taken to this power **/
power_ratio_type power_;
};
@ -122,16 +121,16 @@ namespace xo {
template <typename Int>
inline constexpr bool
operator==(const bpu<Int> & x, const bpu<Int> & y) {
return ((x.native_dim_ == y.native_dim_)
&& (x.scalefactor_ == y.scalefactor_)
return ((x.native_dim() == y.native_dim())
&& (x.scalefactor() == y.scalefactor())
&& (x.power_ == y.power_));
}
template <typename Int>
inline constexpr bool
operator!=(const bpu<Int> & x, const bpu<Int> & y) {
return ((x.native_dim_ != y.native_dim_)
|| (x.scalefactor_ != y.scalefactor_)
return ((x.native_dim() != y.native_dim())
|| (x.scalefactor() != y.scalefactor())
|| (x.power_ != y.power_));
}

View file

@ -5,7 +5,7 @@
namespace xo {
namespace unit {
/** @class basis_unit
/** @class mpl_basis_unit
*
* @brief A dimensionless multiple with natively-specified (i.e. at compile-time) dimension
**/

View file

@ -495,7 +495,7 @@ namespace xo {
}
/** @addtogroup quantity-unit-conversion **/
/** @addtogroup mpl-quantity-unit-conversion **/
///@{
/** @brief convert to quantity with same dimension, different {unit_type, repr_type}
*
@ -513,7 +513,7 @@ namespace xo {
}
///@}
/** @defgroup quantity-print-support **/
/** @defgroup mpl-quantity-print-support **/
///@{
/** @brief write printed representation on stream
*
@ -524,7 +524,7 @@ namespace xo {
}
///@}
/** @defgroup quantity-assignment **/
/** @defgroup mpl-quantity-assignment **/
///@{
/** @brief copy constructor **/
quantity & operator=(quantity const & x) = default;

View file

@ -84,11 +84,14 @@ namespace xo {
// unit_qty
// zero_qty
/** @defgroup quantity-arithmetic-support **/
///@{
constexpr
auto reciprocal() const {
return quantity<s_scaled_unit.reciprocal(),
repr_type>(1.0 / scale_);
}
///@}
template <typename Repr2>
constexpr
@ -96,6 +99,8 @@ namespace xo {
return quantity<s_scaled_unit, Repr2>(scale_);
}
/** @defgroup quantity-unit-conversion **/
///@{
/* parallel implementation to Quantity<Repr, Int>::rescale(),
* except that NaturalUnit2 is a compile-time-only template-argument
*
@ -149,6 +154,7 @@ namespace xo {
return quantity<ScaledUnit2, Repr>(std::numeric_limits<repr_type>::quiet_NaN());
}
}
///@}
template <typename Dimensionless>
requires std::is_arithmetic_v<Dimensionless>
@ -165,6 +171,8 @@ namespace xo {
// add
// subtract
/** @defgroup quantity-comparison-support **/
///@{
/* parallel implementation to Quantity<Repr, Int> */
template <typename Quantity2>
static constexpr
@ -173,6 +181,7 @@ namespace xo {
return x.scale() <=> y2.scale();
}
///@}
// operator-
// operator+=
@ -184,11 +193,15 @@ namespace xo {
return s_scaled_unit.natural_unit_.abbrev();
}
/** @defgroup quantity-assignment quantity assignment operators **/
///@{
/** @brief assignment from quantity with identical units **/
quantity & operator=(const quantity & x) {
this->scale_ = x.scale_;
return *this;
}
/** @brief assignment from quantity with compatible units **/
template <typename Q2>
requires(quantity_concept<Q2>
&& Q2::always_constexpr_unit)
@ -199,13 +212,17 @@ namespace xo {
return *this;
}
///@}
/** @defgroup quantity-unit-conversion **/
///@{
template <typename Q2>
requires(quantity_concept<Q2>
&& Q2::always_constexpr_unit)
constexpr operator Q2() const {
return this->template rescale_ext<Q2::s_scaled_unit>().template with_repr<typename Q2::repr_type>();
}
///@}
constexpr operator Repr() const
requires (ScaledUnit.is_dimensionless())
@ -213,10 +230,18 @@ namespace xo {
return scale_;
}
public: /* need public members so that a quantity instance can be a non-type template parameter (is a structural type) */
public: /* need public members so that instance can be a non-type template parameter (is a structural type) */
/** @defgroup quantity-static-vars **/
///@{
/** @brief unit for quantity of this type. Determined at compile-time **/
static constexpr scaled_unit<ratio_int_type> s_scaled_unit = ScaledUnit;
///@}
/** @defgroup quantity-instance-vars **/
///@{
/** @brief quantity represents this multiple of @ref s_scaled_unit **/
Repr scale_ = Repr{};
///@}
};
template <typename Quantity, typename Int, typename Int2x>

View file

@ -38,8 +38,8 @@ namespace xo {
{
constexpr natural_unit<int64_t> v
= (nu_maker<int64_t>::make_nu
(bpu<int64_t>(dim::distance, scalefactor_ratio_type(1, 1000), power_ratio_type(2, 1)),
bpu<int64_t>(dim::mass, scalefactor_ratio_type(1, 1000), power_ratio_type(-1, 1))));
(bpu<int64_t>(dim::distance, scalefactor_ratio_type(1, 1000), power_ratio_type(2, 1)) /*mm^2*/,
bpu<int64_t>(dim::mass, scalefactor_ratio_type(1, 1000), power_ratio_type(-1, 1)) /*mg^-1*/));
static_assert(v.n_bpu() == 2);