From 4b3e31f40d0e3dcfac695a67677098d8ac2b2bdc Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 21 Jun 2023 10:55:18 +0200 Subject: [PATCH] docs: initial V2 documenatation added --- .github/workflows/documentation.yml | 88 +-- CMakeLists.txt | 5 +- README.md | 10 +- cmake/FindSphinx.cmake | 7 - cmake/documentation.cmake | 123 ---- conanfile.py | 6 - docs/.overrides/main.html | 8 + docs/CHANGELOG.md | 241 ------- docs/CMakeLists.txt | 261 ------- docs/Doxyfile.in | 93 --- docs/_static/css/custom.css | 20 - docs/_static/img/concepts.svg | 116 ---- docs/_static/img/dimensions.svg | 35 - docs/_static/img/downcast_1.png | Bin 10416 -> 0 bytes docs/_static/img/downcast_2.png | Bin 33103 -> 0 bytes docs/_static/img/quantity_like.svg | 37 - docs/_static/img/units.svg | 158 ----- docs/appendix/glossary.md | 0 docs/appendix/release_notes.md | 1 + docs/conf.py | 139 ---- docs/defining_systems.rst | 9 - docs/defining_systems/angular_units.rst | 175 ----- docs/defining_systems/isq.rst | 48 -- docs/defining_systems/si.rst | 231 ------- docs/design.rst | 17 - docs/design/directories.rst | 64 -- docs/design/downcasting.rst | 161 ----- docs/design/quantity.rst | 62 -- docs/design/quantity_kind.rst | 52 -- docs/examples.rst | 11 - docs/examples/basics.rst | 18 - docs/examples/basics/avg_speed.rst | 7 - docs/examples/basics/box_example.rst | 7 - docs/examples/basics/capacitor_time_curve.rst | 7 - docs/examples/basics/clcpp_response.rst | 7 - docs/examples/basics/experimental_angle.rst | 7 - docs/examples/basics/foot_pound_second.rst | 7 - docs/examples/basics/glide_computer.rst | 81 --- docs/examples/basics/hello_units.rst | 7 - docs/examples/basics/total_energy.rst | 7 - docs/examples/basics/unknown_dimension.rst | 7 - docs/examples/custom_representation.rst | 10 - .../custom_representation/linear_algebra.rst | 7 - .../custom_representation/measurement.rst | 7 - docs/examples/custom_systems.rst | 9 - .../custom_systems/custom_systems.rst | 7 - docs/examples/custom_utilities.rst | 9 - .../custom_utilities/conversion_factor.rst | 7 - docs/examples/kalman_filter.rst | 17 - docs/examples/kalman_filter/example_1.rst | 9 - docs/examples/kalman_filter/example_2.rst | 9 - docs/examples/kalman_filter/example_3.rst | 9 - docs/examples/kalman_filter/example_4.rst | 9 - docs/examples/kalman_filter/example_5.rst | 9 - docs/examples/kalman_filter/example_6.rst | 9 - docs/examples/kalman_filter/example_7.rst | 9 - docs/examples/kalman_filter/example_8.rst | 9 - docs/examples/kalman_filter/kalman.rst | 7 - docs/faq.rst | 131 ---- docs/framework.rst | 25 - docs/framework/arithmetics.rst | 148 ---- docs/framework/basic_concepts.rst | 117 ---- docs/framework/constants.rst | 33 - docs/framework/conversions_and_casting.rst | 190 ------ docs/framework/dimensions.rst | 206 ------ docs/framework/magnitudes.rst | 121 ---- docs/framework/quantities.rst | 643 ------------------ docs/framework/quantity_kinds.rst | 77 --- docs/framework/quantity_like.rst | 51 -- docs/framework/quantity_points.rst | 52 -- docs/framework/text_output.rst | 224 ------ docs/framework/units.rst | 453 ------------ docs/genindex.rst | 4 - docs/getting_started/code_example.md | 83 +++ docs/getting_started/faq.md | 176 +++++ .../getting_started/installation_and_usage.md | 449 ++++++++++++ docs/getting_started/introduction.md | 50 ++ docs/getting_started/quick_start.md | 76 +++ docs/glossary.rst | 222 ------ docs/index.md | 32 + docs/index.rst | 62 -- docs/introduction.rst | 71 -- docs/library_reference/core_library.md | 7 + docs/quick_start.rst | 88 --- docs/reference/core.rst | 12 - docs/reference/core/concepts.rst | 169 ----- docs/reference/core/customization_points.rst | 13 - docs/reference/core/downcasting.rst | 20 - docs/reference/core/metafunctions.rst | 4 - docs/reference/core/types.rst | 16 - docs/reference/core/types/dimensions.rst | 11 - docs/reference/core/types/kinds.rst | 8 - docs/reference/core/types/prefixes.rst | 5 - docs/reference/core/types/quantity.rst | 6 - docs/reference/core/types/quantity_kind.rst | 6 - docs/reference/core/types/quantity_point.rst | 6 - .../core/types/quantity_point_kind.rst | 6 - docs/reference/core/types/reference.rst | 6 - docs/reference/core/types/units.rst | 26 - docs/reference/core/types/utilities.rst | 9 - .../types/utilities/basic_fixed_string.rst | 6 - .../types/utilities/basic_symbol_text.rst | 6 - docs/reference/core/types/utilities/ratio.rst | 6 - docs/reference/random.rst | 40 -- docs/reference/systems.rst | 12 - docs/reference/systems/generic.rst | 10 - docs/reference/systems/generic/angle.rst | 13 - .../systems/generic/dimensionless.rst | 10 - .../reference/systems/generic/solid_angle.rst | 8 - docs/reference/systems/generic/unknown.rst | 6 - docs/reference/systems/isq.rst | 26 - .../systems/isq/dimensions_and_concepts.rst | 47 -- docs/reference/systems/isq/iec80000.rst | 11 - .../systems/isq/iec80000/binary_prefixes.rst | 4 - .../systems/isq/iec80000/modulation_rate.rst | 4 - .../systems/isq/iec80000/storage_capacity.rst | 4 - .../isq/iec80000/traffic_intensity.rst | 4 - .../systems/isq/iec80000/transfer_rate.rst | 4 - docs/reference/systems/isq/natural.rst | 16 - .../systems/isq/natural/acceleration.rst | 4 - .../systems/isq/natural/constants.rst | 4 - docs/reference/systems/isq/natural/energy.rst | 4 - docs/reference/systems/isq/natural/force.rst | 4 - docs/reference/systems/isq/natural/length.rst | 4 - docs/reference/systems/isq/natural/mass.rst | 4 - .../systems/isq/natural/momentum.rst | 4 - docs/reference/systems/isq/natural/speed.rst | 4 - docs/reference/systems/isq/natural/time.rst | 4 - docs/reference/systems/isq/natural/units.rst | 4 - docs/reference/systems/isq/si.rst | 48 -- .../systems/isq/si/absorbed_dose.rst | 4 - .../reference/systems/isq/si/acceleration.rst | 4 - .../systems/isq/si/amount_of_substance.rst | 4 - docs/reference/systems/isq/si/area.rst | 4 - docs/reference/systems/isq/si/capacitance.rst | 4 - .../systems/isq/si/catalytic_activity.rst | 4 - .../systems/isq/si/cgs/acceleration.rst | 4 - docs/reference/systems/isq/si/cgs/area.rst | 4 - docs/reference/systems/isq/si/cgs/energy.rst | 4 - docs/reference/systems/isq/si/cgs/force.rst | 4 - docs/reference/systems/isq/si/cgs/length.rst | 4 - docs/reference/systems/isq/si/cgs/mass.rst | 4 - docs/reference/systems/isq/si/cgs/power.rst | 4 - .../reference/systems/isq/si/cgs/pressure.rst | 4 - docs/reference/systems/isq/si/cgs/speed.rst | 4 - docs/reference/systems/isq/si/cgs/time.rst | 4 - .../systems/isq/si/charge_density.rst | 4 - .../systems/isq/si/concentration.rst | 4 - docs/reference/systems/isq/si/conductance.rst | 4 - docs/reference/systems/isq/si/constants.rst | 4 - .../systems/isq/si/current_density.rst | 4 - docs/reference/systems/isq/si/density.rst | 4 - .../systems/isq/si/dynamic_viscosity.rst | 4 - .../systems/isq/si/electric_charge.rst | 4 - .../systems/isq/si/electric_current.rst | 4 - .../isq/si/electric_field_strength.rst | 4 - docs/reference/systems/isq/si/energy.rst | 4 - docs/reference/systems/isq/si/force.rst | 4 - .../systems/isq/si/fps/acceleration.rst | 4 - docs/reference/systems/isq/si/fps/area.rst | 4 - docs/reference/systems/isq/si/fps/density.rst | 4 - docs/reference/systems/isq/si/fps/energy.rst | 4 - docs/reference/systems/isq/si/fps/force.rst | 4 - docs/reference/systems/isq/si/fps/length.rst | 4 - docs/reference/systems/isq/si/fps/mass.rst | 4 - docs/reference/systems/isq/si/fps/power.rst | 4 - .../reference/systems/isq/si/fps/pressure.rst | 4 - docs/reference/systems/isq/si/fps/speed.rst | 4 - docs/reference/systems/isq/si/fps/time.rst | 4 - docs/reference/systems/isq/si/fps/volume.rst | 4 - docs/reference/systems/isq/si/frequency.rst | 4 - .../systems/isq/si/heat_capacity.rst | 4 - docs/reference/systems/isq/si/hep/area.rst | 4 - docs/reference/systems/isq/si/hep/energy.rst | 4 - docs/reference/systems/isq/si/hep/mass.rst | 4 - .../reference/systems/isq/si/hep/momentum.rst | 4 - docs/reference/systems/isq/si/iau/length.rst | 4 - .../systems/isq/si/imperial/length.rst | 4 - docs/reference/systems/isq/si/inductance.rst | 4 - .../systems/isq/si/international/area.rst | 4 - .../systems/isq/si/international/length.rst | 4 - .../systems/isq/si/international/speed.rst | 4 - .../systems/isq/si/international/volume.rst | 4 - docs/reference/systems/isq/si/length.rst | 4 - docs/reference/systems/isq/si/luminance.rst | 4 - .../systems/isq/si/luminous_intensity.rst | 4 - .../systems/isq/si/magnetic_flux.rst | 4 - .../systems/isq/si/magnetic_induction.rst | 4 - docs/reference/systems/isq/si/mass.rst | 4 - .../reference/systems/isq/si/molar_energy.rst | 4 - docs/reference/systems/isq/si/momentum.rst | 4 - .../reference/systems/isq/si/permeability.rst | 4 - .../reference/systems/isq/si/permittivity.rst | 4 - docs/reference/systems/isq/si/power.rst | 4 - docs/reference/systems/isq/si/prefixes.rst | 4 - docs/reference/systems/isq/si/pressure.rst | 4 - docs/reference/systems/isq/si/resistance.rst | 4 - docs/reference/systems/isq/si/speed.rst | 4 - .../systems/isq/si/surface_tension.rst | 4 - .../systems/isq/si/thermal_conductivity.rst | 4 - .../isq/si/thermodynamic_temperature.rst | 4 - docs/reference/systems/isq/si/time.rst | 4 - .../systems/isq/si/typographic/length.rst | 4 - docs/reference/systems/isq/si/uscs/length.rst | 4 - .../systems/isq/si/uscs/pressure.rst | 4 - docs/reference/systems/isq/si/voltage.rst | 4 - docs/reference/systems/isq/si/volume.rst | 4 - docs/reference/systems/isq/si_cgs.rst | 16 - docs/reference/systems/isq/si_fps.rst | 18 - docs/reference/systems/isq/si_hep.rst | 10 - docs/reference/systems/isq/si_iau.rst | 7 - docs/reference/systems/isq/si_imperial.rst | 7 - .../systems/isq/si_international.rst | 10 - docs/reference/systems/isq/si_typographic.rst | 7 - docs/reference/systems/isq/si_uscs.rst | 8 - docs/references.rst | 6 - docs/requirements.txt | 4 - docs/usage.rst | 496 -------------- docs/use_cases.rst | 20 - .../use_cases/custom_representation_types.rst | 308 --------- docs/use_cases/extensions.rst | 307 --------- docs/use_cases/interoperability.rst | 125 ---- docs/use_cases/legacy_interfaces.rst | 55 -- docs/use_cases/linear_algebra.rst | 88 --- docs/use_cases/natural_units.rst | 11 - docs/use_cases/unknown_dimensions.rst | 118 ---- docs/users_guide/basic_concepts.md | 0 .../simple_and_typed_quantities.md | 407 +++++++++++ docs/users_guide/systems_of_quantities.md | 0 docs/users_guide/systems_of_units.md | 0 docs/users_guide/terms_and_definitions.md | 9 + docs/users_guide/value_conversions.md | 70 ++ docs_disabled/reference/core/functions.rst | 4 - docs_disabled/reference/math.rst | 10 - mkdocs.yml | 100 +++ requirements.txt | 2 + 236 files changed, 1495 insertions(+), 7967 deletions(-) delete mode 100644 cmake/FindSphinx.cmake delete mode 100644 cmake/documentation.cmake create mode 100644 docs/.overrides/main.html delete mode 100644 docs/CHANGELOG.md delete mode 100644 docs/CMakeLists.txt delete mode 100644 docs/Doxyfile.in delete mode 100644 docs/_static/css/custom.css delete mode 100644 docs/_static/img/concepts.svg delete mode 100644 docs/_static/img/dimensions.svg delete mode 100644 docs/_static/img/downcast_1.png delete mode 100644 docs/_static/img/downcast_2.png delete mode 100644 docs/_static/img/quantity_like.svg delete mode 100644 docs/_static/img/units.svg create mode 100644 docs/appendix/glossary.md create mode 120000 docs/appendix/release_notes.md delete mode 100644 docs/conf.py delete mode 100644 docs/defining_systems.rst delete mode 100644 docs/defining_systems/angular_units.rst delete mode 100644 docs/defining_systems/isq.rst delete mode 100644 docs/defining_systems/si.rst delete mode 100644 docs/design.rst delete mode 100644 docs/design/directories.rst delete mode 100644 docs/design/downcasting.rst delete mode 100644 docs/design/quantity.rst delete mode 100644 docs/design/quantity_kind.rst delete mode 100644 docs/examples.rst delete mode 100644 docs/examples/basics.rst delete mode 100644 docs/examples/basics/avg_speed.rst delete mode 100644 docs/examples/basics/box_example.rst delete mode 100644 docs/examples/basics/capacitor_time_curve.rst delete mode 100644 docs/examples/basics/clcpp_response.rst delete mode 100644 docs/examples/basics/experimental_angle.rst delete mode 100644 docs/examples/basics/foot_pound_second.rst delete mode 100644 docs/examples/basics/glide_computer.rst delete mode 100644 docs/examples/basics/hello_units.rst delete mode 100644 docs/examples/basics/total_energy.rst delete mode 100644 docs/examples/basics/unknown_dimension.rst delete mode 100644 docs/examples/custom_representation.rst delete mode 100644 docs/examples/custom_representation/linear_algebra.rst delete mode 100644 docs/examples/custom_representation/measurement.rst delete mode 100644 docs/examples/custom_systems.rst delete mode 100644 docs/examples/custom_systems/custom_systems.rst delete mode 100644 docs/examples/custom_utilities.rst delete mode 100644 docs/examples/custom_utilities/conversion_factor.rst delete mode 100644 docs/examples/kalman_filter.rst delete mode 100644 docs/examples/kalman_filter/example_1.rst delete mode 100644 docs/examples/kalman_filter/example_2.rst delete mode 100644 docs/examples/kalman_filter/example_3.rst delete mode 100644 docs/examples/kalman_filter/example_4.rst delete mode 100644 docs/examples/kalman_filter/example_5.rst delete mode 100644 docs/examples/kalman_filter/example_6.rst delete mode 100644 docs/examples/kalman_filter/example_7.rst delete mode 100644 docs/examples/kalman_filter/example_8.rst delete mode 100644 docs/examples/kalman_filter/kalman.rst delete mode 100644 docs/faq.rst delete mode 100644 docs/framework.rst delete mode 100644 docs/framework/arithmetics.rst delete mode 100644 docs/framework/basic_concepts.rst delete mode 100644 docs/framework/constants.rst delete mode 100644 docs/framework/conversions_and_casting.rst delete mode 100644 docs/framework/dimensions.rst delete mode 100644 docs/framework/magnitudes.rst delete mode 100644 docs/framework/quantities.rst delete mode 100644 docs/framework/quantity_kinds.rst delete mode 100644 docs/framework/quantity_like.rst delete mode 100644 docs/framework/quantity_points.rst delete mode 100644 docs/framework/text_output.rst delete mode 100644 docs/framework/units.rst delete mode 100644 docs/genindex.rst create mode 100644 docs/getting_started/code_example.md create mode 100644 docs/getting_started/faq.md create mode 100644 docs/getting_started/installation_and_usage.md create mode 100644 docs/getting_started/introduction.md create mode 100644 docs/getting_started/quick_start.md delete mode 100644 docs/glossary.rst create mode 100644 docs/index.md delete mode 100644 docs/index.rst delete mode 100644 docs/introduction.rst create mode 100644 docs/library_reference/core_library.md delete mode 100644 docs/quick_start.rst delete mode 100644 docs/reference/core.rst delete mode 100644 docs/reference/core/concepts.rst delete mode 100644 docs/reference/core/customization_points.rst delete mode 100644 docs/reference/core/downcasting.rst delete mode 100644 docs/reference/core/metafunctions.rst delete mode 100644 docs/reference/core/types.rst delete mode 100644 docs/reference/core/types/dimensions.rst delete mode 100644 docs/reference/core/types/kinds.rst delete mode 100644 docs/reference/core/types/prefixes.rst delete mode 100644 docs/reference/core/types/quantity.rst delete mode 100644 docs/reference/core/types/quantity_kind.rst delete mode 100644 docs/reference/core/types/quantity_point.rst delete mode 100644 docs/reference/core/types/quantity_point_kind.rst delete mode 100644 docs/reference/core/types/reference.rst delete mode 100644 docs/reference/core/types/units.rst delete mode 100644 docs/reference/core/types/utilities.rst delete mode 100644 docs/reference/core/types/utilities/basic_fixed_string.rst delete mode 100644 docs/reference/core/types/utilities/basic_symbol_text.rst delete mode 100644 docs/reference/core/types/utilities/ratio.rst delete mode 100644 docs/reference/random.rst delete mode 100644 docs/reference/systems.rst delete mode 100644 docs/reference/systems/generic.rst delete mode 100644 docs/reference/systems/generic/angle.rst delete mode 100644 docs/reference/systems/generic/dimensionless.rst delete mode 100644 docs/reference/systems/generic/solid_angle.rst delete mode 100644 docs/reference/systems/generic/unknown.rst delete mode 100644 docs/reference/systems/isq.rst delete mode 100644 docs/reference/systems/isq/dimensions_and_concepts.rst delete mode 100644 docs/reference/systems/isq/iec80000.rst delete mode 100644 docs/reference/systems/isq/iec80000/binary_prefixes.rst delete mode 100644 docs/reference/systems/isq/iec80000/modulation_rate.rst delete mode 100644 docs/reference/systems/isq/iec80000/storage_capacity.rst delete mode 100644 docs/reference/systems/isq/iec80000/traffic_intensity.rst delete mode 100644 docs/reference/systems/isq/iec80000/transfer_rate.rst delete mode 100644 docs/reference/systems/isq/natural.rst delete mode 100644 docs/reference/systems/isq/natural/acceleration.rst delete mode 100644 docs/reference/systems/isq/natural/constants.rst delete mode 100644 docs/reference/systems/isq/natural/energy.rst delete mode 100644 docs/reference/systems/isq/natural/force.rst delete mode 100644 docs/reference/systems/isq/natural/length.rst delete mode 100644 docs/reference/systems/isq/natural/mass.rst delete mode 100644 docs/reference/systems/isq/natural/momentum.rst delete mode 100644 docs/reference/systems/isq/natural/speed.rst delete mode 100644 docs/reference/systems/isq/natural/time.rst delete mode 100644 docs/reference/systems/isq/natural/units.rst delete mode 100644 docs/reference/systems/isq/si.rst delete mode 100644 docs/reference/systems/isq/si/absorbed_dose.rst delete mode 100644 docs/reference/systems/isq/si/acceleration.rst delete mode 100644 docs/reference/systems/isq/si/amount_of_substance.rst delete mode 100644 docs/reference/systems/isq/si/area.rst delete mode 100644 docs/reference/systems/isq/si/capacitance.rst delete mode 100644 docs/reference/systems/isq/si/catalytic_activity.rst delete mode 100644 docs/reference/systems/isq/si/cgs/acceleration.rst delete mode 100644 docs/reference/systems/isq/si/cgs/area.rst delete mode 100644 docs/reference/systems/isq/si/cgs/energy.rst delete mode 100644 docs/reference/systems/isq/si/cgs/force.rst delete mode 100644 docs/reference/systems/isq/si/cgs/length.rst delete mode 100644 docs/reference/systems/isq/si/cgs/mass.rst delete mode 100644 docs/reference/systems/isq/si/cgs/power.rst delete mode 100644 docs/reference/systems/isq/si/cgs/pressure.rst delete mode 100644 docs/reference/systems/isq/si/cgs/speed.rst delete mode 100644 docs/reference/systems/isq/si/cgs/time.rst delete mode 100644 docs/reference/systems/isq/si/charge_density.rst delete mode 100644 docs/reference/systems/isq/si/concentration.rst delete mode 100644 docs/reference/systems/isq/si/conductance.rst delete mode 100644 docs/reference/systems/isq/si/constants.rst delete mode 100644 docs/reference/systems/isq/si/current_density.rst delete mode 100644 docs/reference/systems/isq/si/density.rst delete mode 100644 docs/reference/systems/isq/si/dynamic_viscosity.rst delete mode 100644 docs/reference/systems/isq/si/electric_charge.rst delete mode 100644 docs/reference/systems/isq/si/electric_current.rst delete mode 100644 docs/reference/systems/isq/si/electric_field_strength.rst delete mode 100644 docs/reference/systems/isq/si/energy.rst delete mode 100644 docs/reference/systems/isq/si/force.rst delete mode 100644 docs/reference/systems/isq/si/fps/acceleration.rst delete mode 100644 docs/reference/systems/isq/si/fps/area.rst delete mode 100644 docs/reference/systems/isq/si/fps/density.rst delete mode 100644 docs/reference/systems/isq/si/fps/energy.rst delete mode 100644 docs/reference/systems/isq/si/fps/force.rst delete mode 100644 docs/reference/systems/isq/si/fps/length.rst delete mode 100644 docs/reference/systems/isq/si/fps/mass.rst delete mode 100644 docs/reference/systems/isq/si/fps/power.rst delete mode 100644 docs/reference/systems/isq/si/fps/pressure.rst delete mode 100644 docs/reference/systems/isq/si/fps/speed.rst delete mode 100644 docs/reference/systems/isq/si/fps/time.rst delete mode 100644 docs/reference/systems/isq/si/fps/volume.rst delete mode 100644 docs/reference/systems/isq/si/frequency.rst delete mode 100644 docs/reference/systems/isq/si/heat_capacity.rst delete mode 100644 docs/reference/systems/isq/si/hep/area.rst delete mode 100644 docs/reference/systems/isq/si/hep/energy.rst delete mode 100644 docs/reference/systems/isq/si/hep/mass.rst delete mode 100644 docs/reference/systems/isq/si/hep/momentum.rst delete mode 100644 docs/reference/systems/isq/si/iau/length.rst delete mode 100644 docs/reference/systems/isq/si/imperial/length.rst delete mode 100644 docs/reference/systems/isq/si/inductance.rst delete mode 100644 docs/reference/systems/isq/si/international/area.rst delete mode 100644 docs/reference/systems/isq/si/international/length.rst delete mode 100644 docs/reference/systems/isq/si/international/speed.rst delete mode 100644 docs/reference/systems/isq/si/international/volume.rst delete mode 100644 docs/reference/systems/isq/si/length.rst delete mode 100644 docs/reference/systems/isq/si/luminance.rst delete mode 100644 docs/reference/systems/isq/si/luminous_intensity.rst delete mode 100644 docs/reference/systems/isq/si/magnetic_flux.rst delete mode 100644 docs/reference/systems/isq/si/magnetic_induction.rst delete mode 100644 docs/reference/systems/isq/si/mass.rst delete mode 100644 docs/reference/systems/isq/si/molar_energy.rst delete mode 100644 docs/reference/systems/isq/si/momentum.rst delete mode 100644 docs/reference/systems/isq/si/permeability.rst delete mode 100644 docs/reference/systems/isq/si/permittivity.rst delete mode 100644 docs/reference/systems/isq/si/power.rst delete mode 100644 docs/reference/systems/isq/si/prefixes.rst delete mode 100644 docs/reference/systems/isq/si/pressure.rst delete mode 100644 docs/reference/systems/isq/si/resistance.rst delete mode 100644 docs/reference/systems/isq/si/speed.rst delete mode 100644 docs/reference/systems/isq/si/surface_tension.rst delete mode 100644 docs/reference/systems/isq/si/thermal_conductivity.rst delete mode 100644 docs/reference/systems/isq/si/thermodynamic_temperature.rst delete mode 100644 docs/reference/systems/isq/si/time.rst delete mode 100644 docs/reference/systems/isq/si/typographic/length.rst delete mode 100644 docs/reference/systems/isq/si/uscs/length.rst delete mode 100644 docs/reference/systems/isq/si/uscs/pressure.rst delete mode 100644 docs/reference/systems/isq/si/voltage.rst delete mode 100644 docs/reference/systems/isq/si/volume.rst delete mode 100644 docs/reference/systems/isq/si_cgs.rst delete mode 100644 docs/reference/systems/isq/si_fps.rst delete mode 100644 docs/reference/systems/isq/si_hep.rst delete mode 100644 docs/reference/systems/isq/si_iau.rst delete mode 100644 docs/reference/systems/isq/si_imperial.rst delete mode 100644 docs/reference/systems/isq/si_international.rst delete mode 100644 docs/reference/systems/isq/si_typographic.rst delete mode 100644 docs/reference/systems/isq/si_uscs.rst delete mode 100644 docs/references.rst delete mode 100644 docs/requirements.txt delete mode 100644 docs/usage.rst delete mode 100644 docs/use_cases.rst delete mode 100644 docs/use_cases/custom_representation_types.rst delete mode 100644 docs/use_cases/extensions.rst delete mode 100644 docs/use_cases/interoperability.rst delete mode 100644 docs/use_cases/legacy_interfaces.rst delete mode 100644 docs/use_cases/linear_algebra.rst delete mode 100644 docs/use_cases/natural_units.rst delete mode 100644 docs/use_cases/unknown_dimensions.rst create mode 100644 docs/users_guide/basic_concepts.md create mode 100644 docs/users_guide/simple_and_typed_quantities.md create mode 100644 docs/users_guide/systems_of_quantities.md create mode 100644 docs/users_guide/systems_of_units.md create mode 100644 docs/users_guide/terms_and_definitions.md create mode 100644 docs/users_guide/value_conversions.md delete mode 100644 docs_disabled/reference/core/functions.rst delete mode 100644 docs_disabled/reference/math.rst create mode 100644 mkdocs.yml 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 203d90397b3ee4896dcbe7f5dae47b8364614f8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10416 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 Iol`;+08|+EIRF3v diff --git a/docs/_static/img/downcast_2.png b/docs/_static/img/downcast_2.png deleted file mode 100644 index 94729025f831438fce7aee9da36f2d1922094951..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33103 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 DiTRY6 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