diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 3b732935..ff7096ee 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -5,6 +5,8 @@ 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 basis-unit-class.rst dimension-enum.rst + unit-reference.rst unit-concept.rst unit-quantities.rst basis-unit-reference.rst + basis-unit-class.rst basis-unit-constants.rst + dimension-enum.rst ) #xo_utest_coverage_config2() diff --git a/docs/basis-unit-class.rst b/docs/basis-unit-class.rst index 9907f260..cd0a03a9 100644 --- a/docs/basis-unit-class.rst +++ b/docs/basis-unit-class.rst @@ -10,14 +10,11 @@ Basis Unit A :code:`basis_unit` represents a unit belonging to a single native dimension. For example :code:`bu::meter` representing a distance of 1 meter. +Class +----- + .. doxygenclass:: xo::qty::basis_unit -Constants ---------- - -.. doxygengroup:: basis-unit-mass-units -.. doxygengroup:: basis-unit-distance-units - Member Variables ---------------- diff --git a/docs/basis-unit-constants.rst b/docs/basis-unit-constants.rst new file mode 100644 index 00000000..279be732 --- /dev/null +++ b/docs/basis-unit-constants.rst @@ -0,0 +1,34 @@ +.. _basis-unit-constants: + +Basis Unit Constants +==================== + +These constants represent low-level building blocks. +Relative scalefactors for each unit are chosen here. + +Application code will not use this class directly; +instead it's expected to use units from the :code:`xo::qty::u` namespace. +Those units are implemented on top of the basis units described here. + +.. code-block:: cpp + + #include + + using xo::qty::detail::bu; + +Mass Units +---------- + +.. doxygenfunction:: xo::qty::abbrev::mass_unit2_abbrev + +.. doxygengroup:: basis-unit-mass-units + +Distance Units +-------------- + +.. doxygengroup:: basis-unit-distance-units + +Time Units +---------- + +.. doxygengroup:: basis-unit-time-units diff --git a/docs/basis-unit-reference.rst b/docs/basis-unit-reference.rst new file mode 100644 index 00000000..d5adcec9 --- /dev/null +++ b/docs/basis-unit-reference.rst @@ -0,0 +1,11 @@ +.. _basis-unit-reference: + +Basis Unit Reference +==================== + +.. toctree:: + :maxdepth: 2 + :caption: Basis-Unit Reference + + basis-unit-class + basis-unit-constants diff --git a/docs/implementation.rst b/docs/implementation.rst index 1705a3e6..46952feb 100644 --- a/docs/implementation.rst +++ b/docs/implementation.rst @@ -50,7 +50,7 @@ Abstraction tower for *xo-unit* components. A power of a basis unit. Has a single dimension. -- basis_unit: see :doc:`basis-unit-class`. +- basis_unit: see :doc:`basis-unit-reference`. A unit with a single dimension and scale. diff --git a/docs/index.rst b/docs/index.rst index ff73eae7..ad724f8d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -36,7 +36,7 @@ runtime (since we can't construct new c++ types at runtime). unit-quantities quantity-reference unit-reference - basis-unit-class + basis-unit-reference dimension-enum Indices and Tables diff --git a/include/xo/unit/basis_unit.hpp b/include/xo/unit/basis_unit.hpp index 68f32781..dabe91cb 100644 --- a/include/xo/unit/basis_unit.hpp +++ b/include/xo/unit/basis_unit.hpp @@ -63,97 +63,115 @@ namespace xo { } ///@} - namespace bu { - // ----- mass ----- + namespace detail { + 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)); - constexpr basis_unit milligram = basis_unit(dim::mass, scalefactor_ratio_type( 1, 1000)); - constexpr basis_unit gram = basis_unit(dim::mass, scalefactor_ratio_type( 1, 1)); - constexpr basis_unit kilogram = basis_unit(dim::mass, scalefactor_ratio_type( 1000, 1)); - constexpr basis_unit tonne = basis_unit(dim::mass, scalefactor_ratio_type( 1000000, 1)); - 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)); - ///@} + constexpr basis_unit mass_unit(std::int64_t num, std::int64_t den) { + return basis_unit(dimension::mass, scalefactor_ratio_type(num, den)); + } - // ----- distance ----- + /** @defgroup basis-unit-mass-units **/ + ///@{ + constexpr basis_unit picogram = mass_unit( 1, 1000000000000); + constexpr basis_unit nanogram = mass_unit( 1, 1000000000); + constexpr basis_unit microgram = mass_unit( 1, 1000000); + constexpr basis_unit milligram = mass_unit( 1, 1000); + constexpr basis_unit gram = mass_unit( 1, 1); + constexpr basis_unit kilogram = mass_unit( 1000, 1); + constexpr basis_unit tonne = mass_unit( 1000000, 1); + constexpr basis_unit kilotonne = mass_unit( 1000000000, 1); + constexpr basis_unit megatonne = mass_unit( 1000000000000, 1); + constexpr basis_unit gigatonne = mass_unit(1000000000000000, 1); + ///@} - /** @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)); - constexpr basis_unit micrometre = basis_unit(dim::distance, scalefactor_ratio_type( 1, 1000000)); - constexpr basis_unit millimetre = basis_unit(dim::distance, scalefactor_ratio_type( 1, 1000)); - constexpr basis_unit metre = basis_unit(dim::distance, scalefactor_ratio_type( 1, 1)); - constexpr basis_unit kilometre = basis_unit(dim::distance, scalefactor_ratio_type( 1000, 1)); - constexpr basis_unit megametre = basis_unit(dim::distance, scalefactor_ratio_type( 1000000, 1)); - constexpr basis_unit gigametre = basis_unit(dim::distance, scalefactor_ratio_type( 1000000000, 1)); + // ----- distance ----- - constexpr basis_unit lightsecond = basis_unit(dim::distance, scalefactor_ratio_type( 299792458, 1)); - constexpr basis_unit astronomicalunit = basis_unit(dim::distance, scalefactor_ratio_type( 149597870700, 1)); + constexpr basis_unit distance_unit(std::int64_t num, std::int64_t den) { + return basis_unit(dimension::distance, scalefactor_ratio_type(num, den)); + } - /* US spelling */ - constexpr basis_unit picometer = picometre; - constexpr basis_unit nanometer = nanometre; - constexpr basis_unit micrometer = micrometre; - constexpr basis_unit millimeter = millimetre; - constexpr basis_unit meter = metre; - constexpr basis_unit kilometer = kilometre; - constexpr basis_unit megameter = megametre; - constexpr basis_unit gigameter = gigametre; + /** @defgroup basis-unit-distance-units **/ + ///@{ + /* International spelling */ + constexpr basis_unit picometre = distance_unit( 1, 1000000000000); + constexpr basis_unit nanometre = distance_unit( 1, 1000000000); + constexpr basis_unit micrometre = distance_unit( 1, 1000000); + constexpr basis_unit millimetre = distance_unit( 1, 1000); + constexpr basis_unit metre = distance_unit( 1, 1); + constexpr basis_unit kilometre = distance_unit( 1000, 1); + constexpr basis_unit megametre = distance_unit( 1000000, 1); + constexpr basis_unit gigametre = distance_unit( 1000000000, 1); - /** @brief basis-unit representing 1 inch; defined as exactly 1/12 feet **/ - constexpr basis_unit inch = basis_unit(dim::distance, scalefactor_ratio_type( 3048, 120000)); - /** @brief basis-unit representing 1 foot; defined as exactly 0.3048 meters **/ - constexpr basis_unit foot = basis_unit(dim::distance, scalefactor_ratio_type( 3048, 10000)); - /** @brief basis-unit representing 1 yard; defined as exactly 3 feet **/ - 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)); - ///@} + constexpr basis_unit lightsecond = distance_unit( 299792458, 1); + constexpr basis_unit astronomicalunit = distance_unit( 149597870700, 1); - // ----- time ----- + /* US spelling */ + constexpr basis_unit picometer = picometre; + constexpr basis_unit nanometer = nanometre; + constexpr basis_unit micrometer = micrometre; + constexpr basis_unit millimeter = millimetre; + constexpr basis_unit meter = metre; + constexpr basis_unit kilometer = kilometre; + constexpr basis_unit megameter = megametre; + constexpr basis_unit gigameter = gigametre; - /** @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)); - constexpr basis_unit millisecond = basis_unit(dim::time, scalefactor_ratio_type( 1, 1000)); - constexpr basis_unit second = basis_unit(dim::time, scalefactor_ratio_type( 1, 1)); - constexpr basis_unit minute = basis_unit(dim::time, scalefactor_ratio_type( 60, 1)); - constexpr basis_unit hour = basis_unit(dim::time, scalefactor_ratio_type( 3600, 1)); - constexpr basis_unit day = basis_unit(dim::time, scalefactor_ratio_type( 24*3600, 1)); - constexpr basis_unit week = basis_unit(dim::time, scalefactor_ratio_type( 7*24*3600, 1)); - constexpr basis_unit month = basis_unit(dim::time, scalefactor_ratio_type( 30*24*3600, 1)); - constexpr basis_unit year = basis_unit(dim::time, scalefactor_ratio_type((365*24+6)*3600, 1)); + /** @brief basis-unit representing 1 inch; defined as exactly 1/12 feet **/ + constexpr basis_unit inch = distance_unit( 3048, 120000); + /** @brief basis-unit representing 1 foot; defined as exactly 0.3048 meters **/ + constexpr basis_unit foot = distance_unit( 3048, 10000); + /** @brief basis-unit representing 1 yard; defined as exactly 3 feet **/ + constexpr basis_unit yard = distance_unit( 3*3048, 10000); + /** @brief basis-unit representing 1 mile; defined as exactly 1760 yards = 5280 feet **/ + constexpr basis_unit mile = distance_unit( 5280*3048, 10000); + ///@} - /* alt conventions used in finance */ - constexpr basis_unit year365 = basis_unit(dim::time, scalefactor_ratio_type( 365*24*3600, 1)); - 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)); - ///@} + // ----- time ----- - // ----- currency ----- + constexpr basis_unit time_unit(std::int64_t num, std::int64_t den) { + return basis_unit(dimension::time, scalefactor_ratio_type(num, den)); + } - /** @defgroup basis-unit-misc-units **/ - ///@{ + /** @defgroup basis-unit-time-units **/ + ///@{ + constexpr basis_unit picosecond = time_unit( 1, 1000000000000); + constexpr basis_unit nanosecond = time_unit( 1, 1000000000); + constexpr basis_unit microsecond = time_unit( 1, 1000000); + constexpr basis_unit millisecond = time_unit( 1, 1000); + constexpr basis_unit second = time_unit( 1, 1); + constexpr basis_unit minute = time_unit( 60, 1); + constexpr basis_unit hour = time_unit( 3600, 1); + constexpr basis_unit day = time_unit( 24*3600, 1); + constexpr basis_unit week = time_unit( 7*24*3600, 1); + constexpr basis_unit month = time_unit( 30*24*3600, 1); + constexpr basis_unit year = time_unit( (365*24+6)*3600, 1); - /* pseudounit -- placeholder for any actual currency amount */ - constexpr basis_unit currency = basis_unit(dim::currency, scalefactor_ratio_type( 1, 1)); + /* alt conventions used in finance */ + constexpr basis_unit year365 = time_unit( 365*24*3600, 1); + constexpr basis_unit year360 = time_unit( 360*24*3600, 1); + /* 250 = approx number of trading days in a calendar year */ + constexpr basis_unit year250 = time_unit( 250*24*3600, 1); - // ----- price ----- + constexpr basis_unit century = time_unit( 100L*(365*24+6)*3600, 1); + constexpr basis_unit millenium = time_unit(1000L*(365*24+6)*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)); + + // ----- price ----- + + /* psuedounit -- context-dependent interpretation */ + constexpr basis_unit price = basis_unit(dim::price, scalefactor_ratio_type( 1, 1)); + ///@} + } /*namespace bu*/ + } /*namespace detail*/ - /* psuedounit -- context-dependent interpretation */ - constexpr basis_unit price = basis_unit(dim::price, scalefactor_ratio_type( 1, 1)); - ///@} - } namespace units { /** for runtime work, would like to be able to promptly find special abbreviation diff --git a/include/xo/unit/basis_unit_abbrev.hpp b/include/xo/unit/basis_unit_abbrev.hpp index 98998c1a..1a5346db 100644 --- a/include/xo/unit/basis_unit_abbrev.hpp +++ b/include/xo/unit/basis_unit_abbrev.hpp @@ -31,6 +31,17 @@ namespace xo { // ----- units for dim::mass ----- + /** @brief return abbreviated suffix to use for a mass unit + * of (relative) size @p scalefactor. + * + * Example: + * @code + * using namespace xo::qty; + * + * static_assert(abbrev::mass_unit2_abbrev(scalefactor_ratio_type(1,1000)) + * == xo::flatstring("mg")); + * @endcode + **/ static constexpr basis_unit2_abbrev_type mass_unit2_abbrev(const scalefactor_ratio_type & scalefactor) diff --git a/include/xo/unit/natural_unit.hpp b/include/xo/unit/natural_unit.hpp index 78d9085c..d3f05da8 100644 --- a/include/xo/unit/natural_unit.hpp +++ b/include/xo/unit/natural_unit.hpp @@ -374,61 +374,60 @@ namespace xo { // ----- mass ----- - constexpr auto picogram = natural_unit::from_bu(bu::picogram); - constexpr auto nanogram = natural_unit::from_bu(bu::nanogram); - constexpr auto microgram = natural_unit::from_bu(bu::microgram); - constexpr auto milligram = natural_unit::from_bu(bu::milligram); - constexpr auto gram = natural_unit::from_bu(bu::gram); - constexpr auto kilogram = natural_unit::from_bu(bu::kilogram); - constexpr auto tonne = natural_unit::from_bu(bu::tonne); - constexpr auto kilotonne = natural_unit::from_bu(bu::kilotonne); - constexpr auto megatonne = natural_unit::from_bu(bu::megatonne); - constexpr auto gigatonne = natural_unit::from_bu(bu::gigatonne); + constexpr auto picogram = natural_unit::from_bu(detail::bu::picogram); + constexpr auto nanogram = natural_unit::from_bu(detail::bu::nanogram); + constexpr auto microgram = natural_unit::from_bu(detail::bu::microgram); + constexpr auto milligram = natural_unit::from_bu(detail::bu::milligram); + constexpr auto gram = natural_unit::from_bu(detail::bu::gram); + constexpr auto kilogram = natural_unit::from_bu(detail::bu::kilogram); + constexpr auto tonne = natural_unit::from_bu(detail::bu::tonne); + constexpr auto kilotonne = natural_unit::from_bu(detail::bu::kilotonne); + constexpr auto megatonne = natural_unit::from_bu(detail::bu::megatonne); + constexpr auto gigatonne = natural_unit::from_bu(detail::bu::gigatonne); // ----- distance ----- - constexpr auto picometer = natural_unit::from_bu(bu::picometer); - constexpr auto nanometer = natural_unit::from_bu(bu::nanometer); - constexpr auto micrometer = natural_unit::from_bu(bu::micrometer); - constexpr auto millimeter = natural_unit::from_bu(bu::millimeter); - constexpr auto meter = natural_unit::from_bu(bu::meter); - constexpr auto kilometer = natural_unit::from_bu(bu::kilometer); - constexpr auto megameter = natural_unit::from_bu(bu::megameter); - constexpr auto gigameter = natural_unit::from_bu(bu::gigameter); - constexpr auto lightsecond = natural_unit::from_bu(bu::lightsecond); - constexpr auto astronomicalunit = natural_unit::from_bu(bu::astronomicalunit); + constexpr auto picometer = natural_unit::from_bu(detail::bu::picometer); + constexpr auto nanometer = natural_unit::from_bu(detail::bu::nanometer); + constexpr auto micrometer = natural_unit::from_bu(detail::bu::micrometer); + constexpr auto millimeter = natural_unit::from_bu(detail::bu::millimeter); + constexpr auto meter = natural_unit::from_bu(detail::bu::meter); + constexpr auto kilometer = natural_unit::from_bu(detail::bu::kilometer); + constexpr auto megameter = natural_unit::from_bu(detail::bu::megameter); + constexpr auto gigameter = natural_unit::from_bu(detail::bu::gigameter); + constexpr auto lightsecond = natural_unit::from_bu(detail::bu::lightsecond); + constexpr auto astronomicalunit = natural_unit::from_bu(detail::bu::astronomicalunit); - constexpr auto inch = natural_unit::from_bu(bu::inch); - constexpr auto foot = natural_unit::from_bu(bu::foot); - constexpr auto yard = natural_unit::from_bu(bu::yard); - constexpr auto mile = natural_unit::from_bu(bu::mile); + constexpr auto inch = natural_unit::from_bu(detail::bu::inch); + constexpr auto foot = natural_unit::from_bu(detail::bu::foot); + constexpr auto yard = natural_unit::from_bu(detail::bu::yard); + constexpr auto mile = natural_unit::from_bu(detail::bu::mile); // ----- time ----- - constexpr auto picosecond = natural_unit::from_bu(bu::picosecond); - constexpr auto nanosecond = natural_unit::from_bu(bu::nanosecond); - constexpr auto microsecond = natural_unit::from_bu(bu::microsecond); - constexpr auto millisecond = natural_unit::from_bu(bu::millisecond); - constexpr auto second = natural_unit::from_bu(bu::second); - constexpr auto minute = natural_unit::from_bu(bu::minute); - constexpr auto hour = natural_unit::from_bu(bu::hour); - constexpr auto day = natural_unit::from_bu(bu::day); - constexpr auto week = natural_unit::from_bu(bu::week); - constexpr auto month = natural_unit::from_bu(bu::month); - constexpr auto year = natural_unit::from_bu(bu::year); - constexpr auto year250 = natural_unit::from_bu(bu::year250); - constexpr auto year360 = natural_unit::from_bu(bu::year360); - constexpr auto year365 = natural_unit::from_bu(bu::year365); + constexpr auto picosecond = natural_unit::from_bu(detail::bu::picosecond); + constexpr auto nanosecond = natural_unit::from_bu(detail::bu::nanosecond); + constexpr auto microsecond = natural_unit::from_bu(detail::bu::microsecond); + constexpr auto millisecond = natural_unit::from_bu(detail::bu::millisecond); + constexpr auto second = natural_unit::from_bu(detail::bu::second); + constexpr auto minute = natural_unit::from_bu(detail::bu::minute); + constexpr auto hour = natural_unit::from_bu(detail::bu::hour); + constexpr auto day = natural_unit::from_bu(detail::bu::day); + constexpr auto week = natural_unit::from_bu(detail::bu::week); + constexpr auto month = natural_unit::from_bu(detail::bu::month); + constexpr auto year = natural_unit::from_bu(detail::bu::year); + constexpr auto year250 = natural_unit::from_bu(detail::bu::year250); + constexpr auto year360 = natural_unit::from_bu(detail::bu::year360); + constexpr auto year365 = natural_unit::from_bu(detail::bu::year365); - constexpr auto currency = natural_unit::from_bu(bu::currency); + constexpr auto currency = natural_unit::from_bu(detail::bu::currency); - constexpr auto price = natural_unit::from_bu(bu::price); + constexpr auto price = natural_unit::from_bu(detail::bu::price); - constexpr auto volatility_30d = natural_unit::from_bu(bu::month, power_ratio_type(-1,2)); - constexpr auto volatility_250d = natural_unit::from_bu(bu::year250, power_ratio_type(-1,2)); - constexpr auto volatility_360d = natural_unit::from_bu(bu::year360, power_ratio_type(-1,2)); - constexpr auto volatility_365d = natural_unit::from_bu(bu::year365, power_ratio_type(-1,2)); - } /*namespace nu*/ + constexpr auto volatility_30d = natural_unit::from_bu(detail::bu::month, power_ratio_type(-1,2)); + constexpr auto volatility_250d = natural_unit::from_bu(detail::bu::year250, power_ratio_type(-1,2)); + constexpr auto volatility_360d = natural_unit::from_bu(detail::bu::year360, power_ratio_type(-1,2)); + constexpr auto volatility_365d = natural_unit::from_bu(detail::bu::year365, power_ratio_type(-1,2)); } /*namespace nu*/ } /*namespace qty*/ } /*namespace xo*/ diff --git a/utest/basis_unit.test.cpp b/utest/basis_unit.test.cpp index 5a69612c..326dc453 100644 --- a/utest/basis_unit.test.cpp +++ b/utest/basis_unit.test.cpp @@ -12,7 +12,7 @@ namespace xo { using xo::qty::basis_unit2_abbrev_type; using xo::qty::native_unit2_v; using xo::qty::dim; - namespace bu = xo::qty::bu; + namespace bu = xo::qty::detail::bu; namespace ut { diff --git a/utest/bpu.test.cpp b/utest/bpu.test.cpp index 601b8347..a3691c8e 100644 --- a/utest/bpu.test.cpp +++ b/utest/bpu.test.cpp @@ -19,8 +19,10 @@ namespace xo { constexpr bpu_abbrev_type bpu_mpl_abbrev = bpu.abbrev(); TEST_CASE("bpu", "[bpu]") { - static_assert(bpu_mpl_abbrev == bpu64_type::unit_power(bu::gram).abbrev()); - REQUIRE(bpu_mpl_abbrev == bpu64_type::unit_power(bu::gram).abbrev()); + static_assert(bpu_mpl_abbrev + == bpu64_type::unit_power(detail::bu::gram).abbrev()); + REQUIRE(bpu_mpl_abbrev + == bpu64_type::unit_power(detail::bu::gram).abbrev()); } /*TEST_CASE(bpu)*/ TEST_CASE("flatstring_from_exponent", "[flatstring_from_exponent]") {