diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 71708b47..94614fea 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -24,79 +24,29 @@ name: Documentation on: push: - paths: - - ".github/workflows/documentation.yml" - - "docs/**" - - "src/**" - - "example/**" - pull_request: - paths: - - ".github/workflows/documentation.yml" - - "docs/**" - - "src/**" - - "example/**" + branches: + - master + - main +permissions: + contents: write jobs: - docs: - name: Generate documentation - runs-on: ${{ matrix.os }} - env: - CC: gcc-10 - CXX: g++-10 - CMAKE_GENERATOR: Ninja - CONAN_CMAKE_GENERATOR: Ninja - OS: ubuntu-22.04 - BUILD_TYPE: Debug - COMPILER_TYPE: GCC - COMPILER_VERSION: 10 - STDLIB: libstdc++11 - strategy: - fail-fast: false - matrix: - os: ["ubuntu-latest"] + deploy: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Cache Conan data - uses: actions/cache@v3 - env: - cache-name: cache-conan-data + - uses: actions/setup-python@v4 with: - path: ~/.conan2/p - key: build-${{ matrix.os }}-$BUILD_TYPE-$COMPILER_TYPE-$COMPILER_VERSION-$STDLIB-docs + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache restore-keys: | - build-${{ matrix.os }}-$BUILD_TYPE-$COMPILER_TYPE-$COMPILER_VERSION-$STDLIB - build-${{ matrix.os }}-$BUILD_TYPE-$COMPILER_TYPE-$COMPILER_VERSION- - build-${{ matrix.os }}-$BUILD_TYPE-$COMPILER_TYPE- - build-${{ matrix.os }}-$BUILD_TYPE- - build-${{ matrix.os }}- - - name: Install Ninja + mkdocs-material- + - name: Installing pip packages run: | - sudo apt install -y ninja-build - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.8" - - name: Install Python dependencies + pip install conan mkdocs-material mike + - name: Building docs run: | - pip install -Ur docs/requirements.txt - - name: Install Conan - run: | - pip install -U conan - - name: Configure Conan - run: | - conan profile detect --force - conan remote add artifactory https://mpusz.jfrog.io/artifactory/api/conan/conan-oss - - name: Install Conan dependencies - run: | - conan install . -s compiler.cppstd=20 -s compiler.libcxx=$STDLIB -c user.build:all=True -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" -b missing - - name: Configure CMake - run: | - cmake --preset conan-default - - name: Generate documentation - run: | - cmake --build --preset conan-release --target documentation - - name: Deploy documentation - if: github.ref == 'refs/heads/master' - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build/docs/sphinx + mike deploy --push --update-aliases `conan inspect . | sed -n -r 's/version: ([0-9]+.[0-9]+).[0-9]+/\1/p'` latest diff --git a/CMakeLists.txt b/CMakeLists.txt index f9ffe517..f03cef2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ project(mp-units-dev LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") -set(projectPrefix UNITS_) +set(projectPrefix MP_UNITS_) option(${projectPrefix}BUILD_LA "Build code depending on the linear algebra library" ON) message(STATUS "${projectPrefix}BUILD_LA: ${${projectPrefix}BUILD_LA}") @@ -70,9 +70,6 @@ add_subdirectory(src) # add usage example add_subdirectory(example) -# generate project documentation -# add_subdirectory(docs) - # add unit tests enable_testing() diff --git a/README.md b/README.md index 40ceab70..56f122a2 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ enable the rest of mainstream compilers and update the documentation to reflect ## Documentation -An extensive project documentation for the previous release library version can be found on -[mp-units GitHub Pages](https://mpusz.github.io/mp-units). It includes installation instructions and user's guide. +An extensive project documentation can be found on [mp-units GitHub Pages](https://mpusz.github.io/mp-units). +It includes installation instructions and a detailed user's guide. ## Terms and Definitions @@ -100,8 +100,8 @@ int main() constexpr auto v1 = 110 * (km / h); constexpr auto v2 = 70 * mph; - constexpr auto v3 = avg_speed(220. * km, 2 * h); - constexpr auto v4 = avg_speed(isq::distance(140. * mi), 2 * isq::duration[h]); + constexpr auto v3 = avg_speed(220. * isq::distance[km], 2 * h); + constexpr auto v4 = avg_speed(isq::distance(140. * mi), 2 * h); constexpr auto v5 = v3[m / s]; constexpr auto v6 = value_cast(v4); constexpr auto v7 = value_cast(v6); @@ -116,4 +116,4 @@ int main() } ``` -_Try it on the [Compiler Explorer](https://godbolt.org/z/rrTojn47v)._ +_Try it on the [Compiler Explorer](https://godbolt.org/z/T8bovrqTP)._ diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake deleted file mode 100644 index a7d4382d..00000000 --- a/cmake/FindSphinx.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# Look for an executable called sphinx-build -find_program(SPHINX_EXECUTABLE NAMES sphinx-build DOC "Path to sphinx-build executable") - -include(FindPackageHandleStandardArgs) - -# Handle standard arguments to find_package like REQUIRED and QUIET -find_package_handle_standard_args(Sphinx "Failed to find sphinx-build executable" SPHINX_EXECUTABLE) diff --git a/cmake/documentation.cmake b/cmake/documentation.cmake deleted file mode 100644 index 6d272bcd..00000000 --- a/cmake/documentation.cmake +++ /dev/null @@ -1,123 +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. - -cmake_minimum_required(VERSION 3.5) - -# TODO Switch to CONFIG when Conan will start supporting imported executables in CMakeDeps -find_package(Doxygen MODULE REQUIRED) -find_package(Sphinx REQUIRED) - -# -# add_documentation(TargetName [ALL] -# BREATHE_PROJECT projectName -# [DOXYFILE_TEMPLATE Doxyfile.in] -# [CODE_SOURCE_DIR dir] -# [DOCS_SOURCE_DIR dir] -# [INSTALL_DIR dir] -# CODE_DEPENDS codeDeps... -# DOC_DEPENDS docDeps...) -# -function(add_documentation targetName) - set(_options ALL) - set(_one_value_args BREATHE_PROJECT DOXYFILE_TEMPLATE CODE_SOURCE_DIR DOCS_SOURCE_DIR INSTALL_DIR) - set(_multi_value_args CODE_DEPENDS DOCS_DEPENDS) - cmake_parse_arguments(_args "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN}) - - if(NOT _args_BREATHE_PROJECT) - message(FATAL_ERROR "BREATHE_PROJECT not provided") - endif() - - # Validate arguments - if(NOT _args_DOXYFILE_TEMPLATE) - set(_args_DOXYFILE_TEMPLATE Doxyfile.in) - endif() - get_filename_component(_doxyfileIn ${_args_DOXYFILE_TEMPLATE} REALPATH) - if(NOT EXISTS ${_doxyfileIn}) - message(FATAL_ERROR "'${_args_DOXYFILE_TEMPLATE}' does not exist") - endif() - - if(_args_DOCS_SOURCE_DIR) - if(NOT EXISTS ${_args_DOCS_SOURCE_DIR}) - message(FATAL_ERROR "'${_args_DOCS_SOURCE_DIR}' does not exist") - endif() - else() - set(_args_DOCS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - endif() - - # Validate CODE_SOURCE_DIR and set input for the configuration file - if(_args_CODE_SOURCE_DIR) - if(NOT EXISTS ${_args_CODE_SOURCE_DIR}) - message(FATAL_ERROR "'${_args_CODE_SOURCE_DIR}' does not exist") - endif() - set(DOXYGEN_INPUT_DIR "${_args_CODE_SOURCE_DIR}") - else() - set(DOXYGEN_INPUT_DIR "${PROJECT_SOURCE_DIR}") - endif() - set(DOXYGEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doxygen") - - # Replace variables inside @@ with the current values - set(_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile") - configure_file("${_doxyfileIn}" "${_doxyfile}" @ONLY) - - set(_doxygenIndexFile "${DOXYGEN_OUTPUT_DIR}/xml/index.xml") - - # Only regenerate Doxygen when the Doxyfile or given dependencies change - add_custom_command( - OUTPUT "${_doxygenIndexFile}" - COMMAND ${CMAKE_COMMAND} -E make_directory ${DOXYGEN_OUTPUT_DIR} - COMMAND Doxygen::doxygen ARGS "${_doxyfile}" - MAIN_DEPENDENCY "${_doxyfileIn}" - DEPENDS "${_doxyfile}" "${_args_CODE_DEPENDS}" - COMMENT "Generating doxygen XML metadata" - USES_TERMINAL VERBATIM - ) - - set(_sphinx_docs_dir "${CMAKE_CURRENT_BINARY_DIR}/sphinx") - set(_sphinx_index_file "${_sphinx_docs_dir}/index.html") - - # Only regenerate Sphinx when: - # - Doxygen has rerun - # - Our doc files have been updated - # - The Sphinx config has been updated - add_custom_command( - OUTPUT "${_sphinx_index_file}" - COMMAND "${SPHINX_EXECUTABLE}" ARGS -b html -j auto - "-Dbreathe_projects.${_args_BREATHE_PROJECT}=${DOXYGEN_OUTPUT_DIR}/xml" "${_args_DOCS_SOURCE_DIR}" - "${_sphinx_docs_dir}" - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" - MAIN_DEPENDENCY "${_args_DOCS_SOURCE_DIR}/conf.py" - DEPENDS "${_doxygenIndexFile}" "${_args_DOCS_DEPENDS}" - COMMENT "Generating documentation with Sphinx" - USES_TERMINAL VERBATIM - ) - - # Custom target - if(_args_ALL) - set(_all ALL) - endif() - add_custom_target(${targetName} ${_all} DEPENDS "${_sphinx_index_file}") - - if(_args_INSTALL_DIR) - # Add an install step to install the docs - install(DIRECTORY ${_sphinx_docs_dir} TYPE DOC) - endif() -endfunction() diff --git a/conanfile.py b/conanfile.py index 8c555699..5a7acebc 100644 --- a/conanfile.py +++ b/conanfile.py @@ -82,10 +82,6 @@ class MPUnitsConan(ConanFile): def _skip_la(self): return bool(self.conf.get("user.build:skip_la", default=False)) - @property - def _skip_docs(self): - return bool(self.conf.get("user.build:skip_docs", default=True)) - @property def _use_libfmt(self): compiler = self.settings.compiler @@ -118,8 +114,6 @@ class MPUnitsConan(ConanFile): self.test_requires("catch2/3.3.2") if not self._skip_la: self.test_requires("wg21-linear_algebra/0.7.3") - if not self._skip_docs: - self.tool_requires("doxygen/1.9.4") def validate(self): check_min_cppstd(self, self._min_cppstd) diff --git a/docs/.overrides/main.html b/docs/.overrides/main.html new file mode 100644 index 00000000..0d556b68 --- /dev/null +++ b/docs/.overrides/main.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block outdated %} +You're not viewing the latest version. + + Click here to go to latest. + +{% endblock %} \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md deleted file mode 100644 index f8756365..00000000 --- a/docs/CHANGELOG.md +++ /dev/null @@ -1,241 +0,0 @@ -# Release notes - -- **2.0.0 WIP** - - `units` namespace renamed to `mp_units` (#317) - - header files in the `` rather then in `` (#317) - - the downcasting facility is removed (#383, #211, #32) - - unified and simplified quantity creation (#274) - - Determining the best way to create a quantity (#413) - - V2 quantity_point (#414) - - introduction of `quantity_spec` to store not only `dimension` but also additional information about quantities (#405) - - `quantity` now takes `reference` object, which aggregates `quantity_spec` and a `unit` and a `representation` type - - units, prefixes, dimensions, quantity specifications, and references are passed as NTTPs to templates and provide arithmetic operations and comparison - - expression templates consistently used in all derived types to increase the readability (#351, #166) - - derived dimensions are now factors of only base dimensions (#281) - - Interconvertibility of derived quantities (#427) - - dimensions, quantity specifications, units, and references are now composable, significantly reducing the number of definitions and resulting types - - heavily simplified unit systems definitions (no need to define unnamed derived units, systems-specific dimensions, aliases for quantities, concepts, UDLs, ... anymore) - - improved definition of all systems - - support for all (or at least most) ISO 80000 quantities - - faster than lightspeed constants (#169) - - extensions to quantity formatting with `fmt` - - `quantity_kind` removed - - much easier and safe casting of unit with `operator[]` and `.number_in(Unit)` - - quantity can no longer be constructed with a raw value (#434) - - Implicit construction of quantities from a value (#410) - - `ceil` and `floor` are dangerous (#432) - - quecto, ronto, ronna, quetta new SI prefixes support - - many smaller changes not possible to address with the previous design (#205, #210, #134) - -- **0.8.0 June 14, 2023** - - (!) refactor: `common_quantity`, `common_quantity_for`, `common_quantity_point`, `common_quantity_kind`, and `common_quantity_point_kind` removed - - (!) refactor: `named_derived_unit` removed as it was not used - - (!) refactor: `derived_unit` renamed to `derived_scaled_unit` - - (!) refactor: `unit` renamed to `derived_unit` - - (!) refactor: `U::is_named` removed from the unit types and replaced with `NamedUnit` concept - - (!) refactor: `PrefixFamily` support removed - - (!) refactor: `mi(naut)` renamed to `nmi` - - (!) refactor: `knot` unit helper renamed to `kn` in FPS - - (!) refactor: `knot` text symbol changed from `"knot"` to `"kn"` - - refactor: `quantity` `op+()` and `op-()` reimplemented in terms of `reference` rather then `quantity` types - - refactor(example): `glide_computer` now use dimensionless quantities with `ranged_representation` as `rep` - - feat: HEP system support added (thanks [@RalphSteinhagen](https://github.com/RalphSteinhagen)) - - feat: `floor()`, `ceil()`, and `round()` support added (thanks [@hofbi](https://github.com/hofbi)) - - feat: `std::format` support for compliant compilers added - - feat: conversion helpers from `mp-units` to `std::chrono` types added - - feat: math functions can now be safely used with user-defined types - - feat: conversion from `quantity_point` to `std::chrono::time_point` added - - feat: `nautical_mile_per_hour` and `knot` added to `si::international` system - - (!) fix: add `quantity_point::origin`, like `std::chrono::time_point::clock` - - fix: enable any prefixes for most of the named units (beside those that use prefixes already) - - fix: `hectare` definition fixed to be a prefixed version of `are` + other units - - fix: account for different dimensions in `quantity_point_cast`'s constraint - - fix: output stream operator now properly handles state - - fix: `fmt` algorithms were overconstrained with `forward_iterator` - - fix: CTAD for aliases fixed - - fix: `derived_ratio` calculation - - fix: `fill_t` assignment operator fixed - - fix: improve downcast mode off - - fix: `radioactivity` header compilation fixed - - fix: `si::hep::dim_momentum` duplicated definition fixed - - fix: `fps` can now coexist with `international` system - - fix: public headers fixed to be standalone - - test: standalone public headers tests added - - (!) build: CMake generator in Conan is no longer obtained from an environment variable - - (!) build: Required Conan version bumped to 1.48 - - (!) build: Conan 1.48 does not set `CMAKE_BUILD_TYPE` in the `conan_toolchain.cmake` anymore - - build: AppleClang 13 support added (thanks [@fdischner](https://github.com/fdischner)) - - build: most of the `conanfile.py` refactored to be Conan 2.0 ready - - build: `validate()` replaced with `configure()` to raise errors during `conan install` in Conan 1.X - - build: minimum Conan version changed to 1.40 - - build: `linear-algebra` Conan repo is no needed anymore - - build: Gitpod support added - - build: clang-format-15 support added - - build: export config to local build (#322) - - build: fix export name of `mp-units-system` - - build: fmt updated to 8.0.1 - - build: gsl-lite updated to 0.40.0 - - build: catch2 updated to 2.13.9 - - build: doxygen updated to 1.9.4 - - build: linear_algebra/0.7.0 switched to wg21-linear_algebra/0.7.2 - - ci: VS2022, gcc-11, clang-13, clang-14, and AppleClang 13 support added - - ci: pre-commit support added (thanks [@hofbi](https://github.com/hofbi)) - - docs: Project documentation updated - - docs: `CITATION.cff` file added - - docs: `CONTRIBUTING.md` updated - -- **0.7.0 May 11, 2021** - - (!) refactor: `ScalableNumber` renamed to `Representation` - - (!) refactor: output stream operators moved to the `units/quantity_io.h` header file - - (!) refactor: Refactored the library file tree - - (!) refactor: `quantity::count()` renamed to `quantity::number()` - - (!) refactor: `data` system renamed to `isq::iec80000` (quantity names renamed too) - - (!) refactor: `*deduced_unit` renamed to `*derived_unit` - - (!) refactor: got rid of a `noble_derived_unit` - - refactor: quantity (kind) point updated to reflect latest changes to `quantity` - - refactor: basic concepts, `quantity` and `quantity_cast` refactored - - refactor: `abs()` definition refactored to be more explicit about the return type - - feat: quantity (point) kind support added (thanks [@johelegp](https://github.com/johelegp)) - - feat: quantity references support added (thanks [@johelegp](https://github.com/johelegp)) - - feat: quantity aliases support addded - - feat: interoperability with `std::chrono::duration` and other units libraries - - feat: CTAD for dimensionless quantity added - - feat: `modulation_rate` support added (thanks [@go2sh](https://github.com/go2sh)) - - feat: SI prefixes for `isq::iec80000` support added (thanks [@go2sh](https://github.com/go2sh)) - - feat: a possibility to disable quantity UDLs support with `UNITS_NO_LITERALS` preprocessor define - - feat: a support to define ISQ derived dimensions in terms of different number or order of components - - perf: preconditions check do not influence the runtime performance of a Release build - - perf: `quantity_cast()` generates less assembly instructions - - perf: temporary string creation removed from `quantity::op<<()` - - perf: value initialization for quantity value removed (left with a default initialization) - - perf: limited the `equivalent` trait usage - - perf: limited the C++ Standard Library headers usage - - perf: rvalue references support added for constructors and getters - - (!) fix: `exp()` has sense only for dimensionless quantities - - (!) fix: `dim_torque` now properly divides by an angle (instead of multiply) + default unit name change - - fix: quantity's operators fixed to behave like the underlying types do - - fix: `quantity_cast()` fixed to work correctly with representation types not convertible from `std::intmax_t` - - fix: ambiguous case for empty type list resolved - - fix: downcasting facility for non-default-constructible types - - fix: restore user-warnings within the library implementation - - fix: the text symbol of `foot_pound_force` and `foot_pound_force_per_second` - - fix: quantity modulo arithmetics fixed - - (!) build: Conan testing version is now hosted on [Artifactory](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units) - - (!) build: Linear Algebra is now hosted on its [Artifactory](https://twonington.jfrog.io/artifactory/api/conan/conan-oss) - - (!) build: `BUILD_DOCS` CMake option renamed to `UNITS_BUILD_DOCS` - - build: doxygen updated to 1.8.20 - - build: catch2 updated to 2.13.4 - - build: fmt updated to 7.1.3 - - build: ms-gsl replaced with gsl-lite/0.38.0 - - build: Conan generator switched to `cmake_find_package_multi` - - build: Conan CMakeToolchain support added - - build: CMake scripts cleanup - - build: ccache support added - - ci: CI switched from Travis CI to GitHub Actions - -- **0.6.0 September 13, 2020** - - feat: `quantity_point` support added (thanks [@johelegp](https://github.com/johelegp)) - - feat: Added angle as SI base dimension (thanks [@kwikius](https://github.com/kwikius)) - - feat: `si::angular_velocity` support added (thanks [@mikeford3](https://github.com/mikeford3)) - - feat: FPS system added (thanks [@mikeford3](https://github.com/mikeford3)) - - feat: Added support for mathematical function `exp(quantity)` - - feat: Localization support for text output added (thanks [@rbrugo](https://github.com/rbrugo)) - - feat: Added STL random number distribution wrappers (thanks [@yasamoka](https://github.com/yasamoka)) - - (!) refactor: Refactored and cleaned up the library file tree - - (!) refactor: `q_*` UDL renamed to `_q_*` - - (!) refactor: UDLs with "per" in name renamed from `*p*` to `*_per_*` - - (!) refactor: `ratio` changed to the NTTP kind - - (!) refactor: `exp` and `Exp` renamed to `exponent` and `Exponent` - - (!) refactor: `Scalar` concept renamed to `ScalableNumber` - - (!) refactor: Dimensionless quantities redesigned to be of a `quantity` type - - refactor: `math.h` function signatures refactored to use a `Quantity` concept (thanks [@kwikius](https://github.com/kwikius)) - - refactor: `[[nodiscard]]` added to many functions - - fix: `si::day` unit symbol fixed to `d` (thanks [@komputerwiz](https://github.com/komputerwiz)) - - fix: `si::mole` unit symbol fixed to `mol` (thanks [@mikeford3](https://github.com/mikeford3)) - - (!) build: gcc-9 is no longer supported (at least gcc-10 is required) - - build: Visual Studio 16.7 support added - - build: linear_algebra updated to 0.7.0/stable - - build: fmt updated to 7.0.3 - - build: range-v3 updated to 0.11.0 - - build: catch2 updated to 2.13.0 - - build: doxygen updated to 1.8.18 - - build: ms-gsl 3.1.0 dependency added - - build: Removed the dependency on a git submodule with common CMake scripts - -- **0.5.0 May 17, 2020** - - Major refactoring and rewrite of the library - - Units are now independent from dimensions - - Dimensions now depend on units (base or coherent units are provided in a class template) - - Quantity gets a Dimension template parameter again (as unit does not provide information about - its dimension anymore) - - Spaceship operator support added - - Added official CGS system support - - Added official data information system support - - Repository file tree cleanup - - `ratio` refactored to contain `Exp` template parameter (thanks a lot [@oschonrock](https://github.com/oschonrock)!) - - SI fundamental constants added - - `q_` prefix applied to all the UDLs (thanks [@kwikius](https://github.com/kwikius)) - - `unknown_unit` renamed to `unknown_coherent_unit` - - Project documentation greatly extended and switched to Sphinx - - A few more usage examples added - - ASCII-only output support added (thanks [@yasamoka](https://github.com/yasamoka)) - - Representation values formatting extended (thanks [@rbrugo](https://github.com/rbrugo)) - - Output streams formatting support added - - Linear algebra from `std::experimental::math` support added - - Named SI units and their dimensions added (thanks [@rbrugo](https://github.com/rbrugo) - - libfmt updated to 6.2.0 - - Added absolute functions and epsilon to math.h (thanks [@mikeford3](https://github.com/mikeford3)) - - Added a lot of prefixes to named units and introduced `alias_unit` (thanks [@yasamoka](https://github.com/yasamoka)) - - Linking with Conan targets only when they exists ([#98](https://github.com/mpusz/units/issues/98)) - - All physical dimensions and units put into `physical` namespace - - CMake improvements - - Velocity renamed to speed - - Many thanks to GitHub users [@oschonrock](https://github.com/oschonrock), - [@kwikius](https://github.com/kwikius), and [@i-ky](https://github.com/i-ky) for their support - in drafting a new library design. - -- **0.4.0 Nov 17, 2019** - - Support for derived dimensions in `exp` added - - Added `pow()` and `sqrt()` operations on quantities - - `units` removed from a `std::experimental` namespace - - Downcasting facility refactored so the user does not have to write the boilerplate code anymore - - From now on base dimensions should inherit from `base_dimension` class template - - Added unit symbols definitions to `base_dimension` and derived units - - Added support for `operator<<` on `quantity` - - `fmt` support added - - Derived unit factory helpers refactored - - Refactored the way prefixed units are defined - -- **0.3.1 Sep 18, 2019** - - cmcstl2 dependency changed to range-v3 0.9.1 - -- **0.3.0 Sep 16, 2019 (CppCon 2019 design)** - - The design as described on CppCon 2019 talk () - - Applied the feedback from the Cologne evening session - - `upcasting_traits` renamed to `downcasting_traits` - - `Dimension` template parameter removed from quantity - - `units` moved to a `std::experimental` namespace - - Leading underscore prefix removed from UDLs - - Added a few more derived dimensions - - `meter` renamed to `metre` - - Missing `operator*` added - - Predefined dimensions moved to a dedicated directory - - `dimension_` prefix removed from names of derived dimensions - - cmcstl2 library updated to 2019.09.19 - - `base_dimension` is a value provided as `const&` to the `exp` type - - integrated with Compiler Explorer - - gsl-lite dependency removed - - Fractional dimension exponents support added - - `QuantityOf` concept introduced - - `quantity_cast()` support added - -- **0.2.0 July 18, 2019 (C++Now 2019 design)** - - The design as described on C++Now 2019 talk () - - Added C++20 features supported by gcc-9.1 (`std::remove_cvref_t`, down with typename, `std::type_identity`) - - Compile-time performance optimizations (`type_list`, `common_ratio`, `ratio`, `conditional_t`) - -- **0.1.0 May 18, 2019** - - Initial library release - - Begin semantic versioning - - The last version to work with gcc-8 diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt deleted file mode 100644 index 297261a7..00000000 --- a/docs/CMakeLists.txt +++ /dev/null @@ -1,261 +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. - -cmake_minimum_required(VERSION 3.2) - -option(${projectPrefix}BUILD_DOCS "Generate project documentation" ON) -message(STATUS "${projectPrefix}BUILD_DOCS: ${${projectPrefix}BUILD_DOCS}") - -if(NOT ${projectPrefix}BUILD_DOCS) - return() -endif() - -# set paths to Conan packages (needed for doxygen) -# TODO: remove when Conan will learn how to properly create imported build tools targets -include(${CMAKE_BINARY_DIR}/conan_paths.cmake OPTIONAL) - -# Find all the public headers -file(GLOB_RECURSE unitsPublicHeaders "${PROJECT_SOURCE_DIR}/src/*.h") - -# Sphinx documentation dependencies -set(unitsSphinxDocs - "${CMAKE_CURRENT_SOURCE_DIR}/_static/css/custom.css" - "${CMAKE_CURRENT_SOURCE_DIR}/_static/img/concepts.svg" - "${CMAKE_CURRENT_SOURCE_DIR}/_static/img/dimensions.svg" - "${CMAKE_CURRENT_SOURCE_DIR}/_static/img/downcast_1.png" - "${CMAKE_CURRENT_SOURCE_DIR}/_static/img/downcast_2.png" - "${CMAKE_CURRENT_SOURCE_DIR}/_static/img/units.svg" - "${CMAKE_CURRENT_SOURCE_DIR}/_static/img/quantity_like.svg" - "${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md" - "${CMAKE_CURRENT_SOURCE_DIR}/defining_systems.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/defining_systems/angular_units.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/defining_systems/isq.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/defining_systems/si.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/design.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/design/directories.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/design/downcasting.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/design/quantity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/design/quantity_kind.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/avg_speed.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/box_example.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/capacitor_time_curve.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/clcpp_response.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/experimental_angle.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/foot_pound_second.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/glide_computer.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/hello_units.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/total_energy.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/basics/unknown_dimension.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_representation.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_representation/linear_algebra.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_representation/measurement.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_systems.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_systems/custom_systems.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_utilities.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/custom_utilities/conversion_factor.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_1.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_2.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_3.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_4.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_5.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_6.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_7.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/example_8.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/examples/kalman_filter/kalman.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/faq.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/arithmetics.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/basic_concepts.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/constants.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/conversions_and_casting.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/dimensions.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/magnitudes.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/quantities.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/quantity_kinds.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/quantity_like.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/quantity_points.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/text_output.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/framework/units.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/genindex.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/glossary.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/index.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/introduction.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/quick_start.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/concepts.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/customization_points.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/downcasting.rst" - # "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/functions.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/metafunctions.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/dimensions.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/kinds.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/prefixes.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/reference.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/quantity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/quantity_kind.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/quantity_point_kind.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/quantity_point.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/units.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/utilities.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/utilities/basic_fixed_string.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/utilities/basic_symbol_text.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/core/types/utilities/ratio.rst" - # "${CMAKE_CURRENT_SOURCE_DIR}/reference/math.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/random.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/generic.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/generic/angle.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/generic/dimensionless.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/generic/unknown.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/iec80000.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/iec80000/binary_prefixes.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/iec80000/modulation_rate.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/iec80000/storage_capacity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/iec80000/traffic_intensity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/iec80000/transfer_rate.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/acceleration.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/constants.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/energy.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/force.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/mass.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/momentum.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/speed.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/time.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/natural/units.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_cgs.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/acceleration.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/area.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/energy.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/force.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/mass.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/power.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/pressure.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/speed.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/cgs/time.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/dimensions_and_concepts.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_fps.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/acceleration.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/area.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/density.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/energy.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/force.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/mass.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/power.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/pressure.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/speed.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/time.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/fps/volume.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_iau.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/iau/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_imperial.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/imperial/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_international.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/international/area.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/international/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/international/speed.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/international/volume.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/absorbed_dose.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/acceleration.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/amount_of_substance.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/area.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/capacitance.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/catalytic_activity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/charge_density.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/concentration.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/conductance.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/constants.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/current_density.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/density.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/dynamic_viscosity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/electric_charge.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/electric_current.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/electric_field_strength.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/energy.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/force.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/frequency.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/heat_capacity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/inductance.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/luminance.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/luminous_intensity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/magnetic_flux.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/magnetic_induction.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/mass.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/molar_energy.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/momentum.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/permeability.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/permittivity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/power.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/prefixes.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/pressure.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/resistance.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/speed.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/surface_tension.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/thermal_conductivity.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/thermodynamic_temperature.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/time.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/voltage.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/volume.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_typographic.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/typographic/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si_uscs.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/reference/systems/isq/si/uscs/length.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/references.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/custom_representation_types.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/extensions.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/interoperability.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/legacy_interfaces.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/linear_algebra.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/natural_units.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/use_cases/unknown_dimensions.rst" - "${CMAKE_CURRENT_SOURCE_DIR}/usage.rst" -) - -include(documentation) -include(GNUInstallDirs) - -add_documentation( - documentation ALL - BREATHE_PROJECT mp-units - CODE_SOURCE_DIR "${PROJECT_SOURCE_DIR}/src" - INSTALL_DIR ${CMAKE_INSTALL_DOCDIR} - CODE_DEPENDS ${unitsPublicHeaders} - DOCS_DEPENDS ${unitsSphinxDocs} -) - -add_custom_command( - TARGET documentation POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/_static/img/*.svg - ${CMAKE_CURRENT_BINARY_DIR}/sphinx/_images -) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in deleted file mode 100644 index 9dec7d17..00000000 --- a/docs/Doxyfile.in +++ /dev/null @@ -1,93 +0,0 @@ -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIR@" - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = "@DOXYGEN_INPUT_DIR@" - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = YES - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = NO - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = YES - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = YES - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = units::detail - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = YES diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css deleted file mode 100644 index e84a5219..00000000 --- a/docs/_static/css/custom.css +++ /dev/null @@ -1,20 +0,0 @@ -@import 'theme.css'; - -a.reference.internal + code.sig-name.descname { - padding-left: 4px; -} - -.breatheparameterlist li tt + p { - display: inline; -} -.breatheenumvalues li tt + p { - display: inline; -} - -.rst-content .admonition-try-it-on-compiler-explorer { - background-color: #e2f6d5; -} - -.rst-content .admonition-try-it-on-compiler-explorer > .admonition-title { - background-color: #66c52a; -} diff --git a/docs/_static/img/concepts.svg b/docs/_static/img/concepts.svg deleted file mode 100644 index 349f3281..00000000 --- a/docs/_static/img/concepts.svg +++ /dev/null @@ -1,116 +0,0 @@ -KindPointKindPointOriginQuantityQuantityPointQuantityKindQuantityPointKindUnitDimensionkindDimensionpoint_kindKind, PointOriginpoint_originDimensionquantityDimension, Unit, Reprep number()quantity_pointPointOrigin, Unit, Repquantity relative()quantity_kindKind, Unit, Repquantity common()quantity_point_kindPointKind, Unit, Repquantity_kind relative() diff --git a/docs/_static/img/dimensions.svg b/docs/_static/img/dimensions.svg deleted file mode 100644 index e9ecf42e..00000000 --- a/docs/_static/img/dimensions.svg +++ /dev/null @@ -1,35 +0,0 @@ -Dimensionbase_dimensionSymbol, UnitexponentDimension, Num, Denderived_dimensionUnit, Exponent...0..n diff --git a/docs/_static/img/downcast_1.png b/docs/_static/img/downcast_1.png deleted file mode 100644 index 203d9039..00000000 Binary files a/docs/_static/img/downcast_1.png and /dev/null differ diff --git a/docs/_static/img/downcast_2.png b/docs/_static/img/downcast_2.png deleted file mode 100644 index 94729025..00000000 Binary files a/docs/_static/img/downcast_2.png and /dev/null differ diff --git a/docs/_static/img/quantity_like.svg b/docs/_static/img/quantity_like.svg deleted file mode 100644 index bcc1c0ff..00000000 --- a/docs/_static/img/quantity_like.svg +++ /dev/null @@ -1,37 +0,0 @@ -quantityquantity_pointquantity_kindquantity_point_kindRepnumber()relative()common()relative() diff --git a/docs/_static/img/units.svg b/docs/_static/img/units.svg deleted file mode 100644 index c19aae88..00000000 --- a/docs/_static/img/units.svg +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - Unit - - - - - scaled_unit - - UnitRatio, Unit - - - - - prefixed_alias_unit - - Unit, Prefix, AliasUnit - - - - - - alias_unit - - Unit, Symbol - - - - - - derived_scaled_unit - - Dimension, Unit, Unit... - - - - - - derived_unit - - - - - - prefixed_unit - - Prefix, Unit - - - - - - named_scaled_unit - - Symbol, Ratio, Unit - - - - - - named_unit - - Symbol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/appendix/glossary.md b/docs/appendix/glossary.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/appendix/release_notes.md b/docs/appendix/release_notes.md new file mode 120000 index 00000000..699cc9e7 --- /dev/null +++ b/docs/appendix/release_notes.md @@ -0,0 +1 @@ +../../CHANGELOG.md \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 06acf0a1..00000000 --- a/docs/conf.py +++ /dev/null @@ -1,139 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. -# For a full list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -import re - - -def get_version(): - try: - with open("../src/CMakeLists.txt", "r") as file: - content = file.read() - version = re.search( - r"project\([^\)]+VERSION (\d+\.\d+\.\d+)[^\)]*\)", content - ).group(1) - return version.strip() - except Exception: - return None - - -# -- Project information ----------------------------------------------------- - -project = "mp-units" -copyright = "2018-present, Mateusz Pusz" -author = "Mateusz Pusz" - -# The major project version, used as the replacement for |version|. -version = get_version() - -# The full project version, used as the replacement for |release| and -# e.g. in the HTML templates. -release = get_version() - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.autosectionlabel", - "sphinx.ext.githubpages", - "sphinx.ext.graphviz", - "sphinx_rtd_theme", - "recommonmark", - "breathe", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - -# If true, Sphinx will warn about all references where the target cannot -# be found. Default is False. -nitpicky = True - -# A list of (type, target) tuples (by default empty) that should be ignored -# when generating warnings in “nitpicky mode”. Note that type should include -# the domain name if present. Example entries would be ('py:func', 'int') -# or ('envvar', 'LD_LIBRARY_PATH'). -nitpick_ignore = [] - -# True to prefix each section label with the name of the document it is in, -# followed by a colon. Useful for avoiding ambiguity when the same section -# heading appears in different documents. -autosectionlabel_prefix_document = True - -# -- C++ configuration --------------------------------------------------- - -# The name of the default domain. Can also be None to disable a default -# domain. The default is 'py'. -primary_domain = "cpp" - -# The reST default role (used for this markup: `text`) to use for all documents. -default_role = "cpp:any" - -# The default language to highlight source code in. The default is 'python3'. -# The value should be a valid Pygments lexer name (https://pygments.org/docs/lexers). -highlight_language = "cpp" - -# The style name to use for Pygments highlighting of source code. If not set, -# either the theme’s default style or 'sphinx' is selected for HTML output. -pygments_style = "default" - -# A list of prefixes that will be ignored when sorting C++ objects in the global -# index. For example ['awesome_lib::']. -cpp_index_common_prefix = ["units::"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "sphinx_rtd_theme" - -# A dictionary of options that influence the look and feel of the selected theme. -# These are theme-specific. -html_theme_options = { - # WARNING: unsupported theme option 'github_url' given - # 'github_url': 'https://github.com/mpusz/units' -} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# If given, this must be the name of an image file (path relative to the -# configuration directory) that is the logo of the docs. It is placed at the -# top of the sidebar; its width should therefore not exceed 200 pixels. -# Default: None. -# html_logo = - -# These paths are either relative to html_static_path or fully qualified -# paths (eg. https://...) -html_css_files = ["css/custom.css"] - - -# -- Breathe configuration --------------------------------------------------- - - -# This should be a dictionary in which the keys are project names and the values -# are paths to the folder containing the doxygen output for that project. -breathe_projects = {"mp-units": "build/xml"} - -# This should match one of the keys in the breathe_projects dictionary and -# indicates which project should be used when the project is not specified on -# the directive. -breathe_default_project = "mp-units" - -# Allows you to specify domains for particular files according to their extension. -breathe_domain_by_extension = {"h": "cpp"} - -# Provides the directive flags that should be applied to all directives which -# take :members:, :private-members: and :undoc-members: options. By default, -# this is set to an empty list, which means no members are displayed. -breathe_default_members = ("members",) diff --git a/docs/defining_systems.rst b/docs/defining_systems.rst deleted file mode 100644 index f40c9f8e..00000000 --- a/docs/defining_systems.rst +++ /dev/null @@ -1,9 +0,0 @@ -Defining Systems -================ - -.. toctree:: - :maxdepth: 2 - - defining_systems/isq - defining_systems/si - defining_systems/angular_units diff --git a/docs/defining_systems/angular_units.rst b/docs/defining_systems/angular_units.rst deleted file mode 100644 index 8574efb6..00000000 --- a/docs/defining_systems/angular_units.rst +++ /dev/null @@ -1,175 +0,0 @@ -.. namespace:: units - -Angular Units -============= - -Some background information ---------------------------- - -As per today's SI, both radian and steradian are dimensionless. This forces the convention to set the angle ``1 radian`` -equal to the number ``1`` within equations (similar to what natural units system does for ``c`` constant). - -Following `Wikipedia `_: - - Giacomo Prando says "the current state of affairs leads inevitably to ghostly appearances and disappearances of the radian - in the dimensional analysis of physical equations." For example, a mass hanging by a string from a pulley will rise or drop - by :math:`y=rθ`` centimeters, where :math:`r` is the radius of the pulley in centimeters and :math:`θ` is the angle - the pulley turns in radians. When multiplying :math:`r` by :math:`θ` the unit of radians disappears from the result. - Similarly in the formula for the angular velocity of a rolling wheel, :math:`ω=v/r`, radians appear in the units of - :math:`ω` but not on the right hand side. - Anthony French calls this phenomenon "a perennial problem in the teaching of mechanics". Oberhofer says that the typical - advice of ignoring radians during dimensional analysis and adding or removing radians in units according to convention - and contextual knowledge is "pedagogically unsatisfying". - -At least a dozen scientists have made proposals to treat the radian as a base unit of measure defining its own dimension of "angle", -as early as 1936 and as recently as 2022. This would bring the advantages of a physics-based, consistent, and logically-robust -unit system, with unambiguous units for all physical quantities. At the same time the only notable changes for typical -end-users would be: improved units for the quantities **torque**, **angular momentum** and **moment of inertia**. - -Paul Quincey in his proposal *"Angles in the SI: a detailed proposal for solving the problem"* [Quincey]_ states: - - The familiar units assigned to some angular quantities are based on equations that have adopted the radian convention, - and so are missing `rad`s that would be present if the complete equation is used. The physically-correct units are - those with the `rad`s reinstated. Numerical values would not change, and the physical meanings of all quantities would - also be unaffected. - -He proposes the following changes: - -- The **radian** would become either a new base unit or a 'complementary' unit -- The **steradian** would become a derived unit equal to :math:`1\:rad^2` -- The SI units for - - - **Torque** would change from :math:`N\:m` (= J) to :math:`J\:rad^{-1}` - - **Angular momentum** would change from :math:`J\:s` to :math:`J\:s\:rad^{-1}` (i.e. :math:`J/(rad/s)`) - - **Moment of inertia** would change from :math:`kg\:m^2` to :math:`kg\:m^2\:rad^{-2}` (i.e. :math:`J/(rad/s)^2`) - -- The option to omit the radian from the SI units for **angle**, **angular velocity**, **angular frequency**, - **angular acceleration**, and **angular wavenumber** would be removed, the only correct SI units being - :math:`rad`, :math:`rad/s`, :math:`rad/s`, :math:`rad/s^2` and :math:`rad/m` respectively. - -Paul Quincey summarizes that with the above in action: - - However, the physical clarity this would build into the SI should be recognised very quickly. The units would tell us that - :math:`torque \times angle = energy`, and :math:`angular\:momentum \times angle = action`, for example, in the same way that they do for - :math:`force \times distance = energy`, :math:`linear\:momentum \times distance = action`, and - :math:`radiant\:intensity \times solid\:angle = radiant\:flux`. - Dimensional analysis could be used to its full extent. Software involving angular quantities would be rationalised. - Arguments about the correct units for frequency and angular frequency, and the meaning of the unit Hz, could be left behind. - The explanation of these changes would be considerably easier and more rewarding than explaining how a kilogram-sized mass - can be measured in terms of the Planck constant. - - -Angular quantities in the :term:`SI` ------------------------------------- - -Even though the :term:`SI` somehow ignores the dimensionality of angle: - - Plane and solid angles, when expressed in radians and steradians respectively, are in effect - also treated within the SI as quantities with the unit one. The symbols :math:`rad` - and :math:`sr` are written explicitly where appropriate, in order to emphasize that, for radians or - steradians, the quantity being considered is, or involves the plane angle or solid angle - respectively. For steradians it emphasizes the distinction between units of flux and intensity - in radiometry and photometry for example. However, it is a long-established practice in - mathematics and across all areas of science to make use of :math:`rad = 1` and :math:`sr = 1`. - For historical reasons the radian and steradian are treated as derived units. - -It also explicitly states: - - The SI unit of frequency is hertz, the SI unit of angular velocity and angular frequency is - radian per second, and the SI unit of activity is becquerel, implying counts per second. - Although it is formally correct to write all three of these units as the reciprocal second, the - use of the different names emphasizes the different nature of the quantities concerned. It is - especially important to carefully distinguish frequencies from angular frequencies, because - by definition their numerical values differ by a factor of :math:`2\pi`. Ignoring this fact may cause - an error of :math:`2\pi`. Note that in some countries, frequency values are conventionally expressed - using “cycle/s” or “cps” instead of the SI unit :math:`Hz`, although “cycle” and “cps” are not units - in the SI. Note also that it is common, although not recommended, to use the term - frequency for quantities expressed in :math:`rad/s`. Because of this, it is recommended that - quantities called “frequency”, “angular frequency”, and “angular velocity” always be given - explicit units of :math:`Hz` or :math:`rad/s`` and not :math:`s^{-1}`. - - -Angular quantities in the library ---------------------------------- - -The mp-units library strives to define physically-correct quantities and their units to provide maximum help -to its users. As treating angle as a dimensional quantity can lead to many "trivial" mistakes in dimensional -analysis and calculation, it was decided to follow the above approach and treat angle as a base quantity -with a base unit of radian and solid angle as its derived quantity. - -As those the above (at least for now) not a part of :term:`SI`, the plain angle and solid -angle definitions can be found in the *units/generic* subdirectory. However, in the sake of correctness, -they are consistently used in the dimensional recipes of all angle-based :term:`SI` quantities like -torque or angular velocity:: - - #include - #include - #include - #include - #include - - int main() - { - using namespace units; - using namespace units::isq; - using namespace units::aliases; - using namespace units::aliases::isq::si; - - const Length auto lever = cm<>(20); - const Force auto force = N<>(500); - const Angle auto angle = deg<>(90); - const Torque auto torque = lever * force * sin(angle) / cotes_angle<>; - - std::cout << "Applying a perpendicular force of " << force << " to a " - << lever << " long lever results in " - << quantity_cast(torque) << " of torque.\n"; - } - -The above program prints: - -.. code-block:: - - Applying a perpendicular force of 500 N to a 20 cm long lever results in 100 N⋅m/rad of torque. - -.. note:: - - `cotes_angle` is a constant which represents an angle with the value of exactly ``1 radian``. - You can find more information about this constant in [Quincey]_. - - -Radians and degrees support ---------------------------- - -Thanks to :ref:`framework/magnitudes:Magnitudes` usage the library provides efficient strong types for all -angular types. This means that with the built-in support for magnitudes of :math:`\pi` we can provide -accurate conversions between radians and degrees. The library also provides common trigonometric functions -for angular quantities:: - - using namespace units::aliases::isq::si; - - auto velocity = km_per_h<>(110); - auto rate_of_climb = m_per_s<>(-0.63657); - auto glide_ratio = velocity / -rate_of_climb; - auto glide_angle = asin(1 / glide_ratio); - - std::cout << std::format("Glide ratio: {:%.1Q %q}\n", quantity_cast(glide_ratio)); - std::cout << "Glide angle:\n"; - std::cout << std::format(" - {:%.4Q %q}\n", glide_angle); - std::cout << std::format(" - {:%.2Q %q}\n", quantity_cast(glide_angle)); - std::cout << std::format(" - {:%.2Q %q}\n", quantity_cast(glide_angle)); - -The above program prints: - -.. code-block:: - - Glide ratio: 48.0 - Glide angle: - - 0.0208 rad - - 1.19 ° - - 1.33 ᵍ - -.. note:: - - The above ``velocity`` and ``rate_of_climb`` in the production code should be modelled as - :ref:`framework/quantity_kinds:Quantity Kinds`. - A better but longer code can be found in the :ref:`examples/basics/glide_computer:glide_computer` example. diff --git a/docs/defining_systems/isq.rst b/docs/defining_systems/isq.rst deleted file mode 100644 index 3c243afd..00000000 --- a/docs/defining_systems/isq.rst +++ /dev/null @@ -1,48 +0,0 @@ -.. namespace:: units - -International System of Quantities (ISQ) -======================================== - -According to [ISO80000]_: - - The system of quantities, including the relations among them the quantities used as the basis of the units of - the SI, is named the **International System of Quantities**, denoted "ISQ", in all languages. - - -Base dimensions and their symbols ---------------------------------- - -According to the [SIBrochure]_: - - Physical quantities can be organized in a system of dimensions, where the system used is - decided by convention. Each of the seven base quantities used in the SI is regarded as - having its own dimension. The symbols used for the base quantities and the symbols used - to denote their dimension are shown in Table 3. - -Following that the library provides the following definitions:: - - namespace units::isq { - - template struct dim_time : base_dimension<"T", U> {}; - template struct dim_length : base_dimension<"L", U> {}; - template struct dim_mass : base_dimension<"M", U> {}; - template struct dim_electric_current : base_dimension<"I", U> {}; - template struct dim_thermodynamic_temperature : base_dimension<"Θ", U> {}; - template struct dim_amount_of_substance : base_dimension<"N", U> {}; - template struct dim_luminous_intensity : base_dimension<"J", U> {}; - - } - -Base dimension symbols provided above are consistently defined by both [SIBrochure]_ and [ISO80000]_. - - -Derived dimensions ------------------- - -[SIBrochure]_ states: - - Since the number of quantities is without limit, it is not possible to - provide a complete list of derived quantities and derived units. - -The authors of this library decided to limit the set of defined quantities to all -quantities defined in the [ISO80000]_ series of documents. diff --git a/docs/defining_systems/si.rst b/docs/defining_systems/si.rst deleted file mode 100644 index 22706e39..00000000 --- a/docs/defining_systems/si.rst +++ /dev/null @@ -1,231 +0,0 @@ -.. namespace:: units - -The International System of Units (SI) -====================================== - -The :term:`SI` system is defined in the [SIBrochure]_ and standardizes units for quantities provided in -the :term:`ISQ` system: - - The SI is a consistent system of units for use in all aspects of life, including international - trade, manufacturing, security, health and safety, protection of the environment, and in the - basic science that underpins all of these. The system of quantities underlying the SI and the - equations relating them are based on the present description of nature and are familiar to all - scientists, technologists and engineers. - -As the :term:`SI` is defined on top of the :term:`ISQ` the C++ namespace for all of its definitions -is ``units::isq::si``. - -Base units ----------- - -Even though from 2019 the :term:`SI` system is defined in terms of the `Defining constants`_, -base units still are really important. As the [SIBrochure]_ states: - - Prior to the definitions adopted in 2018, the SI was defined through seven base units from - which the derived units were constructed as products of powers of the base units. Defining - the SI by fixing the numerical values of seven defining constants has the effect that this - distinction is, in principle, not needed, since all units, base as well as derived units, may be - constructed directly from the defining constants. Nevertheless, the concept of base and - derived units is maintained because it is useful and historically well established, noting - also that the ISO/IEC 80000 series of Standards specify base and derived quantities which - necessarily correspond to the SI base and derived units defined here. - -The base units and quantities of the :term:`SI` system are defined as follows:: - - namespace units::isq::si { - - struct second : named_unit {}; - struct dim_time : isq::dim_time {}; - template U, Representation Rep = double> - using time = quantity; - - struct metre : named_unit {}; - struct dim_length : isq::dim_length {}; - template U, Representation Rep = double> - using length = quantity; - - struct gram : named_unit {}; - struct kilogram : prefixed_unit {}; - struct dim_mass : isq::dim_mass {}; - template U, Representation Rep = double> - using mass = quantity; - - struct ampere : named_unit {}; - struct dim_electric_current : isq::dim_electric_current {}; - template U, Representation Rep = double> - using electric_current = quantity; - - struct kelvin : named_unit {}; - struct dim_thermodynamic_temperature : isq::dim_thermodynamic_temperature {}; - template U, Representation Rep = double> - using thermodynamic_temperature = quantity; - - struct mole : named_unit {}; - struct dim_amount_of_substance : isq::dim_amount_of_substance {}; - template U, Representation Rep = double> - using amount_of_substance = quantity; - - struct candela : named_unit {}; - struct dim_luminous_intensity : isq::dim_luminous_intensity {}; - template U, Representation Rep = double> - using luminous_intensity = quantity; - - } - - -Derived units -------------- - -The [SIBrochure]_ states: - - Derived units are defined as products of powers of the base units. When the numerical - factor of this product is one, the derived units are called coherent derived units. The base - and coherent derived units of the SI form a coherent set, designated the set of coherent SI - units. The word “coherent” here means that equations between the numerical values of - quantities take exactly the same form as the equations between the quantities themselves. - Some of the coherent derived units in the SI are given special names. ... Together with the - seven base units they form the core of the set of SI units. All other SI units are combinations - of some of these 29 units. - - -Unit prefixes -------------- - -According to [SIBrochure]_: - - Prefixes may be used with any of the 29 SI units with special names with - the exception of the base unit kilogram. - -Here is a complete list of all the :term:`SI` prefixes supported by the library:: - - namespace si { - - struct yocto : prefix()> {}; - struct zepto : prefix()> {}; - struct atto : prefix()> {}; - struct femto : prefix()> {}; - struct pico : prefix()> {}; - struct nano : prefix()> {}; - struct micro : prefix()> {}; - struct milli : prefix()> {}; - struct centi : prefix()> {}; - struct deci : prefix()> {}; - struct deca : prefix()> {}; - struct hecto : prefix()> {}; - struct kilo : prefix()> {}; - struct mega : prefix()> {}; - struct giga : prefix()> {}; - struct tera : prefix()> {}; - struct peta : prefix()> {}; - struct exa : prefix()> {}; - struct zetta : prefix()> {}; - struct yotta : prefix()> {}; - - } - - -Other definitions for names units ---------------------------------- - -For all of the above units the library also provides: - -- prefixed versions using SI prefixes:: - - namespace units::isq::si { - - struct millisecond : prefixed_unit {}; - - } - -- :ref:`framework/quantities:Quantity References (Experimental)`:: - - namespace units::isq::si { - - namespace time_references { - - inline constexpr auto s = reference{}; - - } - - namespace references { - - using namespace time_references; - - } - -- :ref:`framework/quantities:Unit-Specific Aliases (Experimental)`:: - - namespace units::aliases::isq::si::inline time { - - template - using s = units::isq::si::time; - - } - -- :ref:`framework/quantities:User Defined Literals (Experimental)`:: - - namespace units::isq::si::inline literals { - - constexpr auto operator"" _q_s(unsigned long long l) - { - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); - } - constexpr auto operator"" _q_s(long double l) { return time(l); } - - } - -For some of the units, when accepted by the :term:`SI`, other non-standard scaled versions are also provided:: - - namespace units::isq::si { - - struct minute : named_scaled_unit(), second> {}; - struct hour : named_scaled_unit(), minute> {}; - struct day : named_scaled_unit(), hour> {}; - - } - - - - -Defining constants ------------------- - -[SIBrochure]_ states that: - - The definition of the SI units is established in terms of a set of seven defining constants. - The complete system of units can be derived from the fixed values of these defining - constants, expressed in the units of the SI. - -Those constants are provided in the *units/isq/si/constants.h* header file as:: - - namespace units::isq::si::si2019 { - - template - inline constexpr auto hyperfine_structure_transition_frequency = frequency(Rep{9'192'631'770}); - - template - inline constexpr auto speed_of_light = speed(299'792'458); - - template - inline constexpr auto planck_constant = energy(6.62607015e-34) * time(1); - - template - inline constexpr auto elementary_charge = electric_charge(1.602176634e-19); - - template - inline constexpr auto boltzmann_constant = energy(1.380649e-23) / thermodynamic_temperature(1); - - template - inline constexpr auto avogadro_constant = Rep(6.02214076e23) / amount_of_substance(1); - - template - inline constexpr auto luminous_efficacy = luminous_flux(683) / power(1); - - } - -.. note:: - - Please note the nested `si2019` namespace. It is introduced in case those constants were changed/updated - by the :term:`SI` in the future. diff --git a/docs/design.rst b/docs/design.rst deleted file mode 100644 index 613a0e11..00000000 --- a/docs/design.rst +++ /dev/null @@ -1,17 +0,0 @@ -Design Deep Dive -================ - -.. note:: - - For brevity all the code examples in this chapter assume:: - - using namespace units; - using namespace units::isq; - -.. toctree:: - :maxdepth: 2 - - design/directories - design/quantity - design/quantity_kind - design/downcasting diff --git a/docs/design/directories.rst b/docs/design/directories.rst deleted file mode 100644 index 562ab07d..00000000 --- a/docs/design/directories.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. namespace:: units - -Library Directories Structure -============================= - -.. code-block:: text - - units - ├── bits - │ └── external - ├── generic - └── isq - ├── dimensions - ├── iec80000 - ├── natural - └── si - ├── cgs - ├── fps - ├── iau - ├── imperial - ├── international - ├── typographic - └── us - -- *./units* - - - The main directory of the library. - - Contains headers files that define a public interface of the library framework. - -- *./units/bits* - - - Contains header files with implementation details for the library. Interface of - the tools provided here should not be standardized. - -- *./units/bits/external* - - - Contains header files of general purpose utilities that are not necessary - **mp-units** library specific. They are either implementation details of the - library or should be (or already are) the subject of separate standardization - proposals not related to a Physical Units library proposal. - -- *./units/generic* - - - Provides quantity types not related to any :term:`system of quantities` - (e.g. `dimensionless`, `angle`). - -- *./units/isq* - - - Contains the definition of quantity dimensions of International System of Quantities - (:term:`ISQ`). - - Its subfolders provide the definitions of various - :term:`systems of units ` with International System of Units (:term:`SI`) - being the most popular one. - -.. seealso:: - - More information on provided :term:`systems of units ` can be - found in :ref:`reference/systems:Systems` chapter. - -.. important:: - - While working with predefined systems please always include a header file with all - the definitions for the current system to limit the possibility of an ODR violation - (e.g. *units/isq/si/si.h*). diff --git a/docs/design/downcasting.rst b/docs/design/downcasting.rst deleted file mode 100644 index ebce55ba..00000000 --- a/docs/design/downcasting.rst +++ /dev/null @@ -1,161 +0,0 @@ -.. namespace:: units - -The Downcasting Facility -======================== - -Problem statement ------------------ - -Most of the C++ libraries in the world use template aliases to provide a friendly name for a -developer. Unfortunately, such aliases are quickly lost in a compilation process and as a -result the potential error log contains a huge source type rather than a short alias for it. -The same can be observed during debugging of a source code that use template aliases. - -Let's assume that we want to provide a user friendly name for a derived dimension of capacitance -quantity. Other libraries will do it in the following way:: - - using dim_capacitance = detail::derived_dimension_base, - exponent, - exponent, - exponent>; - -The above solution does provide a good developer's experience but a really poor one for the end -user. If we will get a compilation error message containing ``dim_capacitance`` in most cases -the compiler will print the following type instead of the alias:: - - units::detail::derived_dimension_base, - units::exponent, units::exponent, units::exponent > - -You can notice that in case of **mp-units** even this long syntax was carefully selected to -provide quite good user experience (some other units libraries produce a type that cannot easily -fit on one slide) but it is not questionable less readable than just ``dim_capacitance``. - -.. note:: - - To better understand how the framework works and not clutter the text and graphs with - long types in the following examples we will switch from ``dim_capacitance`` to ``dim_area``. - The latter one has much shorter definition but the end result for both will be exactly the same - - user-friendly, short name printed by the compiler and the debugger. - - -As we lack opaque/strong typedefs in the C++ language the only way to improve our case is -to use inheritance: - -.. image:: /_static/img/downcast_1.png - :align: center - -.. - http://www.nomnoml.com - - [derived_dimension_base>]<:-[dim_area] - -This gives us a nice looking strong type when directly used by the user. However, we just got -ourselves into problems. The library's framework does not know how to switch from a long -instantiation of a ``derived_dimension_base`` class template that was generated as a result -of dimensional calculation to a nicely named child class assigned by the user for this -instantiation. - - -How it works? -------------- - -To support this **mp-units** library introduces a new downcasting facility implemented fully -as a library feature. It creates 1-to-1 link between a long class template instantiation and a -strong type provided by the user. This provides automatic type substitution mechanism in the -framework. - -.. important:: - - The above 1-1 correspondence means that only one child class can be provided for a specific - base class template instantiation. If a user will try to assign another child class to - already used base class template instantiation the program will not compile. - -The downcasting facility is provided by injecting two classes into our hierarchy: - -.. image:: /_static/img/downcast_2.png - :align: center - -.. - http://www.nomnoml.com - - [downcast_base>>]<:-[detail::derived_dimension_base>] - [detail::derived_dimension_base>]<:-[downcast_child>>] - [downcast_child>>]<:-[dim_area] - -In the above example: - -- ``dim_area`` is a downcasting target (child class) - -- ``detail::derived_dimension_base`` class template instantiation is a downcasting source (base class) - -- `downcast_base` is a class that implements :abbr:`CRTP (Curiously Recurring Template Pattern)` - idiom, stores the base of a downcasting operation in a ``downcast_base_type`` member type, - and provides only a Hidden Friend non-member function declaration of ``downcast_guide`` which is an - :abbr:`ADL (Argument Dependent Lookup)` entry point for the downcasting operation:: - - template - struct downcast_base { - using downcast_base_type = BaseType; - friend auto downcast_guide(downcast_base); // declaration only (no implementation) - }; - - .. important:: - - An important design point here is that this friend function does not return any specific type - in its declaration and no definition is provided at this point. - -- `downcast_child` is another :abbr:`CRTP (Curiously Recurring Template Pattern)` class template - that defines the implementation of a non-member friend function of the `downcast_base` class - template:: - - template - struct downcast_child : T { - friend auto downcast_guide(typename T::downcast_base) { return Target(); } - }; - - This is the place where the actual return type of the ``downcast_guide`` function is provided - which serves as a target type of the downcasting operation. - - In the above class template definition `Downcastable` is a concepts that verifies if a type - implements and can be used in a downcasting facility:: - - template - concept Downcastable = - requires { - typename T::downcast_base_type; - } && - std::derived_from>; - - -With such :abbr:`CRTP (Curiously Recurring Template Pattern)` types the only thing the user -has to do in order to register a new type in the downcasting facility is to publicly derive -from `downcast_child` and pass this type as the first template argument of the `downcast_child` -class template. - -Until now we scoped on how we define the base and target of a downcasting operation. To -perform the actual downcasting operation a dedicated alias template is provided:: - - template - using downcast = decltype(detail::downcast_impl()); - -`downcast` is used to obtain the target type of the downcasting operation registered for a -given instantiation in a base type. ``detail::downcast_impl`` checks if a downcasting -target is registered for the specific base class. If yes, it returns the registered type, -otherwise it works like a regular identity type trait returning a provided base class:: - - namespace detail { - - template - concept has_downcast_guide = requires(T t) { downcast_guide(t); }; - - template - constexpr auto downcast_impl() - { - if constexpr(has_downcast_guide) - return decltype(downcast_guide(std::declval>()))(); - else - return T(); - } - - } diff --git a/docs/design/quantity.rst b/docs/design/quantity.rst deleted file mode 100644 index 47f65096..00000000 --- a/docs/design/quantity.rst +++ /dev/null @@ -1,62 +0,0 @@ -.. namespace:: units - -quantity -======== - -Interface ---------- - - The value of a quantity is generally expressed as the product of a number and a unit. The - unit is simply a particular example of the quantity concerned which is used as a reference, - and the number is the ratio of the value of the quantity to the unit. - - -`quantity` class template provides a similar interface to -`std::chrono::duration `_. -The difference is that it uses ``double`` as a default representation and has -a few additional member types and functions:: - - template U, Representation Rep = double> - class quantity { - public: - using dimension = D; - using unit = U; - using rep = Rep; - - [[nodiscard]] static constexpr quantity one() noexcept; - // ... - }; - - template - requires detail::basic_arithmetic && (!equivalent>) - [[nodiscard]] constexpr Quantity auto operator*(const quantity& lhs, - const quantity& rhs); - - template - requires std::magma - [[nodiscard]] constexpr Quantity auto operator/(const Value& v, - const quantity& q); - - template - requires detail::basic_arithmetic && (!equivalent) - [[nodiscard]] constexpr Quantity auto operator/(const quantity& lhs, - const quantity& rhs); - -Additional functions provide the support for operations that result in a -different dimension type than those of their arguments. ``equivalent`` -constraint requires two dimensions to be either the same or have convertible -units of base dimension (with the same reference unit). - -Beside adding new elements a few other changes where applied compared to the -`std::chrono::duration `_ -class template: - -1. The ``std::chrono::duration`` is using ``std::common_type_t`` to find a common - representation for a calculation result. Such a design was reported as problematic - by SG6 (numerics study group) members as sometimes we want to provide a different - type in case of multiplication and different in case of division. ``std::common_type`` - lacks that additional information. That is why `quantity` uses the resulting - type of a concrete operator operation. -2. ``quantity::operator%()`` is constrained with `treat_as_floating_point` type trait to limit the - types to integral representations only. Also ``quantity::operator%(Rep)`` takes ``Rep`` as a - template argument to limit implicit conversions. diff --git a/docs/design/quantity_kind.rst b/docs/design/quantity_kind.rst deleted file mode 100644 index 2ba41356..00000000 --- a/docs/design/quantity_kind.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. namespace:: units - -quantity_kind -============= - -The ``quantity_kind`` class template provides a similar interface to ``quantity``. - -Kinds ------ - -The first template parameter of ``quantity_kind`` is a ``Kind``. - -``Kind`` s, by themselves: - - * Wrap a ``Dimension``, and - * opt into the downcasting facility. - -If a dimensional analysis operator on a quantity of kind *A* -can result on a quantity of kind *B*, -*A* and *B* are *related*. - -The library provides two ``Kind`` bases, ``kind`` and ``derived_kind``. - -``kind`` is an entry point, and there's only one per set of related kinds. - -``derived_kind`` is used to explicitly name other related kinds. -Unnamed, they look like ``detail::_kind_base``. - -Unnamed kinds, like unnamed units and dimensions, -allows (intermediate) results in formulas without having to name them. - -Quantity kinds --------------- - -``quantity_kind`` wraps a ``quantity`` and layers over its dimensional analysis. -While all properties of the ``quantity`` apply transparently, -results are always ``quantity_kind`` s related to the kind(s) of the argument(s). - -One of the arguments to the dimensional analysis operators can also be ``Quantity``. - -The way back to ``quantity`` is through the ``.common()`` observer. - -Intra-kind operations ---------------------- - -``quantity_kind`` takes care of operators between related quantity kinds. -Intra-kind operations can be opted into as follows:: - - struct width : kind {}; - struct height : kind {}; - - size2d operator+(QuantityKindOf auto, QuantityKindOf auto); diff --git a/docs/examples.rst b/docs/examples.rst deleted file mode 100644 index 342dadd1..00000000 --- a/docs/examples.rst +++ /dev/null @@ -1,11 +0,0 @@ -Examples -======== - -.. toctree:: - :maxdepth: 2 - - examples/basics - examples/kalman_filter - examples/custom_representation - examples/custom_systems - examples/custom_utilities diff --git a/docs/examples/basics.rst b/docs/examples/basics.rst deleted file mode 100644 index 8db47e03..00000000 --- a/docs/examples/basics.rst +++ /dev/null @@ -1,18 +0,0 @@ -Basics -====== - -The following examples highlight the basics of the library design. - -.. toctree:: - :maxdepth: 1 - - basics/hello_units - basics/clcpp_response - basics/avg_speed - basics/box_example - basics/capacitor_time_curve - basics/unknown_dimension - basics/foot_pound_second - basics/experimental_angle - basics/total_energy - basics/glide_computer diff --git a/docs/examples/basics/avg_speed.rst b/docs/examples/basics/avg_speed.rst deleted file mode 100644 index 46906984..00000000 --- a/docs/examples/basics/avg_speed.rst +++ /dev/null @@ -1,7 +0,0 @@ -avg_speed -========= - -.. literalinclude:: ../../../example/references/avg_speed.cpp - :caption: avg_speed.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/box_example.rst b/docs/examples/basics/box_example.rst deleted file mode 100644 index c75116d3..00000000 --- a/docs/examples/basics/box_example.rst +++ /dev/null @@ -1,7 +0,0 @@ -box_example -=========== - -.. literalinclude:: ../../../example/references/box_example.cpp - :caption: box_example.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/capacitor_time_curve.rst b/docs/examples/basics/capacitor_time_curve.rst deleted file mode 100644 index ea9e4f58..00000000 --- a/docs/examples/basics/capacitor_time_curve.rst +++ /dev/null @@ -1,7 +0,0 @@ -capacitor_time_curve -==================== - -.. literalinclude:: ../../../example/references/capacitor_time_curve.cpp - :caption: capacitor_time_curve.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/clcpp_response.rst b/docs/examples/basics/clcpp_response.rst deleted file mode 100644 index 417b8ac0..00000000 --- a/docs/examples/basics/clcpp_response.rst +++ /dev/null @@ -1,7 +0,0 @@ -clcpp_response -============== - -.. literalinclude:: ../../../example/references/clcpp_response.cpp - :caption: clcpp_response.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/experimental_angle.rst b/docs/examples/basics/experimental_angle.rst deleted file mode 100644 index 71c060b3..00000000 --- a/docs/examples/basics/experimental_angle.rst +++ /dev/null @@ -1,7 +0,0 @@ -experimental_angle -================== - -.. literalinclude:: ../../../example/references/experimental_angle.cpp - :caption: experimental_angle.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/foot_pound_second.rst b/docs/examples/basics/foot_pound_second.rst deleted file mode 100644 index 9d15c786..00000000 --- a/docs/examples/basics/foot_pound_second.rst +++ /dev/null @@ -1,7 +0,0 @@ -foot_pound_second -================= - -.. literalinclude:: ../../../example/references/foot_pound_second.cpp - :caption: foot_pound_second.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/glide_computer.rst b/docs/examples/basics/glide_computer.rst deleted file mode 100644 index 002d9a2e..00000000 --- a/docs/examples/basics/glide_computer.rst +++ /dev/null @@ -1,81 +0,0 @@ -.. namespace:: units - -glide_computer -============== - -This example presents the usage of: - -- `quantity_point` to mark "absolute" quantities like ``timestamp`` -- `quantity_point_kind` to mark "absolute" kinds of quantities like ``altitude`` (as opposed to ``height``), -- different kinds for length, time, and speed, -- the use of quantity kinds to show how to handle 3D space for aviation needs, -- unit constants to initialize the database -- quantities text output formatting, -- cooperation with `std::chrono`. - -.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h - :caption: glide_computer.h - :start-at: #include - :end-at: // - flight path exactly on a shortest possible line to destination - :linenos: - :lineno-match: - -The use of `quantity_kind` and `quantity_point_kind` provides strong typing -that divide quantities and quantity points to the ones on a horizontal (X, Y) plane and vertical (Z) axis. -Their purpose is to make different kinds of quantity -(i.e. length) separate strong types (i.e. distance, height). -Additionally, separating a quantity from its quantity point -means that we can define a ``height`` and ``altitude`` as different strong types. -A quantity point provides a more restricted interface meant for absolute calculations. - -The glide calculator engine also take benefits from different :term:`kinds of quantities `. -For example we have 3 for a quantity of length: - -- ``distance`` - a relative horizontal distance between 2 points on Earth -- ``height`` - a relative altitude difference between 2 points in the air -- ``altitude`` - an absolute altitude value measured form the mean sea level (AMSL). - -.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h - :caption: glide_computer.h - :start-after: // - flight path exactly on a shortest possible line to destination - :end-before: // text output - :linenos: - :lineno-match: - -Next a custom text output is provided both for C++ output streams and the text formatting facility. - -.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h - :caption: glide_computer.h - :start-at: // text output - :end-before: // definition of glide computer databases and utilities - :linenos: - :lineno-match: - -The engine of this simple glide computer works on quantities of the SI units with a floating-point -representation. The user can pass any unit valid for a given quantity and the library will automatically -convert it to the one required by the engine interface. - -The glide calculator takes task created as a list of waypoints, glider performance data, weather conditions, -safety constraints, and a towing height. - -.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h - :caption: glide_computer.h - :start-at: // definition of glide computer databases and utilities - :linenos: - :lineno-match: - -.. literalinclude:: ../../../example/references/glide_computer_example.cpp - :caption: glide_computer_example.cpp - :start-at: #include - :linenos: - :lineno-match: - -Having all of that it estimates the number of flight phases (towing, circling, gliding, final glide) -needed to finish a task. As an output it provides the duration needed to finish the task while -flying a selected glider in the specific weather conditions. - -.. literalinclude:: ../../../example/glide_computer/glide_computer.cpp - :caption: glide_computer.cpp - :start-at: #include - :linenos: - :lineno-match: diff --git a/docs/examples/basics/hello_units.rst b/docs/examples/basics/hello_units.rst deleted file mode 100644 index ab33ce32..00000000 --- a/docs/examples/basics/hello_units.rst +++ /dev/null @@ -1,7 +0,0 @@ -hello_units -=========== - -.. literalinclude:: ../../../example/hello_units.cpp - :caption: hello_units.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/total_energy.rst b/docs/examples/basics/total_energy.rst deleted file mode 100644 index f65cc23d..00000000 --- a/docs/examples/basics/total_energy.rst +++ /dev/null @@ -1,7 +0,0 @@ -total_energy -============ - -.. literalinclude:: ../../../example/references/total_energy.cpp - :caption: total_energy.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/basics/unknown_dimension.rst b/docs/examples/basics/unknown_dimension.rst deleted file mode 100644 index 27876666..00000000 --- a/docs/examples/basics/unknown_dimension.rst +++ /dev/null @@ -1,7 +0,0 @@ -unknown_dimension -================= - -.. literalinclude:: ../../../example/references/unknown_dimension.cpp - :caption: unknown_dimension.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/custom_representation.rst b/docs/examples/custom_representation.rst deleted file mode 100644 index f8c48445..00000000 --- a/docs/examples/custom_representation.rst +++ /dev/null @@ -1,10 +0,0 @@ -Custom Representation Types -=========================== - -The following examples show how to work with custom represenation types. - -.. toctree:: - :maxdepth: 1 - - custom_representation/measurement - custom_representation/linear_algebra diff --git a/docs/examples/custom_representation/linear_algebra.rst b/docs/examples/custom_representation/linear_algebra.rst deleted file mode 100644 index 9bb9ac1e..00000000 --- a/docs/examples/custom_representation/linear_algebra.rst +++ /dev/null @@ -1,7 +0,0 @@ -linear_algebra -============== - -.. literalinclude:: ../../../example/references/linear_algebra.cpp - :caption: linear_algebra.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/custom_representation/measurement.rst b/docs/examples/custom_representation/measurement.rst deleted file mode 100644 index da278975..00000000 --- a/docs/examples/custom_representation/measurement.rst +++ /dev/null @@ -1,7 +0,0 @@ -measurement -=========== - -.. literalinclude:: ../../../example/measurement.cpp - :caption: measurement.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/custom_systems.rst b/docs/examples/custom_systems.rst deleted file mode 100644 index 19600114..00000000 --- a/docs/examples/custom_systems.rst +++ /dev/null @@ -1,9 +0,0 @@ -Custom Systems -============== - -The following examples show how to define custom systems of units and quantities. - -.. toctree:: - :maxdepth: 1 - - custom_systems/custom_systems diff --git a/docs/examples/custom_systems/custom_systems.rst b/docs/examples/custom_systems/custom_systems.rst deleted file mode 100644 index 673bb0b2..00000000 --- a/docs/examples/custom_systems/custom_systems.rst +++ /dev/null @@ -1,7 +0,0 @@ -custom_systems -============== - -.. literalinclude:: ../../../example/custom_systems.cpp - :caption: custom_systems.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/custom_utilities.rst b/docs/examples/custom_utilities.rst deleted file mode 100644 index 47149287..00000000 --- a/docs/examples/custom_utilities.rst +++ /dev/null @@ -1,9 +0,0 @@ -Custom Utilites -=============== - -The following examples present how to reuse library facilities to create custom utilities. - -.. toctree:: - :maxdepth: 1 - - custom_utilities/conversion_factor diff --git a/docs/examples/custom_utilities/conversion_factor.rst b/docs/examples/custom_utilities/conversion_factor.rst deleted file mode 100644 index 79de28d2..00000000 --- a/docs/examples/custom_utilities/conversion_factor.rst +++ /dev/null @@ -1,7 +0,0 @@ -conversion_factor -================= - -.. literalinclude:: ../../../example/conversion_factor.cpp - :caption: conversion_factor.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter.rst b/docs/examples/kalman_filter.rst deleted file mode 100644 index 690b452d..00000000 --- a/docs/examples/kalman_filter.rst +++ /dev/null @@ -1,17 +0,0 @@ -Kalman Filter Tutorial -====================== - -The following examples are based on the `Kalman Filter `_ tutorial. - -.. toctree:: - :maxdepth: 1 - - kalman_filter/kalman - kalman_filter/example_1 - kalman_filter/example_2 - kalman_filter/example_3 - kalman_filter/example_4 - kalman_filter/example_5 - kalman_filter/example_6 - kalman_filter/example_7 - kalman_filter/example_8 diff --git a/docs/examples/kalman_filter/example_1.rst b/docs/examples/kalman_filter/example_1.rst deleted file mode 100644 index 28a7da5b..00000000 --- a/docs/examples/kalman_filter/example_1.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 1 - Weighting the gold -============================== - -Implementation of: https://www.kalmanfilter.net/alphabeta.html#ex1 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_1.cpp - :caption: kalman_filter-example_1.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_2.rst b/docs/examples/kalman_filter/example_2.rst deleted file mode 100644 index 58312b4b..00000000 --- a/docs/examples/kalman_filter/example_2.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 2 - Tracking the constant velocity aircraft in one dimension -==================================================================== - -Implementation of: https://www.kalmanfilter.net/alphabeta.html#ex2 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_2.cpp - :caption: kalman_filter-example_2.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_3.rst b/docs/examples/kalman_filter/example_3.rst deleted file mode 100644 index a0adfe76..00000000 --- a/docs/examples/kalman_filter/example_3.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 3 - Tracking accelerating aircraft in one dimension -=========================================================== - -Implementation of: https://www.kalmanfilter.net/alphabeta.html#ex3 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_3.cpp - :caption: kalman_filter-example_3.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_4.rst b/docs/examples/kalman_filter/example_4.rst deleted file mode 100644 index a97a1f06..00000000 --- a/docs/examples/kalman_filter/example_4.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 4 - Tracking accelerating aircraft with the α−β−γ filter -================================================================ - -Implementation of: https://www.kalmanfilter.net/alphabeta.html#ex4 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_4.cpp - :caption: kalman_filter-example_4.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_5.rst b/docs/examples/kalman_filter/example_5.rst deleted file mode 100644 index e1e10d78..00000000 --- a/docs/examples/kalman_filter/example_5.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 5 - Estimating the building height -========================================== - -Implementation of: https://www.kalmanfilter.net/kalman1d.html#ex5 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_5.cpp - :caption: kalman_filter-example_5.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_6.rst b/docs/examples/kalman_filter/example_6.rst deleted file mode 100644 index 0f2b5b54..00000000 --- a/docs/examples/kalman_filter/example_6.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 6 - Estimating the temperature of the liquid in a tank -============================================================== - -Implementation of: https://www.kalmanfilter.net/kalman1d.html#ex6 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_6.cpp - :caption: kalman_filter-example_6.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_7.rst b/docs/examples/kalman_filter/example_7.rst deleted file mode 100644 index ea5abef8..00000000 --- a/docs/examples/kalman_filter/example_7.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 7 - Estimating the temperature of the heating liquid I -============================================================== - -Implementation of: https://www.kalmanfilter.net/kalman1d.html#ex7 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_7.cpp - :caption: kalman_filter-example_7.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/example_8.rst b/docs/examples/kalman_filter/example_8.rst deleted file mode 100644 index 87c1b0cb..00000000 --- a/docs/examples/kalman_filter/example_8.rst +++ /dev/null @@ -1,9 +0,0 @@ -Example 8 - Estimating the temperature of the heating liquid II -=============================================================== - -Implementation of: https://www.kalmanfilter.net/kalman1d.html#ex8 - -.. literalinclude:: ../../../example/kalman_filter/kalman_filter-example_8.cpp - :caption: kalman_filter-example_8.cpp - :start-at: #include - :linenos: diff --git a/docs/examples/kalman_filter/kalman.rst b/docs/examples/kalman_filter/kalman.rst deleted file mode 100644 index cabf2043..00000000 --- a/docs/examples/kalman_filter/kalman.rst +++ /dev/null @@ -1,7 +0,0 @@ -Common utility header file (``kalman.h``) -========================================= - -.. literalinclude:: ../../../example/kalman_filter/kalman.h - :caption: kalman.h - :start-at: #include - :linenos: diff --git a/docs/faq.rst b/docs/faq.rst deleted file mode 100644 index 0aab20c8..00000000 --- a/docs/faq.rst +++ /dev/null @@ -1,131 +0,0 @@ -.. namespace:: units - -FAQ -=== - -.. contents:: Questions: - :local: - - -General -------- - -Why dimensions depend on units and not vice versa? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Most of the libraries define units in terms of dimensions and this was also an -initial approach for this library. However, it turns out that for such a design -it is hard to provide support for all the required scenarios. - -The first of them is to support multiple unit systems (like SI, CGS, ...) where -each of can have a different base unit for the same dimension. Base quantity of -dimension length in SI should use ``m`` to print the unit symbol to the text -output, while the same dimension for CGS should use ``cm``. Also, it helps in -conversions among those systems. - -The second one is to support natural units where more than one dimension can be -measured with the same unit (i.e. ``GeV``). Also if someone will decide to -implement a systems where SI quantities of the same kind are expressed as -different dimensions (i.e. height, width, and depth) all of them will just be -measured in meters. - - -Why other systems are defined in the `isq::si` namespace? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -All systems defined in the `isq::si` namespace are defined in terms of -base units that are convertible to the :term:`SI` units. This enables conversions -of units of the same physical dimension between different systems. - -.. seealso:: - - More details on this subject can be found in the - :ref:`use_cases/extensions:Custom Systems` chapter. - - -Why a dimensionless quantity is not just an fundamental arithmetic type? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In the initial design of this library the resulting type of the division of -two quantities was their common representation type:: - - static_assert(std::is_same_v); - -The reasoning behind it was to not provide a false impression of a strong `quantity` type -for something that looks and feels like a regular number. Also all of the mathematic -and trigonometric functions were working fine out of the box with such representation -types, so we did not have to rewrite ``sin()``, ``cos()``, ``exp()``, and others. - -However, the feedback we got from the production usage was that such an approach -is really bad for generic programming. It is really hard to handle the result of -division (or multiplication) of two quantities as it might be either a `quantity` -or a fundamental type. If we want to raise such a result to some power we have to -either use ``units::pow`` or ``std::pow`` depending on the resulting type. Those -are only a few from many similar issues related to such an approach. - -This is why it was decided to go with the current approach. - -.. seealso:: - - More information on the current design can be found in - the :ref:`framework/quantities:Dimensionless Quantities` chapter. - - -Why do we spell ``metre`` instead of ``meter``? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Well, this is how [ISO80000]_ defines it (British English spelling by default). - - -User Defined Literals (UDLs) ----------------------------- - -Why all UDLs are prefixed with ``_q_`` instead of just using unit symbol? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. note:: - - Every ``_q_*`` UDL will be replaced by the ``q_*`` literal when/if **mp-units** - will become a part of the C++ Standard Library. - -Usage of only unit symbols in UDLs would be a preferred approach (less to type, -easier to understand and maintain). However, while increasing the coverage for -the library we learned that there are a lot unit symbols that conflict with -built-in types or numeric extensions. A few of those are: ``F`` (farad), -``J`` (joule), ``W`` (watt), ``K`` (kelvin), ``d`` (day), -``l`` or ``L`` (litre), ``erg``, ``ergps``. For a while for those we used ``_`` -prefix to make the library work at all, but at some point we had to unify the -naming and we came up with ``_q_`` prefix which results in a creation of -quantity of a provided unit. - - -Text formatting ---------------- - -Why Unicode quantity symbols are used by default instead of ASCII-only characters? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Both C++ and :term:`SI` ([ISO80000]_) are standardized by the -:abbr:`ISO (International Organization for Standardization)`. :term:`SI` standard -specifies Unicode symbols as the official unit names for some quantities (i.e. ``Ω`` -symbol for the resistance quantity). As **mp-units** library -is being proposed for standardization as a part of the C++ Standard Library we have -to obey the rules and be consistent with ISO specifications. - -.. seealso:: - - We do understand engineering reality and constraints and that is why the library - has the option of :ref:`framework/text_output:ASCII-only quantity symbols`. - - -Compilation Errors ------------------- - -error: reference to ‘time’ is ambiguous -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Unfortunately, if `using-directives `_ -(i.e. ``using namespace units::isq::si``) are being used, `units::isq::si::time` -will collide with C `time `_ function. In -such a case the library's ``time`` function needs to be prefixed with at least one (or all) -namespace names. diff --git a/docs/framework.rst b/docs/framework.rst deleted file mode 100644 index 952d66fc..00000000 --- a/docs/framework.rst +++ /dev/null @@ -1,25 +0,0 @@ -Framework Basics -================ - -.. note:: - - For brevity all the code examples in this chapter assume:: - - using namespace units; - using namespace units::isq; - -.. toctree:: - :maxdepth: 2 - - framework/basic_concepts - framework/quantity_like - framework/quantities - framework/quantity_points - framework/quantity_kinds - framework/dimensions - framework/magnitudes - framework/units - framework/arithmetics - framework/constants - framework/conversions_and_casting - framework/text_output diff --git a/docs/framework/arithmetics.rst b/docs/framework/arithmetics.rst deleted file mode 100644 index 22030a10..00000000 --- a/docs/framework/arithmetics.rst +++ /dev/null @@ -1,148 +0,0 @@ -.. namespace:: units - -Arithmetics -=========== - -Quantities ----------- - -Quantities of the same dimension can be easily added or subtracted with -each other and the result will always be a quantity of the same dimension: - -.. code-block:: - :emphasize-lines: 3-4 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - Length auto res1 = dist1 + dist2; - Length auto res2 = dist1 - dist2; - -Additionally, we can always multiply or divide a quantity by a -:term:`scalable number` and in such a case the quantity's dimension will also -not change: - -.. code-block:: - :emphasize-lines: 2-4 - - Length auto dist = 2 * m; - Length auto res1 = dist * 2; // 4 m - Length auto res2 = 3 * res1; // 12 m - Length auto res3 = res2 / 2; // 6 m - -However, if we try to multiply or divide quantities of the same or -different dimensions, or we will divide a scalable number by a quantity, we most -probably will always end up in a quantity of a yet another dimension: - -.. code-block:: - :emphasize-lines: 4-6 - - Length auto dist1 = 2 * m; - Length auto dist2 = 3 * m; - Time auto dur1 = 2 * s; - Area auto res1 = dist1 * dist2; // 6 m² - Speed auto res2 = dist1 / dur1; // 1 m/s - Frequency auto res3 = 10 / dur1; // 5 Hz - -However, please note that there is an exception from the above rule. -In case we divide the same dimensions, or multiply by the inverted -dimension, than we will end up with just a dimensionless quantity: - -.. code-block:: - :emphasize-lines: 4-5 - - Time auto dur1 = 10 * s; - Time auto dur2 = 2 * s; - Frequency auto fr1 = 5 * Hz; - Dimensionless auto v1 = dur1 / dur2; // quantity(5) - Dimensionless auto v2 = dur1 * fr1; // quantity(50) - -Quantity Kinds --------------- - -Quantity kinds behave the same as quantities for all operations, -except that the quantity types in the operators' declarations -are quantity kind types instead. -Additionally, for the dimensional analysis operators, -you can use a quantity argument instead of a quantity kind. - -.. code-block:: - :emphasize-lines: 8-9 - - struct height_kind : kind {}; - struct rate_of_climb_kind : derived_kind {}; - - template using height = quantity_kind; - template using rate_of_climb = quantity_kind; - - height h{100 * m}; - rate_of_climb rate = h / (25 * s); - // quantity_kind(4 * m / s) - -.. code-block:: - :emphasize-lines: 8-12 - - struct width_kind : kind {}; - struct horizontal_area_kind : derived_kind {}; - - template using width = quantity_kind; - template using horizontal_area = quantity_kind; - - width w{5 * m}; - horizontal_area area1 = w * w; - // quantity_kind(25 * m * m) - width w2 = area1 / w; // quantity_kind(5 * m) - auto q1 = w / w; // Dimensionless quantity kinds related to width - auto q2 = w / (5 * m); // with .common() equal to quantity{1} - -Quantity Points ---------------- - -Quantity points have a more restricted set of operations. -Quantity can be added to or subtracted -from a quantity point of the same origin. -The result will always be a quantity point of the same origin: - -.. code-block:: - :emphasize-lines: 3-5 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - QuantityPoint auto res1 = quantity_point{dist1} + dist2; - QuantityPoint auto res2 = dist1 + quantity_point{dist2}; - QuantityPoint auto res3 = quantity_point{dist1} - dist2; - -We can also subtract two quantity points. -The result is a relative quantity of the same dimension: - -.. code-block:: - :emphasize-lines: 3 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - Length auto res1 = quantity_point{dist1} - quantity_point{dist2}; - -.. note:: - - It is not allowed to: - - - add quantity points, - - subtract a quantity point from a quantity, - - multiply nor divide quantity points with anything else, and - - mix quantity points with different origins: - - .. code-block:: - :emphasize-lines: 3-5 - - Length auto dist1 = 2 * m; - Length auto dist2 = 1 * m; - auto res1 = quantity_point{dist1} + quantity_point{dist2}; // ERROR - auto res2 = dist1 - quantity_point{dist2}; // ERROR - auto res3 = quantity_point{dist1} / (2 * s); // ERROR - auto res4 = quantity_point{std::chrono::utc_second{1s}} + - quantity_point{std::chrono::sys_second{1s}}; // ERROR - -Quantity Point Kinds --------------------- - -The same restrictions of a quantity point with respect to its quantity -apply to a quantity point kind with respect to its quantity kind. diff --git a/docs/framework/basic_concepts.rst b/docs/framework/basic_concepts.rst deleted file mode 100644 index 93139bd8..00000000 --- a/docs/framework/basic_concepts.rst +++ /dev/null @@ -1,117 +0,0 @@ -.. namespace:: units - -Basic Concepts -============== - -The most important concepts in the library are `Unit`, `Dimension`, -`Quantity`, `QuantityPoint`, `QuantityKind`, and `QuantityPointKind`: - - -.. raw:: html - - - -.. - https://www.planttext.com - - @startuml - - skinparam monochrome true - skinparam shadowing false - skinparam backgroundColor #fcfcfc - - hide circle - hide members - show class methods - - package Unit <> [[../../framework/units.html]] { - } - - package Dimension <> [[../../framework/dimensions.html]] { - } - - package Kind <> [[../../framework/quantity_kinds.html#kind-creation]] { - abstract kind [[../../framework/quantity_kinds.html#kind-creation]] - } - - package PointKind <> [[../../framework/quantity_kinds.html#quantity-point-kinds]] { - abstract point_kind [[../../framework/quantity_kinds.html#quantity-point-kinds]] - } - - package PointOrigin <> [[../../framework/quantity_points.html#point-origins]] { - abstract point_origin [[../../framework/quantity_points.html#point-origins]] - } - - package Quantity <> [[../../framework/quantities.html]] { - class quantity [[../../framework/quantities.html#construction]] { - rep number() - } - } - - package QuantityPoint <> [[../../framework/quantity_points.html]] { - class quantity_point [[../../framework/quantity_points.html#construction]] { - quantity relative() - } - } - - package QuantityKind <> [[../../framework/quantity_kinds.html]] { - class quantity_kind [[../../framework/quantity_kinds.html#construction]] { - quantity common() - } - } - - package QuantityPointKind <> [[../../framework/quantity_kinds.html#quantity-point-kinds]] { - class quantity_point_kind [[../../framework/quantity_kinds.html#quantity-point-kinds]] { - quantity_kind relative() - } - } - - - Unit <.. Dimension - - Dimension <... Quantity - Unit <... Quantity - - Dimension <... Kind - Dimension <... PointOrigin - PointOrigin <... PointKind - Kind <... PointKind - - Unit <... QuantityPoint - PointOrigin <... QuantityPoint - quantity --* quantity_point - - Unit <... QuantityKind - Kind <... QuantityKind - quantity --* quantity_kind - - Unit <... QuantityPointKind - PointKind <... QuantityPointKind - quantity_kind --* quantity_point_kind - - @enduml - -`Unit` is a basic building block of the library. Every dimension works with -a concrete hierarchy of units. Such hierarchy defines a reference unit and -often a few scaled versions of it. Examples: ``second``, ``metre``, ``kilometre_per_hour``. - -`Dimension` concept matches a dimension of either a base or derived quantity. -`base_dimension` is instantiated with a unique symbol identifier and a base -unit. `derived_dimension` is a list of exponents of either base or other -derived dimensions. Examples: ``si::dim_time``, ``si::dim_length``, ``si::dim_speed``. - -`Quantity` is a concrete amount of a unit for a specified dimension with a -specific representation. Examples: ``quantity``, -``si::length``, ``si::speed``. - -`QuantityPoint` is an absolute `Quantity` with respect to an origin. -Examples: timestamp (as opposed to duration), absolute temperature -(as opposed to temperature difference). - -`QuantityKind` is a `Quantity` with more specific usage. Examples: -distance (``horizonal_kind``) and height (``vertical_kind``) are different kinds -of a length quantity. - -`QuantityPointKind` is an absolute `QuantityKind` with respect to an origin. -Examples: altitude is a quantity point of ``vertical_kind`` (as opposed to -height). diff --git a/docs/framework/constants.rst b/docs/framework/constants.rst deleted file mode 100644 index 46995c27..00000000 --- a/docs/framework/constants.rst +++ /dev/null @@ -1,33 +0,0 @@ -.. namespace:: units - -Quantity Constants -================== - -In the **mp-units** library quantity constants are implemented as variable -templates of `quantity` types parametrized by the quantity's representation -type. - -Additionally, in case of the :term:`SI` its physical constants are put in -separate namespaces named after the official release of the :term:`SI` -specification. This is needed to be able to provide backward and forward -compatibility as exact values of physical constants tend to change with time -(in most cases they are getting more and more accurate with every -specification release). - -For example the speed of light constant in :term:`SI` is defined as:: - - namespace si::si2019 { - - template - inline constexpr auto speed_of_light = speed(299792458); - - } - -The same constant defined for natural units may be provided as:: - - namespace natural { - - template - inline constexpr auto speed_of_light = speed(1); - - } diff --git a/docs/framework/conversions_and_casting.rst b/docs/framework/conversions_and_casting.rst deleted file mode 100644 index ecc2b348..00000000 --- a/docs/framework/conversions_and_casting.rst +++ /dev/null @@ -1,190 +0,0 @@ -.. namespace:: units - -Conversions and Casting -======================= - - Programmers who are not full-time programming language geeks **hate lack of - implicit conversions** that they consider reasonable. Violate their expectations - for reasons they consider hypothetical problems and you get disuse. In type - terms, I usually **translate "reasonable" to "not narrowing" aka "not loosing - information."** That can reasonably easily be explained to non-language-experts. - - -- *Bjarne Stroustrup* - -The library tries to follow the above principle and at the same time is also consistent -with conversions of ``std::chrono::duration``. - - -No Conversions --------------- - -No conversions (either implicit or explicit) are available across quantities of -different dimensions:: - - si::length d1 = 1 * s; // Compile-time error - si::length d2(1 * s); // Compile-time error - auto d3 = quantity_cast(1 * s); // Compile-time error - - -Implicit --------- - -Implicit conversions are allowed only across quantities of the same dimension: - -- for integral types with ratios that guarantee no precision loss:: - - si::length d1 = 1 * km + 1 * m; // OK - si::length d2 = 1 * km + 1 * m; // OK - si::length d3 = 1 * km + 1 * m; // Compile-time error - si::length d4(1 * km + 1 * m); // Compile-time error - si::length d5 = 1 * m + 1 * ft; // Compile-time error - si::length d6(1 * m + 1 * ft); // Compile-time error - -- from an integral to a floating-point representation even in case of a truncating - ratio:: - - si::length d7 = 1 * km + 1 * m; // OK - si::length d8 = 1 * m + 1 * ft; // OK - -- when both sides use a floating-point representation:: - - si::length d9 = 1.23 * m; // Compile-time error - si::length d10 = 1.23 * m; // OK - - -Explicit --------- - -Explicit conversions are available with the `quantity_cast`, `quantity_point_cast`, -`quantity_kind_cast`, and `quantity_point_kind_cast` function templates. -They are especially useful to force a truncating conversion across quantities of the same -dimension for integral representation types and ratios that may cause precision loss:: - - si::length d1 = quantity_cast(1 * km + 1 * m); // OK - si::length d2 = quantity_cast(1 * s); // Error - -.. seealso:: - - Explicit casts are also really useful when working with legacy interfaces. - More information on this subject can be found in the - :ref:`use_cases/legacy_interfaces:Working with Legacy Interfaces` chapter. - -Quantity Cast Overloads -^^^^^^^^^^^^^^^^^^^^^^^ - -`quantity_cast` comes with several overloads: - -.. code-block:: - :linenos: - - std::cout << "Distance: " << quantity_cast>(d) << '\n'; - std::cout << "Distance: " << quantity_cast(d) << '\n'; - std::cout << "Distance: " << quantity_cast(d) << '\n'; - std::cout << "Distance: " << quantity_cast(d) << '\n'; - std::cout << "Distance: " << quantity_cast(d) << '\n'; - -`quantity_cast` in line #1 takes a specific target `quantity` type to which an explicit -cast should be performed. This option will change multiple quantity properties at once -(unit, representation, etc). However, it is also possible to force only some properties at -once and leave the rest intact: - -- line #2 forces only a specific destination dimension type, -- line #3 forces only a specific destination unit type, -- line #4 sets only a representation type to the type provided by the user, -- line #5 forces both a specific dimension and a unit while preserving the original - representation type. - -`quantity_point_cast` takes anything that works for `quantity_point` -or a specific target `quantity_point`:: - - std::cout << "Point: " << quantity_point_cast(d) << '\n'; - -For a single explicit template argument, `quantity_point_kind_cast` is a superset of -`quantity_kind_cast`, which is also a superset of `quantity_cast`. -For the (dimension, unit) pair of explicit arguments case of `quantity_cast`, -`quantity_point_kind_cast` and `quantity_kind_cast` accept a `PointKind` and `Kind` -instead of a `Dimension`, respectively. - -.. seealso:: - - For more information on conversion and casting and on how to extend the above - "integral" vs "floating-point" logic please refer to the - :ref:`use_cases/custom_representation_types:Using Custom Representation Types` chapter. - - -Implicit conversions of dimensionless quantities ------------------------------------------------- - -As noted in the :ref:`framework/quantities:Dimensionless Quantities` chapter, -:term:`quantity of dimension one` is somehow special but still obey most of the rules defined -for quantities. However, as they represent numbers it would be highly uncomfortable to every -time type:: - - const auto d1 = 10 * km; - const auto d2 = 3 * km; - if(d1 / d2 > dimensionless(2)) { - // ... - } - -or:: - - const auto fill_time_left = (box.height / box.fill_level(measured_mass) - - dimensionless(1)) * fill_time; - -This is why it was decided to allow the ``dimensionless`` quantity of any -representation type to be implicitly constructible from this representation type. -With that the above examples can be rewritten as follows:: - - const auto d1 = 10 * km; - const auto d2 = 3 * km; - if(d1 / d2 > 2) { - // ... - } - -and:: - - const auto fill_time_left = (box.height / box.fill_level(measured_mass) - 1) * fill_time; - -The above is true only for dimensionless quantities of `one` unit. If our quantity have a unit with -ratio different than ``1`` the implicit conversion will not happen. This is to prevent cases were the code -could be ambiguous. For example:: - - Dimensionless auto foo(Length auto d1, Length auto d2) - { - return d1 / d2 + 1; - } - -As long as we can reason about what such code means for ``foo(10 * km, 2 * km)`` it is not that obvious -at all in the case of ``foo(10 * cm, 2 * ft)``. To make such code to compile for every case we have to -either change the type of the resulting unit to the one having ``ratio(1)`` (:term:`coherent derived unit`):: - - Dimensionless auto foo(Length auto d1, Length auto d2) - { - return quantity_cast(d1 / d2) + 1; - } - -or to explicitly state what is the unit of our dimensionless value, e.g. `one`, `percent`, etc:: - - Dimensionless auto foo(Length auto d1, Length auto d2) - { - return d1 / d2 + dimensionless(1); - } - -There is one more important point to note here. As the the dimensionless quantity is more than just -a number, it is never implicitly converted back to the representation type. This means that the following -code will not compile:: - - auto v = std::exp(10 * m / (5 * m)); - -To make it compile fine we have to either explicitly get the value stored in the quantity:: - - auto v = std::exp(quantity_cast(10 * m / (5 * m)).number()); - -or use a mathematical wrapper function from `units` namespace:: - - auto v = units::exp(10 * m / (5 * m)); - -.. important:: - - Always remember to explicitly cast the quantity to the destination unit with `quantity_cast` before - calling `quantity::number()`! diff --git a/docs/framework/dimensions.rst b/docs/framework/dimensions.rst deleted file mode 100644 index 1e1c298d..00000000 --- a/docs/framework/dimensions.rst +++ /dev/null @@ -1,206 +0,0 @@ -.. namespace:: units - -Dimensions -========== - -In the previous chapter we briefly introduced the notion of a physical -:term:`dimension`. Now it is time to learn much more about this subject. -Length, time, speed, area, energy are only a few examples of physical -dimensions. - -.. raw:: html - - - -.. - https://www.planttext.com - - -Base Dimensions ---------------- - -The quantities of base dimensions are called -:term:`base quantities ` which are the atomic building blocks -of a :term:`system of quantities`. For example the The International System -of Units (:term:`SI`) defines 7 of them: length, mass, time, electric -current, thermodynamic temperature, substance, and luminous intensity. - -To define a new base dimension the `base_dimension` class template is -provided. For example the SI base dimension of length can be defined as:: - - namespace si { - - struct dim_length : base_dimension<"L", metre> {}; - - } - -In the above code sample ``"L"`` is an base dimension's unique identifier -and `isq::si::metre` is a :term:`base unit` of this base dimension. We can -obtain those back easily with:: - - static_assert(si::dim_length::symbol == "L"); - static_assert(is_same_v); - - -Derived Dimensions ------------------- - -The quantities of derived dimensions are called -:term:`derived quantities ` and are derived from base -quantities. This means that they are created by multiplying or dividing -quantities of other dimensions. - -The [SIBrochure]_ states: - - All other quantities, with the exception of counts, are derived quantities, which may be - written in terms of base quantities according to the equations of physics. The dimensions of - the derived quantities are written as products of powers of the dimensions of the base - quantities using the equations that relate the derived quantities to the base quantities. - In general the dimension of any quantity :math:`Q` is written in the form of a dimensional product, - - :math:`dim Q = T^\alpha L^\beta M^\gamma I^\delta \Theta^\varepsilon N^\zeta J^\eta` - - where the exponents :math:`\alpha`, :math:`\beta`, :math:`\gamma`, :math:`\delta`, :math:`\varepsilon`, - :math:`\zeta` and :math:`\eta`, which are generally small integers, which can be positive, - negative, or zero, are called the dimensional exponents. - -Looking at the previous code snippets the area, speed, or frequency are -the examples of such quantities. Each derived quantity can be represented -as a unique list of exponents of base quantities. For example: - -- an area is a length base quantity raised to the exponent ``2`` -- a speed is formed from the length base quantity with exponent ``1`` - and time base quantity with exponent ``-1``. - -The above dimensions can be defined in the library with the -`derived_dimension` class template as follows:: - - namespace si { - - struct dim_area : derived_dimension> {}; - struct dim_speed : derived_dimension, exponent> {}; - - } - -In the above code sample `isq::si::square_metre` and -`isq::si::metre_per_second` are the -:term:`coherent derived units ` of those derived dimensions. - -Coherent unit argument is followed by the list of exponents that form this -derived dimension. This list is called a :term:`recipe` of this derived -dimension and may contain both base and derived dimensions. In the latter -case the dimension is being extracted to base dimensions by the framework -itself. The order and types of dimensions used in the recipe determine how -an dimension's unnamed unit symbol is being printed in the text output. - -.. seealso:: - - More information on how the :term:`recipe` affect the printed symbol - of unnamed unit can be found in the :ref:`framework/units:Derived Unnamed Units` - chapter. - -It is important to mention here that beside text output the order and -the number of elements in the `derived_dimension` definition does not -matter. Even if we define the above as: - -.. code-block:: - :emphasize-lines: 4, 6 - - namespace si { - - struct dim_area : derived_dimension, exponent> {}; - struct dim_speed : derived_dimension, exponent> {}; - - } - -the library will do its magic and will end up with the same -:term:`normalized derived dimension` which will allow the dimensional -analysis in the library to work as expected. - -.. note:: - - The first template argument of `derived_dimension` is the type of the - child class inherited from the instantiation of this `derived_dimension` - class template. This is called a - :abbr:`CRTP (Curiously Recurring Template Parameter)` Idiom and is used - in many places in this library to provide - :ref:`design/downcasting:The Downcasting Facility`. - - -Obtaining a Unit of the Dimension ---------------------------------- - -In order to obtain the base/coherent unit of any dimension type a -`dimension_unit` helper was introduced:: - - static_assert(is_same_v, si::metre>); - static_assert(is_same_v, si::metre_per_second>); - - - - -How do you feel about: - -inline constexpr second second; -? - -We could do the same to dimensions to not have to type dim_length{} all the time. - -6 replies 2 new -@JohelEGP -JohelEGP -2 days ago -mp_units::units::second is a variable. The reference isq::si::second could stay a type and s continue to be a variable. - -@mpusz -mpusz -2 days ago -Maintainer -Author -The problem is the following: - -Variables are really needed for a new design. We can ask users to put {} after every dimension unit, and reference types but it would be really nasty and a lot of boilerplate. -Short names have to be opt-in as they collide with a lot of code (especially on MSVC). -@JohelEGP -JohelEGP -yesterday -As pointed out by #389 (reply in thread), I think it'd be OK suffix _t to the types. - -@mpusz -mpusz -10 hours ago -Maintainer -Author -It will be visible in the compilation errors, which is inconvenient :-( - -Instead of: - -quantity>, derived_unit>> -we will have something like: - -quantity>, derived_unit>> -Personally, I like the first output more. - -Note that definition like: - -inline constexpr second second; -besides, being really unconventional, is allowed by the language and will not impact our users at all. A user is about to always work with values in the code and observe types in the compilation errors. Using the same nicely blends those two domains together. - -@mpusz -mpusz -10 hours ago -Maintainer -Author -I could use a list of values instead of types as template parameters in the dervied_dimension and derived_unit but in such case the error would look like: - -quantity{}>{}, derived_unit{}>{}>> -which also is not that nice. - -@JohelEGP -JohelEGP -6 hours ago -That's convincing. This justification should definitely be part of the documentation. diff --git a/docs/framework/magnitudes.rst b/docs/framework/magnitudes.rst deleted file mode 100644 index ed9f80f5..00000000 --- a/docs/framework/magnitudes.rst +++ /dev/null @@ -1,121 +0,0 @@ -.. namespace:: units - -Magnitudes -========== - -The ratio of two Units of the same Dimension---say, ``inches`` and ``centimeters``---is some -constant number, which is known at compile time. It's a positive real number---a *Magnitude*. - -We also use Magnitudes for *Dimensionless* Units. ``percent`` has a Magnitude of :math:`1/100`, and -``dozen`` would have a Magnitude of :math:`12`. - -Interestingly, it turns out that the usual numeric types are not up to this task. We need a -Magnitude representation that can do everything Units can do. This means, among other things: - -1. We need *exact* symbolic computation of the core operations of Quantity Calculus (i.e., products - and rational powers). - -2. We must support *irrational* Magnitudes, because they frequently occur in practice (e.g., - consider the ratio between ``degrees`` and ``radians``). - -3. We should *avoid overflow* wherever possible (note that ``std::intmax_t`` can't even handle - certain simple SI prefixes, such as ``yotta``, representing :math:`10^{24}`). - -Integers' inadequacies are clear enough, but even floating point falls short. Imagine if we -implemented all angular units in terms of ``radians``: then both ``degrees`` and ``revolutions`` -pick up a factor of :math:`\pi`. The arithmetic with *its floating point representation* is -unlikely to cancel *exactly*. - -Another common alternative choice is ``std::ratio``, but this fails the first requirement: rational -numbers are (`rather infamously `_!) *not* closed under rational -powers. - -The only viable solution we have yet encountered is the *vector space representation*. The -implementation is fascinating---but, for purposes of this present page, it's also a distraction. -*Here,* we're more focused on how to *use* these Magnitudes. - -One type per Magnitude, one value per type ------------------------------------------- - -Each typical numeric type (``double``, ``int64_t``, ...) can represent a wide variety of values: the -more, the better. However, Magnitudes are **not** like that. Instead, they comprise a *variety* of -types, and each type can hold only *one* value. - -.. tip:: - - A given Magnitude represents the *same* number, whether you use it as a *type*, or as a *value* - (i.e., an *instance* of that type). - - Use whichever is more convenient. (In practice, this is usually the *value*: especially for end - users rather than library developers.) - -If these types can only represent one value each, why would we bother to instantiate them? Because -*values are easier to use*. - -- ``mag()`` gives the Magnitude value corresponding to any integer ``N``. - You can combine - values in the usual way using ``*``, ``/``, ``==``, and ``!=``, as well as ``pow(m)`` and - ``root(m)`` for any Magnitude value ``m``. - -Traits: integers and rational Magnitudes ----------------------------------------- - -If you have a Magnitude instance ``m``, we provide traits to help you reason about integers and -rational numbers, or manipulate integer or rational parts. - -- ``is_integral(m)``: indicates whether ``m`` represents an *integral* Magnitude. -- ``is_rational(m)``: indicates whether ``m`` represents a *rational* Magnitude. - -The above traits indicate what kind of Magnitude we already have. The next traits *manipulate* a -Magnitude, letting us break it apart into *constituent* Magnitudes which may be more meaningful. -(For example, imagine going from ``inches`` to ``feet``. Naively, we might multiply by the floating -point representation of ``1.0 / 12.0``. However, if we broke this apart into separate numerator and -denominator, it would let us simply *divide by 12*, yielding **exact** results for inputs that -happen to be multiples of 12.) - -- ``numerator(m)`` (value): a Magnitude representing the "numerator", i.e., the largest integer - which divides ``m``, without turning any of its base powers' exponents negative (or making any - previously-negative exponents *more* negative). - ``denominator(m)`` (value): the "numerator" of - the *inverse* of ``m``. - -These traits interact as one would hope. For example, ``is_rational(m)`` is exactly equivalent to -``m == numerator(m) / denominator(m)``. - -Why these particular definitions? Because they are equivalent to the numerator and denominator when -we have a rational number, and they are compatible with how humans write numbers when we don't. -Example: - -- :math:`m1 = \frac{27 \pi^2}{25}`. Then ``numerator(m1) == mag<27>()``, and - ``denominator(m1) == mag<25>()``. -- :math:`m2 = \sqrt{m1}`. Then ``numerator(m2) == mag<3>()``, and ``denominator(m2) == mag<5>()``. - Note that this is consistent with how humans would typically write ``m2``, as - :math:`\frac{3\sqrt{3} \pi}{5}`. - -Getting values out ------------------- - -Magnitude types represent numbers in non-numeric types. They've got some amazing strengths (exact -rational powers!), and some significant weaknesses (no support for basic addition!). So what if you -just want to turn a Magnitude ``m`` into a traditional numeric type ``T``? - -You call ``get_value(m)``. - -This does what it looks like it does, and it does it at compile time. Any intermediate computations -take place in the "widest type in category"---``long double`` for floating point, and -``std::intmax_t`` or ``std::uintmax_t`` for signed or unsigned integers---before ultimately being -cast back to the target type. For ``T = float``, say, this means we get all the precision we'd have -with something like ``long double``, but without any speed penalty at runtime! - -``get_value(m)`` also has the protections you would hope: for example, if ``T`` is an integral -type, we require ``is_integral(m)``. - -How to use Magnitudes ---------------------- - -- First, start with your basic inputs: this will typically be ``mag()`` for any integer ``N``, or - the built-in Magnitude constant ``mag_pi``. (Again, these are all *values*, not types.) - -- Next, combine and manipulate these using the various "Magnitude math" operations, all of which are - **exact**: ``*``, ``/``, ``pow``, ``root``, ``numerator()``, ``denominator()``. - -- If you need to translate a Magnitude ``m`` to a "real" numeric type ``T``, call - ``get_value(m)``. diff --git a/docs/framework/quantities.rst b/docs/framework/quantities.rst deleted file mode 100644 index 32bb228a..00000000 --- a/docs/framework/quantities.rst +++ /dev/null @@ -1,643 +0,0 @@ -.. namespace:: units - -Quantities -========== - -A :term:`quantity` is a concrete amount of a unit for a specified dimension -with a specific representation and is represented in the library with a -`quantity` class template. - - -Construction ------------- - -To create the quantity object from a :term:`scalable number` we just have to pass -the value to the `quantity` class template explicit constructor:: - - quantity d(123); - quantity v(70); - -.. note:: - - As the constructor is explicit, the quantity object can be created from - an "unsafe" fundamental type only via - `direct initialization `_. - This is why the code below using - `copy initialization `_ - **does not compile**:: - - quantity d = 123; // ERROR - - -Quantity Construction Helpers ------------------------------ - -.. important:: - - Currently the library provides multiple experimental helpers to instantiate - quantities of different dimensions and units. Users are encourages to try them - out, vote, and share feedback in this - `discussion on GitHub `_. - - Most probably only one of the options will be included in the final product so - please do not hesitate to vote on the one that suits you the best. - -Dimension-Specific Aliases (Experimental) -+++++++++++++++++++++++++++++++++++++++++ - -To simplify `quantity` objects creation the library provides helper aliases for -quantities of each :term:`dimension` which additionally set the representation -type to ``double`` by default:: - - namespace si { - - template - using length = quantity; - - template - using speed = quantity; - - } - -Thanks to that, the above example can be rewritten as follows:: - - si::length d(123); - si::speed v(70); - -Unit-Specific Aliases (Experimental) -++++++++++++++++++++++++++++++++++++ - -Additionally to the dimension-specific aliases there are also ones provided for -each and every :term:`unit` in the library:: - - #ifndef UNITS_NO_ALIASES - - namespace units::aliases::isq::si::inline length { - - template using m = units::isq::si::length; - template using km = units::isq::si::length; - - } - - namespace units::aliases::isq::si::inline speed { - - template using m_per_s = units::isq::si::speed; - template using km_per_h = units::isq::si::speed; - - } - - #endif // UNITS_NO_ALIASES - -Using the above our code can look as follows:: - - using namespace units::aliases::isq; - si::length::km<> d(123); - si::speed::km_per_h v(70); - -Please note that with the C++20 :abbr:`CTAD (Class Template Argument Deduction)` support -for alias templates the above can be rewritten as:: - - using namespace units::aliases::isq; - si::length::km d(123.); - si::speed::km_per_h v(70); - -which will deduce the representation type automatically from the initializer provided -by the user. - -Also, this feature allows to be more terse if desired:: - - using namespace units::aliases::isq::si; - auto d = km(123.); - auto v = km_per_h(70); - -Quantity References (Experimental) -++++++++++++++++++++++++++++++++++ - -Quantity References provide an alternative and simplified way to create quantities. -They are defined using the `reference` class template:: - - #ifndef UNITS_NO_REFERENCES - - namespace length_references { - - inline constexpr auto km = reference{}; - - } // namespace length_references - - namespace time_references { - - inline constexpr auto h = reference{}; - - } // namespace time_references - - namespace references { - - using namespace length_references; - using namespace time_references; - - } // namespace references - - #endif // UNITS_NO_REFERENCES - -With the above our code can look as follows:: - - using namespace units::isq::si::references; - auto d = 123. * km; // si::length - auto v = 70 * (km / h); // si::speed - -.. important:: - - The following syntaxes are not allowed: - ``2 / s``, ``km * 3``, ``s / 4``, ``70 * km / h``. - -It is also possible to easily define custom quantity references from existing ones:: - - inline constexpr auto Nm = N * m; - inline constexpr auto km_per_h = km / h; - inline constexpr auto mph = mi / h; - - -User Defined Literals (Experimental) -++++++++++++++++++++++++++++++++++++ - -Alternatively, to construct quantities with compile-time known values the library provides -:abbr:`UDL (User Defined Literal)` s for each :term:`unit` of every :term:`dimension`:: - - #ifndef UNITS_NO_LITERALS - - inline namespace literals { - - constexpr auto operator"" _q_km(unsigned long long l) { return length(l); } - constexpr auto operator"" _q_km(long double l) { return length(l); } - - constexpr auto operator"" _q_km_per_h(unsigned long long l) { return speed(l); } - constexpr auto operator"" _q_km_per_h(long double l) { return speed(l); } - - } - - #endif // UNITS_NO_LITERALS - -Thanks to them the same code can be as simple as:: - - using namespace units::isq::si::literals; - auto d = 123._q_km; // si::length - auto v = 70_q_km_per_h; // si::speed - -.. note:: - - ``123._q_km`` should be read as a quantity of length in kilometers. Initially the - library did not use the ``_q_`` prefix for UDLs but it turned out that there are - a few unit symbols that collide with literals already existing in C and C++ - language (i.e. ``F`` (farad), ``J`` (joule), ``W`` (watt), ``K`` (kelvin), - ``d`` (day), ``l`` or ``L`` (litre), ``erg``, ``ergps``). This is why the - ``_q_`` prefix was consistently applied to all the UDLs. - -UDLs vs Quantity References -+++++++++++++++++++++++++++ - -UDLs are helpful but they also have some disadvantages compared to Quantity References: - -1. UDLs are only for compile-time known values and do not work for runtime variables - - - UDLs:: - - using namespace units::isq::si::literals; - auto v1 = 120_q_km / 2_q_h; - auto v2 = length(distance) / time(duration); - - - Quantity References:: - - using namespace units::isq::si::references; - auto v1 = 120 * km / (2 * h); - auto v2 = distance * (1 * km) / (duration * (1 * h)); - - References treat both cases in a unified way. It is also worth to notice that we work - mostly with runtime variables and compile-time known values mostly appear only in physical - constants and unit tests. - -2. UDLs cannot be disambiguated with a namespace name - - - UDLs:: - - using namespace units::isq::si::literals; - using namespace units::isq::si::cgs::literals; - auto d = 1_q_cm; // FAILS TO COMPILE - - - Quantity References:: - - inline constexpr auto si_cm = units::isq::si::references::cm; - inline constexpr auto cgs_cm = units::isq::si::cgs::references::cm; - - auto d1 = 1. * si_cm; // si::length - auto d2 = 1. * cgs_cm; // si::cgs::length - -3. Poor control over the representation types as UDLs return only ``std::int64_t`` or - ``long double`` - - - UDLs:: - - using namespace units::isq::si::literals; - auto d1 = 123._q_km; // si::length - auto d2 = 123_q_km; // si::length - - No possibility to obtain any other representation type. Additionally this gets contagious - as the result of every arithmetic expression on quantities is always expanded to the common - type of its arguments. For example `si::length(1) + 1_q_m` results in a - `si::length` type. - - - Quantity References:: - - using namespace units::isq::si::references; - auto d1 = 123. * km; // si::length - auto d2 = 123 * km; // si::length - auto d3 = 123.f * km; // si::length - auto d4 = 123.L * km; // si::length - auto d5 = 123ul * km; // si::length - auto d6 = 123ll * km; // si::length - -4. UDLs are verbose to define and standardize - - - UDLs: - - - for each unit an integral and a floating-point UDL have to be defined - - have to be provided for unnamed derived units (i.e. ``_q_km_per_h``) - - - Quantity References: - - - one reference per unit - - unnamed derived units are constructed from base references so no explicit - definition is required (i.e. ``km / h``) - -5. Typical UDL definition for quantities when compiled with a ``-Wsign-conversion`` - flag results in a compilation warning. This warning could be silenced with a - ``static_cast(value)`` in every UDL, but in a such case other safety - and security issues could be silently introduced. - Quantity References, on the opposite, always use the exact representation type provided - by the user so there is no chance for a truncating conversion on a quantity construction. - -6. UDLs take long to compile - - - UDLs: - - Every unit requires two UDLs to be defined which in turns requires two instantiations - of "heavy" `quantity` class template. Those are then not often used by non-UDL construction - as most users instantiate `quantity` class template with `int` or `double` which - again have to be separately instantiated. This has a significant impact on the compile-time - performance. - - - Quantity References: - - `reference` class template is "cheaper" to instantiate. Additionally, every unit requires - only one instantiation of a `reference` class template. Such pre-defined reference instance - is then shared among all the instantiations of `quantity` class template for this specific - unit (no matter of its representation type). With this approach we end up with much less class - template instantiations in the application. - - -Quantity References vs Unit-specific Aliases -++++++++++++++++++++++++++++++++++++++++++++ - -1. Shadowing issues - - - Quantity References - - References occupy a pool of many short identifiers which sometimes shadow the variables, - function arguments, or even template parameters provided by the user or other libraries. This - results in warnings being generated by some compilers. The most restrictive here is MSVC which - for example emits a warning of shadowing ``N`` template parameter for an array size provided - in a header file with Newton unit included via namespace declaration in the ``main()`` program - function (see `experimental_angle `_). - In other cases user is forced to rename its local identifiers to not collide with predefined - references (see `capacitor_time_curve `_). - - - Unit-specific Aliases - - As aliases are defined in terms of types rather variables no major shadowing issues were found - so far. In case of identifiers ambiguity it was always possible to disambiguate with more - namespaces prefixed in front of the alias. - -2. Adjustable verbosity - - - Quantity References - - References allow creating custom helpers for complex units. Instead of typing:: - - static_assert(2 * km / (2 * (km / h)) == 1 * h); - - one can do the following:: - - inline constexpr auto kmph = km / h; - static_assert(2 * km / (2 * kmph) == 1 * h); - - - Unit-specific Aliases - - There is no need to create custom helpers for complex units as most of them are predefined in - a library already. However, this feature also allows controlling verbosity of the code. For - example in the below example ``d1``, ``d2``, and ``d3`` will end up being of the same type - and having the same value:: - - auto d1 = m(123.45); - double a = 123.45; - auto d2 = m(a); - auto d3 = length::m(a); - -3. Readability - - - Quantity References - - As long as references are easy to understand in the following code:: - - auto d = 123 * m; - - it is not that nice when a variable is used instead of a compile time number:: - - constexpr Speed auto avg_speed(double d, double t) - { - using namespace units::isq::si::length_references; - using namespace units::isq::si::time_references; - return d * m / (t * s); - } - - Notice that if ``using namespace units::isq::si::references;`` was used instead above it could - cause a clash of ``t`` function parameter with ``si::tonne`` unit symbol if ``si/mass.h`` was - included. - - - Unit-specific Aliases - - The same using aliases can look as follows:: - - constexpr Speed auto avg_speed(double d, double t) - { - using namespace units::aliases::isq::si; - return m(d) / s(t); - } - - or:: - - constexpr Speed auto avg_speed(double d, double t) - { - using namespace units::aliases::isq::si; - return length::m(d) / time::s(t); - } - -4. Operators Precedence - - - Quantity References - - The syntax for references uses ``*`` operator which has some predefined precedence. This operator - always takes a magnitude or a reference as ``lhs`` and a reference as ``rhs``. All other combinations - are not allowed. It means that in order to satisfy the operators precedence sometimes quite a lot - of parenthesis have to be sprinkled in the code in order for the code to compile:: - - static_assert(2 * km / (2 * (km / h)) == 1 * h); - - - Unit-specific Aliases - - Aliases do not use operator syntax thus they are not affected by the precedence issue. - -5. Composition for unnamed derived units - - - Quantity References - - References have only to be defined for named units. Also for the user's convenience references are - predefined for units raised to a specific power (e.g. ``m2``, ``km3``, etc). All other derived units - can be constructed using the provided ones already even if they do not correspond to any predefined - dimension:: - - inline constexpr auto kmph = km / h; - inline constexpr auto kmph3 = kmph * kmph * kmph; - - - Unit-specific Aliases - - Such a feature is not possible with aliases. In order to create a derived unit a full alias template - has to be explicitly provided:: - - template using km_per_h = units::isq::si::speed; - -6. Explicit control over the representation type - - Both options here allow to preserve user provide representation type but only aliases allow - to override it if needed. - -7. Simplified quantity casting - - Aliases can easily replace ``quantity_cast()`` which is not possible with references:: - - constexpr auto meter = 1 * m; - std::cout << " = " << quantity_cast(meter) << '\n'; - - The above code for references may look as follows:: - - constexpr auto meter = m(1); - std::cout << " = " << international::ft(meter) << '\n'; - std::cout << " = " << ft(meter) << '\n'; - - The above will preserve the representation type of the source type. - -8. Compilation performance - - For our experiments it seems that aliases are 2-5x faster to compile than references (declaring an - alias template is much faster than instantiating a class template). - - -Summary -+++++++ - -+-----------------------------------------------+-------------+------------+---------------+ -| Feature | Aliases | References | UDLs | -+===============================================+=============+============+===============+ -| Literals and variables support | **Yes** | **Yes** | Literals only | -+-----------------------------------------------+-------------+------------+---------------+ -| Preserves user provided representation type | **Yes** | **Yes** | No | -+-----------------------------------------------+-------------+------------+---------------+ -| Explicit control over the representation type | **Yes** | No | No | -+-----------------------------------------------+-------------+------------+---------------+ -| Possibility to resolve ambiguity | **Yes** | **Yes** | No | -+-----------------------------------------------+-------------+------------+---------------+ -| Readability | **Good** | Medium | **Good** | -+-----------------------------------------------+-------------+------------+---------------+ -| Hard to resolve shadowing issues | **No** | Yes | **No** | -+-----------------------------------------------+-------------+------------+---------------+ -| Operators precedence issue | **No** | Yes | **No** | -+-----------------------------------------------+-------------+------------+---------------+ -| Controlled verbosity | **Yes** | No | No | -+-----------------------------------------------+-------------+------------+---------------+ -| Easy composition for derived units | No | **Yes** | No | -+-----------------------------------------------+-------------+------------+---------------+ -| Simplified quantity casting | **Yes** | No | No | -+-----------------------------------------------+-------------+------------+---------------+ -| Implementation and standardization effort | Medium | **Lowest** | Highest | -+-----------------------------------------------+-------------+------------+---------------+ -| Compile-time performance | **Fastest** | Medium | Slowest | -+-----------------------------------------------+-------------+------------+---------------+ - - -Don't pay for what you don't use (compile-time performance) -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -As noted in the previous chapter, each quantity creation helper has a different impact on the compile-time -performance. Aliases tend to be the fastest to compile but even their definition can be expensive for some -if it is not used in the source code. This is why it is possible to opt-out from each or every quantity -creation helper with the following preprocessor defines:: - - #define UNITS_NO_ALIASES - #define UNITS_NO_REFERENCES - #define UNITS_NO_LITERALS - - -Dimension-specific Concepts ---------------------------- - -In case the user does not care about the specific unit and representation but -requires quantity of a concrete dimension than dimension-specific concepts can -be used:: - - using namespace units::isq::si::references; - constexpr Length auto d = 123 * km; // si::length - -.. note:: - - All instances of `quantity` class always match the `Quantity` concept. - All other regular types that are not quantities are called - :term:`scalable numbers ` by the library and match the - `Representation` concept. - -However, the above is not the most important usage of those concepts. Let's -assume that the user wants to implement an ``avg_speed`` function that will -be calculating the average speed based on provided distance and duration -quantities. The usage of such a function can look as follows:: - - using namespace units::isq::si::references; - using namespace units::isq::si::international::references; - constexpr Speed auto v1 = avg_speed(220 * km, 2 * h); - constexpr Speed auto v2 = avg_speed(140 * mi, 2 * h); - -In this and all other physical units libraries such a function can be -implemented as:: - - constexpr si::speed avg_speed(si::length d, - si::time t) - { - return d / t; - } - -While being correct, this function performs unnecessary intermediate -conversions (from kilometers to meters, from hours to seconds, -and from meters per second to kilometers per hour) which can affect -runtime performance and the precision of the final result. To eliminate -all that overhead we have to write a template function:: - - template - constexpr auto avg_speed(si::length d, si::time t) - { - return d / t; - } - -This function will work for every SI unit and representation without any -unnecessary overhead. It is also simple enough to prove its implementation -being correct just by a simple inspection. However, it might not always be -the case. For more complicated calculations we would like to ensure that we -are returning a physical quantity of a correct dimension. For this -dimension-specific concepts come handy again and with usage of C++20 generic -functions our function can look as simple as:: - - constexpr Speed auto avg_speed(Length auto d, Time auto t) - { - return d / t; - } - -Now we are sure that the dimension of returned quantity is correct. Also -please note that with the above code we implemented a truly generic function -that works efficiently not only with SI units but also with other systems of -units like CGS. - -.. seealso:: - - Please refer to :ref:`examples/basics/avg_speed:avg_speed` example for more - information on different kinds of interfaces supported by the library. - - -Working With Constrained Deduced Quantity Types ------------------------------------------------ - -It is important to note that when we assign a result from the function to an -automatically deduced type, even if it is constrained by a dimension-specific -concept, we still do not know what is the exact unit and representation type -of such a quantity. In many cases it might be exactly what we want to get, -but often we would like to know a specific type too. We have two options here: - -- query the actual dimension, unit, and representation types:: - - constexpr Speed auto v = avg_speed(220 * km, 2 * h); - using quantity_type = decltype(v); - using dimension_type = quantity_type::dimension; - using unit_type = quantity_type::unit; - using rep_type = quantity_type::rep; - -- convert or cast to a desired quantity type:: - - constexpr Speed auto v1 = avg_speed(220. * km, 2 * h); - constexpr si::speed v2 = v1; - constexpr Speed auto v3 = quantity_cast(v1); - -.. seealso:: - - More information on this subject can be found in the - :ref:`framework/conversions_and_casting:Conversions and Casting` chapter. - - -Dimensionless Quantities ------------------------- - -Whenever we divide two quantities of the same dimension we end up with a -:term:`dimensionless quantity` otherwise known as :term:`quantity of dimension one`:: - - static_assert(10 * km / (5 * km) == 2); - static_assert(std::is_same_v>); - -According to the official ISO definition `dim_one` is a dimension "for which all the -exponents of the factors corresponding to the base quantities in its quantity dimension -are zero". - -.. seealso:: - - Reasoning for the above design is provided in - :ref:`faq:Why a dimensionless quantity is not just an fundamental arithmetic type?` - -To simplify the usage of the dimensionless quantity a following concept and alias template -are provided:: - - template - concept Dimensionless = QuantityOf; - - template - using dimensionless = quantity; - -There are two special units provided for usage with such a quantity: - -- `one` which is the :term:`coherent derived unit` of dimensionless quantity and does not - provide any textual symbol (according to the ISO definition "the measurement units and - values of quantities of dimension one are numbers"), -- `percent` which has the symbol ``%`` and ``ratio(1, 100)`` of the `one` unit. - -For example the following code:: - - std::cout << quantity_cast(50. * m / (100. * m)) << '\n'; - -will print ``50 %`` to the console output. - -Again, according to the ISO definition "such quantities convey more information than a -number". This is exactly what we observe in the above example. The value stored inside -the quantity, the text output, and the value returned by the `quantity::number()` member -function is ``50`` rather than ``0.5``. It means that dimensionless quantities behave -like all other quantities and store the value in terms of a ratio of a coherent unit. -This allows us to not loose precision when we divide quantities of the same dimensions -but with units having vastly different ratios, e.g. -`Dimensionless Hubble parameter `_ -is expressed as a ratio of kilometers and megaparsecs. - -.. seealso:: - - More information on dimensionless quantities can be found in the - :ref:`framework/conversions_and_casting:Implicit conversions of dimensionless quantities` - chapter. diff --git a/docs/framework/quantity_kinds.rst b/docs/framework/quantity_kinds.rst deleted file mode 100644 index 9d908b24..00000000 --- a/docs/framework/quantity_kinds.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. namespace:: units - -Quantity Kinds -============== - -A quantity kind is a quantity of more specific usage. -It is represented in the library with a `quantity_kind` class template. - - -Kind Creation -------------- - -We need a `kind` to represent the more specific usage of a quantity:: - - struct radius : kind {}; - -Quantities of kind ``radius`` represent a radius. -They are clearly distinct from more generic usages of length quantities. - - -Construction ------------- - -To create the quantity kind object from a `quantity` we just have to pass -the value to the `quantity_kind` class template constructor:: - - quantity_kind d(123 * km); - -.. note:: - - As the constructor without the kind argument is explicit, - the quantity object can be created from a quantity only via - `direct initialization `_. - This is why the code below using - `copy initialization `_ - **does not compile**:: - - quantity_kind d = 123 * km; // ERROR - - -Differences To Quantity ------------------------ - -The library provides: - -- no kinds, such as ``radius`` or ``width``, therefore - - * no UDLs or quantity references, - * no kind-specific concepts, such as ``Radius``, - (there's the generic `QuantityKind` and kind-specifiable `QuantityKindOf`), - -- a slightly larger set of operations on quantity kinds - (see the :ref:`framework/dimensions:Quantity Kinds` chapter). - - -Quantity Point Kinds --------------------- - -A quantity point kind is the analogous of a quantity point for quantity kinds -(see the :ref:`framework/quantity_points:Quantity Points` chapter). - -They are represented in the library with a `quantity_point_kind` class template. - -First, we need a `point_kind` for a `kind`:: - - struct width : kind {}; - struct x_coordinate : point_kind {}; - -Now ``x`` coordinates can be constructed:: - - quantity_point_kind auto x_pos(123 * m); // QuantityPointKindOf - auto x = x_pos.relative(); // quantity_kind(123 * m) - -.. seealso:: - - Please refer to :ref:`examples/basics/glide_computer:glide_computer` example for more - information on the quantity kinds usage. diff --git a/docs/framework/quantity_like.rst b/docs/framework/quantity_like.rst deleted file mode 100644 index f963fdc7..00000000 --- a/docs/framework/quantity_like.rst +++ /dev/null @@ -1,51 +0,0 @@ -.. namespace:: units - -Quantity-like Types -=================== - -.. raw:: html - - - -.. - https://www.planttext.com - - @startuml - - skinparam monochrome true - skinparam shadowing false - skinparam backgroundColor #fcfcfc - - hide members - hide circle - - class quantity [[../framework/quantities.html]] - class quantity_point [[../framework/quantity_points.html]] - class quantity_kind [[../framework/quantity_kinds.html]] - class quantity_point_kind [[../framework/quantity_kinds.html#quantity-point-kinds]] - - Rep <-- quantity : number() - quantity <-- quantity_point : relative() - quantity <-- quantity_kind : common() - quantity_kind <-- quantity_point_kind : relative() - - @enduml - - -[ISO80000]_ defines a :term:`quantity` as a: - - Property of a phenomenon, body, or substance, where the property has a magnitude that can be expressed by - means of a number and a reference. - -You can use `quantity::number()` member function to get a concrete amount of a unit expressed with a specific -representation type ``Rep``. - -:term:`Kind of quantity ` is defined as: - - Aspect common to mutually comparable quantities. - -We can obtain a `quantity` with a `quantity_kind::common()` member function. - -`quantity_point` and `quantity_point_kind` are absolute quantities and quantity kinds relative to some -specific origin. `quantity` and `quantity_point` types can be obtained from them using a ``relative()`` member -function (`quantity_point::relative()`, `quantity_point_kind::relative()`). diff --git a/docs/framework/quantity_points.rst b/docs/framework/quantity_points.rst deleted file mode 100644 index dd652c69..00000000 --- a/docs/framework/quantity_points.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. namespace:: units - -Quantity Points -=============== - -A quantity point is an absolute quantity with respect to an origin -and is represented in the library with a `quantity_point` class template. - -Point Origins -------------- - -We need a `point_origin` to represent the origin of a quantity point:: - - struct mean_sea_level : point_origin {}; - -Quantities points with this origin represent a point from the mean sea level. - -The library offers a `dynamic_origin` -for quantity points whose origin is not specified in the type system. - - -Construction ------------- - -To create the quantity point object from a `quantity` we just have to pass -the value to the `quantity_point` class template explicit constructor:: - - quantity_point, si::kilometre, double> d(123 * km); - -.. note:: - - As the constructor is explicit, the quantity object can be created from - a quantity only via - `direct initialization `_. - This is why the code below using - `copy initialization `_ - **does not compile**:: - - quantity_point, si::kilometre, double> d = 123 * km; // ERROR - - -Differences To Quantity ------------------------ - -Unlike `quantity`, the library provides: - -- no helper aliases for quantity points, such as ``length_point``, -- no UDLs for quantity points, -- no dimension-specific concepts, such as ``LengthPoint`` - (there's the dimension-agnostic `QuantityPoint`), -- a more limited set of operations on quantity points - (see the :ref:`framework/arithmetics:Quantity Points` chapter) diff --git a/docs/framework/text_output.rst b/docs/framework/text_output.rst deleted file mode 100644 index e760a2da..00000000 --- a/docs/framework/text_output.rst +++ /dev/null @@ -1,224 +0,0 @@ -.. namespace:: units - -Text Output -=========== - -Beside providing dimensional analysis and units conversions, the library -also tries really hard to print any quantity in the most user friendly way. - -.. note:: - - The library provides no text output for - quantity points or quantity (point) kinds. - -Output Streams --------------- - -.. tip:: - - The streaming support is provided via the ```` header file. - -The easiest way to print a quantity is to provide its object to the output -stream:: - - using namespace units::isq::si::references; - using namespace units::isq::si::international::references; - constexpr Speed auto v1 = avg_speed(220. * km, 2 * h); - constexpr Speed auto v2 = avg_speed(140. * mi, 2 * h); - std::cout << v1 << '\n'; // 110 km/h - std::cout << v2 << '\n'; // 70 mi/h - -The text output will always print the :term:`value of a quantity` followed -by a space and then the symbol of a :term:`unit` associated with this quantity. - -.. important:: - - Remember that it is a good practice to always `quantity_cast()` a quantity - of an unknown ``auto`` type before passing it to the text output:: - - std::cout << quantity_cast(v1) << '\n'; // 110 km/h - std::cout << quantity_cast(v1) << '\n'; // 30.5556 m/s - - -Stream Output Formatting -^^^^^^^^^^^^^^^^^^^^^^^^ - -Only a basic formatting can be applied for output streams. It includes control -over width, fill, and alignment:: - - os << "|" << std::setw(10) << 123 * m << "|"; // | 123 m| - os << "|" << std::setw(10) << std::left << 123 * m << "|"; // |123 m | - os << "|" << std::setw(10) << std::setfill('*') << 123 * m << "|"; // |*****123 m| - - -std::format ------------ - -.. tip:: - - The text formatting support is provided via the ```` header file. - -The **mp-units** via ``std::format`` provides a fine-grained control over what -and how is being printed on the text output. - - -Grammar -^^^^^^^ - -.. productionlist:: - units-format-spec: [fill-and-align] [width] [units-specs] - units-specs: conversion-spec - : units-specs conversion-spec - : units-specs literal-char - literal-char: any character other than '{' or '}' - conversion-spec: '%' units-type - units-type: [units-rep-modifier] 'Q' - : [units-unit-modifier] 'q' - : one of "nt%" - units-rep-modifier: [sign] [#] [precision] [L] [units-rep-type] - units-rep-type: one of "aAbBdeEfFgGoxX" - units-unit-modifier: 'A' - -In the above grammar: - -- ``fill-and-align``, ``width``, ``sign``, ``#``, ``precision`` and ``L`` tokens and - individual tokens of :token:`units-rep-type` are defined in the - `format.string.std `_ chapter of the C++ - standard specification, -- tokens ``Q``, ``q``, ``n``, ``t``, and ``%`` of :token:`units-type` are described - in the `time.format `_ chapter of the C++ standard - specification, -- ``A`` token of :token:`units-unit-modifier` forces ASCII-only output (instead of the - default Unicode symbols defined by the :term:`SI` specification). - - -Default formatting -^^^^^^^^^^^^^^^^^^ - -To format `quantity` values the formatting facility uses :token:`units-format-spec`. -In case it is left empty the default formatting of ``{:%Q %q}`` is applied. The same -default formatting is also applied to the output streams. This is why the following -code lines produce the same output:: - - std::cout << "Distance: " << 123 * km << "\n"; - std::cout << std::format("Distance: {}\n", 123 * km); - std::cout << std::format("Distance: {:%Q %q}\n", 123 * km); - - -Quantity Value, Symbol, or Both? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The user can easily decide to either print a whole quantity (value and symbol) or -only its parts. Also a different quantity formatting might be applied:: - - std::cout << std::format("{:%Q}", 123 * km); // 123 - std::cout << std::format("{:%q}", 123 * km); // km - std::cout << std::format("{:%Q%q}", 123 * km); // 123km - - -Controlling Width, Fill, and Alignment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To control width, fill, and alignment the C++ standard grammar tokens ``fill-and-align`` -and ``width`` are being used and they treat a quantity value and symbol as a contiguous -text:: - - std::cout << std::format("|{:0}|", 123 * m); // |123 m| - std::cout << std::format("|{:10}|", 123 * m); // | 123 m| - std::cout << std::format("|{:<10}|", 123 * m); // |123 m | - std::cout << std::format("|{:>10}|", 123 * m); // | 123 m| - std::cout << std::format("|{:^10}|", 123 * m); // | 123 m | - std::cout << std::format("|{:*<10}|", 123 * m); // |123 m*****| - std::cout << std::format("|{:*>10}|", 123 * m); // |*****123 m| - std::cout << std::format("|{:*^10}|", 123 * m); // |**123 m***| - - -ASCII-only Quantity Symbols -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Unit symbols of some quantities are specified to use Unicode signs by the :term:`SI` -standard (i.e. ``Ω`` symbol for the resistance quantity). **mp-units** library follows -this by default. From the engineering point of view sometimes Unicode text might -not be a solution as terminals of many (especially embedded) devices are ASCII-only. -In such a case the unit symbol can be forced to be printed using ASCII-only characters:: - - std::cout << std::format("{}", 10 * R); // 10 Ω - std::cout << std::format("{:%Q %Aq}", 10 * R); // 10 ohm - std::cout << std::format("{}", 125 * us); // 125 µs - std::cout << std::format("{:%Q %Aq}", 125 * us); // 125 us - inline constexpr auto s2 = s * s; - std::cout << std::format("{}", 9.8 * (m / s2)); // 9.8 m/s² - std::cout << std::format("{:%Q %Aq}", 9.8 * (m / s2)); // 9.8 m/s^2 - - -Controlling on How the Quantity Value Is Being Printed -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -``sign`` token allows us to specify on how the value's sign is being printed:: - - std::cout << std::format("{0:%Q %q},{0:%+Q %q},{0:%-Q %q},{0:% Q %q}", 1 * m); // 1 m,+1 m,1 m, 1 m - std::cout << std::format("{0:%Q %q},{0:%+Q %q},{0:%-Q %q},{0:% Q %q}", -1 * m); // -1 m,-1 m,-1 m,-1 m - -where: - -- ``+`` indicates that a sign should be used for both non-negative and negative numbers, -- ``-`` indicates that a sign should be used for negative numbers and negative zero only - (this is the default behavior), -- ```` indicates that a leading space should be used for non-negative numbers other - than negative zero, and a minus sign for negative numbers and negative zero. - -``precision`` token is allowed only for floating-point representation types:: - - std::cout << std::format("{:%.0Q %q}", 1.2345 * m); // 1 m - std::cout << std::format("{:%.1Q %q}", 1.2345 * m); // 1.2 m - std::cout << std::format("{:%.2Q %q}", 1.2345 * m); // 1.23 m - - -:token:`units-rep-type` specifies how a value of the representation type is being -printed. For integral types:: - - std::cout << std::format("{:%bQ %q}", 42 * m); // 101010 m - std::cout << std::format("{:%BQ %q}", 42 * m); // 101010 m - std::cout << std::format("{:%dQ %q}", 42 * m); // 42 m - std::cout << std::format("{:%oQ %q}", 42 * m); // 52 m - std::cout << std::format("{:%xQ %q}", 42 * m); // 2a m - std::cout << std::format("{:%XQ %q}", 42 * m); // 2A m - -The above can be printed in an alternate version thanks to the ``#`` token:: - - std::cout << std::format("{:%#bQ %q}", 42 * m); // 0b101010 m - std::cout << std::format("{:%#BQ %q}", 42 * m); // 0B101010 m - std::cout << std::format("{:%#oQ %q}", 42 * m); // 052 m - std::cout << std::format("{:%#xQ %q}", 42 * m); // 0x2a m - std::cout << std::format("{:%#XQ %q}", 42 * m); // 0X2A m - -For floating-point values the :token:`units-rep-type` token works as follows:: - - std::cout << std::format("{:%aQ %q}", 1.2345678 * m); // 0x9.e065152d8eae841p-3 m - std::cout << std::format("{:%.3aQ %q}", 1.2345678 * m); // 0x9.e06p-3 m - std::cout << std::format("{:%AQ %q}", 1.2345678 * m); // 0X9.E065152D8EAE841P-3 m - std::cout << std::format("{:%.3AQ %q}", 1.2345678 * m); // 0X9.E06P-3 m - std::cout << std::format("{:%eQ %q}", 1.2345678 * m); // 1.234568e+00 m - std::cout << std::format("{:%.3eQ %q}", 1.2345678 * m); // 1.235e+00 m - std::cout << std::format("{:%EQ %q}", 1.2345678 * m); // 1.234568E+00 m - std::cout << std::format("{:%.3EQ %q}", 1.2345678 * m); // 1.235E+00 m - std::cout << std::format("{:%gQ %q}", 1.2345678 * m); // 1.23457 m - std::cout << std::format("{:%gQ %q}", 1.2345678e8 * m); // 1.23457e+08 m - std::cout << std::format("{:%.3gQ %q}", 1.2345678 * m); // 1.23 m - std::cout << std::format("{:%.3gQ %q}", 1.2345678e8 * m); // 1.23e+08 m - std::cout << std::format("{:%GQ %q}", 1.2345678 * m); // 1.23457 m - std::cout << std::format("{:%GQ %q}", 1.2345678e8 * m); // 1.23457E+08 m - std::cout << std::format("{:%.3GQ %q}", 1.2345678 * m); // 1.23 m - std::cout << std::format("{:%.3GQ %q}", 1.2345678e8 * m); // 1.23E+08 m - - -Special Signs -^^^^^^^^^^^^^ - -Beside adding any list of regular characters as a separator between the value and the -symbol, it is possible to type a few special signs there too:: - - std::cout << std::format("{:%Q_%q}", 123 * km); // 123_km - std::cout << std::format("{:%Q%t%q}", 123 * km); // 123\tkm - std::cout << std::format("{:%Q%n%q}", 123 * km); // 123\nkm - std::cout << std::format("{:%Q%% %q}", 123 * km); // 123% km diff --git a/docs/framework/units.rst b/docs/framework/units.rst deleted file mode 100644 index 226fb24d..00000000 --- a/docs/framework/units.rst +++ /dev/null @@ -1,453 +0,0 @@ -.. namespace:: units - -Units -===== - -Each quantity has a magnitude (a numerical value). In order to be able to -compare quantities of the same dimension a notion of a :term:`measurement unit` -was introduced. Units are designated by conventionally assigned names and -symbols. Thanks to them it is possible to compare two quantities of the -same dimension and express the ratio of the second quantity to the first -one as a number. For example ``10 s`` is ``10`` times more than ``1 s``. - -Base quantities are expressed in terms of :term:`base units ` -(i.e. ``m`` (meter), ``s`` (second)), while derived quantities are expressed -in terms of :term:`derived units `. - - -Class Hierarchy ---------------- - -All of the described here class templates to produce unit types inherit from some instance -of a `scaled_unit` class template: - -.. raw:: html - - - -.. - https://www.planttext.com - - @startuml - - skinparam monochrome true - skinparam shadowing false - skinparam backgroundColor #fcfcfc - - hide members - hide circle - - left to right direction - - package Unit <> [[../../framework/units.html]] { - - abstract scaled_unit - - abstract prefixed_alias_unit [[../../framework/units.html#aliased-units]] - abstract alias_unit [[../../framework/units.html#aliased-units]] - abstract derived_scaled_unit [[../../framework/units.html#derived-scaled-units]] - abstract derived_unit [[../../framework/units.html#derived-unnamed-units]] - abstract prefixed_unit [[../../framework/units.html#prefixed-unit]] - abstract named_scaled_unit [[../../framework/units.html#named-scaled-units]] - abstract named_unit [[../../framework/units.html#base-units]] - - scaled_unit <|-- named_unit - scaled_unit <|-- named_scaled_unit - scaled_unit <|-- prefixed_unit - scaled_unit <|-- derived_unit - scaled_unit <|-- derived_scaled_unit - scaled_unit <|-- alias_unit - scaled_unit <|-- prefixed_alias_unit - } - - @enduml - -`scaled_unit` is a class template used exclusively by the library's framework -and user should not instantiate it by him/her-self. However the user can sometimes -observe this type in case an unit/dimension conversion expression will end up with an -unknown/undefined unit type like in the below example:: - - using namespace units::isq::si::references; - - Length auto l = 100 * (km / h) * (10 * s); - -The type of ``l`` above will be -``si::length, long double>``. This is caused -by the fact that the library does not define a unit of a length quantity that has the -ratio ``10/36`` of a ``si::metre``. If such a unit was predefined we would see its concrete -type here instead. - - -Base Units ----------- - -:term:`Base units ` are the units of -:term:`base quantities ` defined for -:term:`base dimensions `. For example in :term:`SI` -``m`` (meter) is a base unit of length, ``s`` (second) is a base unit of -time. In each :term:`coherent system of units`, there is only one base -unit for each base quantity. This is why a base unit type is required by -the `base_dimension` definition in this library. For example ``si::dim_length`` -can be defined in the following way:: - - namespace si { - - struct dim_length : base_dimension<"L", metre> {}; - - } - -where ``si::metre`` is defined as:: - - namespace si { - - struct metre : named_unit {}; - - } - -In the above definition ``"m"`` is the unit symbol to be used in the text -output, and ``si::prefix`` specifies that the library should allow -definitions of prefixed units using ``si::metre`` as a reference (i.e. -``si::centimetre``). - -.. seealso:: - - For more information on prefixes and scaling please refer to - `Scaled Units`_. - -.. note:: - - The first template argument of `named_unit` is the type of the - child class inherited from the instantiation of this `named_unit` - class template. This is called a - :abbr:`CRTP (Curiously Recurring Template Parameter)` Idiom and is used - in many places in this library to provide - :ref:`design/downcasting:The Downcasting Facility`. - - -It is important to notice here that :term:`SI` is not the only system used -in the industry and the library has to support other systems too. Also -in some cases conversions between such systems should be allowed. Thanks to -the fact that the `base_dimension` takes the base unit type in its definition -allows us to easily define various systems of units for the same physical -dimension. For example length in the -`CGS `_ -could be defined as:: - - namespace si::cgs { - - struct dim_length : base_dimension<"L", si::centimetre> {}; - - } - -The fact that both base dimensions use the same identifier ``"L"`` tells -the library that both definitions refer to the same physical dimension of -length. The only difference is the measurement unit used to define their -base dimensions. Thanks to using the unit that is defined in terms of the -the same reference unit as the one provided to ``si::dim_length`` definition -(namely ``si::centimetre`` which is ``1/100`` of ``si::metre``) we also enabled -the ability to easily convert between those 2 base dimensions (as the library -knows how to convert ``si::metre`` to ``si::centimetre`` and vice versa). - -.. seealso:: - - More details on custom systems definitions and conversions between - units of the same physical dimension can be found in the - :ref:`use_cases/extensions:Custom Systems` chapter. - - -Scaled Units ------------- - -Described above base units (in case of base quantities) and -:term:`coherent units ` (in case of derived quantities), -in their system of units, have proportionality factor/ratio equal to one. -However, quantities of such dimensions can also use units of measurement -with other ratios to describe their magnitude (numerical value). - - -Named Scaled Units -^^^^^^^^^^^^^^^^^^ - -We are used to use minutes, hours, or days to measure quantities of time. -Those units are the scaled versions of a time dimension's base unit, -namely second. Those can be defined easily in the library using -`named_scaled_unit` class template:: - - struct minute : named_scaled_unit {}; - struct hour : named_scaled_unit {}; - struct day : named_scaled_unit {}; - -The `ratio` type used in the definition is really similar to ``std::ratio`` but it takes -an additional ``Exponent`` template parameter that defines the exponent of the ratio. -Another important difference is the fact that the objects of that class are used -as class NTTPs rather then a type template parameter kind. - -Thanks to it we can address nearly infinite scaling factors between units -and define units like:: - - struct electronvolt : named_scaled_unit {}; - -Finally, the last of the `named_scaled_unit` class template parameters -provide a reference unit for scaling. Please note that it can be a dimension's -base/coherent unit (like ``si::second``) or any other unit (i.e. ``si::minute``, -``si::hour``) that is a scaled version of the dimension's base/coherent unit. - - -Prefixed Unit -^^^^^^^^^^^^^ - -Prefixed units are just scaled units with a standardized ratio. For example -:term:`SI` defines prefixes based on the exponent of ``10``. Here is a -complete list of all the :term:`SI` prefixes supported by the library:: - - namespace si { - - struct yocto : prefix()> {}; - struct zepto : prefix()> {}; - struct atto : prefix()> {}; - struct femto : prefix()> {}; - struct pico : prefix()> {}; - struct nano : prefix()> {}; - struct micro : prefix()> {}; - struct milli : prefix()> {}; - struct centi : prefix()> {}; - struct deci : prefix()> {}; - struct deca : prefix()> {}; - struct hecto : prefix()> {}; - struct kilo : prefix()> {}; - struct mega : prefix()> {}; - struct giga : prefix()> {}; - struct tera : prefix()> {}; - struct peta : prefix()> {}; - struct exa : prefix()> {}; - struct zetta : prefix()> {}; - struct yotta : prefix()> {}; - - } - -Alternative hierarchy of prefixes is the one used in data information -domain:: - - namespace iec80000 { - - struct kibi : prefix()> {}; - struct mebi : prefix()> {}; - struct gibi : prefix()> {}; - struct tebi : prefix()> {}; - struct pebi : prefix()> {}; - struct exbi : prefix()> {}; - struct zebi : prefix()> {}; - struct yobi : prefix()> {}; - - } - -With the definitions like above we can easily define prefixed unit. For -example we can define ``si::kilometre`` as:: - - namespace si { - - struct kilometre : prefixed_unit {}; - - } - -.. important:: - - Prefixed units have to use named units as a reference. For unnamed - units we could end up with some strange, misleading, and sometimes - wrong definitions ("kilo square metre" seams strange and spelled - as ``km²`` would be invalid). - - -.. note:: - - [SIBrochure]_ states: - - However, when prefixes are used with SI units, the resulting units are no - longer coherent, because the prefix introduces a numerical factor other than one. - - -Derived Units -------------- - -:term:`Derived units ` are the units used to measure -:term:`derived quantities `. They can either have their own unique -names (i.e. ``N`` (newton)) or can be composed from the names of units of quantities -used to define thier derived quantity (i.e. ``km/h``). - -The [SIBrochure]_ states: - - Derived units are defined as products of powers of the base units. When the numerical - factor of this product is one, the derived units are called coherent derived units. The base - and coherent derived units of the SI form a coherent set, designated the set of coherent SI - units. The word “coherent” here means that equations between the numerical values of - quantities take exactly the same form as the equations between the quantities themselves. - -Derived Named Units -^^^^^^^^^^^^^^^^^^^ - -The [SIBrochure]_ also says: - - Some of the coherent derived units in the SI are given special names. - -Derived named units have a unique symbol (i.e. ``N`` (newton) or ``Pa`` -(pascal)) and they are defined in the same way as base units (which -always have to be a named unit):: - - namespace si { - - struct newton : named_unit {}; - - } - - -Derived Unnamed Units -^^^^^^^^^^^^^^^^^^^^^ - -Derived unnamed units are the units where the symbol is derived from the -base quantities symbols and the expression of the dependence of the derived -quantity on the base quantities (i.e. ``m/s`` (metre per second), ``m²`` -(square metre)). To support such use cases a library introduced a notion of -:term:`derived dimension recipe` which stores the information about the -order, exponents, and types of dimensions used to define this particular -derived dimension. For example each of the below ``momentum`` definitions -will result in a different unnamed unit symbol: - -.. code-block:: - :emphasize-lines: 2-4, 6-8, 10-12 - - struct dim_momentum : derived_dimension, - exponent, - exponent> {}; // kg⋅m/s - struct dim_momentum : derived_dimension, - exponent, - exponent> {}; // m⋅kg/s - struct dim_momentum : derived_dimension, - exponent, - exponent> {}; // 1/s⋅m⋅kg - -where ``kilogram_metre_per_second`` is defined as:: - - struct kilogram_metre_per_second : derived_unit {}; - -However, the easiest way to define momentum is just to use the -``si::dim_speed`` derived dimension in the recipe: - -.. code-block:: - :emphasize-lines: 3 - - struct dim_momentum : derived_dimension, - exponent> {}; // kg⋅m/s - -In such a case the library will do its magic and will automatically -unpack a provided derived dimension to its base dimensions in order to -end up with a :term:`normalized derived dimension` for a parent entity. - -The need to support a derived dimension in the recipe is not just a -syntactic sugar that allows us to do less typing. It is worth to notice -here that some of the derived unnamed units are defined in terms of other -derived named units (i.e. surface tension quantity is measured in terms -of ``N/m``): - -.. code-block:: - :emphasize-lines: 2 - - struct dim_surface_tension : derived_dimension, - exponent> {}; // N/m - -If we defined the above in terms of base units we would end up with -a ``kg/s²`` derived unit symbol. - - -Derived Scaled Units -^^^^^^^^^^^^^^^^^^^^ - -For some units determining of a correct scaling ratio may not be trivial, -and even if done correctly, may be a pain to maintain. For a simple example -let's take a "kilometre per hour" unit. What is the easiest to maintain -ratio in reference to the "metre per second": - -- ``1000/3600`` -- ``10/36`` -- ``5/18`` - -Whichever, we choose there will always be someone not happy with our choice. - -Thanks to a `derived_scaled_unit` class template provided by the library this problem -does not exist at all. With it ``si::kilometre_per_hour`` can be defined as:: - - namespace si { - - struct kilometre_per_hour : derived_scaled_unit {}; - - } - -In case the scaled derived unit should serve as a named one we can use -a `named_derived_unit` where the user is able to provide a symbol for the unit -by him/her-self:: - - namespace si::fps { - - struct knot : named_derived_unit {}; - - } - -Please note that the dervided scaled units are the only unit-related class templates -that take a dimension as its parameter. This derived dimension provides a :term:`recipe` -used for its definition. Based on the information stored in the recipe -(order, type, and exponents of composite dimensions) and the ratios of units -provided in the template parameter list after the derived dimension parameter, -the library calculates the final ratio for this unit. - - -Aliased Units -------------- - -In order to make our life easier people tend to assign alternative/aliased names -to some popular units. As an example we often use "tonne" instead of "megagram", -"litre" instead of "cubic decimetre", or "hectare" instead of "square hectometre". - -This library provides facilities to define aliased names to already defined units -with `alias_unit` class template:: - - namespace si { - - struct litre : alias_unit {}; - - } - -Also, it is possible to add prefixes to such aliased units with `prefixed_alias_unit` -class template:: - - namespace si { - - struct millilitre : prefixed_alias_unit {}; - - } - - -.. seealso:: - - To learn more about unknown units please refer to the - :ref:`use_cases/unknown_dimensions:Working with Unknown Dimensions and Their Units` chapter. - - -## System reference - -"It is important to emphasize that each physical quantity has only one coherent SI unit, even -though this unit can be expressed in different forms by using some of the special names and -symbols." -The converse, however, is not true, because in general several different quantities may -share the same SI unit. - - -For example, for the quantity heat capacity as well as for the -quantity entropy the SI unit is joule per kelvin. Similarly, for the base quantity electric -current as well as the derived quantity magnetomotive force the SI unit is the ampere. It is -therefore important not to use the unit alone to specify the quantity. diff --git a/docs/genindex.rst b/docs/genindex.rst deleted file mode 100644 index cd7f6675..00000000 --- a/docs/genindex.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. This file is a placeholder and will be replaced during Sphinx build - -Index -##### diff --git a/docs/getting_started/code_example.md b/docs/getting_started/code_example.md new file mode 100644 index 00000000..e9445371 --- /dev/null +++ b/docs/getting_started/code_example.md @@ -0,0 +1,83 @@ +# Code Example + +Here is a small example of operations possible on scalar quantities: + +```cpp +#include + +using namespace mp_units::si::unit_symbols; + +// simple numeric operations +static_assert(10 * km / 2 == 5 * km); + +// unit conversions +static_assert(1 * h == 3600 * s); +static_assert(1 * km + 1 * m == 1001 * m); + +// dimension conversions +inline constexpr auto kmph = km / h; +static_assert(1 * km / (1 * s) == 1000 * (m / s)); +static_assert(2 * kmph * (2 * h) == 4 * km); +static_assert(2 * km / (2 * kmph) == 1 * h); + +static_assert(2 * m * (3 * m) == 6 * m2); + +static_assert(10 * km / (5 * km) == 2); + +static_assert(1000 / (1 * s) == 1 * kHz); +``` + +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/j8afKnarv)" + + +This library requires some C++20 features ([concepts and constraints](https://en.cppreference.com/w/cpp/language/constraints), +[classes as NTTP](https://en.cppreference.com/w/cpp/language/template_parameters), ...). Thanks to them, +the user gets a powerful but still easy-to-use interface where all unit conversions and dimensional analysis can be +performed without sacrificing accuracy. Please see the below example for a quick preview of basic library features: + +*[NTTP]: Non-Type Template Parameter + +```cpp +#include +#include +#include +#include +#include +#include + +using namespace mp_units; + +constexpr QuantityOf auto avg_speed(QuantityOf auto d, + QuantityOf auto t) +{ + return d / t; +} + +int main() +{ + using namespace mp_units::si::unit_symbols; + using namespace mp_units::international::unit_symbols; + + constexpr auto v1 = 110 * (km / h); + constexpr auto v2 = 70 * mph; + constexpr auto v3 = avg_speed(220. * isq::distance[km], 2 * h); + constexpr auto v4 = avg_speed(isq::distance(140. * mi), 2 * h); + constexpr auto v5 = v3[m / s]; + constexpr auto v6 = value_cast(v4); + constexpr auto v7 = value_cast(v6); + + std::cout << v1 << '\n'; // 110 km/h + std::cout << v2 << '\n'; // 70 mi/h + std::cout << std::format("{}", v3) << '\n'; // 110 km/h + std::cout << std::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** + std::cout << std::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s + std::cout << std::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s + std::cout << std::format("{:%Q}", v7) << '\n'; // 31 +} +``` + +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/T8bovrqTP)" + +!!! note + + You can find more code examples in the Examples chapter. diff --git a/docs/getting_started/faq.md b/docs/getting_started/faq.md new file mode 100644 index 00000000..18fd1018 --- /dev/null +++ b/docs/getting_started/faq.md @@ -0,0 +1,176 @@ +# Frequently Asked Questions + +## Why do we spell `metre` instead of `meter`? + +This is how ISO 80000 defines it (British English spelling by default). + + +## Why don't we use UDLs to create quantities? + +Many reasons make UDLs a poor choice for a physical units library: + +1. UDLs work only with literals (compile-time known values). Our observation is that besides + the unit tests, there are few compile-time known constants used in the production code. +2. Typical implementations of UDLs tend to always use the widest representation type available. + In the case of `std::chrono::duration`, the following is true: + + ```cpp + using namespace std::chrono_literals; + auto d1 = 42s; + auto d2 = 42.s; + static_assert(std::is_same_v); + static_assert(std::is_same_v); + ``` + +3. While increasing the coverage for the library, we learned that many unit symbols conflict with + built-in types or numeric extensions. A few of those are: `F` (farad), `J` (joule), `W` (watt), + `K` (kelvin), `d` (day), `l` or `L` (litre), `erg`, `ergps`. For a while for those we used `_` prefix + to make the library work at all, but at some point, we had to unify the naming, and we came up with `_q_` + prefix, which resulted in creating a quantity of a provided unit. So in case the library is + standardized, all quantities would be created with UDLs having `q_` prefix (i.e. `42q_s`) + which is not that nice anymore. + +4. UDLs with the same identifiers defined in different namespace can't be disambiguated in the C++ + language. If both SI and CGS systems define `_q_s` UDL for a second unit, then it would not be possible + to specify which one to use in case both namespaces are "imported". + +5. Another bad property of UDLs is that they do not compose. A coherent unit of angular momentum would + have a UDL specified as `_q_kg_m2_per_s`. Now imagine that you want to make every possible user happy. + How many variations of that unit would you predefine for differently scaled versions of unit ingredients? + +6. UDLs are also really expensive to define and specify. For each unit, we need two definitions. One for + integral and another one for floating-point representation. Before the V2 framework, the coherent unit of + angular momentum was defined as: + + ```cpp + constexpr auto operator"" _q_kg_m2_per_s(unsigned long long l) + { + gsl_ExpectsAudit(std::in_range(l)); + return angular_momentum(static_cast(l)); + } + constexpr auto operator"" _q_kg_m2_per_s(long double l) + { + return angular_momentum(l); + } + ``` + + +## Why `60 * km / h` does not compile? + +The library design does not allow multiplying or dividing a quantity (the result of `60 * km`) +by another unit. This significantly limits the number of possible errors and surprises in the +quantity equations. + +Consider the following expression: + +```cpp +auto q = 60 * km / 2 * h; +``` + +Looks like `30 km/h`, right? But it is not. If the above code was allowed, it would result +in `30 km⋅h`. In case you want to divide `60 * km` by `2 * h` a parenthesis is needed +`60 * km / (2 * h)`. + +Another surprising issue could result from the following code: + +```cpp +template +auto make_length(T v) { return v * si::metre; } + +auto v = 42; +auto q = make_length(v); +``` + +The above might look like a good idea, but consider what would happen in the user provided +an already existing quantity: + +```cpp +auto v = 42 * m; +auto q = make_length(v); +``` + +Fortunately, with the current design, such issues are detected at compile-time. + + +## Why a dimensionless quantity is not just a fundamental arithmetic type? + +In the initial design of this library, the resulting type of division of two quantities was their +common representation type: + +```cpp +static_assert(std::is_same_v); +``` + +First of all, this was consistent with +[`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration/operator_arith4) behavior. +Additional reasoning behind it was not providing a false impression of a strong `quantity` type for +something that looks and feels like a regular number. Also, all of the mathematic and trigonometric functions +were working fine out of the box with such representation types, so we did not have to rewrite +`sin()`, `cos()`, `exp()`, and others. + +However, the feedback we got from the production usage was that such an approach is really bad for generic +programming. It is hard to handle the result of the two quantities' division (or multiplication) as +it might be either a quantity or a fundamental type. If we want to raise such a result to some power, we +must use `units::pow` or `std::pow` depending on the resulting type. Those are only a few issues related +to such an approach. + +Moreover, suppose you divide quantities of the same dimension but with units of significantly different +magnitudes. In that case, you may end up with a really small or a huge floating-point value, which may result +in losing lots of precision. Returning a dimensionless quantity from such cases allows us to benefit from +all the properties of scaled units and is consistent with the rest of the library. + +!!! info + + More information on the current design can be found in the Dimensionless Quantities chapter. + + +## Why Unicode quantity symbols are used by default instead of ASCII-only characters? + +Both C++ and ISO 80000 are standardized by the ISO. ISO 80000 and the SI standards specify Unicode symbols +as the official unit names for some quantities (i.e. `Ω` symbol for the resistance quantity). +As **mp-units** library will be proposed for standardization as a part of the C++ Standard Library +we have to obey the rules and be consistent with ISO specifications. + +!!! info + + We do understand engineering reality and the constraints of some environments. This is why the library + has the option of ASCII-only Quantity Symbols. + + +## Why don't you have CMake options to disable the building of tests and examples? + +Over time many people provided PRs proposing adding options to build tests and examples conditionally. +Here are a few examples: + +- [Add CMake options for disabling docs, examples and tests](https://github.com/mpusz/mp-units/pull/124) +- [build: add options to disable part of the build](https://github.com/mpusz/mp-units/pull/402) +- [CMake Refactoring and Option Cleanup](https://github.com/mpusz/mp-units/pull/456) + +We admit this is a common practice in the industry, but we also believe this is a bad pattern. + +First, the only need for such options comes when a user wants to use `add_subdirectory()` in CMake +to handle dependencies. Such an approach does not scale and should be discouraged. There is little +use for such a practice in times when we have dedicated package managers like Conan. + +The second thing is that our observation is that many people are fixed on disabling "unneeded" subdirectories +from compilation, but they do not see or address the biggest issue, which is polluting user's build +environment with our development-specific settings. Propagating our restrictive compilation flags to user's +project is not the best idea as it might cause a lot of harm if this project stops to compile +because of that. + +Last but not least, not having those options is on purpose. Top level _CMakeLists.txt_ file should only +be used by **mp-units** developers and contributors as an entry point for project's development. +We want to ensure that everyone will build **ALL** the code correctly before pushing a commit. Having +such options would allow unintended issues to leak to PRs and CI. + +This is why our projects have two entry points: + +- _./CMakeLists.txt_ is to be used by projects developers to build **ALL** the project code with really + restrictive compilation flags, +- _./src/CMakeLists.txt_ contains only a pure library definition and should be used by the customers + that prefer to use CMake's `add_subdirectory()` to handle the dependencies. + +!!! info + + For more details on this please refer to the [CMake + Conan: 3 Years Later - Mateusz Pusz](https://youtu.be/mrSwJBJ-0z8?t=1931) + lecture that Mateusz Pusz provided at the C++Now 2021 conference. diff --git a/docs/getting_started/installation_and_usage.md b/docs/getting_started/installation_and_usage.md new file mode 100644 index 00000000..063fcbb4 --- /dev/null +++ b/docs/getting_started/installation_and_usage.md @@ -0,0 +1,449 @@ +# Installation And Usage + +!!! info + + **mp-units** library tries to provide the best user experience possible with the C++ language. + To achieve that, it extensively uses C++20 features and the + [explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter) + from C++23. + + Even though the library benefits from C++23 (if available), C++20 is enough to compile and + use all of the library's functionality. C++23 features are hidden behind a preprocessor macro + providing a backward-compatible way to use it. + + Sadly, as of today, not many compilers provide full C++20 support. The library compiles fine + on the following compilers (or newer): + + - gcc-12.2 + + In the upcoming weeks, we will be actively working to extend the support to other compilers as well. + + +## Repository Structure and Dependencies + +This repository contains three independent CMake-based projects: + +- _./src_ + + - header-only project containing whole **mp-units** library + - _./src/CMakeList.txt_ file is intended as an **entry point for library users** + - in case this library becomes part of the C++ standard, it will have no external dependencies + but until then, it depends on the following: + + - [gsl-lite](https://github.com/gsl-lite/gsl-lite) to verify runtime contracts with + the `gsl_Expects` macro, + - [{fmt}](https://github.com/fmtlib/fmt) to provide text formatting of quantities + (if `std::format` is not supported yet on a specific compiler), + - [only for clang < 14 with libc++] [range-v3](https://github.com/ericniebler/range-v3) + to provide needed C++20 concepts and utilities. + +- _._ + + - project used as an **entry point for library development and CI/CD** + - it wraps _./src_ project together with usage examples and tests + - additionally to the dependencies of _./src_ project, it uses: + + - `Catch2 `_ library as a unit tests framework, + - `linear algebra `_ + library based on proposal `P1385 `_ used in some examples + and tests. + + - in case you also want to generate the project's documentation, you will need: + + - [Material for MkDocs](https://squidfunk.github.io/mkdocs-material) + +- *./test_package* + + - library installation and Conan package verification. + + +!!! tip + + Top level _CMakeLists.txt_ file should only be used by **mp-units** developers and contributors + as an entry point for the project's development. We want to ensure that everyone will build **ALL** + the code correctly before pushing a commit. Having such options would allow unintended issues to + leak to PRs and CI. + + This is why our projects have two entry points: + + - _./CMakeLists.txt_ is to be used by projects developers to build **ALL** the project code with really + restrictive compilation flags, + - _./src/CMakeLists.txt_ contains only a pure library definition and should be used by the customers + that prefer to use CMake's `add_subdirectory()` to handle the dependencies. + + To learn more about the rationale, please check our [FAQ](../faq/#why-dont-you-have-cmake-options-to-disable-building-of-tests-and-examples). + + +## Obtaining Dependencies + +This library assumes that most of the dependencies will be provided by the +[Conan Package Manager](https://conan.io/). If you want to obtain required +dependencies by other means, some modifications to the library's CMake files might be needed. +The rest of the dependencies responsible for documentation generation are provided by +`python3-pip`. + + +### Conan Quick Intro + +In case you are not familiar with Conan, to install it (or upgrade) just do: + +```shell +pip3 install -U conan +``` + +After that, you might need to add a custom profile file for your development environment +in _~/.conan2/profiles_ directory. An example profile can look as follows: + +```ini hl_lines="5" title="~/.conan2/profiles/gcc12" +[settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=20 +compiler.libcxx=libstdc++11 +compiler.version=12 +os=Linux + +[conf] +tools.build:compiler_executables={"c": "gcc-12", "cpp": "g++-12"} +``` + +!!! tip + + Please note that the **mp-units** library requires C++20 to be set in a Conan profile or forced + via the Conan command line. If you do the former, you will not need to provide `-s compiler.cppstd=20` + every time your run a Conan command line (as provided in the command line instructions below). + +Additionally, it is recommended to set Ninja as a CMake generator for Conan. To do so, you should create +a _~/.conan2/global.conf_ file that will set `tools.cmake.cmaketoolchain:generator` to one of Ninja +generators. For example: + +```text title="~/.conan2/global.conf" +tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" +``` + +!!! note + + _~/.conan2/global.conf_ file may also set `tools.cmake.cmake_layout:build_folder_vars` which + [makes working with several compilers or build configurations easier](https://docs.conan.io/2/reference/tools/cmake/cmake_layout.html#multi-setting-option-cmake-layout). + For example, the below line will force Conan to generate separate CMake presets and folders for + each compiler: + + ```text title="~/.conan2/global.conf" + tools.cmake.cmake_layout:build_folder_vars=["settings.compiler", "settings.compiler.version"] + ``` + + In such a case, you will need to use a configuration-specific preset name in the Conan instructions + provided below rather then just `conan-default` and `conan-release` + (i.e. `conan-gcc-11` and `conan-gcc-11-release`) + + +## Build Options + +### Conan Configuration Properties + +[`user.build:all`](#user-build-all){ #user-build-all } + +: [:octicons-tag-24: 0.8.0][build all support] · :octicons-milestone-24: `True`/`False` (Default: `False`) + + Enables compilation of all the source code including tests and examples. To support + this it requires some additional Conan build dependencies described in + [Repository Structure and Dependencies](#repository-structure-and-dependencies). + It also runs unit tests during Conan build (unless `tools.build:skip_test` + configuration property is set to `True`). + +[build all support]: https://github.com/mpusz/mp-units/releases/tag/v0.8.0 + + +[`user.build:skip_la`](#user-skip-la){ #user-skip-la } + +: [:octicons-tag-24: 0.8.0][skip la support] · :octicons-milestone-24: `True`/`False` (Default: `False`) + + If `user.build:all` is enabled, among others, Conan installs the external + [wg21-linear_algebra](https://conan.io/center/wg21-linear_algebra) + dependency and enables the compilation of linear algebra-based tests and usage examples. + Such behavior can be disabled with this option. + + [skip la support]: https://github.com/mpusz/mp-units/releases/tag/v0.8.0 + + +### CMake Options + +[`MP_UNITS_AS_SYSTEM_HEADERS`](#MP_UNITS_AS_SYSTEM_HEADERS){ #MP_UNITS_AS_SYSTEM_HEADERS } + +: [:octicons-tag-24: 2.0.0][as system headers support] · :octicons-milestone-24: `ON`/`OFF` (Default: `OFF`) + + Exports library as system headers. + + [as system headers support]: https://github.com/mpusz/mp-units/releases/tag/v2.0.0 + + +[`MP_UNITS_BUILD_LA`](#MP_UNITS_BUILD_LA){ #MP_UNITS_BUILD_LA } + +: [:octicons-tag-24: 2.0.0][build la support] · :octicons-milestone-24: `ON`/`OFF` (Default: `ON`) + + Enables building code depending on the linear algebra library. + + [build la support]: https://github.com/mpusz/mp-units/releases/tag/v2.0.0 + + +[`MP_UNITS_IWYU`](#MP_UNITS_IWYU){ #MP_UNITS_IWYU } + +: [:octicons-tag-24: 2.0.0][iwyu support] · :octicons-milestone-24: `ON`/`OFF` (Default: `OFF`) + + Enables `include-what-you-use` when compiling with a clang compiler. + Additionally turns on [`MP_UNITS_AS_SYSTEM_HEADERS`](#MP_UNITS_AS_SYSTEM_HEADERS). + + [iwyu support]: https://github.com/mpusz/mp-units/releases/tag/v2.0.0 + + +[`MP_UNITS_USE_LIBFMT`](#MP_UNITS_USE_LIBFMT){ #MP_UNITS_USE_LIBFMT } + +: [:octicons-tag-24: 2.0.0][use libfmt support] · :octicons-milestone-24: `ON`/`OFF` (Default: `ON`) + + Enables usage of [{fmt}](https://github.com/fmtlib/fmt) library instead of the C++20 Standard + Library feature. + + [use libfmt support]: https://github.com/mpusz/mp-units/releases/tag/v2.0.0 + + +## CMake with Presets Support + +It is recommended to use at least CMake 3.23 to build this project as this version introduced support +for CMake Presets schema version 4 used now by Conan to generate presets files. All build instructions +below assume that you have such support. If not, your CMake invocations have to be replaced with something +like: + +```shell +mkdir build && cd build +cmake .. -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=/conan_toolchain.cmake +cmake --build . --config Release +``` + +!!! note + + In case you can't use CMake 3.23 but you have access to CMake 3.20 or later, you can append + `-c tools.cmake.cmaketoolchain.presets:max_schema_version=2` to the `conan install` command + which will force Conan to use an older version of the CMake Presets schema. + + +## Installation and Reuse + +There are many different ways of installing/reusing **mp-units** in your project. Below we mention +only a few of many options possible. + +!!! info + + The easiest and most recommended way to obtain **mp-units** is with the Conan package manager. + See [Conan + CMake (release)](#conan-cmake-release) for a detailed instruction. + + +### Copy + +As **mp-units** is a C++ header-only library you can simply copy all needed _src/*/include_ subdirectories +to your source tree. + +!!! note + + In such a case, you are on your own to ensure all the dependencies are installed, and their header + files can be located during the build. Please also note that some compiler-specific flags are needed + to make the code compile without issues. + + +### Copy + CMake + +If you copy the whole **mp-units** repository to your project's file tree, you can reuse CMake targets +defined by the library. To do so, you should use _CMakeLists.txt_ file from the _./src_ directory: + +```cmake +add_subdirectory(/src) +# ... +target_link_libraries( mp-units::mp-units) +``` + +!!! note + + You are still on your own to make sure all the dependencies are installed and their header and CMake + configuration files can be located during the build. + + +### Conan + CMake (release) + +!!! tip + + If you are new to the Conan package manager, it is highly recommended to read + [Obtaining Dependencies](#obtaining-dependencies) and refer to + [Consuming packages](https://docs.conan.io/2/tutorial/consuming_packages.html) + chapter of the official Conan documentation for more information. + +**mp-units** releases are hosted on [Conan-Center](https://conan.io/center/mp-units). +To obtain an official library release, the following steps may be performed: + +1. Create Conan configuration file (either _conanfile.txt_ or _conanfile.py_) in your + project's top-level directory and add **mp-units** as a dependency of your project. + For example, the simplest file may look as follows: + + ```ini title="conanfile.txt" + [requires] + mp-units/0.8.0 + + [layout] + cmake_layout + + [generators] + CMakeToolchain + CMakeDeps + ``` + +2. Import **mp-units** and its dependencies definitions to your project's build procedure + with `find_package`: + + ```cmake + find_package(mp-units CONFIG REQUIRED) + ``` + +3. Link your CMake targets with **mp-units**: + + ```cmake + target_link_libraries( mp-units::mp-units) + ``` + +4. Download, build, and install Conan dependencies before running the CMake configuration step: + + ```shell + conan install . -pr -s compiler.cppstd=20 -b=missing + cmake --preset conan-default + cmake --build --preset conan-release + ``` + +### Conan + CMake (Live At Head) + +This chapter describes the procedure to Live At Head, which means using the latest version +of **mp-units** all the time. + +!!! note + + Please note that even though the Conan packages that you will be using are generated **ONLY** + for builds that are considered stable (passed our CI tests) some minor regressions may happen + (our CI and C++20 build environment is not perfect yet). Also, please expect that the library + interface might, and probably will, change occasionally. Even though we do our best, such + changes might not be reflected in the project's documentation right away. + +The procedure is similar to the one described in [Conan + CMake (release)](#conan-cmake-release) +with the following differences: + +1. Before starting the previous procedure, add **mp-units** remote to your Conan configuration: + + ```shell + conan remote add conan-mpusz https://mpusz.jfrog.io/artifactory/api/conan/conan-oss + ``` + +2. In your Conan configuration file, provide the package identifier of the `mpusz/testing` stream: + + ```ini title="conanfile.txt" hl_lines="2" + [requires] + mp-units/2.0.0@mpusz/testing + + [layout] + cmake_layout + + [generators] + CMakeToolchain + CMakeDeps + ``` + + !!! tip + + The identifiers of the latest packages can always be found in + [the project's README file](https://github.com/mpusz/mp-units/blob/master/README.md) or on + [the project's Artifactory](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units). + +3. Force Conan to check for updated recipes with `-u`: + + ```shell + conan install . -pr -s compiler.cppstd=20 -b=missing -u + ``` + + +### Install + +In case you don't want to use Conan in your project and just want to install the **mp-units** +library on your file system and use `find_package(mp-units)` from another repository +to find it, it is enough to perform the following steps: + +```shell +conan install . -pr -s compiler.cppstd=20 -b=missing +mv CMakeUserPresets.json src +cd src +cmake --preset conan-default -DCMAKE_INSTALL_PREFIX= +cmake --build --preset conan-release --target install +``` + + +## Contributing (or just building all the tests and examples) + +In case you would like to build all the **mp-units** source code (with unit tests and examples), +you should: + +1. Use the _CMakeLists.txt_ from the top-level directory. +2. Run Conan with [`user.build:all`](#user-build-all) = `True`. + +```shell +git clone https://github.com/mpusz/mp-units.git && cd units +conan build . -pr -s compiler.cppstd=20 -c user.build:all=True -b missing +``` + +The above will download and install all of the dependencies needed for the development of the library, +build all of the source code, and run unit tests. + +If you prefer to build the project via CMake rather than Conan, then you should replace +the `conan build` with `conan install` command and then follow with a regular CMake build: + +```shell +cmake --preset conan-default +cmake --build --preset conan-release +cmake --build --preset conan-release --target test +``` + + +## Building documentation + +Starting from **mp-units 2.0** we are using [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) +to build our documentation. The easiest way to install all the required dependencies +is with `pip`: + +```shell +pip install -U mkdocs-material +``` + +After that, you can either: + +- easily [start a live server to preview the documentation as you write](https://squidfunk.github.io/mkdocs-material/creating-your-site/#previewing-as-you-write) + +```shell +mkdocs serve +``` + +- [build the documentation](https://squidfunk.github.io/mkdocs-material/creating-your-site/#building-your-site) + +```shell +mkdocs build +``` + + +## Packaging + +To test CMake installation and Conan packaging or create a Conan package run: + +```shell +conan create . / -pr -s compiler.cppstd=20 -c user.build:all=True -b missing +``` + +The above will create a Conan package and run tests provided in _./test_package_ directory. + + +## Uploading **mp-units** Package to the Conan Server + +```shell +conan upload -r --all mp-units/2.0.0@/ +``` diff --git a/docs/getting_started/introduction.md b/docs/getting_started/introduction.md new file mode 100644 index 00000000..c67950d5 --- /dev/null +++ b/docs/getting_started/introduction.md @@ -0,0 +1,50 @@ +# Introduction + +**mp-units** is a Modern C++ library that provides compile-time dimensional analysis and unit/quantity +manipulation. The initial versions of the library were inspired by the +[`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration) +but with each release, the interfaces diverged from the original to provide a better user +experience. + + +## Open Source + +**mp-units** is Free and Open Source, with a permissive +[MIT license](https://github.com/mpusz/mp-units/blob/master/LICENSE.md). Check out the source +code and issue tracking (for questions and support, reporting bugs, suggesting feature requests +and improvements) at . + + +## With the User's Experience in Mind + +Most of the critical design decisions in the library are dictated by the requirement of +providing the best user experience possible. Other C++ physical units libraries are +"famous" for their enormous and hard-to-understand error messages (one line of the error log often +do not fit on one slide). The ultimate goal of **mp-units** is to improve this and make compile-time +errors and debugging as easy and user-friendly as possible. + +To achieve this goal, several techniques are applied: + +- usage of C++20 concepts, +- using strong types for framework entities (instead of type aliases), +- usage of expression templates to improve the readability of generated types, +- limiting the number of template arguments to the bare minimum. + +!!! note + + In many generic C++ libraries compile-time errors do not happen often. It is hard to + break `std::string` or `std::vector` in a way it won't compile with a huge error + log. Physical Units libraries are different. **Generation of compile-time errors + is the main reason to use such a library.** + + +## Key Features + +| Feature | Description | +|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Safety** | - The affine space strong types (`quantity` and `quantity_point`)
- Compile-time checked conversions of quantities and units
- Unique support for many quantities of the same kind
- Type-safe equations on scalar, vector, and tensor quantities and their units
- Value-preserving conversions | +| **Performance** | - All the compile-time logic implemented as immediate (`consteval`) functions
- As fast or even faster than working with fundamental types
- No space size overhead needed to implement high-level abstractions | +| **Great User Experience** | - Optimized for readable compilation errors and great debugging experience
- Efficient and composable way to specify a unit of choice
- Value-based dimension, unit, and quantity equations | +| **Feature Rich** | - Systems of Quantities
- Systems of Units
- Scalar, vector, and tensor quantities
- The affine space
- [Natural units systems](https://en.wikipedia.org/wiki/Natural_units) support
- Strong angular system
- Supports any unit's magnitude (huge, small, floating-point)
- Faster-than-lightspeed constants
- Highly adjustable text-output formatting | +| **Easy to Extend** | - Each entity can be defined with a single line of code
- User can easily extend the systems with custom dimensions, quantities, and units | +| **Low Standardization Cost** | - Small number of predefined entities needed thanks to composability
- No external dependencies (assuming full C++20 support)
- No macros in the user interface (besides portability and standard-compliance issues)
- Possibility to be standardized as a [freestanding](https://en.cppreference.com/w/cpp/freestanding) part of the C++ Standard Library | diff --git a/docs/getting_started/quick_start.md b/docs/getting_started/quick_start.md new file mode 100644 index 00000000..50c121ed --- /dev/null +++ b/docs/getting_started/quick_start.md @@ -0,0 +1,76 @@ +# Quick Start + +A **quantity** is a concrete amount of a unit for a quantity type of a specified dimension with a +specific representation, and is represented in the library with a `quantity` class template. + + +## Creating a quantity + +The quantity is created by multiplying a number with a predefined unit: + +```cpp +#include + +using namespace mp_units; + +auto q = 42 * si::metre; +``` + +!!! note + + The above spelling of `metre` is not a typo. For motivation, please check our + [FAQ](../faq/#why-do-we-spell-metre-instead-of-meter). + +The above creates an instance of `quantity`. The same can be obtained using +an optional unit symbol: + +```cpp +#include + +using namespace mp_units; +using namespace mp_units::si::unit_symbols; + +auto q = 42 * m; +``` + +!!! note + + Unit symbols introduce a lot of short identifiers into the current namespace, and that is + why they are opt-in. A user has to explicitly "import" them from a dedicated `unit_symbols` + namespace. + + +## User-provided unit wrappers + +Sometimes it might be awkward to type some derived units: + +```cpp +auto speed = 60 * (km / h); +``` + +!!! note + + Please note that `60 * km / h` will not compile. To read more about the rationale for such + a design please check our [FAQ](../faq/#why-dont-we-use-udls-to-create-a-quantity). + +In case such a unit is used a lot in the project, a user can easily provide a nicely named +wrapper for it with: + +```cpp +constexpr auto kmph = km / h; +auto speed = 60 * kmph; +``` + +or even: + +```cpp +constexpr auto kilometre = si::kilo; +constexpr auto kilometre_per_hour = kilometre / si::hour; +constexpr auto kmph = kilometre_per_hour; +auto speed = 60 * kmph; +``` + +!!! note + + In case you wonder why this library does not use UDLs to create quantities, please check + our [FAQ](../faq/#why-dont-we-use-udls-to-create-quantities). \ No newline at end of file diff --git a/docs/glossary.rst b/docs/glossary.rst deleted file mode 100644 index 3e2a4e42..00000000 --- a/docs/glossary.rst +++ /dev/null @@ -1,222 +0,0 @@ -.. default-role:: term - -Glossary -======== - -ISO 80000 [1]_ definitions --------------------------- - -.. glossary:: - - quantity - - Property of a phenomenon, body, or substance, where the property has a magnitude that can - be expressed by means of a number and a reference. - - A reference can be a measurement unit, a measurement procedure, a reference material, or - a combination of such. - - A quantity as defined here is a scalar. However, a vector or a tensor, the components of - which are quantities, is also considered to be a quantity. - - The concept ’quantity’ may be generically divided into, e.g. ‘physical quantity’, - ‘chemical quantity’, and ‘biological quantity’, or ‘base quantity’ and ‘derived quantity’. - - Examples of quantities are: mass, length, density, magnetic field strength, etc. - - kind of quantity - kind - - Aspect common to mutually comparable `quantities `. - - The division of the concept ‘quantity’ into several kinds is to some extent arbitrary - - - i.e. the quantities diameter, circumference, and wavelength are generally considered - to be quantities of the same kind, namely, of the kind of quantity called length. - - - Quantities of the same kind within a given `system of quantities` have the same quantity - `dimension`. However, `quantities ` of the same `dimension` are not necessarily - of the same kind. - - - For example, the absorbed dose and the dose equivalent have the same `dimension`. - However, the former measures the absolute amount of radiation one receives whereas - the latter is a weighted measurement taking into account the kind of radiation - on was exposed to. - - system of quantities - system - - Set of `quantities ` together with a set of non-contradictory equations - relating those `quantities `. - - Examples of systems of quantities are: the International System of Quantities, - the Imperial System, etc. - - base quantity - - `Quantity ` in a conventionally chosen subset of a given `system of quantities`, - where no `quantity` in the subset can be expressed in terms of the other - `quantities ` within that subset. - - Base quantities are referred to as being mutually independent since a base quantity - cannot be expressed as a product of powers of the other base quantities. - - derived quantity - - `Quantity `, in a `system of quantities`, defined in terms of the base - quantities of that system. - - International System of Quantities - ISQ - - `System of quantities ` based on the seven - `base quantities `: length, mass, time, electric current, thermodynamic - temperature, amount of substance, and luminous intensity. - - The International System of Units (SI) is based on the ISQ. - - dimension of a quantity - quantity dimension - dimension - - Expression of the dependence of a `quantity` on the `base quantities ` - of a `system of quantities` as a product of powers of factors corresponding to the - `base quantities `, omitting any numerical factors. - - A power of a factor is the factor raised to an exponent. Each factor is the dimension - of a `base quantity`. - - In deriving the dimension of a quantity, no account is taken of its scalar, vector, or - tensor character. - - In a given `system of quantities`: - - - `quantities ` of the same `kind` have the same quantity dimension, - - `quantities ` of different quantity dimensions are always of different `kinds `, - - `quantities ` having the same quantity dimension are not necessarily of the same `kind`. - - quantity of dimension one - dimensionless quantity - - `quantity` for which all the exponents of the factors corresponding to the - `base quantities ` in its `quantity dimension` are zero. - - The term “dimensionless quantity” is commonly used and is kept here for historical - reasons. It stems from the fact that all exponents are zero in the symbolic - representation of the `dimension` for such `quantities `. The term “quantity - of dimension one” reflects the convention in which the symbolic representation of the - `dimension` for such `quantities ` is the symbol ``1``. This `dimension` is - not a number, but the neutral element for multiplication of `dimensions `. - - The `measurement units ` and values of quantities of dimension one - are numbers, but such `quantities ` convey more information than a number. - - Some quantities of dimension one are defined as the ratios of two - `quantities of the same kind `. The `coherent derived unit` is the number one, - symbol ``1``. - - Numbers of entities are quantities of dimension one. - - unit of measurement - measurement unit - unit - - Real scalar `quantity`, defined and adopted by convention, with which any other - `quantity of the same kind ` can be compared to express the ratio of the - second `quantity` to the first one as a number. - - Measurement units are designated by conventionally assigned names and symbols. - - Measurement units of `quantities ` of the same `quantity dimension` may - be designated by the same name and symbol even when the `quantities ` are - not of the same `kind`. - - For example, joule per kelvin and J/K are respectively the name and symbol of both a - measurement unit of heat capacity and a measurement unit of entropy, which are generally - not considered to be `quantities of the same kind `. However, in some cases special - measurement unit names are restricted to be used with `quantities ` of specific - `kind` only. For example, the measurement unit ‘second to the power minus one’ (``1/s``) is - called hertz (``Hz``) when used for frequencies and becquerel (``Bq``) when used for - activities of radionuclides. As another example, the joule (``J``) is used as a unit of - energy, but never as a unit of moment of force, i.e. the newton metre (``N · m``). - - Measurement units of `quantities of dimension one ` are - numbers. In some cases, these measurement units are given special names, e.g. radian, - steradian, and decibel, or are expressed by quotients such as millimole per mole equal - to :math:`10^{−3}` and microgram per kilogram equal to :math:`10^{−9}`. - - base unit - - Measurement unit that is adopted by convention for a `base quantity`. - - In each `coherent system of units`, there is only one base unit for each `base quantity`. - - A base unit may also serve for a `derived quantity` of the same `quantity dimension`. - - For example, the `ISQ` has the base units of: metre, kilogram, second, Ampere, Kelvin, mole, - and candela. - - derived unit - - Measurement unit for a `derived quantity`. - - For example, in the `ISQ` Newton, Pascal, and katal are derived units. - - coherent derived unit - - `Derived unit ` that, for a given `system of quantities` and for a chosen - set of `base units `, is a product of powers of `base units ` with - no other proportionality factor than one. - - A power of a `base unit` is the `base unit` raised to an exponent. - - Coherence can be determined only with respect to a particular `system of quantities` - and a given set of `base units `. That is, if the metre and the second are - base units, the metre per second is the coherent derived unit of speed. - - system of units - - Set of `base units ` and `derived units `, together with - their multiples and submultiples, defined in accordance with given rules, for a given - `system of quantities`. - - coherent system of units - - - `System of units `, based on a given `system of quantities`, in which - the measurement unit for each `derived quantity` is a `coherent derived unit`. - - A `system of units` can be coherent only with respect to a `system of quantities` and - the adopted `base units `. - - off-system measurement unit - off-system unit - - `Measurement unit ` that does not belong to a given `system of units`. - For example, the electronvolt (:math:`≈ 1,602 18 × 10^{–19} J`) is an off-system measurement - unit of energy with respect to the `SI` or day, hour, minute are off-system measurement - units of time with respect to the `SI`. - - International System of Units - SI - - `System of units `, based on the `International System of Quantities`, - their names and symbols, including a series of prefixes and their names and symbols, - together with rules for their use, adopted by the General Conference on Weights and - Measures (CGPM) - - quantity value - value of a quantity - value - - Number and reference together expressing magnitude of a `quantity`. - - The number can be complex. - - A quantity value can be presented in more than one way. - - In the case of vector or tensor quantities, each component has a quantity value. - - - For example, force acting on a given particle, e.g. in Cartesian components - :math:`(F_x; F_y; F_z) = (−31,5; 43,2; 17,0) N`, where - :math:`(−31,5; 43,2; 17,0)` is a numerical-value vector and :math:`N` (newton) - is the unit, or :math:`(F_x; F_y; F_z) = (−31,5 N; 43,2 N; 17,0 N)` - where each component is a quantity. - - -Other definitions ------------------ - -.. glossary:: - :sorted: - - base dimension - - A `dimension` of a `base quantity`. - - derived dimension - - A `dimension` of a `derived quantity`. - - Often implemented as a list of exponents of `base dimensions `. - - normalized derived dimension - A `derived dimension` in which: - - - `base dimensions ` are not repeated in a list (each base dimension is provided at most once), - - `base dimensions ` are consistently ordered, - - `base dimensions ` having zero exponent are elided. - - derived dimension recipe - recipe - - The ordered list of exponents used to define a derived dimension - - The list may contain both base and derived dimensions (in the latter case - the dimension is being extracted to base dimensions by the framework) - - The order and types of dimensions used in the recipe determine how an unnamed - dimension's unit symbol is being printed in the text output - - scalable number - - Not a `quantity` - - Can be passed as a representation type to the :class:`units::quantity` type or be used as a factor - while multiplying or dividing a `quantity`. - -.. rubric:: Footnotes: - -.. [1] [ISO80000]_ gives general information and definitions concerning quantities, systems of quantities, - units, quantity and unit symbols, and coherent unit systems, especially the International System - of Quantities, ISQ, and the International System of Units, SI. The principles laid down in - ISO 80000-1:2009 are intended for general use within the various fields of science and technology - and as an introduction to other parts of the Quantities and units series. Ordinal quantities and - nominal properties are outside the scope of ISO 80000-1:2009. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..67e4b0f8 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +# Welcome to **mp-units**! + +**mp-units** is a compile-time enabled feature-rich Modern C++ header-only library that provides +compile-time dimensional analysis and unit/quantity manipulation. Its key strengths include safety, +performance, and developer experience. + +The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units) with a permissive +[MIT license](https://github.com/mpusz/units/blob/master/LICENSE.md). + +!!! info "Help needed!" + + The **mp-units** library might be the subject of ISO standardization for C++29. More on this can + be found in the ISO C++ proposal [P1935](https://wg21.link/p1935). We are actively looking for + parties interested in field-trialing the library. + +??? info "Supported compilers" + + This library tries to provide the best user experience possible with the C++ language. + To achieve that, it extensively uses C++20 features and the + [explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter) + from C++23. + + Even though the library benefits from C++23 (if available), C++20 is enough to compile and + use all of the library's functionality. C++23 features are hidden behind a preprocessor macro + providing a backward-compatible way to use it. + + Sadly, as of today, only a few compilers provide full C++20 support. The library compiles fine + on the following compilers (or newer): + + - gcc-12.2 + + In the upcoming weeks, we will be actively working to extend the support to other compilers as well. diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 45d40188..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,62 +0,0 @@ -Welcome to mp-units! -==================== - -**mp-units** is a compile-time enabled Modern C++ library that provides compile-time dimensional -analysis and unit/quantity manipulation. Source code is hosted on `GitHub `_ -with a permissive `MIT license `_. - - -.. important:: - - The **mp-units** library is the subject of ISO standardization for C++23/26. More on this can - be found in ISO C++ paper `P1935 `_ and - `NDC TechTown 2021 talk `_. We are actively looking for - parties interested in field trialing the library. - -.. note:: - - This library targets C++23/26 and extensively uses C++20 features. This is why it requires the latest C++ - compilers. The following compilers (or newer) are supported: - - - gcc-10 - - clang-12 - - Visual Studio 16.9 - - Apple clang 13 - -.. toctree:: - :maxdepth: 2 - :caption: Getting Started: - - introduction - quick_start - framework - defining_systems - use_cases - design - examples - usage - faq - -.. toctree:: - :maxdepth: 2 - :caption: Reference: - - reference/core - reference/systems - reference/math - reference/random - -.. note:: - - Source code documentation tools used to generate the above chapter still do not understand - C++20 to well which results in some issues in the generated output. We do our best to address - this ASAP. - -.. toctree:: - :maxdepth: 1 - :caption: Appendix: - - glossary - genindex - CHANGELOG - references diff --git a/docs/introduction.rst b/docs/introduction.rst deleted file mode 100644 index e380b922..00000000 --- a/docs/introduction.rst +++ /dev/null @@ -1,71 +0,0 @@ -Introduction -============ - -**mp-units** is a compile-time enabled Modern C++ library that provides compile-time -dimensional analysis and unit/quantity manipulation. The basic idea and design -heavily bases on `std::chrono::duration `_ -and extends it to work properly with many dimensions. - -Thanks to compile-time operations no runtime execution cost is introduced, -facilitating the use of this library to provide dimension checking in -performance-critical code. Support for quantities and units for arbitrary unit -system models and arbitrary value types is provided, as is a fine-grained -general facility for unit conversions. - -The library architecture has been designed with flexibility and extensibility -in mind. The demonstrations of the ease of adding new dimensions, their units, -and unit conversions are provided in the :ref:`examples:Examples`. - -Open Source ------------ - -**mp-units** is Free and Open Source, with a permissive -`MIT license `_. Check -out the source code and issue tracking (for questions and support, reporting -bugs and suggesting feature requests and improvements) at https://github.com/mpusz/units. - - -Approach --------- - -1. Safety and performance - - - strong types - - compile-time safety - - ``constexpr`` all the things - - as fast or even faster than when working with fundamental types - -2. The best possible user experience - - - compiler errors - - debugging - -3. No macros in the user interface -4. Easy extensibility -5. No external dependencies -6. Possibility to be standardized as a freestanding part of the C++ Standard - Library - - -With the User's Experience in Mind ----------------------------------- - -Most of the important design decisions in the library are dictated by the requirement of -providing the best user experience as possible. Other C++ physical units libraries are -"famous" for their huge error messages (one line of the error log often do not fit on one -slide). The ultimate goal of **mp-units** is to improve this and make compile-time errors -and debugging as easy and user-friendly as possible. - -To achieve this goal several techniques are applied: - -- usage of C++20 concepts, -- using strong types for framework entities (instead of type aliases), -- limiting the number of template arguments to the bare minimum, -- :ref:`design/downcasting:The Downcasting Facility`. - -.. important:: - - In many generic C++ libraries compile-time errors do not happen often. It is hard to - break ``std::string`` or ``std::vector`` in a way it won't compile with a huge error - log. Physical Units libraries are different. **Generation of compile-time errors - is the main reason to create such a library.** diff --git a/docs/library_reference/core_library.md b/docs/library_reference/core_library.md new file mode 100644 index 00000000..b34d95fc --- /dev/null +++ b/docs/library_reference/core_library.md @@ -0,0 +1,7 @@ +# Core Library + +## Concepts + +## Expression templates + +## Dimensions diff --git a/docs/quick_start.rst b/docs/quick_start.rst deleted file mode 100644 index 7eba57ae..00000000 --- a/docs/quick_start.rst +++ /dev/null @@ -1,88 +0,0 @@ -Quick Start -=========== - -Here is a small example of possible operations:: - - #include - #include - #include - #include - #include - - using namespace units::isq::si::references; - - // simple numeric operations - static_assert(10 * km / 2 == 5 * km); - - // unit conversions - static_assert(1 * h == 3600 * s); - static_assert(1 * km + 1 * m == 1001 * m); - - // dimension conversions - inline constexpr auto kmph = km / h; - static_assert(1 * km / (1 * s) == 1000 * (m / s)); - static_assert(2 * kmph * (2 * h) == 4 * km); - static_assert(2 * km / (2 * kmph) == 1 * h); - - static_assert(2 * m * (3 * m) == 6 * m2); - - static_assert(10 * km / (5 * km) == 2); - - static_assert(1000 / (1 * s) == 1 * kHz); - -.. admonition:: Try it on Compiler Explorer - - `Example #1 `_ - -This library requires some C++20 features (concepts, classes as -:abbr:`NTTP (Non-Type Template Parameter)`, ...). Thanks to them the user gets a powerful -but still easy to use interface where all unit conversions and dimensional analysis can be -performed without sacrificing on accuracy. Please see the below example for a quick preview -of basic library features:: - - #include - #include - #include - #include - #include - #include - #include - #include - - using namespace units::isq; - - constexpr Speed auto avg_speed(Length auto d, Time auto t) - { - return d / t; - } - - int main() - { - using namespace units::isq::si::literals; - using namespace units::isq::si::references; - using namespace units::aliases::isq::si::international; - - constexpr Speed auto v1 = 110 * (km / h); - constexpr Speed auto v2 = mi_per_h(70.); - constexpr Speed auto v3 = avg_speed(220_q_km, 2_q_h); - constexpr Speed auto v4 = avg_speed(si::length(140), si::time(2)); - constexpr Speed auto v5 = quantity_cast>(v3); - constexpr Speed auto v6 = quantity_cast(v4); - constexpr Speed auto v7 = quantity_cast(v6); - - std::cout << v1 << '\n'; // 110 km/h - std::cout << v2 << '\n'; // 70 mi/h - std::cout << std::format("{}", v3) << '\n'; // 110 km/h - std::cout << std::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** - std::cout << std::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s - std::cout << std::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s - std::cout << std::format("{:%Q}", v7) << '\n'; // 31 - } - -.. admonition:: Try it on Compiler Explorer - - `Example #2 `_ - -.. seealso:: - - You can find more code examples in the :ref:`examples:Examples` chapter. diff --git a/docs/reference/core.rst b/docs/reference/core.rst deleted file mode 100644 index 4782d442..00000000 --- a/docs/reference/core.rst +++ /dev/null @@ -1,12 +0,0 @@ -Core Library -============ - -.. toctree:: - :maxdepth: 1 - - core/concepts - core/types - core/functions - core/metafunctions - core/customization_points - core/downcasting diff --git a/docs/reference/core/concepts.rst b/docs/reference/core/concepts.rst deleted file mode 100644 index e835c0bd..00000000 --- a/docs/reference/core/concepts.rst +++ /dev/null @@ -1,169 +0,0 @@ -.. namespace:: units - -Concepts -======== - -.. note:: - - All names defined in this chapter reside in the :any:`units` namespace unless - specified otherwise. - -.. concept:: template Prefix - - A concept matching a symbol prefix. Satisfied by all instantiations of :struct:`prefix`. - -.. concept:: template UnitRatio - - Satisfied by all ratio values for which :expr:`R.num > 0` and :expr:`R.den > 0`. - -.. concept:: template BaseDimension - - A concept matching all base dimensions in the library. Satisfied by all dimension types - derived from the instantiation of :class:`base_dimension`. - -.. concept:: template Exponent - - A concept matching dimension's exponents. Satisfied by all instantiations of :class:`exponent`. - -.. concept:: template DerivedDimension - - A concept matching all derived dimensions in the library. Satisfied by all dimension - types derived from the instantiation of ``detail::derived_dimension_base``. - -.. concept:: template Dimension - - A concept matching all dimensions in the library. Satisfied by all dimension types for - which either :expr:`BaseDimension` or :expr:`DerivedDimension` is ``true``. - -.. concept:: template Unit - - A concept matching all unit types in the library. Satisfied by all unit types derived - from the instantiation of :class:`scaled_unit`. - -.. concept:: template NamedUnit - - A concept matching all unit types that have an atomic text symbol that can be used to aggregate it with - other named units to form a final symbol of a derived unit. - -.. concept:: template AliasUnit - - A concept matching all alias unit types in the library. Satisfied by all unit types derived - from the instantiation of :class:`alias_unit`. - -.. concept:: template UnitOf - - A concept matching only units of a specified dimension. Satisfied by all unit types that - satisfy :expr:`Unit`, :expr:`Dimension`, and for which :expr:`U::reference` and - ``dimension_unit::reference`` denote the same unit type. - - :tparam U: Type to verify against concept constraints. - :tparam D: Dimension type to use for verification. - -.. concept:: template Quantity - - A concept matching all quantities in the library. Satisfied by all instantiations of :class:`quantity`. - -.. concept:: template QuantityLike - - A concept matching all quantity-like types other than specialization of :class:`quantity`. Satisfied by - all types for which a correct specialization of :class:`quantity_like_traits` type trait is provided. - -.. concept:: template QuantityPointLike - - A concept matching all quantity-point-like types other than specialization of :class:`quantity_point`. - Satisfied by all types for which a correct specialization of :class:`quantity_point_like_traits` type trait is provided. - -.. concept:: template WrappedQuantity - - A concept matching types that wrap quantity objects. Satisfied by all wrapper types that - satisfy :expr:`Quantity || QuantityLike` recursively - (i.e. ``std::optional>``). - -.. concept:: template Representation - - A concept matching types that can be used as a `Quantity` representation type. Satisfied - by types that match ``(!Quantity) && (!QuantityLike) && (!WrappedQuantity) && std::regular`` - and satisfy one of the following: - - - if ``common_type_with`` is ``true``, then ``std::common_type_t`` - must at least provide binary multiplication and division operators, - - otherwise, ``T::value_type`` must be valid, ``common_type_with`` be - ``true``, and ``std::common_type_t`` must at least provide binary - multiplication and division operators with itself and ``T``. - -.. concept:: template QuantityPoint - - A concept matching all quantity points in the library. Satisfied by all instantiations of - :class:`quantity_point`. - -.. concept:: template Kind - - A concept matching all kind types. Satisfied by all kind types derived from an specialization of - :class:`kind`. - -.. concept:: template PointKind - - A concept matching all point kind types. Satisfied by all point kind types derived from an specialization of - :class:`point_kind`. - -.. concept:: template QuantityKind - - A concept matching all quantity kinds in the library. Satisfied by all specializations of - :class:`quantity_kind`. - -.. concept:: template QuantityPointKind - - A concept matching all quantity point kinds in the library. Satisfied by all specializations of - :class:`quantity_point_kind`. - -.. concept:: template typename DimTemplate> DimensionOfT - - A concept matching all dimensions being the instantiations derived from the provided dimension - class template. - -.. concept:: template typename DimTemplate> QuantityOfT - - A concept matching all quantities with a dimension being the instantiation derived from - the provided dimension class template. - -.. concept:: template QuantityOf - - A concept matching all quantities with a dimension being the instantiation derived from - the provided dimension type. - -.. concept:: template QuantityEquivalentTo - - A concept matching two equivalent quantities. Satisfied by quantities having equivalent dimensions. - -.. concept:: template QuantityPointOf - - A concept matching all quantity points with a dimension being the instantiation derived from - the provided dimension type. - -.. concept:: template QuantityPointEquivalentTo - - A concept matching two equivalent quantity points. Satisfied by quantity points having equivalent - dimensions. - -.. concept:: template QuantityKindOf - - A concept matching only quantity kinds of a specific kind. - - :tparam QK: Quantity kind to verify. - :tparam K: Kind type to use for verification. - -.. concept:: template QuantityKindEquivalentTo - - A concept matching two equivalent quantity kinds. Satisfied by quantity kinds having equivalent kinds. - -.. concept:: template QuantityPointKindOf - - A concept matching only quantity point kinds of a specific point kind. - - :tparam QPK: Quantity point kind to verify. - :tparam PK: Point kind type to use for verification. - -.. concept:: template QuantityPointKindEquivalentTo - - A concept matching two equivalent quantity point kinds. Satisfied by quantity point kinds having - equivalent kinds. diff --git a/docs/reference/core/customization_points.rst b/docs/reference/core/customization_points.rst deleted file mode 100644 index f92fd8df..00000000 --- a/docs/reference/core/customization_points.rst +++ /dev/null @@ -1,13 +0,0 @@ -Customization Points -==================== - -.. doxygenvariable:: units::treat_as_floating_point - -.. doxygenstruct:: units::quantity_values - :members: - -.. doxygenstruct:: units::quantity_like_traits - :members: - -.. doxygenstruct:: units::quantity_point_like_traits - :members: diff --git a/docs/reference/core/downcasting.rst b/docs/reference/core/downcasting.rst deleted file mode 100644 index 9b4bff8e..00000000 --- a/docs/reference/core/downcasting.rst +++ /dev/null @@ -1,20 +0,0 @@ -The Downcasting Facility -======================== - -.. doxygenenum:: downcast_mode - -.. concept:: template Downcastable - -.. doxygenstruct:: units::downcast_base - :members: - -.. doxygenstruct:: units::downcast_child - :members: - -.. doxygenstruct:: units::downcast_poison - :members: - -.. doxygenstruct:: units::downcast_dispatch - :members: - -.. doxygentypedef:: units::downcast diff --git a/docs/reference/core/metafunctions.rst b/docs/reference/core/metafunctions.rst deleted file mode 100644 index 2b63b23c..00000000 --- a/docs/reference/core/metafunctions.rst +++ /dev/null @@ -1,4 +0,0 @@ -Metafunctions -============= - -.. doxygentypedef:: dimension_unit diff --git a/docs/reference/core/types.rst b/docs/reference/core/types.rst deleted file mode 100644 index f2440d33..00000000 --- a/docs/reference/core/types.rst +++ /dev/null @@ -1,16 +0,0 @@ -Types -===== - -.. toctree:: - :maxdepth: 1 - - types/quantity - types/quantity_point - types/kinds - types/quantity_kind - types/quantity_point_kind - types/dimensions - types/units - types/prefixes - types/reference - types/utilities diff --git a/docs/reference/core/types/dimensions.rst b/docs/reference/core/types/dimensions.rst deleted file mode 100644 index 2592ac4b..00000000 --- a/docs/reference/core/types/dimensions.rst +++ /dev/null @@ -1,11 +0,0 @@ -Dimensions -========== - -.. doxygenstruct:: units::base_dimension - :members: - -.. doxygenstruct:: units::exponent - :members: - -.. doxygenstruct:: units::derived_dimension - :members: diff --git a/docs/reference/core/types/kinds.rst b/docs/reference/core/types/kinds.rst deleted file mode 100644 index 57ba9109..00000000 --- a/docs/reference/core/types/kinds.rst +++ /dev/null @@ -1,8 +0,0 @@ -Kinds -===== - -.. doxygenstruct:: units::kind - :members: - -.. doxygenstruct:: units::point_kind - :members: diff --git a/docs/reference/core/types/prefixes.rst b/docs/reference/core/types/prefixes.rst deleted file mode 100644 index 7f160aef..00000000 --- a/docs/reference/core/types/prefixes.rst +++ /dev/null @@ -1,5 +0,0 @@ -Prefixes -======== - -.. doxygenstruct:: units::prefix - :members: diff --git a/docs/reference/core/types/quantity.rst b/docs/reference/core/types/quantity.rst deleted file mode 100644 index cabef4e5..00000000 --- a/docs/reference/core/types/quantity.rst +++ /dev/null @@ -1,6 +0,0 @@ -Quantity -======== - -.. doxygenclass:: units::quantity - :members: - :undoc-members: diff --git a/docs/reference/core/types/quantity_kind.rst b/docs/reference/core/types/quantity_kind.rst deleted file mode 100644 index 882ef3bf..00000000 --- a/docs/reference/core/types/quantity_kind.rst +++ /dev/null @@ -1,6 +0,0 @@ -Quantity Kind -============= - -.. doxygenclass:: units::quantity_kind - :members: - :undoc-members: diff --git a/docs/reference/core/types/quantity_point.rst b/docs/reference/core/types/quantity_point.rst deleted file mode 100644 index 3862f035..00000000 --- a/docs/reference/core/types/quantity_point.rst +++ /dev/null @@ -1,6 +0,0 @@ -Quantity Point -============== - -.. doxygenclass:: units::quantity_point - :members: - :undoc-members: diff --git a/docs/reference/core/types/quantity_point_kind.rst b/docs/reference/core/types/quantity_point_kind.rst deleted file mode 100644 index 6e5010c5..00000000 --- a/docs/reference/core/types/quantity_point_kind.rst +++ /dev/null @@ -1,6 +0,0 @@ -Quantity Point Kind -=================== - -.. doxygenclass:: units::quantity_point_kind - :members: - :undoc-members: diff --git a/docs/reference/core/types/reference.rst b/docs/reference/core/types/reference.rst deleted file mode 100644 index 752314a9..00000000 --- a/docs/reference/core/types/reference.rst +++ /dev/null @@ -1,6 +0,0 @@ -Quantity Reference -================== - -.. doxygenstruct:: units::reference - :members: - :undoc-members: diff --git a/docs/reference/core/types/units.rst b/docs/reference/core/types/units.rst deleted file mode 100644 index ce21fc68..00000000 --- a/docs/reference/core/types/units.rst +++ /dev/null @@ -1,26 +0,0 @@ -Units -===== - -.. doxygenstruct:: units::scaled_unit - :members: - -.. doxygenstruct:: units::named_unit - :members: - -.. doxygenstruct:: units::named_scaled_unit - :members: - -.. doxygenstruct:: units::prefixed_unit - :members: - -.. doxygenstruct:: units::derived_unit - :members: - -.. doxygenstruct:: units::derived_scaled_unit - :members: - -.. doxygenstruct:: units::alias_unit - :members: - -.. doxygenstruct:: units::prefixed_alias_unit - :members: diff --git a/docs/reference/core/types/utilities.rst b/docs/reference/core/types/utilities.rst deleted file mode 100644 index b1f5bd10..00000000 --- a/docs/reference/core/types/utilities.rst +++ /dev/null @@ -1,9 +0,0 @@ -Utilities -========= - -.. toctree:: - :maxdepth: 1 - - utilities/ratio - utilities/basic_symbol_text - utilities/basic_fixed_string diff --git a/docs/reference/core/types/utilities/basic_fixed_string.rst b/docs/reference/core/types/utilities/basic_fixed_string.rst deleted file mode 100644 index f58f7a37..00000000 --- a/docs/reference/core/types/utilities/basic_fixed_string.rst +++ /dev/null @@ -1,6 +0,0 @@ -basic_fixed_string -================== - -.. doxygenstruct:: units::basic_fixed_string - :members: - :undoc-members: diff --git a/docs/reference/core/types/utilities/basic_symbol_text.rst b/docs/reference/core/types/utilities/basic_symbol_text.rst deleted file mode 100644 index f1138735..00000000 --- a/docs/reference/core/types/utilities/basic_symbol_text.rst +++ /dev/null @@ -1,6 +0,0 @@ -basic_symbol_text -================= - -.. doxygenstruct:: units::basic_symbol_text - :members: - :undoc-members: diff --git a/docs/reference/core/types/utilities/ratio.rst b/docs/reference/core/types/utilities/ratio.rst deleted file mode 100644 index b4d40c92..00000000 --- a/docs/reference/core/types/utilities/ratio.rst +++ /dev/null @@ -1,6 +0,0 @@ -ratio -===== - -.. doxygenstruct:: units::ratio - :members: - :undoc-members: diff --git a/docs/reference/random.rst b/docs/reference/random.rst deleted file mode 100644 index ad168c2d..00000000 --- a/docs/reference/random.rst +++ /dev/null @@ -1,40 +0,0 @@ -Random -====== - -.. doxygenstruct:: units::uniform_int_distribution - -.. doxygenstruct:: units::uniform_real_distribution - -.. doxygenstruct:: units::binomial_distribution - -.. doxygenstruct:: units::negative_binomial_distribution - -.. doxygenstruct:: units::geometric_distribution - -.. doxygenstruct:: units::poisson_distribution - -.. doxygenstruct:: units::exponential_distribution - -.. doxygenstruct:: units::gamma_distribution - -.. doxygenstruct:: units::weibull_distribution - -.. doxygenstruct:: units::extreme_value_distribution - -.. doxygenstruct:: units::normal_distribution - -.. doxygenstruct:: units::lognormal_distribution - -.. doxygenstruct:: units::chi_squared_distribution - -.. doxygenstruct:: units::cauchy_distribution - -.. doxygenstruct:: units::fisher_f_distribution - -.. doxygenstruct:: units::student_t_distribution - -.. doxygenstruct:: units::discrete_distribution - -.. doxygenstruct:: units::piecewise_constant_distribution - -.. doxygenstruct:: units::piecewise_linear_distribution diff --git a/docs/reference/systems.rst b/docs/reference/systems.rst deleted file mode 100644 index 52fb3f72..00000000 --- a/docs/reference/systems.rst +++ /dev/null @@ -1,12 +0,0 @@ -Systems -======= - -.. toctree:: - :maxdepth: 2 - - systems/generic - -.. toctree:: - :maxdepth: 2 - - systems/isq diff --git a/docs/reference/systems/generic.rst b/docs/reference/systems/generic.rst deleted file mode 100644 index 10c2574c..00000000 --- a/docs/reference/systems/generic.rst +++ /dev/null @@ -1,10 +0,0 @@ -Generic -======= - -.. toctree:: - :maxdepth: 2 - - generic/unknown - generic/dimensionless - generic/angle - generic/solid_angle diff --git a/docs/reference/systems/generic/angle.rst b/docs/reference/systems/generic/angle.rst deleted file mode 100644 index b780a15b..00000000 --- a/docs/reference/systems/generic/angle.rst +++ /dev/null @@ -1,13 +0,0 @@ -Angle -===== - -.. doxygenstruct:: units::radian -.. doxygenstruct:: units::revolution -.. doxygenstruct:: units::degree -.. doxygenstruct:: units::gradian - -.. doxygenstruct:: units::dim_angle - -.. doxygentypedef:: units::angle - -.. doxygenvariable:: cotes_angle diff --git a/docs/reference/systems/generic/dimensionless.rst b/docs/reference/systems/generic/dimensionless.rst deleted file mode 100644 index 4bd1b829..00000000 --- a/docs/reference/systems/generic/dimensionless.rst +++ /dev/null @@ -1,10 +0,0 @@ -Dimensionless -============= - -.. doxygenstruct:: units::one - -.. doxygenstruct:: units::percent - -.. doxygenstruct:: units::dim_one - -.. doxygentypedef:: units::dimensionless diff --git a/docs/reference/systems/generic/solid_angle.rst b/docs/reference/systems/generic/solid_angle.rst deleted file mode 100644 index 704afeab..00000000 --- a/docs/reference/systems/generic/solid_angle.rst +++ /dev/null @@ -1,8 +0,0 @@ -Solid Angle -=========== - -.. doxygenstruct:: units::steradian - -.. doxygenstruct:: units::dim_solid_angle - -.. doxygentypedef:: units::solid_angle diff --git a/docs/reference/systems/generic/unknown.rst b/docs/reference/systems/generic/unknown.rst deleted file mode 100644 index 0f563f71..00000000 --- a/docs/reference/systems/generic/unknown.rst +++ /dev/null @@ -1,6 +0,0 @@ -Unknown -======= - -.. doxygenstruct:: units::unknown_coherent_unit - -.. doxygenstruct:: units::unknown_dimension diff --git a/docs/reference/systems/isq.rst b/docs/reference/systems/isq.rst deleted file mode 100644 index aba644e5..00000000 --- a/docs/reference/systems/isq.rst +++ /dev/null @@ -1,26 +0,0 @@ -International System of Quantities (ISQ) -======================================== - -.. toctree:: - :maxdepth: 2 - - isq/dimensions_and_concepts - isq/si - isq/iec80000 - isq/natural - - -Systems of Units based on the SI --------------------------------- - -.. toctree:: - :maxdepth: 2 - - isq/si_cgs - isq/si_international - isq/si_uscs - isq/si_imperial - isq/si_fps - isq/si_iau - isq/si_hep - isq/si_typographic diff --git a/docs/reference/systems/isq/dimensions_and_concepts.rst b/docs/reference/systems/isq/dimensions_and_concepts.rst deleted file mode 100644 index cf629a37..00000000 --- a/docs/reference/systems/isq/dimensions_and_concepts.rst +++ /dev/null @@ -1,47 +0,0 @@ -Dimensions and Concepts -======================= - -.. doxygenfile:: isq/dimensions/absorbed_dose.h -.. doxygenfile:: isq/dimensions/acceleration.h -.. doxygenfile:: isq/dimensions/amount_of_substance.h -.. doxygenfile:: isq/dimensions/angular_velocity.h -.. doxygenfile:: isq/dimensions/area.h -.. doxygenfile:: isq/dimensions/capacitance.h -.. doxygenfile:: isq/dimensions/catalytic_activity.h -.. doxygenfile:: isq/dimensions/charge_density.h -.. doxygenfile:: isq/dimensions/concentration.h -.. doxygenfile:: isq/dimensions/conductance.h -.. doxygenfile:: isq/dimensions/current_density.h -.. doxygenfile:: isq/dimensions/density.h -.. doxygenfile:: isq/dimensions/dynamic_viscosity.h -.. doxygenfile:: isq/dimensions/electric_charge.h -.. doxygenfile:: isq/dimensions/electric_current.h -.. doxygenfile:: isq/dimensions/electric_field_strength.h -.. doxygenfile:: isq/dimensions/energy.h -.. doxygenfile:: isq/dimensions/energy_density.h -.. doxygenfile:: isq/dimensions/force.h -.. doxygenfile:: isq/dimensions/frequency.h -.. doxygenfile:: isq/dimensions/heat_capacity.h -.. doxygenfile:: isq/dimensions/inductance.h -.. doxygenfile:: isq/dimensions/length.h -.. doxygenfile:: isq/dimensions/luminance.h -.. doxygenfile:: isq/dimensions/luminous_intensity.h -.. doxygenfile:: isq/dimensions/magnetic_flux.h -.. doxygenfile:: isq/dimensions/magnetic_induction.h -.. doxygenfile:: isq/dimensions/mass.h -.. doxygenfile:: isq/dimensions/molar_energy.h -.. doxygenfile:: isq/dimensions/momentum.h -.. doxygenfile:: isq/dimensions/permeability.h -.. doxygenfile:: isq/dimensions/permittivity.h -.. doxygenfile:: isq/dimensions/power.h -.. doxygenfile:: isq/dimensions/pressure.h -.. doxygenfile:: isq/dimensions/radioactivity.h -.. doxygenfile:: isq/dimensions/resistance.h -.. doxygenfile:: isq/dimensions/speed.h -.. doxygenfile:: isq/dimensions/surface_tension.h -.. doxygenfile:: isq/dimensions/thermal_conductivity.h -.. doxygenfile:: isq/dimensions/thermodynamic_temperature.h -.. doxygenfile:: isq/dimensions/time.h -.. doxygenfile:: isq/dimensions/torque.h -.. doxygenfile:: isq/dimensions/voltage.h -.. doxygenfile:: isq/dimensions/volume.h diff --git a/docs/reference/systems/isq/iec80000.rst b/docs/reference/systems/isq/iec80000.rst deleted file mode 100644 index 8e89cceb..00000000 --- a/docs/reference/systems/isq/iec80000.rst +++ /dev/null @@ -1,11 +0,0 @@ -IEC 80000 -========= - -.. toctree:: - :maxdepth: 2 - - iec80000/binary_prefixes - iec80000/modulation_rate - iec80000/storage_capacity - iec80000/traffic_intensity - iec80000/transfer_rate diff --git a/docs/reference/systems/isq/iec80000/binary_prefixes.rst b/docs/reference/systems/isq/iec80000/binary_prefixes.rst deleted file mode 100644 index 916f3aa2..00000000 --- a/docs/reference/systems/isq/iec80000/binary_prefixes.rst +++ /dev/null @@ -1,4 +0,0 @@ -Binary Prefixes -=============== - -.. doxygenfile:: iec80000/binary_prefixes.h diff --git a/docs/reference/systems/isq/iec80000/modulation_rate.rst b/docs/reference/systems/isq/iec80000/modulation_rate.rst deleted file mode 100644 index 42f347a2..00000000 --- a/docs/reference/systems/isq/iec80000/modulation_rate.rst +++ /dev/null @@ -1,4 +0,0 @@ -Modulation Rate -=============== - -.. doxygenfile:: iec80000/modulation_rate.h diff --git a/docs/reference/systems/isq/iec80000/storage_capacity.rst b/docs/reference/systems/isq/iec80000/storage_capacity.rst deleted file mode 100644 index 12d84b75..00000000 --- a/docs/reference/systems/isq/iec80000/storage_capacity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Storage Capacity -================ - -.. doxygenfile:: iec80000/storage_capacity.h diff --git a/docs/reference/systems/isq/iec80000/traffic_intensity.rst b/docs/reference/systems/isq/iec80000/traffic_intensity.rst deleted file mode 100644 index 89e9a07b..00000000 --- a/docs/reference/systems/isq/iec80000/traffic_intensity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Traffic Intensity -================= - -.. doxygenfile:: iec80000/traffic_intensity.h diff --git a/docs/reference/systems/isq/iec80000/transfer_rate.rst b/docs/reference/systems/isq/iec80000/transfer_rate.rst deleted file mode 100644 index e81dac39..00000000 --- a/docs/reference/systems/isq/iec80000/transfer_rate.rst +++ /dev/null @@ -1,4 +0,0 @@ -Transfer Rate -============= - -.. doxygenfile:: iec80000/transfer_rate.h diff --git a/docs/reference/systems/isq/natural.rst b/docs/reference/systems/isq/natural.rst deleted file mode 100644 index 5d08f8e5..00000000 --- a/docs/reference/systems/isq/natural.rst +++ /dev/null @@ -1,16 +0,0 @@ -Natural -======= - -.. toctree:: - :maxdepth: 2 - - natural/units - natural/constants - natural/acceleration - natural/energy - natural/force - natural/length - natural/mass - natural/momentum - natural/speed - natural/time diff --git a/docs/reference/systems/isq/natural/acceleration.rst b/docs/reference/systems/isq/natural/acceleration.rst deleted file mode 100644 index eb79ef95..00000000 --- a/docs/reference/systems/isq/natural/acceleration.rst +++ /dev/null @@ -1,4 +0,0 @@ -Acceleration -============ - -.. doxygenfile:: natural/acceleration.h diff --git a/docs/reference/systems/isq/natural/constants.rst b/docs/reference/systems/isq/natural/constants.rst deleted file mode 100644 index dc012c09..00000000 --- a/docs/reference/systems/isq/natural/constants.rst +++ /dev/null @@ -1,4 +0,0 @@ -Constants -========= - -.. doxygenfile:: natural/constants.h diff --git a/docs/reference/systems/isq/natural/energy.rst b/docs/reference/systems/isq/natural/energy.rst deleted file mode 100644 index 58d84946..00000000 --- a/docs/reference/systems/isq/natural/energy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Energy -====== - -.. doxygenfile:: natural/energy.h diff --git a/docs/reference/systems/isq/natural/force.rst b/docs/reference/systems/isq/natural/force.rst deleted file mode 100644 index 3f80c2c5..00000000 --- a/docs/reference/systems/isq/natural/force.rst +++ /dev/null @@ -1,4 +0,0 @@ -Force -===== - -.. doxygenfile:: natural/force.h diff --git a/docs/reference/systems/isq/natural/length.rst b/docs/reference/systems/isq/natural/length.rst deleted file mode 100644 index 3f004be7..00000000 --- a/docs/reference/systems/isq/natural/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: natural/length.h diff --git a/docs/reference/systems/isq/natural/mass.rst b/docs/reference/systems/isq/natural/mass.rst deleted file mode 100644 index 4d60670b..00000000 --- a/docs/reference/systems/isq/natural/mass.rst +++ /dev/null @@ -1,4 +0,0 @@ -Mass -==== - -.. doxygenfile:: natural/mass.h diff --git a/docs/reference/systems/isq/natural/momentum.rst b/docs/reference/systems/isq/natural/momentum.rst deleted file mode 100644 index db1408a3..00000000 --- a/docs/reference/systems/isq/natural/momentum.rst +++ /dev/null @@ -1,4 +0,0 @@ -Momentum -======== - -.. doxygenfile:: natural/momentum.h diff --git a/docs/reference/systems/isq/natural/speed.rst b/docs/reference/systems/isq/natural/speed.rst deleted file mode 100644 index d1025b01..00000000 --- a/docs/reference/systems/isq/natural/speed.rst +++ /dev/null @@ -1,4 +0,0 @@ -Speed -===== - -.. doxygenfile:: natural/speed.h diff --git a/docs/reference/systems/isq/natural/time.rst b/docs/reference/systems/isq/natural/time.rst deleted file mode 100644 index 4a46dddc..00000000 --- a/docs/reference/systems/isq/natural/time.rst +++ /dev/null @@ -1,4 +0,0 @@ -Time -==== - -.. doxygenfile:: natural/time.h diff --git a/docs/reference/systems/isq/natural/units.rst b/docs/reference/systems/isq/natural/units.rst deleted file mode 100644 index 602f8ce0..00000000 --- a/docs/reference/systems/isq/natural/units.rst +++ /dev/null @@ -1,4 +0,0 @@ -Units -===== - -.. doxygenfile:: natural/units.h diff --git a/docs/reference/systems/isq/si.rst b/docs/reference/systems/isq/si.rst deleted file mode 100644 index 122fa55f..00000000 --- a/docs/reference/systems/isq/si.rst +++ /dev/null @@ -1,48 +0,0 @@ -International System of Units (SI) -================================== - -.. toctree:: - :maxdepth: 2 - - si/prefixes - si/constants - si/absorbed_dose - si/acceleration - si/amount_of_substance - si/area - si/capacitance - si/catalytic_activity - si/charge_density - si/concentration - si/conductance - si/current_density - si/density - si/dynamic_viscosity - si/electric_charge - si/electric_current - si/electric_field_strength - si/energy - si/force - si/frequency - si/heat_capacity - si/inductance - si/length - si/luminance - si/luminous_intensity - si/magnetic_flux - si/magnetic_induction - si/mass - si/molar_energy - si/momentum - si/permeability - si/permittivity - si/power - si/pressure - si/resistance - si/speed - si/surface_tension - si/thermal_conductivity - si/thermodynamic_temperature - si/time - si/voltage - si/volume diff --git a/docs/reference/systems/isq/si/absorbed_dose.rst b/docs/reference/systems/isq/si/absorbed_dose.rst deleted file mode 100644 index 30826f1a..00000000 --- a/docs/reference/systems/isq/si/absorbed_dose.rst +++ /dev/null @@ -1,4 +0,0 @@ -Absorbed Dose -============= - -.. doxygenfile:: si/absorbed_dose.h diff --git a/docs/reference/systems/isq/si/acceleration.rst b/docs/reference/systems/isq/si/acceleration.rst deleted file mode 100644 index da1884b1..00000000 --- a/docs/reference/systems/isq/si/acceleration.rst +++ /dev/null @@ -1,4 +0,0 @@ -Acceleration -============ - -.. doxygenfile:: si/acceleration.h diff --git a/docs/reference/systems/isq/si/amount_of_substance.rst b/docs/reference/systems/isq/si/amount_of_substance.rst deleted file mode 100644 index 39753e85..00000000 --- a/docs/reference/systems/isq/si/amount_of_substance.rst +++ /dev/null @@ -1,4 +0,0 @@ -Amount of Substance -=================== - -.. doxygenfile:: si/amount_of_substance.h diff --git a/docs/reference/systems/isq/si/area.rst b/docs/reference/systems/isq/si/area.rst deleted file mode 100644 index b1f8c2c4..00000000 --- a/docs/reference/systems/isq/si/area.rst +++ /dev/null @@ -1,4 +0,0 @@ -Area -==== - -.. doxygenfile:: si/area.h diff --git a/docs/reference/systems/isq/si/capacitance.rst b/docs/reference/systems/isq/si/capacitance.rst deleted file mode 100644 index 00fe1dc3..00000000 --- a/docs/reference/systems/isq/si/capacitance.rst +++ /dev/null @@ -1,4 +0,0 @@ -Capacitance -=========== - -.. doxygenfile:: si/capacitance.h diff --git a/docs/reference/systems/isq/si/catalytic_activity.rst b/docs/reference/systems/isq/si/catalytic_activity.rst deleted file mode 100644 index ec5ceb09..00000000 --- a/docs/reference/systems/isq/si/catalytic_activity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Catalytic Activity -================== - -.. doxygenfile:: si/catalytic_activity.h diff --git a/docs/reference/systems/isq/si/cgs/acceleration.rst b/docs/reference/systems/isq/si/cgs/acceleration.rst deleted file mode 100644 index 4a04598d..00000000 --- a/docs/reference/systems/isq/si/cgs/acceleration.rst +++ /dev/null @@ -1,4 +0,0 @@ -Acceleration -============ - -.. doxygenfile:: si/cgs/acceleration.h diff --git a/docs/reference/systems/isq/si/cgs/area.rst b/docs/reference/systems/isq/si/cgs/area.rst deleted file mode 100644 index e97b1dfa..00000000 --- a/docs/reference/systems/isq/si/cgs/area.rst +++ /dev/null @@ -1,4 +0,0 @@ -Area -==== - -.. doxygenfile:: si/cgs/area.h diff --git a/docs/reference/systems/isq/si/cgs/energy.rst b/docs/reference/systems/isq/si/cgs/energy.rst deleted file mode 100644 index 1026e75f..00000000 --- a/docs/reference/systems/isq/si/cgs/energy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Energy -====== - -.. doxygenfile:: si/cgs/energy.h diff --git a/docs/reference/systems/isq/si/cgs/force.rst b/docs/reference/systems/isq/si/cgs/force.rst deleted file mode 100644 index 4f3e2cb5..00000000 --- a/docs/reference/systems/isq/si/cgs/force.rst +++ /dev/null @@ -1,4 +0,0 @@ -Force -===== - -.. doxygenfile:: si/cgs/force.h diff --git a/docs/reference/systems/isq/si/cgs/length.rst b/docs/reference/systems/isq/si/cgs/length.rst deleted file mode 100644 index 5deefb4b..00000000 --- a/docs/reference/systems/isq/si/cgs/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/cgs/length.h diff --git a/docs/reference/systems/isq/si/cgs/mass.rst b/docs/reference/systems/isq/si/cgs/mass.rst deleted file mode 100644 index 9be1a471..00000000 --- a/docs/reference/systems/isq/si/cgs/mass.rst +++ /dev/null @@ -1,4 +0,0 @@ -Mass -==== - -.. doxygenfile:: si/cgs/mass.h diff --git a/docs/reference/systems/isq/si/cgs/power.rst b/docs/reference/systems/isq/si/cgs/power.rst deleted file mode 100644 index 8725ef62..00000000 --- a/docs/reference/systems/isq/si/cgs/power.rst +++ /dev/null @@ -1,4 +0,0 @@ -Power -===== - -.. doxygenfile:: si/cgs/power.h diff --git a/docs/reference/systems/isq/si/cgs/pressure.rst b/docs/reference/systems/isq/si/cgs/pressure.rst deleted file mode 100644 index 5efd0777..00000000 --- a/docs/reference/systems/isq/si/cgs/pressure.rst +++ /dev/null @@ -1,4 +0,0 @@ -Pressure -======== - -.. doxygenfile:: si/cgs/pressure.h diff --git a/docs/reference/systems/isq/si/cgs/speed.rst b/docs/reference/systems/isq/si/cgs/speed.rst deleted file mode 100644 index 37d6226e..00000000 --- a/docs/reference/systems/isq/si/cgs/speed.rst +++ /dev/null @@ -1,4 +0,0 @@ -Speed -===== - -.. doxygenfile:: si/cgs/speed.h diff --git a/docs/reference/systems/isq/si/cgs/time.rst b/docs/reference/systems/isq/si/cgs/time.rst deleted file mode 100644 index 30e42097..00000000 --- a/docs/reference/systems/isq/si/cgs/time.rst +++ /dev/null @@ -1,4 +0,0 @@ -Time -==== - -.. doxygenfile:: si/cgs/time.h diff --git a/docs/reference/systems/isq/si/charge_density.rst b/docs/reference/systems/isq/si/charge_density.rst deleted file mode 100644 index 5474ab48..00000000 --- a/docs/reference/systems/isq/si/charge_density.rst +++ /dev/null @@ -1,4 +0,0 @@ -Charge Density -============== - -.. doxygenfile:: si/charge_density.h diff --git a/docs/reference/systems/isq/si/concentration.rst b/docs/reference/systems/isq/si/concentration.rst deleted file mode 100644 index 3c5bb235..00000000 --- a/docs/reference/systems/isq/si/concentration.rst +++ /dev/null @@ -1,4 +0,0 @@ -Concentration -============= - -.. doxygenfile:: si/concentration.h diff --git a/docs/reference/systems/isq/si/conductance.rst b/docs/reference/systems/isq/si/conductance.rst deleted file mode 100644 index 47af0e27..00000000 --- a/docs/reference/systems/isq/si/conductance.rst +++ /dev/null @@ -1,4 +0,0 @@ -Conductance -=========== - -.. doxygenfile:: si/conductance.h diff --git a/docs/reference/systems/isq/si/constants.rst b/docs/reference/systems/isq/si/constants.rst deleted file mode 100644 index 61e64b60..00000000 --- a/docs/reference/systems/isq/si/constants.rst +++ /dev/null @@ -1,4 +0,0 @@ -Constants -========= - -.. doxygenfile:: si/constants.h diff --git a/docs/reference/systems/isq/si/current_density.rst b/docs/reference/systems/isq/si/current_density.rst deleted file mode 100644 index a3441a83..00000000 --- a/docs/reference/systems/isq/si/current_density.rst +++ /dev/null @@ -1,4 +0,0 @@ -Current density -=============== - -.. doxygenfile:: si/current_density.h diff --git a/docs/reference/systems/isq/si/density.rst b/docs/reference/systems/isq/si/density.rst deleted file mode 100644 index 4cf74da7..00000000 --- a/docs/reference/systems/isq/si/density.rst +++ /dev/null @@ -1,4 +0,0 @@ -Density -======= - -.. doxygenfile:: si/density.h diff --git a/docs/reference/systems/isq/si/dynamic_viscosity.rst b/docs/reference/systems/isq/si/dynamic_viscosity.rst deleted file mode 100644 index 667e1310..00000000 --- a/docs/reference/systems/isq/si/dynamic_viscosity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Dynamic Viscosity -================= - -.. doxygenfile:: si/dynamic_viscosity.h diff --git a/docs/reference/systems/isq/si/electric_charge.rst b/docs/reference/systems/isq/si/electric_charge.rst deleted file mode 100644 index 93b5497f..00000000 --- a/docs/reference/systems/isq/si/electric_charge.rst +++ /dev/null @@ -1,4 +0,0 @@ -Electric Charge -=============== - -.. doxygenfile:: si/electric_charge.h diff --git a/docs/reference/systems/isq/si/electric_current.rst b/docs/reference/systems/isq/si/electric_current.rst deleted file mode 100644 index 6cbb37ad..00000000 --- a/docs/reference/systems/isq/si/electric_current.rst +++ /dev/null @@ -1,4 +0,0 @@ -Electric Current -================ - -.. doxygenfile:: si/electric_current.h diff --git a/docs/reference/systems/isq/si/electric_field_strength.rst b/docs/reference/systems/isq/si/electric_field_strength.rst deleted file mode 100644 index 71f09277..00000000 --- a/docs/reference/systems/isq/si/electric_field_strength.rst +++ /dev/null @@ -1,4 +0,0 @@ -Electric Field Strength -======================= - -.. doxygenfile:: si/electric_field_strength.h diff --git a/docs/reference/systems/isq/si/energy.rst b/docs/reference/systems/isq/si/energy.rst deleted file mode 100644 index db30ee27..00000000 --- a/docs/reference/systems/isq/si/energy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Energy -====== - -.. doxygenfile:: si/energy.h diff --git a/docs/reference/systems/isq/si/force.rst b/docs/reference/systems/isq/si/force.rst deleted file mode 100644 index f47473ae..00000000 --- a/docs/reference/systems/isq/si/force.rst +++ /dev/null @@ -1,4 +0,0 @@ -Force -===== - -.. doxygenfile:: si/force.h diff --git a/docs/reference/systems/isq/si/fps/acceleration.rst b/docs/reference/systems/isq/si/fps/acceleration.rst deleted file mode 100644 index dfc5d510..00000000 --- a/docs/reference/systems/isq/si/fps/acceleration.rst +++ /dev/null @@ -1,4 +0,0 @@ -Acceleration -============ - -.. doxygenfile:: si/fps/acceleration.h diff --git a/docs/reference/systems/isq/si/fps/area.rst b/docs/reference/systems/isq/si/fps/area.rst deleted file mode 100644 index 00cc067c..00000000 --- a/docs/reference/systems/isq/si/fps/area.rst +++ /dev/null @@ -1,4 +0,0 @@ -Area -==== - -.. doxygenfile:: si/fps/area.h diff --git a/docs/reference/systems/isq/si/fps/density.rst b/docs/reference/systems/isq/si/fps/density.rst deleted file mode 100644 index c0b70ddf..00000000 --- a/docs/reference/systems/isq/si/fps/density.rst +++ /dev/null @@ -1,4 +0,0 @@ -Density -======= - -.. doxygenfile:: si/fps/density.h diff --git a/docs/reference/systems/isq/si/fps/energy.rst b/docs/reference/systems/isq/si/fps/energy.rst deleted file mode 100644 index 949cbd91..00000000 --- a/docs/reference/systems/isq/si/fps/energy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Energy -====== - -.. doxygenfile:: si/fps/energy.h diff --git a/docs/reference/systems/isq/si/fps/force.rst b/docs/reference/systems/isq/si/fps/force.rst deleted file mode 100644 index 02b355b7..00000000 --- a/docs/reference/systems/isq/si/fps/force.rst +++ /dev/null @@ -1,4 +0,0 @@ -Force -===== - -.. doxygenfile:: si/fps/force.h diff --git a/docs/reference/systems/isq/si/fps/length.rst b/docs/reference/systems/isq/si/fps/length.rst deleted file mode 100644 index e32c16f3..00000000 --- a/docs/reference/systems/isq/si/fps/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/fps/length.h diff --git a/docs/reference/systems/isq/si/fps/mass.rst b/docs/reference/systems/isq/si/fps/mass.rst deleted file mode 100644 index e77ac1ba..00000000 --- a/docs/reference/systems/isq/si/fps/mass.rst +++ /dev/null @@ -1,4 +0,0 @@ -Mass -==== - -.. doxygenfile:: si/fps/mass.h diff --git a/docs/reference/systems/isq/si/fps/power.rst b/docs/reference/systems/isq/si/fps/power.rst deleted file mode 100644 index 28f52f3c..00000000 --- a/docs/reference/systems/isq/si/fps/power.rst +++ /dev/null @@ -1,4 +0,0 @@ -Power -===== - -.. doxygenfile:: si/fps/power.h diff --git a/docs/reference/systems/isq/si/fps/pressure.rst b/docs/reference/systems/isq/si/fps/pressure.rst deleted file mode 100644 index 5144b50d..00000000 --- a/docs/reference/systems/isq/si/fps/pressure.rst +++ /dev/null @@ -1,4 +0,0 @@ -Pressure -======== - -.. doxygenfile:: si/fps/pressure.h diff --git a/docs/reference/systems/isq/si/fps/speed.rst b/docs/reference/systems/isq/si/fps/speed.rst deleted file mode 100644 index 3f3388d9..00000000 --- a/docs/reference/systems/isq/si/fps/speed.rst +++ /dev/null @@ -1,4 +0,0 @@ -Speed -===== - -.. doxygenfile:: si/fps/speed.h diff --git a/docs/reference/systems/isq/si/fps/time.rst b/docs/reference/systems/isq/si/fps/time.rst deleted file mode 100644 index 0be4a9ad..00000000 --- a/docs/reference/systems/isq/si/fps/time.rst +++ /dev/null @@ -1,4 +0,0 @@ -Time -==== - -.. doxygenfile:: si/fps/time.h diff --git a/docs/reference/systems/isq/si/fps/volume.rst b/docs/reference/systems/isq/si/fps/volume.rst deleted file mode 100644 index 788fd445..00000000 --- a/docs/reference/systems/isq/si/fps/volume.rst +++ /dev/null @@ -1,4 +0,0 @@ -Volume -====== - -.. doxygenfile:: si/fps/volume.h diff --git a/docs/reference/systems/isq/si/frequency.rst b/docs/reference/systems/isq/si/frequency.rst deleted file mode 100644 index da111def..00000000 --- a/docs/reference/systems/isq/si/frequency.rst +++ /dev/null @@ -1,4 +0,0 @@ -Frequency -========= - -.. doxygenfile:: si/frequency.h diff --git a/docs/reference/systems/isq/si/heat_capacity.rst b/docs/reference/systems/isq/si/heat_capacity.rst deleted file mode 100644 index 5f3183c9..00000000 --- a/docs/reference/systems/isq/si/heat_capacity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Heat Capacity -============= - -.. doxygenfile:: si/heat_capacity.h diff --git a/docs/reference/systems/isq/si/hep/area.rst b/docs/reference/systems/isq/si/hep/area.rst deleted file mode 100644 index e6f9d5fc..00000000 --- a/docs/reference/systems/isq/si/hep/area.rst +++ /dev/null @@ -1,4 +0,0 @@ -Area -==== - -.. doxygenfile:: si/hep/area.h diff --git a/docs/reference/systems/isq/si/hep/energy.rst b/docs/reference/systems/isq/si/hep/energy.rst deleted file mode 100644 index a05e04b3..00000000 --- a/docs/reference/systems/isq/si/hep/energy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Energy -====== - -.. doxygenfile:: si/hep/energy.h diff --git a/docs/reference/systems/isq/si/hep/mass.rst b/docs/reference/systems/isq/si/hep/mass.rst deleted file mode 100644 index 3ce4448d..00000000 --- a/docs/reference/systems/isq/si/hep/mass.rst +++ /dev/null @@ -1,4 +0,0 @@ -Mass -==== - -.. doxygenfile:: si/hep/mass.h diff --git a/docs/reference/systems/isq/si/hep/momentum.rst b/docs/reference/systems/isq/si/hep/momentum.rst deleted file mode 100644 index d1d1cdab..00000000 --- a/docs/reference/systems/isq/si/hep/momentum.rst +++ /dev/null @@ -1,4 +0,0 @@ -Momentum -======== - -.. doxygenfile:: si/hep/momentum.h diff --git a/docs/reference/systems/isq/si/iau/length.rst b/docs/reference/systems/isq/si/iau/length.rst deleted file mode 100644 index a87bd7b7..00000000 --- a/docs/reference/systems/isq/si/iau/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/iau/length.h diff --git a/docs/reference/systems/isq/si/imperial/length.rst b/docs/reference/systems/isq/si/imperial/length.rst deleted file mode 100644 index bf66246d..00000000 --- a/docs/reference/systems/isq/si/imperial/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/imperial/length.h diff --git a/docs/reference/systems/isq/si/inductance.rst b/docs/reference/systems/isq/si/inductance.rst deleted file mode 100644 index 8a128cbd..00000000 --- a/docs/reference/systems/isq/si/inductance.rst +++ /dev/null @@ -1,4 +0,0 @@ -Inductance -========== - -.. doxygenfile:: si/inductance.h diff --git a/docs/reference/systems/isq/si/international/area.rst b/docs/reference/systems/isq/si/international/area.rst deleted file mode 100644 index f4841300..00000000 --- a/docs/reference/systems/isq/si/international/area.rst +++ /dev/null @@ -1,4 +0,0 @@ -Area -==== - -.. doxygenfile:: si/international/area.h diff --git a/docs/reference/systems/isq/si/international/length.rst b/docs/reference/systems/isq/si/international/length.rst deleted file mode 100644 index 878b4b17..00000000 --- a/docs/reference/systems/isq/si/international/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/international/length.h diff --git a/docs/reference/systems/isq/si/international/speed.rst b/docs/reference/systems/isq/si/international/speed.rst deleted file mode 100644 index 19f2e2eb..00000000 --- a/docs/reference/systems/isq/si/international/speed.rst +++ /dev/null @@ -1,4 +0,0 @@ -Speed -===== - -.. doxygenfile:: speed/speed.h diff --git a/docs/reference/systems/isq/si/international/volume.rst b/docs/reference/systems/isq/si/international/volume.rst deleted file mode 100644 index 2530bbbe..00000000 --- a/docs/reference/systems/isq/si/international/volume.rst +++ /dev/null @@ -1,4 +0,0 @@ -Volume -====== - -.. doxygenfile:: si/international/volume.h diff --git a/docs/reference/systems/isq/si/length.rst b/docs/reference/systems/isq/si/length.rst deleted file mode 100644 index 34aace98..00000000 --- a/docs/reference/systems/isq/si/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/length.h diff --git a/docs/reference/systems/isq/si/luminance.rst b/docs/reference/systems/isq/si/luminance.rst deleted file mode 100644 index 2621b0b6..00000000 --- a/docs/reference/systems/isq/si/luminance.rst +++ /dev/null @@ -1,4 +0,0 @@ -Luminance -========= - -.. doxygenfile:: si/luminance.h diff --git a/docs/reference/systems/isq/si/luminous_intensity.rst b/docs/reference/systems/isq/si/luminous_intensity.rst deleted file mode 100644 index a1ed45c5..00000000 --- a/docs/reference/systems/isq/si/luminous_intensity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Luminous Intensity -================== - -.. doxygenfile:: si/luminous_intensity.h diff --git a/docs/reference/systems/isq/si/magnetic_flux.rst b/docs/reference/systems/isq/si/magnetic_flux.rst deleted file mode 100644 index 99f2b06f..00000000 --- a/docs/reference/systems/isq/si/magnetic_flux.rst +++ /dev/null @@ -1,4 +0,0 @@ -Magnetic Flux -============= - -.. doxygenfile:: si/magnetic_flux.h diff --git a/docs/reference/systems/isq/si/magnetic_induction.rst b/docs/reference/systems/isq/si/magnetic_induction.rst deleted file mode 100644 index be77904b..00000000 --- a/docs/reference/systems/isq/si/magnetic_induction.rst +++ /dev/null @@ -1,4 +0,0 @@ -Magnetic Induction -================== - -.. doxygenfile:: si/magnetic_induction.h diff --git a/docs/reference/systems/isq/si/mass.rst b/docs/reference/systems/isq/si/mass.rst deleted file mode 100644 index a569508d..00000000 --- a/docs/reference/systems/isq/si/mass.rst +++ /dev/null @@ -1,4 +0,0 @@ -Mass -==== - -.. doxygenfile:: si/mass.h diff --git a/docs/reference/systems/isq/si/molar_energy.rst b/docs/reference/systems/isq/si/molar_energy.rst deleted file mode 100644 index 60401a69..00000000 --- a/docs/reference/systems/isq/si/molar_energy.rst +++ /dev/null @@ -1,4 +0,0 @@ -Molar Energy -============ - -.. doxygenfile:: si/molar_energy.h diff --git a/docs/reference/systems/isq/si/momentum.rst b/docs/reference/systems/isq/si/momentum.rst deleted file mode 100644 index 76949ccb..00000000 --- a/docs/reference/systems/isq/si/momentum.rst +++ /dev/null @@ -1,4 +0,0 @@ -Momentum -======== - -.. doxygenfile:: si/momentum.h diff --git a/docs/reference/systems/isq/si/permeability.rst b/docs/reference/systems/isq/si/permeability.rst deleted file mode 100644 index da5e0ec7..00000000 --- a/docs/reference/systems/isq/si/permeability.rst +++ /dev/null @@ -1,4 +0,0 @@ -Permeability -============ - -.. doxygenfile:: si/permeability.h diff --git a/docs/reference/systems/isq/si/permittivity.rst b/docs/reference/systems/isq/si/permittivity.rst deleted file mode 100644 index befdb2a2..00000000 --- a/docs/reference/systems/isq/si/permittivity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Permittivity -============ - -.. doxygenfile:: si/permittivity.h diff --git a/docs/reference/systems/isq/si/power.rst b/docs/reference/systems/isq/si/power.rst deleted file mode 100644 index f3d6e0b9..00000000 --- a/docs/reference/systems/isq/si/power.rst +++ /dev/null @@ -1,4 +0,0 @@ -Power -===== - -.. doxygenfile:: si/power.h diff --git a/docs/reference/systems/isq/si/prefixes.rst b/docs/reference/systems/isq/si/prefixes.rst deleted file mode 100644 index ea673f05..00000000 --- a/docs/reference/systems/isq/si/prefixes.rst +++ /dev/null @@ -1,4 +0,0 @@ -Prefixes -======== - -.. doxygenfile:: si/prefixes.h diff --git a/docs/reference/systems/isq/si/pressure.rst b/docs/reference/systems/isq/si/pressure.rst deleted file mode 100644 index ccd0c014..00000000 --- a/docs/reference/systems/isq/si/pressure.rst +++ /dev/null @@ -1,4 +0,0 @@ -Pressure -======== - -.. doxygenfile:: si/pressure.h diff --git a/docs/reference/systems/isq/si/resistance.rst b/docs/reference/systems/isq/si/resistance.rst deleted file mode 100644 index d5ce1512..00000000 --- a/docs/reference/systems/isq/si/resistance.rst +++ /dev/null @@ -1,4 +0,0 @@ -Resistance -========== - -.. doxygenfile:: si/resistance.h diff --git a/docs/reference/systems/isq/si/speed.rst b/docs/reference/systems/isq/si/speed.rst deleted file mode 100644 index 1b7278be..00000000 --- a/docs/reference/systems/isq/si/speed.rst +++ /dev/null @@ -1,4 +0,0 @@ -Speed -===== - -.. doxygenfile:: si/speed.h diff --git a/docs/reference/systems/isq/si/surface_tension.rst b/docs/reference/systems/isq/si/surface_tension.rst deleted file mode 100644 index 94212027..00000000 --- a/docs/reference/systems/isq/si/surface_tension.rst +++ /dev/null @@ -1,4 +0,0 @@ -Surface Tension -=============== - -.. doxygenfile:: si/surface_tension.h diff --git a/docs/reference/systems/isq/si/thermal_conductivity.rst b/docs/reference/systems/isq/si/thermal_conductivity.rst deleted file mode 100644 index dd6d94cd..00000000 --- a/docs/reference/systems/isq/si/thermal_conductivity.rst +++ /dev/null @@ -1,4 +0,0 @@ -Thermal Conductivity -==================== - -.. doxygenfile:: si/thermal_conductivity.h diff --git a/docs/reference/systems/isq/si/thermodynamic_temperature.rst b/docs/reference/systems/isq/si/thermodynamic_temperature.rst deleted file mode 100644 index 50008dff..00000000 --- a/docs/reference/systems/isq/si/thermodynamic_temperature.rst +++ /dev/null @@ -1,4 +0,0 @@ -Temperature -=========== - -.. doxygenfile:: si/thermodynamic_temperature.h diff --git a/docs/reference/systems/isq/si/time.rst b/docs/reference/systems/isq/si/time.rst deleted file mode 100644 index 54d4b41d..00000000 --- a/docs/reference/systems/isq/si/time.rst +++ /dev/null @@ -1,4 +0,0 @@ -Time -==== - -.. doxygenfile:: si/time.h diff --git a/docs/reference/systems/isq/si/typographic/length.rst b/docs/reference/systems/isq/si/typographic/length.rst deleted file mode 100644 index 363fc1f6..00000000 --- a/docs/reference/systems/isq/si/typographic/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/typographic/length.h diff --git a/docs/reference/systems/isq/si/uscs/length.rst b/docs/reference/systems/isq/si/uscs/length.rst deleted file mode 100644 index 6f7aec18..00000000 --- a/docs/reference/systems/isq/si/uscs/length.rst +++ /dev/null @@ -1,4 +0,0 @@ -Length -====== - -.. doxygenfile:: si/uscs/length.h diff --git a/docs/reference/systems/isq/si/uscs/pressure.rst b/docs/reference/systems/isq/si/uscs/pressure.rst deleted file mode 100644 index a0e3e605..00000000 --- a/docs/reference/systems/isq/si/uscs/pressure.rst +++ /dev/null @@ -1,4 +0,0 @@ -Pressure -======== - -.. doxygenfile:: si/uscs/pressure.h diff --git a/docs/reference/systems/isq/si/voltage.rst b/docs/reference/systems/isq/si/voltage.rst deleted file mode 100644 index 633aac5a..00000000 --- a/docs/reference/systems/isq/si/voltage.rst +++ /dev/null @@ -1,4 +0,0 @@ -Voltage -======= - -.. doxygenfile:: si/voltage.h diff --git a/docs/reference/systems/isq/si/volume.rst b/docs/reference/systems/isq/si/volume.rst deleted file mode 100644 index 7af5cc86..00000000 --- a/docs/reference/systems/isq/si/volume.rst +++ /dev/null @@ -1,4 +0,0 @@ -Volume -====== - -.. doxygenfile:: si/volume.h diff --git a/docs/reference/systems/isq/si_cgs.rst b/docs/reference/systems/isq/si_cgs.rst deleted file mode 100644 index a2cca625..00000000 --- a/docs/reference/systems/isq/si_cgs.rst +++ /dev/null @@ -1,16 +0,0 @@ -CGS (based on SI) -================= - -.. toctree:: - :maxdepth: 2 - - si/cgs/acceleration - si/cgs/area - si/cgs/energy - si/cgs/force - si/cgs/length - si/cgs/mass - si/cgs/power - si/cgs/pressure - si/cgs/speed - si/cgs/time diff --git a/docs/reference/systems/isq/si_fps.rst b/docs/reference/systems/isq/si_fps.rst deleted file mode 100644 index ae1c5e41..00000000 --- a/docs/reference/systems/isq/si_fps.rst +++ /dev/null @@ -1,18 +0,0 @@ -FPS (based on SI) -================= - -.. toctree:: - :maxdepth: 2 - - si/fps/acceleration - si/fps/area - si/fps/density - si/fps/energy - si/fps/force - si/fps/length - si/fps/mass - si/fps/power - si/fps/pressure - si/fps/speed - si/fps/time - si/fps/volume diff --git a/docs/reference/systems/isq/si_hep.rst b/docs/reference/systems/isq/si_hep.rst deleted file mode 100644 index f4d444e5..00000000 --- a/docs/reference/systems/isq/si_hep.rst +++ /dev/null @@ -1,10 +0,0 @@ -HEP (based on SI) -================= - -.. toctree:: - :maxdepth: 2 - - si/hep/area - si/hep/energy - si/hep/mass - si/hep/momentum diff --git a/docs/reference/systems/isq/si_iau.rst b/docs/reference/systems/isq/si_iau.rst deleted file mode 100644 index fb9c13ba..00000000 --- a/docs/reference/systems/isq/si_iau.rst +++ /dev/null @@ -1,7 +0,0 @@ -IAU (based on SI) -================= - -.. toctree:: - :maxdepth: 2 - - si/iau/length diff --git a/docs/reference/systems/isq/si_imperial.rst b/docs/reference/systems/isq/si_imperial.rst deleted file mode 100644 index e3ae129f..00000000 --- a/docs/reference/systems/isq/si_imperial.rst +++ /dev/null @@ -1,7 +0,0 @@ -Imperial (based on SI) -====================== - -.. toctree:: - :maxdepth: 2 - - si/imperial/length diff --git a/docs/reference/systems/isq/si_international.rst b/docs/reference/systems/isq/si_international.rst deleted file mode 100644 index 4976ab01..00000000 --- a/docs/reference/systems/isq/si_international.rst +++ /dev/null @@ -1,10 +0,0 @@ -International (based on SI) -=========================== - -.. toctree:: - :maxdepth: 2 - - si/international/area - si/international/length - si/international/speed - si/international/volume diff --git a/docs/reference/systems/isq/si_typographic.rst b/docs/reference/systems/isq/si_typographic.rst deleted file mode 100644 index 8ef3458d..00000000 --- a/docs/reference/systems/isq/si_typographic.rst +++ /dev/null @@ -1,7 +0,0 @@ -Typographic (based on SI) -========================= - -.. toctree:: - :maxdepth: 2 - - si/typographic/length diff --git a/docs/reference/systems/isq/si_uscs.rst b/docs/reference/systems/isq/si_uscs.rst deleted file mode 100644 index 7d1da787..00000000 --- a/docs/reference/systems/isq/si_uscs.rst +++ /dev/null @@ -1,8 +0,0 @@ -U.S. Customary Units (based on SI) -================================== - -.. toctree:: - :maxdepth: 2 - - si/uscs/length - si/uscs/pressure diff --git a/docs/references.rst b/docs/references.rst deleted file mode 100644 index f721b004..00000000 --- a/docs/references.rst +++ /dev/null @@ -1,6 +0,0 @@ -References -========== - -.. [ISO80000] `ISO 80000-1:2009(E) "Quantities and units — Part 1: General" `_, International Organization for Standardization. -.. [SIBrochure] `The International System of Units (SI) `_, International Bureau of Weights and Measures (20 May 2019), ISBN 978-92-822-2272-0. -.. [Quincey] `"Angles in the SI: a detailed proposal for solving the problem" `_, Quincey, Paul (1 October 2021). diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 17150963..00000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -sphinx>=2.4.4 -sphinx_rtd_theme -recommonmark -breathe>=4.14.1 diff --git a/docs/usage.rst b/docs/usage.rst deleted file mode 100644 index 021d0b59..00000000 --- a/docs/usage.rst +++ /dev/null @@ -1,496 +0,0 @@ -Installation And Usage -====================== - -.. note:: - - This library targets C++23/26 and extensively uses C++20 features. This is why it requires the latest C++ - compilers. The following compilers (or newer) are supported: - - - gcc-10 - - clang-12 - - Visual Studio 16.9 - - Apple clang 13 - -Repository Structure and Dependencies -------------------------------------- - -This repository contains three independent CMake-based projects: - -- *./src* - - - header-only project containing whole **mp-units** library - - when this library will become part of the C++ standard it will have no external dependencies - but until then it depends on: - - - `gsl-lite `_ to verify runtime contracts with the ``gsl_Expects`` macro. - - [for compilers other than VS2022] `{fmt} `_ to provide text formatting of quantities. - - [only for clang < 14 with libc++] `range-v3 `_ to provide needed C++20 concepts and utilities. - -- *.* - - - project used as an entry point for library development and CI/CD - - it wraps *./src* project together with usage examples and tests - - additionally to the dependencies of *./src* project, it uses: - - - `Catch2 `_ library as a unit tests framework. - - `linear algebra `_ - library based on proposal `P1385 `_ used in some examples - and tests. - - - in case you also want to build the project's documentation you will need: - - - `Doxygen `_ to extract C++ entities information from the source - code. - - `Sphinx `_ to build the documentation. - - `Sphinx ReadTheDocs Theme `_ - - `Sphinx recommonmark `_. - - `Breathe `_ as a bridge between the Sphinx and Doxygen - documentation systems. - -- *./test_package* - - - library installation and Conan package verification. - - -Obtaining Dependencies ----------------------- - -This library assumes that most of the dependencies will be provided by the -`Conan Package Manager `_. In case you would like to obtain required -dependencies by other means some modifications to library's CMake files might be needed. -The rest of the dependencies responsible for documentation generation are provided by -:command:`python3-pip`. - -.. seealso:: - - A full list of dependencies can be found in `Repository Structure and Dependencies`_. - -Conan Quick Intro -^^^^^^^^^^^^^^^^^ - -In case you are not familiar with Conan, to install it (or upgrade) just do: - -.. code-block:: shell - - pip3 install -U conan - -After that you might need to add a custom profile file for your development environment -in *~/.conan/profiles* directory. An example profile can look as follows: - -.. code-block:: ini - :emphasize-lines: 8 - - [settings] - os=Linux - os_build=Linux - arch=x86_64 - arch_build=x86_64 - compiler=gcc - compiler.version=12 - compiler.cppstd=20 - compiler.libcxx=libstdc++11 - build_type=Release - - [env] - CC=/usr/bin/gcc-12 - CXX=/usr/bin/g++-12 - -.. tip:: - - Please note that **mp-units** library requires C++20 to be set either in a Conan profile or forced - via Conan command line. If you do the former, you will not need to provide ``-s compiler.cppstd=20`` - every time your run a Conan command line (as provided in the command line instructions below). - -Additionally, it is recommended to set Ninja as a CMake generator for Conan. To do so you should create -a *~/.conan/global.conf* file that will set ``tools.cmake.cmaketoolchain:generator`` to one of Ninja -generators. For example: - -.. code-block:: text - - tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" - -.. note:: - - *~/.conan/global.conf* file may also set ``tools.cmake.cmake_layout:build_folder_vars`` which - `makes working with several compilers or build configurations easier - `_. - For example the below line will force Conan to generate separate CMake presets and folders for each compiler: - - .. code-block:: text - - tools.cmake.cmake_layout:build_folder_vars=["settings.compiler", "settings.compiler.version"] - - In such a case you will need to use a configuration specific preset name in the Conan instructions provided below - rather then just ``default`` and ``release`` (i.e. ``gcc-11`` and ``gcc-11-release``) - - -Build Options -------------- - -Conan Options -^^^^^^^^^^^^^ - -downcast_mode -+++++++++++++ - -**Values**: ``off``/``on``/``auto`` - -**Defaulted to**: ``on`` - -Specifies how :ref:`design/downcasting:The Downcasting Facility` works: - -- ``off`` - no downcasting at all -- ``on`` - downcasting always forced -> compile-time errors in case of duplicated definitions -- ``automatic`` - downcasting automatically enabled if no collisions are present - -Conan Configuration Properties -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -user.build:all -++++++++++++++ - -**Values**: ``True``/``False`` - -**Defaulted to**: ``False`` - -Enables compilation of all the source code (tests and examples) and generating the documentation. -To support this it requires some additional Conan build dependencies described in -`Repository Structure and Dependencies`_. -It also runs unit tests during Conan build (unless ``tools.build:skip_test`` configuration property is set to ``True``) - -user.build:skip_la -++++++++++++++++++ - -**Values**: ``True``/``False`` - -**Defaulted to**: ``False`` - -If `user.build:all`_ is enabled, among others, Conan installs the external `wg21-linear_algebra `_ -dependency and enables compilation of linear algebra based usage examples. Such behavior can be disabled with this option. - -user.build:skip_docs -++++++++++++++++++++ - -**Values**: ``True``/``False`` - -**Defaulted to**: ``False`` - -If `user.build:all`_ is enabled, among others, Conan installs the documentation generation dependencies (i.e. doxygen) and -turns on the project documentation generation. Such behavior can be disabled with this option. - -CMake Options -^^^^^^^^^^^^^ - -UNITS_AS_SYSTEM_HEADERS -+++++++++++++++++++++++ - -**Values**: ``ON``/``OFF`` - -**Defaulted to**: ``OFF`` - -Exports library as system headers. - - -UNITS_BUILD_LA -++++++++++++++ - -**Values**: ``ON``/``OFF`` - -**Defaulted to**: ``ON`` - -Enables building code depending on the linear algebra library. - - -UNITS_BUILD_DOCS -++++++++++++++++ - -**Values**: ``ON``/``OFF`` - -**Defaulted to**: ``ON`` - -Enables project documentation generation. - - -UNITS_DOWNCAST_MODE -+++++++++++++++++++ - -**Values**: ``OFF``/``ON``/``AUTO`` - -**Defaulted to**: ``ON`` - -Equivalent to `downcast_mode`_. - - -UNITS_IWYU -++++++++++ - -**Values**: ``ON``/``OFF`` - -**Defaulted to**: ``OFF`` - -Enables include-what-you-use when compiling with a clang compiler. -Additionally turns on `UNITS_AS_SYSTEM_HEADERS`_. - - -UNITS_USE_LIBFMT -++++++++++++++++ - -**Values**: ``ON``/``OFF`` - -**Defaulted to**: ``ON`` - -Enables usage of `{fmt} `_ library instead of the C++20 Standard Library feature. - - -CMake with Presets Support --------------------------- - -It is recommended to use at least CMake 3.23 to build this project as this version introduced a support -for CMake Presets schema version 4 used now by Conan to generate presets files. All build instructions -below assume that you have such a support. If not, your CMake invocations have to be replaced to something -like: - -.. code-block:: shell - - mkdir build && cd build - cmake .. -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=/conan_toolchain.cmake - cmake --build . --config Release - -.. note:: - - In case you can't use CMake 3.23 but you have access to CMake 3.20 or later, you can append - ``-c tools.cmake.cmaketoolchain.presets:max_schema_version=2`` to the ``conan install`` command - which will force Conan to use an older version of CMake Presets schema. - - -Installation and Reuse ----------------------- - -There are many different ways of installing/reusing **mp-units** in your project. Below we mention -only a few of many options possible. - -Copy -^^^^ - -As **mp-units** is a C++ header-only library you can simply copy all needed ``src/*/include`` subdirectories -to your source tree. - -.. important:: - - In such a case you are on your own to make sure all the dependencies are installed and their header - files can be located during the build. Please also note that some compiler-specific flags are needed - to make the code compile without issues. - - -Copy + CMake -^^^^^^^^^^^^ - -In case you copy the whole **mp-units** repository to your project's file tree you can reuse CMake targets -defined by the library. To do so you should use *CMakeLists.txt* file from the *./src* directory: - -.. code-block:: cmake - - add_subdirectory(/src) - # ... - target_link_libraries( mp-units::mp-units) - -.. important:: - - You are still on your own to make sure all the dependencies are installed and their header and CMake - configuration files can be located during the build. - - -Conan + CMake (release) -^^^^^^^^^^^^^^^^^^^^^^^ - -.. tip:: - - If you are new to Conan package manager it is highly recommended to read `Obtaining Dependencies`_ - and refer to `Getting Started `_ and - `Using packages `_ chapters - of the official Conan documentation for more information. - -**mp-units** releases are hosted on `Conan-Center `_. To obtain official -library release the following steps may be performed: - -1. Create Conan configuration file (either *conanfile.txt* or *conanfile.py*) in your - project's top-level directory and add **mp-units** as a dependency of your project. - For example the simplest file may look as follows: - - .. code-block:: ini - :caption: conanfile.txt - - [requires] - mp-units/0.7.0 - - [generators] - CMakeToolchain - CMakeDeps - -2. Import **mp-units** and its dependencies definitions to your project's build procedure - with ``find_package``: - - .. code-block:: cmake - - find_package(mp-units CONFIG REQUIRED) - -3. Link your CMake targets with **mp-units**: - - .. code-block:: cmake - - target_link_libraries( mp-units::mp-units) - target_compile_features( cxx_std_20) - - .. important:: - - Unfortunately, packages distributed via Conan-Center cannot force the minimum version - of the C++ language used for your build process. This is why it is important to specify - it in `Conan profile file `_ and with ``target_compile_features`` command - for each CMake target directly linking with ``mp-units::mp-units`` in your project. - -4. Download, build, and install Conan dependencies before running CMake configuration step: - - .. code-block:: shell - - mkdir my_project/build && cd my_project/build - conan install .. -pr -s compiler.cppstd=20 -b=missing - cmake .. -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake - cmake --build . --config Release - - -Conan + CMake (Live At Head) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This chapter describes the procedure to Live At Head which means to use the latest version -of **mp-units** all the time. - -.. note:: - - Please note that even though the Conan packages that you will be using are generated **ONLY** - for builds that are considered stable (passed our CI tests) some minor regressions may happen - (our CI and C++20 build environment is not perfect yet). Also, please expect that the library - interface might, and probably will, change from time to time. Even though we do our best, such - changes might not be reflected in the project's documentation right away. - -The procedure is similar to the one described in `Conan + CMake (release)`_ with the following -differences: - -1. Before starting the previous procedure add **mp-units** remote to your Conan configuration: - - .. code-block:: shell - - conan remote add conan-mpusz https://mpusz.jfrog.io/artifactory/api/conan/conan-oss - -2. In your Conan configuration file provide package identifier of the ``mpusz/testing`` stream: - - .. code-block:: ini - :caption: conanfile.txt - - [requires] - mp-units/0.8.0@mpusz/testing - - [layout] - cmake_layout - - [generators] - CMakeToolchain - CMakeDeps - - .. tip:: - - The identifiers of the latest packages can always be found in - `the project's README file `_ or on - `the project's Artifactory `_. - -3. Force Conan to check for updated recipes ``-u`` and to build outdated packages ``-b outdated``: - - .. code-block:: shell - - conan install . -pr -s compiler.cppstd=20 -b=outdated -u - cmake --preset conan-default - cmake --build --preset conan-release - - -Install -^^^^^^^ - -In case you don't want to use Conan in your project and just want to install the **mp-units** -library on your file system and use it via ``find_package(mp-units)`` from another repository -to find it, it is enough to perform the following steps: - -.. code-block:: shell - - conan install . -pr -s compiler.cppstd=20 -b=missing - mv CMakeUserPresets.json src - cd src - cmake --preset conan-default -DCMAKE_INSTALL_PREFIX= - cmake --build --preset conan-release --target install - - -Contributing (or just building all the tests and examples) ----------------------------------------------------------- - -In case you would like to build all the source code (with unit tests and examples) in **mp-units** repository, -you should: - -1. Use the *CMakeLists.txt* from the top-level directory. -2. Run Conan with `user.build:all`_ = ``True`` - (use ``-c user.build:skip_docs=True`` if you want to skip the documentation generation). - -.. code-block:: shell - - git clone https://github.com/mpusz/units.git && cd units - conan install . -pr -s compiler.cppstd=20 -c user.build:all=True -c user.build:skip_docs=True -b missing - conan build . - -The above will download and install all of the dependencies needed for the development of the library, -build all of the source code and run unit tests. - -If you prefer to build the project via CMake rather then Conan, then you should replace the last ``conan build .`` -step with the explicit CMake build: - -.. code-block:: shell - - cmake --preset conan-default - cmake --build --preset conan-release - cmake --build --preset conan-release --target test - - -Building documentation ----------------------- - -In case you would like to build the project's documentation, you should: - -1. Use the *CMakeLists.txt* from the top-level directory. -2. Obtain Python dependencies. -3. Run Conan with `user.build:all`_ = ``True``. - -.. code-block:: shell - - git clone https://github.com/mpusz/units.git && cd units - pip3 install -r docs/requirements.txt - conan install . -pr -s compiler.cppstd=20 -c user.build:all=True -b missing - cmake --preset conan-default - cmake --build --preset conan-release --target documentation - -The above will download and install all of the dependencies needed and build the documentation. - - -Packaging ---------- - -To test CMake installation and Conan packaging or create a Conan package run: - -.. code-block:: shell - - conan create . / -pr -s compiler.cppstd=20 -c user.build:all=True -c user.build:skip_docs=True -b missing - -The above will create a Conan package and run tests provided in *./test_package* directory. - - -Uploading **mp-units** Package to the Conan Server --------------------------------------------------- - -.. code-block:: shell - - conan upload -r --all mp-units/0.8.0@/ diff --git a/docs/use_cases.rst b/docs/use_cases.rst deleted file mode 100644 index 6c84ef70..00000000 --- a/docs/use_cases.rst +++ /dev/null @@ -1,20 +0,0 @@ -Use Cases -========= - -.. note:: - - For brevity all the code examples in this chapter assume:: - - using namespace units; - using namespace units::isq; - -.. toctree:: - :maxdepth: 1 - - use_cases/unknown_dimensions - use_cases/legacy_interfaces - use_cases/custom_representation_types - use_cases/interoperability - use_cases/linear_algebra - use_cases/extensions - use_cases/natural_units diff --git a/docs/use_cases/custom_representation_types.rst b/docs/use_cases/custom_representation_types.rst deleted file mode 100644 index 5a733f5b..00000000 --- a/docs/use_cases/custom_representation_types.rst +++ /dev/null @@ -1,308 +0,0 @@ -.. namespace:: units - -Using Custom Representation Types -================================= - -A custom representation type can be provided as the last `quantity` class template parameter. -With this a user is able to change how a quantity's value is being represented and provide -its own custom logic for it (i.e. use a complex number or a measurement class that will handle -not only a value but also a measurement error). - - -A `Representation` concept --------------------------- - -To support a minimum set of `quantity` operations all custom representation types have to -satisfy at least the `Representation` concept. Which means that they: - -- cannot be quantities by themselves, -- cannot be wrappers over the `quantity` type (i.e. ``std::optional>``), -- have to be regular types (e.g. they have to provide equality operators) -- should either have common type with ``std::intmax_t`` which provides multiplication and - division operators -- or :expr:`T::value_type` must be valid, and common type of ``T::value_type`` and ``std::intmax_t`` - must at least provide multiplication and division operators with itself and ``T``. - -With the above we will be able to construct quantities, convert between the units of the same -dimension, and compare them for equality. - - -The Simplest Custom Representation Type -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The simplest representation type that fulfills the above requirements can look as follows:: - - class my_rep { - std::intmax_t value_; - public: - my_rep() = default; - constexpr explicit my_rep(std::intmax_t v) noexcept : value_(v) {} - - [[nodiscard]] bool operator==(my_rep) const = default; - - [[nodiscard]] friend constexpr my_rep operator*(my_rep lhs, my_rep rhs) - { - return my_rep(lhs.value_ * rhs.value_); - } - [[nodiscard]] friend constexpr my_rep operator/(my_rep lhs, my_rep rhs) - { - return my_rep(lhs.value_ / rhs.value_); - } - }; - -Now we can put ``my_rep`` as the last parameter of the `quantity` class template and the following -code will work just fine:: - - static_assert(si::length(my_rep(2'000)) == si::length(my_rep(2))); - - -Construction of Quantities with Custom Representation Types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Assuming that our custom representation type is constructible from a fundamental integral type, -let's assume two types: - -.. code-block:: - :emphasize-lines: 5, 13 - - class impl { - int value_{}; - public: - impl() = default; - constexpr impl(int v): value_(v) {} - // the rest of the representation type implementation - }; - - class expl { - int value_{}; - public: - expl() = default; - constexpr explicit expl(int v): value_(v) {} - // the rest of the representation type implementation - }; - -The difference between the above types is that ``impl`` class is implicitly constructible -from values of type ``int`` while ``expl`` is not. To create quantities using those as their -representation types we have to obey similar rules:: - - si::length d1(123); // OK - si::length d2(123); // Compile-time error - si::length d3(expl(123)); // OK - -This also applies when we want to create a quantity with a custom representation type -from a regular quantity value:: - - Length auto d = 123 * m; - si::length d1(d); // OK - si::length d2(d); // Compile-time error - si::length d3(quantity_cast(d)); // OK - -The only difference here is that in this case we have to explicitly cast the `quantity` with -`quantity_cast` overload that scopes only on changing the representation type. - -Additional Requirements ------------------------ - -As noted in the previous chapter, the `Representation` concept guarantees us the possibility -to construct quantities, convert between the units of the same dimension, and compare them -for equality. To provide additional `quantity` operations the custom representation type -have to satisfy more requirements. - -.. important:: - - The requirements described in this chapter are optional in a meaning that if someone does - not plan to use a specific quantity's operation his/her custom representation type can - ignore (not implement/satisfy) the requirements for it. - - -Relational Quantity Operators -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In case we want to to compare the values of `quantity` type not only for equality but -also for ordering, we have to provide a corresponding operators to our ``my_rep`` class. -With C++20 it is really easy to do:: - - class my_rep { - public: - [[nodiscard]] constexpr auto operator<=>(my_rep other) const = default; - - // ... - }; - -With the above the following code will compile fine:: - - static_assert(si::length(2'000) < si::length(3)); - - -Arithmetic Quantity Operators -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In case we plan to perform arithmetic operations on our `quantity` type we have to provide -at least the following:: - - class my_rep { - public: - [[nodiscard]] friend constexpr my_rep operator+(my_rep lhs, my_rep rhs) - { - return my_rep(lhs.value_ + rhs.value_); - } - [[nodiscard]] friend constexpr my_rep operator-(my_rep lhs, my_rep rhs) - { - return my_rep(lhs.value_ - rhs.value_); - } - - // ... - }; - -Thanks to it the following code will run as expected:: - - static_assert(si::length(2'000) + si::length(1) == - si::length(3)); - -Of course, the above operators are the smallest possible set to provide support for basic -arithmetic operations. In case the user wants to use faster or more sophisticated operators -the following ones can be provided:: - - class my_rep { - public: - [[nodiscard]] constexpr my_rep operator+() const; - [[nodiscard]] constexpr my_rep operator-() const; - - constexpr my_rep& operator++(); - constexpr my_rep operator++(int); - constexpr my_rep& operator--(); - constexpr my_rep operator--(int); - constexpr my_rep& operator+=(my_rep q); - constexpr my_rep& operator-=(my_rep q); - constexpr my_rep& operator*=(my_rep rhs); - constexpr my_rep& operator/=(my_rep rhs); - constexpr my_rep& operator%=(my_rep rhs); - - [[nodiscard]] friend constexpr my_rep operator%(my_rep lhs, my_rep rhs); - - // ... - }; - -Each of the above operators will enable a respective operator in the `quantity` -type. - - -Customization Points --------------------- - -Up to now we were enabling new functionalities by adding new operations to the custom representation -type. However, we can also enable more operations and customize the engine behavior through a few -customization points. - -`quantity_value` -^^^^^^^^^^^^^^^^ - -The `quantity` class template has a few static member functions: `quantity::zero`, `quantity::one`, -`quantity::min`, and `quantity::max`. Those return the respective quantity values for a specific -representation type. The default implementation is provided through the `quantity_values` class -template:: - - template - struct quantity_values { - static constexpr Rep zero() noexcept { return Rep(0); } - static constexpr Rep one() noexcept { return Rep(1); } - static constexpr Rep min() noexcept { return std::numeric_limits::lowest(); } - static constexpr Rep max() noexcept { return std::numeric_limits::max(); } - }; - -The user can provide an explicit/partial class template specialization for his/her custom -representation type and provide values that should be returned by the respective `quantity` -operations. - -`treat_as_floating_point` -^^^^^^^^^^^^^^^^^^^^^^^^^ - -In the :ref:`framework/conversions_and_casting:Conversions and Casting` chapter we learned -that the conversions provided by the library's framework treat floating-point representation -types differently than the integral ones. This behavior can also be extended to the custom -representation types with `treat_as_floating_point` customization point which default -definition is:: - - template - inline constexpr bool treat_as_floating_point = std::is_floating_point_v; - -If our representation type should have a floating-point semantics or if it is a class -template, in which case we may not know exactly what is the final representation type, -we can specialize this variable template as follows:: - - namespace custom { - - template - class my_rep { - T value_{}; - public: - // ... - }; - - } // namespace custom - - namespace units { - - template - inline constexpr bool treat_as_floating_point> = std::is_floating_point_v; - - } // namespace units - -.. important:: - - Please remember that by the C++ language rules all template specializations have to be put - always in the same namespace as the primary template definition. - - -Conversions of Quantities with Custom Representation Types ----------------------------------------------------------- - -In case we want to mix quantities of our Custom Representation Type with the quantities using -fundamental arithmetic types as their representation we have to provide conversion operators -in our representation type. - -Again let's assume two types, but this time let's scope on conversion operators rather -than on constructors: - -.. code-block:: - :emphasize-lines: 5, 13 - - template - class impl { - T value_{}; - public: - constexpr operator const T&() const& { return value_; } - // the rest of the representation type implementation - }; - - template - class expl { - T value_{}; - public: - constexpr explicit operator const T&() const& { return value_; } - // the rest of the representation type implementation - }; - -If we have instances of the above types we can construct quantities in the following way:: - - impl v_impl(1); - expl v_expl(1); - si::length d1(v_impl); // OK - si::length d2(v_expl); // Compile-time error - si::length d3(int(v_expl); // OK - -Similarly, when we have quantities of the above types we can create quantities of other -representation types with:: - - si::length> d_impl(1); - si::length> d_expl(1); - si::length d1(d_impl); // OK - si::length d2(d_expl); // Compile-time error - si::length d3(quantity_cast(d_expl)); // OK - - -.. seealso:: - - For more examples of custom representation types usage please refer to the - :ref:`use_cases/linear_algebra:Linear Algebra vs. Quantities` chapter and the - :ref:`examples/custom_representation/measurement:measurement` example. diff --git a/docs/use_cases/extensions.rst b/docs/use_cases/extensions.rst deleted file mode 100644 index fd2281a8..00000000 --- a/docs/use_cases/extensions.rst +++ /dev/null @@ -1,307 +0,0 @@ -.. namespace:: units - -Extending the Library -===================== - -The library was designed with a simple extensibility in mind. It is easy to add new units, -dimensions, and prefixes. The systems of units are not closed (classes) but open (namespaces) -and can be easily extended, or its content can be partially/fully imported to other systems. - - -Custom Units ------------- - -It might happen that the user would like to use a unit that is not predefined by the library -or is predefined but the user would like to name it differently, assign a different symbol -to existing unit, or make it a base unit for prefixes. - - -Defining a New Unit -^^^^^^^^^^^^^^^^^^^ - -My working desk is of ``180 cm x 60 cm`` which gives an area of ``0.3 m²``. I would like to -make it a unit of area for my project:: - - struct desk : named_scaled_unit {}; - -With the above I can define a quantity with the area of ``2 desks``:: - - auto d1 = si::area(2); - -In case I feel it is too verbose to type the above every time I can easily create a custom -alias or an :abbr:`UDL (User Defined Literal)`:: - - // alias with fixed integral representation - using desks = si::area; - - // UDLs - constexpr auto operator"" _d(unsigned long long l) { return si::area(l); } - constexpr auto operator"" _d(long double l) { return si::area(l); } - -Right now I am fully set up for my project and can start my work of tracking the area taken -by my desks:: - - auto d1 = si::area(2); - auto d2 = desks(3); - auto d3 = 1_d; - auto sum = d1 + d2 + d3; - std::cout << "Area: " << sum << '\n'; // prints 'Area: 6 desk' - -In case I would like to check how much area ``6 desks`` take in SI units:: - - auto sum_si = quantity_cast(sum); - std::cout << "Area (SI): " << sum_si << '\n'; // prints 'Area (SI): 1.8 m²' - - -Enabling a Unit for Prefixing -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In case I decide it is reasonable to express my desks with SI prefixes, I can define -a new unit named ``kilodesk``:: - - struct kilodesk : prefixed_unit {}; - static_assert(3_d * 1000 == si::area(3)); - -But maybe SI prefixes are not good for me. Maybe I always pack ``6`` desks into one package -for shipment and ``40`` such packages fit into my lorry. To express this new prefix definitions -are needed:: - - struct package : prefix {}; - struct lorry : prefix {}; - -Now we can use it for our unit:: - - struct desk : named_scaled_unit {}; - struct packagedesk : prefixed_unit {}; - struct lorrydesk : prefixed_unit {}; - -With the above:: - - static_assert(6_d == si::area(1)); - static_assert(240_d == si::area(1)); - std::cout << "Area: " << quantity_cast(sum) << '\n'; // prints 'Area: 1 pkgdesk' - -It is important to notice that with the definition of a custom prefix I did not loose SI -units compatibility. If I want to calculate how much area I can cover with desks delivered -by ``3 lorries`` I can do the following:: - - auto area = quantity_cast(si::area(3)); - std::cout << "Area: " << area << '\n'; // prints 'Area: 216 m²' - - -Custom Dimensions ------------------ - -There are cases were a custom unit is not enough and the user would like to define custom -dimensions. The most common case is to define a new derived dimension from other dimensions -already predefined in various systems. But in **mp-units** library it is also really easy to -define a new base dimension for a custom units system. - -Custom Derived Dimensions -^^^^^^^^^^^^^^^^^^^^^^^^^ - -In case I want to track how many desks I can produce over time or what is the consumption -rate of wood during production I need to define a new derived dimension together with its -coherent unit:: - - // coherent unit must apply to the system rules (in this case SI) - struct square_metre_per_second : derived_unit {}; - - // new derived dimensions - struct dim_desk_rate : derived_dimension, exponent> {}; - - // our unit of interest for a new derived dimension - struct desk_per_hour : derived_scaled_unit {}; - - // a quantity of our dimension - template U, Representation Rep = double> - using desk_rate = quantity; - - // a concept matching the above quantity - template - concept DeskRate = QuantityOf; - -With the above we can now check what is the production rate:: - - DeskRate auto rate = quantity_cast(3._d / (20 * min)); - std::cout << "Desk rate: " << rate << '\n'; // prints 'Desk rate: 9 desk/h' - -and how much wood is being consumed over a unit of time:: - - auto wood_rate = quantity_cast(rate); - std::cout << "Wood rate: " << wood_rate << '\n'; // prints 'Wood rate: 0.00075 m²/s' - - -Custom Base Dimensions -^^^^^^^^^^^^^^^^^^^^^^ - -In case I want to monitor what is the average number of people sitting by one desk in -a customer's office I would need a unit called ``person_per_desk`` of a new derived -dimension. However, our library does not know what a ``person`` is. For this I need to -define a new base dimension, its units, quantity helper, concept, and UDLs:: - - struct person : named_unit {}; - struct dim_people : base_dimension<"people", person> {}; - - template U, Representation Rep = double> - using people = quantity; - - template - concept People = QuantityOf; - - constexpr auto operator"" _p(unsigned long long l) { return people(l); } - constexpr auto operator"" _p(long double l) { return people(l); } - - -With the above we can now define a new derived dimension:: - - struct person_per_square_metre : derived_unit {}; - struct dim_occupancy_rate : derived_dimension, - exponent> {}; - - struct person_per_desk : derived_scaled_unit {}; - - template U, Representation Rep = double> - using occupancy_rate = quantity; - - template - concept OccupancyRate = QuantityOf; - -Now we can play with our new feature:: - - People auto employees = 1450._p; - auto office_desks = 967_d; - OccupancyRate auto occupancy = employees / office_desks; - - std::cout << "Occupancy: " << occupancy << '\n'; // prints 'Occupancy: 1.49948 person/desk' - - -Custom Systems --------------- - -Being able to extend predefined systems is a mandatory feature of any physical -units library. Fortunately, for **mp-units** there is nothing special to do here. - -A system is defined in terms of its base dimensions. If you are using only SI -base dimensions then you are in the boundaries of the SI system. If you are -adding new base dimensions, like we did in the `Custom Base Dimensions`_ -chapter, you are defining a new system. - -In **mp-units** library a custom system can either be constructed from -unique/new custom base dimensions or reuse dimensions of other systems. This -allows extending, mixing, reuse, and interoperation between different systems. - -Systems can be defined as standalone or provide interoperability and conversions -with other systems. It is up to the user to decide which one fits better to the -requirements. - -A standalone system is the one that has unique :term:`base units `. -Such units do not share their references with base units of other systems: - -.. code-block:: - :emphasize-lines: 3, 6 - - namespace fps { - - struct foot : named_unit {}; - struct yard : named_scaled_unit {}; - - struct dim_length : base_dimension<"L", foot> {}; - - template U, Representation Rep = double> - using length = quantity; - - } // namespace fps - -If the base unit of one system has the same reference as the base unit of -another system, and both systems share the same base dimension symbol, the -library will enable conversions between units of those dimensions in -different systems: - -.. code-block:: - :emphasize-lines: 3, 6, 13, 16 - - namespace si { - - struct metre : named_unit {}; - struct kilometre : prefixed_unit {}; - - struct dim_length : base_dimension<"L", metre> {}; - - template U, Representation Rep = double> - using length = quantity; - - namespace fps { - - struct foot : named_scaled_unit {}; - struct yard : named_scaled_unit {}; - - struct dim_length : base_dimension<"L", foot> {}; - - template U, Representation Rep = double> - using length = quantity; - - } // namespace fps - } // namespace si - -Having the above two systems we can try the following code:: - - constexpr auto fps_yard = fps::length(1.); - std::cout << quantity_cast(fps_yard) << "\n"; // compile-time error - - constexpr auto si_fps_yard = si::fps::length(1.); - std::cout << quantity_cast(si_fps_yard) << "\n"; // prints "0.0009144 km" - -Even though the base dimension of ``si::fps`` is defined in terms of -``si::metre`` foot is preserved as the base unit of length in both systems:: - - constexpr auto fps_yard = fps::length(1.); - constexpr auto fps_area = fps_yard * fps_yard; - std::cout << fps_yard << "\n"; // 1 yd - std::cout << quantity_cast(fps_area) << "\n"; // 9 ft² - - constexpr auto si_fps_yard = si::fps::length(1.); - constexpr auto si_fps_area = si_fps_yard * si_fps_yard; - std::cout << si_fps_yard << "\n"; // 1 yd - std::cout << quantity_cast(si_fps_area) << "\n"; // 9 ft² - -In most cases we want conversions between systems and that is why nearly all -systems provided with this library are implemented in terms on the :term:`SI` -system. However, such an approach has also its problems. Let's see the -following simple application using the above defined systems:: - - std::ostream& operator<<(std::ostream& os, const ratio& r) - { - return os << "ratio{" << r.num << ", " << r.den << ", " << r.exp << "}"; - } - - std::ostream& operator<<(std::ostream& os, const Unit auto& u) - { - using unit_type = std::remove_cvref_t; - return os << unit_type::ratio << " x " << unit_type::reference::symbol.standard(); - } - - int main() - { - std::cout << "fps: " << fps::yard() << "\n"; // fps: ratio{3, 1, 0} x ft - std::cout << "si::fps: " << si::fps::yard() << "\n"; // si::fps: ratio{1143, 125, -1} x m - } - -As we can see, even though ``si::fps::yard`` is defined as ``3`` feet, -the library always keeps the ratio relative to the primary reference unit -which in this case is ``si::metre``. This results in much bigger ratios -and in case of some units may result with a problem of limited resolution -of ``std::int64_t`` used to store numerator, denominator, and exponent -values of ratio. For example the ``si::fps::cubic_foot`` already has the -ratio of ``ratio{55306341, 1953125, -3}``. In case of more complicated -conversion ratio we can overflow `ratio` and get a compile-time error. -In such a situation the standalone system may be a better choice here. - - -.. seealso:: - - More information on extending the library can be found in the - :ref:`use_cases/custom_representation_types:Using Custom Representation Types` - chapter. diff --git a/docs/use_cases/interoperability.rst b/docs/use_cases/interoperability.rst deleted file mode 100644 index 40f58501..00000000 --- a/docs/use_cases/interoperability.rst +++ /dev/null @@ -1,125 +0,0 @@ -.. namespace:: units - -Interoperability with Other Units Libraries -=========================================== - -Other units libraries can be easily integrated with **mp-units** via specialization of a -`quantity_like_traits` for external quantity-like type. The type trait specialization should -provide the following: - -- type aliases: - - ``dimension`` mapping the source with target dimension type - - ``unit`` mapping the source with target unit type - - ``rep`` mapping the source with target representation type -- a static member function ``number(T)`` that returns the raw value/magnitude of the quantity. - -For example, to provide support for the ``std::chrono::duration`` it is enough to define:: - - #include - #include - #include - - namespace units { - - template - struct quantity_like_traits> { - using dimension = isq::si::dim_time; - using unit = downcast_unit; - using rep = Rep; - [[nodiscard]] static constexpr rep number(const std::chrono::duration& q) { return q.count(); } - }; - - } // namespace units - -Providing the above allows the external quantity-like type to satisfy the `QuantityLike` concept -which in turn enables the explicit `quantity` constructor that provides the type conversion. -A Class Template Argument Deduction (CTAD) guide is provided to improve the user experience of -such an explicit conversion:: - - using namespace std::chrono_literals; - - static_assert(quantity{1s} + 1 * s == 2 * s); - static_assert(quantity{1s} + 1 * min == 61 * s); - static_assert(10 * m / quantity{2s} == 5 * (m / s)); - -.. note:: - - As the constructor is explicit, the quantity object can be created from - quantity-like type only via - `direct initialization `_. - This is why the code below using - `copy initialization `_ - **does not compile**:: - - using namespace std::chrono_literals; - quantity q = 1s; // ERROR - -For external quantity point-like types, `quantity_point_like_traits` is also provided. -It works just like `quantity_like_traits`, except that -``number(T)`` is replaced with ``relative(T)`` that returns the `QuantityLike` value -and ``dimension`` is replaced with ``origin``. - -Similar to `quantity` and `quantity_kind`, `quantity_point` and `quantity_point_kind` -provide a deduction guide from `QuantityPointLike`:: - - using namespace std::chrono_literals; - - static_assert((quantity_point{std::chrono::sys_seconds{1s}} + 1 * s).relative() == 2s); - - -Interoperability with the C++ Standard Library ----------------------------------------------- - -The above ``std::chrono``-specific customization points are already predefined in the ``mp-units`` -library for both ``std::chrono::duration`` as well as ``std::chrono::time_point``. -They are provided in a dedicated header file:: - - #include - -The same header file provides additional conversion helpers from ``mp-units`` to -the C++ Standard Library types: - -- an alias that provides a conversion from `ratio` to ``std::ratio``:: - - template - using to_std_ratio = /* ... */ - -- an explicit conversion of `quantity` of `isq::si::dim_time` to ``std::chrono::duration``:: - - template - [[nodiscard]] constexpr auto to_std_duration(const quantity& q) - -- an explicit conversion of `quantity_point` that previously originated from ``std::chrono`` - to ``std::chrono::time_point``:: - - template - [[nodiscard]] constexpr auto to_std_time_point(const quantity_point, U, Rep>& qp) - -.. note:: - - Only `quantity_point` that was created from a ``std::chrono::time_point`` of a specific - ``std::chrono`` clock can be converted back to ``std::chrono`` domain:: - - const auto qp1 = quantity_point{sys_seconds{1s}}; - const auto tp1 = to_std_time_point(qp1); // OK - - const auto qp2 = quantity_point{1 * s}; - const auto tp2 = to_std_time_point(qp2); // Compile-time Error - -Here is an example of how interoperatibility described in this chapter can be used in practice:: - - using namespace units::aliases::isq::si; - using timestamp = quantity_point, si::second>; - - const auto start_time = timestamp(std::chrono::system_clock::now()); // std::chrono -> units - const auto velocity = speed::km_per_h<>(825); - const auto distance = length::km<>(8111); - const auto flight_time = distance / velocity; - const auto exp_end_time = start_time + flight_time; - - const auto tp = to_std_time_point(exp_end_time); // units -> std::chrono - const auto tp_sec = std::chrono::floor(tp); - const auto tp_days = std::chrono::floor(tp_sec); - const auto ymd = std::chrono::year_month_day(tp_days); - const auto tod = tp_sec - tp_days; - const auto hms = std::chrono::hh_mm_ss(tod); diff --git a/docs/use_cases/legacy_interfaces.rst b/docs/use_cases/legacy_interfaces.rst deleted file mode 100644 index b9db03f9..00000000 --- a/docs/use_cases/legacy_interfaces.rst +++ /dev/null @@ -1,55 +0,0 @@ -.. namespace:: units - -Working with Legacy Interfaces -============================== - -In case we are working with a legacy/unsafe interface we may be forced to -extract the :term:`value of a quantity` with :func:`quantity::number()` -(in addition -to the quantity of a `quantity_point` with :func:`quantity_point::relative()`, -or the quantity of a `quantity_kind` with :func:`quantity_kind::common()`, -or the quantity kind of a `quantity_point_kind` -with :func:`quantity_point_kind::relative()`) -and pass it to the library's output: - -.. code-block:: - :caption: legacy.h - - namespace legacy { - - void print_eta(double speed_in_mps); - void set_path_position(double meter); - - } // namespace legacy - -.. code-block:: - - #include "legacy.h" - #include - #include - - using namespace units::isq; - - constexpr Speed auto avg_speed(Length auto d, Time auto t) - { - return d / t; - } - - void print_eta(Length auto d, Time auto t) - { - Speed auto v = avg_speed(d, t); - legacy::print_eta(quantity_cast(v).number()); - } - - template - requires Length - void set_path_position(QP p) - { - legacy::set_path_position(quantity_point_cast(p).relative().number()); - } - -.. important:: - - When dealing with a quantity of an unknown ``auto`` type please remember - to always use `quantity_cast` to cast it to a desired unit before calling - `quantity::number()` and passing the raw value to the legacy/unsafe interface. diff --git a/docs/use_cases/linear_algebra.rst b/docs/use_cases/linear_algebra.rst deleted file mode 100644 index 0aa7de52..00000000 --- a/docs/use_cases/linear_algebra.rst +++ /dev/null @@ -1,88 +0,0 @@ -.. namespace:: units - -Linear Algebra vs. Quantities -============================= - -Even though **mp-units** library does not implement any Linear Algebra types it is generic -enough to be used with other Linear Algebra libraries existing on the market. - -.. note:: - - All of the examples provided in this chapter refer to the official proposal of the - Linear Algebra Library for the C++23 defined in `P1385 `_ - and its latest implementation from `GitHub `_ - or `Conan `_. - Also, to simplify the examples all of them assume:: - - using namespace STD_LA; - - -Linear Algebra of Quantities ----------------------------- - -The official :term:`quantity` definition states: - - *A quantity as defined here is a scalar. However, a vector or a tensor, the components of - which are quantities, is also considered to be a quantity.* - -So the most common use case would be to create a vector or matrix of quantities:: - - fixed_size_column_vector, 3> v = { 1 * m, 2 * m, 3 * m }; - fixed_size_column_vector, 3> u = { 3 * m, 2 * m, 1 * m }; - fixed_size_column_vector, 3> t = { 3 * km, 2 * km, 1 * km }; - -Having such definitions we can perform full dimensional analysis operations for the operations -allowed by the Linear Algebra rules. For example:: - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << fixed_size_column_vector, 3>(t) << "\n"; - std::cout << "v * u = " << v * u << "\n"; - std::cout << "2 * m * v = " << 2 * m * v << "\n"; - -The above code works as expected and produces the following output: - -.. code-block:: text - - v + u = | 4 m 4 m 4 m | - v + t = | 3001 m 2002 m 1003 m | - t[m] = | 3000 m 2000 m 1000 m | - v * u = 10 m² - 2 * m * v = | 2 m² 4 m² 6 m² | - - -Quantities of Linear Algebra Types ----------------------------------- - -The previous chapter should address most of the Linear Algebra related requirements. -However, it is also possible to use Linear Algebra entities as custom representation -types provided to a `quantity` class template. - -.. seealso:: - - More information on providing custom representation types for `quantity` can be - found in the :ref:`use_cases/custom_representation_types:Using Custom Representation Types` - chapter. - -With this the above vector definitions can be rewritten as follows:: - - si::length> v(fixed_size_column_vector{ 1, 2, 3 }); - si::length> u(fixed_size_column_vector{ 3, 2, 1 }); - si::length> t(fixed_size_column_vector{ 3, 2, 1 }); - -Now the same code doing basic Linear Algebra operations will provide the following -output: - -.. code-block:: text - - v + u = | 4 4 4 | m - v + t = | 3001 2002 1003 | m - t[m] = | 3000 2000 1000 | m - v * u = 10 m² - 2 * m * v = | 2 4 6 | m² - - -.. seealso:: - - For more examples of Linear Algebra definition and operations please refer to - the :ref:`examples/custom_representation/linear_algebra:linear_algebra` example. diff --git a/docs/use_cases/natural_units.rst b/docs/use_cases/natural_units.rst deleted file mode 100644 index 43a2d340..00000000 --- a/docs/use_cases/natural_units.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. namespace:: units - -Working with Natural Units -========================== - -:term:`ISQ` based implementation --------------------------------- - - -"Pure" implementation ---------------------- diff --git a/docs/use_cases/unknown_dimensions.rst b/docs/use_cases/unknown_dimensions.rst deleted file mode 100644 index f3e3140d..00000000 --- a/docs/use_cases/unknown_dimensions.rst +++ /dev/null @@ -1,118 +0,0 @@ -.. namespace:: units - -Working with Unknown Dimensions and Their Units -=============================================== - -From time to time the user of this library will face an `unknown_dimension` and -`unknown_coherent_unit` types. This chapters describes their purpose and usage in -detail. - -What is an unknown dimension? ------------------------------ - -As we learned in the :ref:`framework/dimensions:Dimensions` chapter, in most cases the result -of multiplying or dividing two quantities of specific dimensions is a quantity of yet another -dimension. - -If such a resulting dimension is predefined by the user (and a proper header file with its -definition is included in the current translation unit) -:ref:`design/downcasting:The Downcasting Facility` will determine its type. -The same applies to the resulting unit. For example: - -.. code-block:: - :emphasize-lines: 1,7,9 - - #include - - using namespace units::isq::si; - using namespace units::isq::si::references; - - constexpr auto result = 144 * km / (2 * h); - static_assert(std::is_same_v); - static_assert(std::is_same_v); - -However, if the resulting dimension is not predefined by the user, the library framework -will create an instance of an `unknown_dimension`. The coherent unit of such an unknown -dimension is an `unknown_coherent_unit`. Let's see what happens with our example when -instead including the header with all :term:`SI` definitions we will just provide base -dimensions used in the division operation: - -.. code-block:: - :emphasize-lines: 1-2,8,10 - - #include - #include - - using namespace units::isq::si; - using namespace units::isq::si::references; - - constexpr auto result = 144 * km / (2 * h); - static_assert(std::is_same_v, exponent>>); - static_assert(std::is_same_v, exponent>>>>); - -.. important:: - - To limit the possibility of an ODR violation please always include a header file - with all the definitions for the current system (e.g. *units/isq/si/si.h*). - - -Operations On Unknown Dimensions And Their Units ------------------------------------------------- - -For some cases we can eliminate the need to predefine a specific dimension and just use -the `unknown_dimension` instead. Let's play with the previous example a bit:: - - static_assert(result.number() == 72); - -As we can see the value stored in this quantity can be easily obtained and contains a -correct result. However, if we try to print its value to the text output we will get:: - - std::cout << "Speed: " << result << '\n'; // prints 'Speed: 72 [1/36 × 10¹] m/s' - -The output from above program should not be a surprise. It is an unknown dimensions with -a scaled unknown coherent unit. The library can't know what is the symbol of such unit -so it does its best and prints the unit in terms of units of base dimensions that formed -this particular unknown derived dimension. - -In case we would like to print the result in terms of base units we can simply do the -following:: - - auto s = quantity_cast(result); - std::cout << "Speed: " << s << '\n'; // prints 'Speed: 20 m/s' - -.. seealso:: - - Another good example of unknown dimension usage can be found in the - :ref:`examples/basics/box_example:box_example`:: - - std::cout << "float rise rate = " << box.fill_level(measured_mass) / fill_time << '\n'; - - -Temporary Results ------------------ - -In many cases there is nothing inherently wrong with having unknown dimensions and units -in your program. A typical example here are temporary results of a long calculation: - -.. code-block:: - :emphasize-lines: 5,7 - - auto some_long_calculation(Length auto d, Time auto t) - { - Speed auto s1 = avg_speed(d, t); - - auto temp1 = s1 * (200 * km); // intermediate unknown dimension - - Speed auto s2 = temp1 / (50 * km); // back to known dimensions again - Length auto d2 = s2 * (4 * h); - - // ... - } - -If a programmer wants to break the calculation to several lines/variables he/she does not -have to ensure that the intermediate results are of predefined dimensions or just a clear -science fiction :-) The final result will always be correct. diff --git a/docs/users_guide/basic_concepts.md b/docs/users_guide/basic_concepts.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/users_guide/simple_and_typed_quantities.md b/docs/users_guide/simple_and_typed_quantities.md new file mode 100644 index 00000000..70bd01bf --- /dev/null +++ b/docs/users_guide/simple_and_typed_quantities.md @@ -0,0 +1,407 @@ +# Simple and Typed Quantities + +ISO specifies a quantity as: + +!!! quote + + property of a phenomenon, body, or substance, where the property has a magnitude that can be expressed as a number and a reference + +After that, it says: + +!!! quote + + A reference can be a measurement unit, a measurement procedure, a reference material, or a combination of such. + +## `quantity` class template + +In the **mp-units** library, a quantity is represented with the following class template: + +```cpp +template Rep = double> +class quantity; +``` + +The concept `Reference` is satisfied by either: + +- a unit with an associated quantity type (i.e. `si::metre`) +- a reference type explicitly specifying the quantity type and its unit. + +!!! note + + All units in the SI system have an associated quantity type. + +A reference type is implicitly created as a result of the following expression: + +```cpp +constexpr auto ref = isq::length[m]; +``` + +The above example resulted in the following type `reference` being instantiated. + +Based on this property, the **mp-units** library provides two modes of dealing with quantities. + + +## Simple quantities + +The **simple mode** might be preferred by many developers. It is all about units. Quantities using this mode +have shorter type identifiers, resulting in easier-to-understand error messages and better debugging experience. + +Here is a simple example showing how to deal with such quantities: + +```cpp +#include +#include +#include + +using namespace mp_units; + +constexpr quantity avg_speed(quantity d, + quantity t) +{ + return d / t; +} + +int main() +{ + using namespace mp_units::si::unit_symbols; + + const auto distance = 110 * km; + const auto duration = 2 * h; + const auto speed = avg_speed(distance, duration); + + std::cout << "A car driving " << distance << " in " << duration + << " has an average speed of " << speed + << " (" << speed[km / h] << ")\n"; +} +``` + +The code above prints: + +```text +A car driving 110 km in 2 h has an average speed of 15.2778 m/s (55 km/h) +``` + +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/e5x1cnEqP)" + + +## Easy to understand compilation error messages + +In case a user makes an error in a quantity equation and the result of the calculation +will not match the function return type, the compiler will detect such an issue at +compile-time. + +For example, in case we will make the following error: + +```cpp hl_lines="4" +constexpr quantity avg_speed(quantity d, + quantity t) +{ + return d * t; // (1)! +} +``` + +1. Quantities multiplied (instead of divided) by accident. + +the following compilation error message will be provided: + +```text +In function 'constexpr mp_units::quantity >()> avg_speed(mp_units::quantity, mp_units::quantity)': +error: could not convert 'mp_units::operator*(d, t)' from 'quantity(),[...]>' to 'quantity >(),[...]>' + 11 | return d * t; + | ~~^~~ + | | + | quantity(),[...]> +``` + +## Typed quantities + +Simple mode is all about and just about units. In case you care about a specific quantity type, +**typed quantities** should be preferred. With this mode, for example, you can specify if you +deal with `width`, `height`, or `radius` and ensure you will not assign one to another by +accident. + +The previous example can be re-typed using typed quantities in the following way: + +```cpp +#include +#include +#include +#include + +using namespace mp_units; +using namespace mp_units::si::unit_symbols; + +constexpr quantity avg_speed(quantity d, + quantity t) +{ + return d / t; +} + +int main() +{ + const auto distance = isq::distance(110 * km); + const auto duration = isq::time(2 * h); + const auto speed = avg_speed(distance, duration); + + std::cout << "A car driving " << distance << " in " << duration + << " has an average speed of " << speed + << " (" << speed[km / h] << ")\n"; +} +``` + +```text +A car driving 110 km in 2 h has an average speed of 15.2778 m/s (55 km/h) +``` + +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/je6jabh3o)" + +In case we will accidentally make the same calculation error as before, this time, we will +get a bit longer error message also containing information about the quantity type: + +```log +In function 'constexpr mp_units::quantity >()>()> avg_speed(mp_units::quantity()>, mp_units::quantity()>)': +error: could not convert 'mp_units::operator*(), double, reference(), double>(d, t)' from 'quantity(), mp_units::derived_unit()>(),[...]>' to 'quantity >()>(),[...]>' + 12 | return d * t; + | ~~^~~ + | | + | quantity(), mp_units::derived_unit()>(),[...]> +``` + +As we can see above, the compilation error is longer but still relatively easy to understand. + + +## Additional type safety with typed quantities + +Based on the previous example, it might seem that typed quantities are not that useful, +more to type and provide harder-to-understand error messages. It might be true in some cases, +but there are cases where they provide an additional level of safety. + +Let's see another example: + +=== "Simple" + + ```cpp hl_lines="42" + #include + #include + #include + + using namespace mp_units; + + class StorageTank { + quantity base_; + quantity height_; + public: + constexpr StorageTank(const quantity& base, + const quantity& height) : + base_(base), height_(height) + { + } + + // ... + }; + + class CylindricalStorageTank : public StorageTank { + public: + constexpr CylindricalStorageTank(const quantity& radius, + const quantity& height) : + StorageTank(std::numbers::pi * pow<2>(radius), height) + { + } + }; + + class RectangularStorageTank : public StorageTank { + public: + constexpr RectangularStorageTank(const quantity& length, + const quantity& width, + const quantity& height) : + StorageTank(length * width, height) + { + } + }; + + int main() + { + using namespace mp_units::si::unit_symbols; + auto tank = RectangularStorageTank(1'000 * mm, 500 * mm, 200 * mm); + // ... + } + ``` + +=== "Typed" + + ```cpp hl_lines="53 54 55" + #include + #include + #include + #include + + using namespace mp_units; + using namespace mp_units::si::unit_symbols; + + // add a custom quantity type of kind isq::length + inline constexpr struct horizontal_length + : quantity_spec {} horizontal_length; + + // add a custom derived quantity type of kind isq::area + // with a constrained quantity equation + inline constexpr struct horizontal_area + : quantity_spec {} horizontal_area; + + class StorageTank { + quantity base_; + quantity height_; + public: + constexpr StorageTank(const quantity& base, + const quantity& height) : + base_(base), height_(height) + { + } + + // ... + }; + + class CylindricalStorageTank : public StorageTank { + public: + constexpr CylindricalStorageTank(const quantity& radius, + const quantity& height) : + StorageTank(quantity_cast(std::numbers::pi * pow<2>(radius)), + height) + { + } + }; + + class RectangularStorageTank : public StorageTank { + public: + constexpr RectangularStorageTank(const quantity& length, + const quantity& width, + const quantity& height) : + StorageTank(length * width, height) + { + } + }; + + int main() + { + auto tank = RectangularStorageTank(horizontal_length(1'000 * mm), + isq::width(500 * mm), + isq::height(200 * mm)); + // ... + } + ``` + +In the above example, the highlighted call doesn't look that safe anymore in the case +of simple quantities, right? Suppose someone, either by mistake or due to some refactoring, +will call the function with invalid order of arguments. In that case, the program will compile +fine but not work as expected. + +Let's see what will happen if we reorder the arguments in the case of typed quantities: + +```cpp hl_lines="2 3" +auto tank = RectangularStorageTank(horizontal_length(1'000 * mm), + isq::height(200 * mm), + isq::width(500 * mm)); +``` + +This time a compiler provides the following compilation error: + +```text +In function 'int main()': +error: no matching function for call to 'RectangularStorageTank::RectangularStorageTank(mp_units::quantity()>(), int>, mp_units::quantity()>(), int>, mp_units::quantity()>(), int>)' + 47 | isq::width(500 * mm)); + | ^ +note: candidate: 'constexpr RectangularStorageTank::RectangularStorageTank(const mp_units::quantity()>&, const mp_units::quantity()>&, const mp_units::quantity()>&)' + 35 | constexpr RectangularStorageTank(const quantity& length, + | ^~~~~~~~~~~~~~~~~~~~~~ +note: no known conversion for argument 2 from 'mp_units::quantity()>(), int>' to 'const mp_units::quantity()>&' + 36 | const quantity& width, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~ +``` + +What about derived quantities? In the above example, you probably noticed that we also defined +a custom `horizontal_area` quantity of kind `isq::area`. This quantity has the special property +of being implicitly constructible only from the result of the multiplication of quantities of +`horizontal_area` and `isq::width` or the ones that implicitly convert to them. + +Based on the above error message, we already know that a quantity of `isq::height` is not implicitly +constructible to the quantity of `isq::width`. This property is transitively passed to derived +quantities using them. If by accident, we will try to create a `StorageTank` base class +in the following way: + +```cpp hl_lines="6" +class RectangularStorageTank : public StorageTank { +public: + constexpr RectangularStorageTank(const quantity& length, + const quantity& width, + const quantity& height) : + StorageTank(length * height, height) + { + } +}; +``` + +we will again get a compilation error message like this one: + +```text +In constructor 'constexpr RectangularStorageTank::RectangularStorageTank(const mp_units::quantity()>&, const mp_units::quantity()>&, const mp_units::quantity()>&)': +error: no matching function for call to 'StorageTank::StorageTank(mp_units::quantity(), mp_units::derived_unit >()>(), double>, const mp_units::quantity()>&)' + 39 | StorageTank(length * height, height) + | ^ +note: candidate: 'constexpr StorageTank::StorageTank(const mp_units::quantity >()>()>&, const mp_units::quantity()>&)' + 16 | constexpr StorageTank(const quantity& base, + | ^~~~~~~~~~~ +:16:62: note: no known conversion for argument 1 from 'mp_units::quantity(), mp_units::derived_unit >()>(), double>' to 'const mp_units::quantity >()>()>&' + 16 | constexpr StorageTank(const quantity& base, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ +``` + +!!! tip + + If you need to use various quantities of the same kind, consider using typed quantities + to bring an additional level of safety to your project. + + +## `quantity_cast()` to force unsafe conversions + +Did you notice the `quantity_cast()` usage in the other child class? + +```cpp hl_lines="5" +class CylindricalStorageTank : public StorageTank { +public: + constexpr CylindricalStorageTank(const quantity& radius, + const quantity& height) : + StorageTank(quantity_cast(std::numbers::pi * pow<2>(radius)), + height) + { + } +}; +``` + +As `isq::radius` is not convertible to either a `horizontal_length` or `isq::width`, +the derived quantity of `pow<2>(radius)` can't be converted to `horizontal_area` as well. +It would be unsafe to allow such a conversion as not all of the circles lie flat on the +ground, right? + +In such a case, the user has to explicitly force such an unsafe conversion with the +help of a `quantity_cast()`. This function name is easy to spot in code reviews or while +searching the project for problems if something goes sideways. In case of unexpected issues +related to quantities, this should be the first function to look for. + +!!! tip + + Do not overuse `quantity_cast()`. Use it only when necessary and ensure that the + requested conversion is exactly what you need in this case. + + +## Which mode to use in my project? + +In case you wonder which mode you should choose for your project, we have good news for you. +Simple and typed quantity modes can be freely mixed with each other. When you use different +quantities of the same kind (i.e. radius, wavelength, altitude, ...), you should probably +reach for typed quantities to bring additional safety for those cases. Otherwise, just use +simple mode for the remaining quantities. The **mp-units** library will do its best to protect +your project based on the information provided. + +!!! tip + + You can easily mix simple and typed quantities in your project. diff --git a/docs/users_guide/systems_of_quantities.md b/docs/users_guide/systems_of_quantities.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/users_guide/systems_of_units.md b/docs/users_guide/systems_of_units.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/users_guide/terms_and_definitions.md b/docs/users_guide/terms_and_definitions.md new file mode 100644 index 00000000..26c40182 --- /dev/null +++ b/docs/users_guide/terms_and_definitions.md @@ -0,0 +1,9 @@ +# Terms and Definitions + +The **mp-units** project consistently uses the official metrology vocabulary defined by +the ISO and BIPM. Please familiarize yourself with those terms to better understand +the documentation and improve domain-related communication and discussions. + +You can find essential project-related definitions in [our documentation's "Glossary" chapter](https://mpusz.github.io/mp-units/glossary.html). +Even more, terms are provided in the official vocabulary of the [ISO](https://www.iso.org/obp/ui#iso:std:iso-iec:guide:99:ed-1:v2:en) +and [BIPM](https://jcgm.bipm.org/vim/en). diff --git a/docs/users_guide/value_conversions.md b/docs/users_guide/value_conversions.md new file mode 100644 index 00000000..d0a1c8ae --- /dev/null +++ b/docs/users_guide/value_conversions.md @@ -0,0 +1,70 @@ +# Value Conversions + +## Value-preserving conversions + +```cpp +auto q1 = 5 * km; +std::cout << q1[m] << '\n'; +quantity q2 = q1; +``` + +The second line above converts the current quantity to the one expressed in metres and prints its +contents. The third line converts the quantity expressed in kilometres into the one measured +in metres. + +!!! note + + It is always assumed that one can convert a quantity into another one with a unit of a higher + resolution. There is no protection against overflow of the representation type. In case the target + quantity ends up with a value bigger than the representation type can handle, you will be facing + Undefined Behavior. + +In case a user would like to perform an opposite transformation: + +```cpp +auto q1 = 5 * m; +std::cout << q1[km] << '\n'; +quantity, int> q2 = q1; +``` + +Both conversions will fail to compile. + +There are two ways to make the above work. The first solution is to use a floating-point +representation type: + +```cpp +auto q1 = 5. * m; +std::cout << q1[km] << '\n'; +quantity> q2 = q1; +``` + +The **mp-units** library follows [`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration) +logic and treats floating-point types as value-preserving. + + +## Value-truncating conversions + +The second solution is to force a truncating conversion: + +```cpp +auto q1 = 5 * m; +std::cout << value_cast(q1) << '\n'; +quantity, int> q2 = value_cast(q1); +``` + +This explicit cast makes it clear that something unsafe is going on. It is easy to spot in code +reviews or while chasing a bug in the source code. + +Another place where this cast is useful is when a user wants to convert a quantity with +a floating-point representation to the one using an integral one. Again this is a truncating +conversion, so an explicit cast is needed: + +```cpp +quantity q3 = value_cast(3.14 * m); +``` + +!!! info + + It is often fine to use an integral as a representation type, but in general, floating-point + types provide better precision and are privileged in the library as they are considered + to be value-preserving. diff --git a/docs_disabled/reference/core/functions.rst b/docs_disabled/reference/core/functions.rst deleted file mode 100644 index edef5b40..00000000 --- a/docs_disabled/reference/core/functions.rst +++ /dev/null @@ -1,4 +0,0 @@ -Functions -========= - -.. doxygenfunction:: units::quantity_cast diff --git a/docs_disabled/reference/math.rst b/docs_disabled/reference/math.rst deleted file mode 100644 index 5620120e..00000000 --- a/docs_disabled/reference/math.rst +++ /dev/null @@ -1,10 +0,0 @@ -Math -==== - -.. doxygenfunction:: mp_units::pow - -.. doxygenfunction:: mp_units::sqrt - -.. doxygenfunction:: mp_units::abs - -.. doxygenfunction:: mp_units::epsilon diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..d67de0ce --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,100 @@ +# Project information +site_name: "The mp-units library" +site_description: "A Physical Quantities and Units library for C++" +site_url: https://mpusz.github.io/mp-units +site_author: "mp-units Team" + +# Repository +repo_url: https://github.com/mpusz/mp-units + +# Copyright +copyright: Copyright © 2018-2023 Mateusz Pusz + +# Configuration +theme: + name: material + custom_dir: docs/.overrides + features: + - content.action.edit + - content.action.view + - content.code.annotate + - content.code.copy + - navigation.expand + - navigation.indexes + - navigation.sections + # - navigation.tabs + - navigation.footer + - search.highlight + - search.share + - search.suggest + # - toc.follow + # - toc.integrate + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/weather-night + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: indigo + accent: indigo + toggle: + icon: material/weather-sunny + name: Switch to light mode + font: + text: Roboto + code: Roboto Mono + +# Customization +extra: + version: + provider: mike + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.superfences + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - toc: + permalink: true + +# Page tree +nav: + - Home: index.md + - Getting Started: + - Introduction: getting_started/introduction.md + - Code Example: getting_started/code_example.md + - Quick Start: getting_started/quick_start.md + - Installation and Usage: getting_started/installation_and_usage.md + - FAQ: getting_started/faq.md + - User's Guide: + - Terms and Definitions: users_guide/terms_and_definitions.md + - Systems of Quantities: users_guide/systems_of_quantities.md + - Systems of Units: users_guide/systems_of_units.md + - Value Conversions: users_guide/value_conversions.md + - Simple and Typed Quantities: users_guide/simple_and_typed_quantities.md + - Basic Concepts: users_guide/basic_concepts.md + - Library Reference: + - Core Library: library_reference/core_library.md + - Appendix: + - Glossary: appendix/glossary.md + - Release Notes: appendix/release_notes.md diff --git a/requirements.txt b/requirements.txt index b29065ba..8542ef45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ conan pre-commit identify +mkdocs-material +mike