diff --git a/.clang-format b/.clang-format index 09c47d6f..4938ef9b 100644 --- a/.clang-format +++ b/.clang-format @@ -132,8 +132,11 @@ IncludeCategories: # InsertTrailingCommas: None # IntegerLiteralSeparator: # Binary: 0 +# BinaryMinDigits: 0 # Decimal: 0 +# DecimalMinDigits: 0 # Hex: 0 +# HexMinDigits: 0 # JavaScriptQuotes: Leave # JavaScriptWrapImports: true # KeepEmptyLinesAtTheStartOfBlocks: false diff --git a/.github/workflows/ci-conan.yml b/.github/workflows/ci-conan.yml index 93cca9f9..051e206b 100644 --- a/.github/workflows/ci-conan.yml +++ b/.github/workflows/ci-conan.yml @@ -35,7 +35,7 @@ env: jobs: build: - name: ${{ matrix.config.name }} ${{ matrix.build_type }} [downcast=${{ matrix.downcast_mode }}] + name: ${{ matrix.config.name }} ${{ matrix.build_type }} runs-on: ${{ matrix.config.os }} strategy: fail-fast: false @@ -190,7 +190,6 @@ jobs: conan-config: "", } build_type: ["Release", "Debug"] - downcast_mode: ["on", "auto"] env: CC: ${{ matrix.config.compiler.cc }} @@ -214,7 +213,7 @@ jobs: - uses: hendrikmuhs/ccache-action@v1.2 if: runner.os == 'Linux' with: - key: ${{ matrix.config.os }}-${{ matrix.config.compiler.type }}-${{ matrix.config.compiler.version }}-${{ matrix.config.lib }}-${{ matrix.build_type }}-${{ matrix.downcast_mode }} + key: ${{ matrix.config.os }}-${{ matrix.config.compiler.type }}-${{ matrix.config.compiler.version }}-${{ matrix.config.lib }}-${{ matrix.build_type }} max-size: 50M - name: Install gcc-12 if: matrix.config.compiler.type == 'GCC' && matrix.config.compiler.version == '12' @@ -282,7 +281,7 @@ jobs: run: | conan create . --user mpusz --channel ${CHANNEL} --lockfile-out=package.lock \ -b mp-units/* -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" \ - -o downcast_mode=${{ matrix.downcast_mode }} -c user.build:all=True -c user.build:skip_docs=True ${{ matrix.config.conan-config }} + -c user.build:all=True -c user.build:skip_docs=True ${{ matrix.config.conan-config }} - name: Obtain package reference id: get-package-ref shell: bash diff --git a/.gitpod.yml b/.gitpod.yml index 96ac0471..e4ae10f7 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -36,8 +36,7 @@ vscode: - vivaxy.vscode-conventional-commits - hbenl.vscode-test-explorer - matepek.vscode-catch2-test-adapter - - trond-snekvik.simple-rst - - lextudio.restructuredtext + - redhat.vscode-yaml - ritwickdey.liveserver - ms-python.python @@ -60,7 +59,17 @@ tasks: "restructuredtext.preview.scrollPreviewWithEditor": false, "liveServer.settings.root": "/build/docs/docs/sphinx/", "esbonio.sphinx.confDir": "${workspaceFolder}/docs", - "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "yaml.schemas": { + "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" + }, + "yaml.customTags": [ + "!ENV scalar", + "!ENV sequence", + "tag:yaml.org,2002:python/name:materialx.emoji.to_svg", + "tag:yaml.org,2002:python/name:materialx.emoji.twemoji", + "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format" + ] } EOF diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cc9f58eb..be9b717a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v16.0.0 + rev: v16.0.4 hooks: - id: clang-format - repo: https://github.com/cheshirekow/cmake-format-precommit diff --git a/CMakeLists.txt b/CMakeLists.txt index f0ca1045..f9ffe517 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,9 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") set(projectPrefix UNITS_) +option(${projectPrefix}BUILD_LA "Build code depending on the linear algebra library" ON) +message(STATUS "${projectPrefix}BUILD_LA: ${${projectPrefix}BUILD_LA}") + # make sure that the file is being used as an entry point include(modern_project_structure) ensure_entry_point() @@ -44,6 +47,7 @@ add_compile_definitions($<$:gsl_CONFIG_CONTRACT_CHECKING_AUDIT>) # enable include-what-you-use option(${projectPrefix}IWYU "Enables include-what-you-use" OFF) + if(${projectPrefix}IWYU) include(include-what-you-use) enable_iwyu( @@ -52,12 +56,13 @@ if(${projectPrefix}IWYU) MAX_LINE_LENGTH 120 NO_COMMENTS ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(${projectPrefix}AS_SYSTEM_HEADERS ON) endif() endif() -#enable_clang_tidy() +# enable_clang_tidy() # add project code add_subdirectory(src) @@ -66,10 +71,11 @@ add_subdirectory(src) add_subdirectory(example) # generate project documentation -add_subdirectory(docs) +# add_subdirectory(docs) # add unit tests enable_testing() + add_subdirectory(test) # tests for standalone headers diff --git a/cmake/TestHeaders.cmake b/cmake/TestHeaders.cmake index 6ec30990..154e4fd5 100644 --- a/cmake/TestHeaders.cmake +++ b/cmake/TestHeaders.cmake @@ -115,6 +115,7 @@ function(add_header_test target) set(source "${CMAKE_CURRENT_BINARY_DIR}/headers/${directory}/${filename}.cpp") if(NOT EXISTS "${source}") file(WRITE "${source}" "#include <${header}>") + file(APPEND "${source}" "\n#include <${header}>") # do it twice to ensure that header guards are provided endif() list(APPEND sources "${source}") endforeach() diff --git a/conanfile.py b/conanfile.py index 4f539fdf..67799033 100644 --- a/conanfile.py +++ b/conanfile.py @@ -54,8 +54,6 @@ class MPUnitsConan(ConanFile): license = "MIT" url = "https://github.com/mpusz/units" settings = "os", "arch", "compiler", "build_type" - options = {"downcast_mode": ["off", "on", "auto"]} - default_options = {"downcast_mode": "on"} exports = ["LICENSE.md"] exports_sources = [ "docs/*", @@ -86,7 +84,7 @@ class MPUnitsConan(ConanFile): @property def _skip_docs(self): - return bool(self.conf.get("user.build:skip_docs", default=False)) + return bool(self.conf.get("user.build:skip_docs", default=True)) @property def _use_libfmt(self): @@ -117,7 +115,7 @@ class MPUnitsConan(ConanFile): def build_requirements(self): if self._build_all: - self.test_requires("catch2/3.1.0") + 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: @@ -144,7 +142,6 @@ class MPUnitsConan(ConanFile): def generate(self): tc = CMakeToolchain(self) - tc.variables["UNITS_DOWNCAST_MODE"] = str(self.options.downcast_mode).upper() tc.variables["UNITS_BUILD_LA"] = self._build_all and not self._skip_la tc.variables["UNITS_BUILD_DOCS"] = self._build_all and not self._skip_docs tc.variables["UNITS_USE_LIBFMT"] = self._use_libfmt @@ -188,29 +185,32 @@ class MPUnitsConan(ConanFile): self.cpp_info.components["core-fmt"].requires = ["core"] if self._use_libfmt: self.cpp_info.components["core-fmt"].requires.append("fmt::fmt") + self.cpp_info.components["utility"].requires = ["core", "isq", "si", "angular"] self.cpp_info.components["isq"].requires = ["core"] - self.cpp_info.components["isq-natural"].requires = ["isq"] + self.cpp_info.components["angular"].requires = ["isq"] + self.cpp_info.components["isq_angular"].requires = ["isq", "angular"] + self.cpp_info.components["natural"].requires = ["isq"] self.cpp_info.components["si"].requires = ["isq"] - self.cpp_info.components["si-cgs"].requires = ["si"] - self.cpp_info.components["si-fps"].requires = ["si-international"] - self.cpp_info.components["si-hep"].requires = ["si"] - self.cpp_info.components["si-iau"].requires = ["si"] - self.cpp_info.components["si-imperial"].requires = ["si"] - self.cpp_info.components["si-international"].requires = ["si"] - self.cpp_info.components["si-typographic"].requires = ["si"] - self.cpp_info.components["si-uscs"].requires = ["si"] - self.cpp_info.components["isq-iec80000"].requires = ["si"] + self.cpp_info.components["cgs"].requires = ["si"] + self.cpp_info.components["hep"].requires = ["si"] + self.cpp_info.components["iau"].requires = ["si"] + self.cpp_info.components["imperial"].requires = ["si"] + self.cpp_info.components["international"].requires = ["si"] + self.cpp_info.components["typographic"].requires = ["usc"] + self.cpp_info.components["usc"].requires = ["international"] + self.cpp_info.components["iec80000"].requires = ["isq", "si"] self.cpp_info.components["systems"].requires = [ "isq", - "isq-natural", + "angular", + "isq_angular", + "natural", "si", - "si-cgs", - "si-fps", - "si-hep", - "si-iau", - "si-imperial", - "si-international", - "si-typographic", - "si-uscs", - "isq-iec80000", + "cgs", + "hep", + "iau", + "imperial", + "international", + "typographic", + "usc", + "iec80000", ] diff --git a/docs/design/quantity.rst b/docs/design/quantity.rst index 8c6b6fd5..47f65096 100644 --- a/docs/design/quantity.rst +++ b/docs/design/quantity.rst @@ -6,6 +6,11 @@ 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 diff --git a/docs/framework/dimensions.rst b/docs/framework/dimensions.rst index ff8e0051..1e1c298d 100644 --- a/docs/framework/dimensions.rst +++ b/docs/framework/dimensions.rst @@ -139,3 +139,68 @@ In order to obtain the base/coherent unit of any dimension type a 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/units.rst b/docs/framework/units.rst index 6a0b418a..226fb24d 100644 --- a/docs/framework/units.rst +++ b/docs/framework/units.rst @@ -436,3 +436,18 @@ class template:: 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_disabled/reference/math.rst b/docs_disabled/reference/math.rst index b3f30d09..5620120e 100644 --- a/docs_disabled/reference/math.rst +++ b/docs_disabled/reference/math.rst @@ -1,10 +1,10 @@ Math ==== -.. doxygenfunction:: units::pow +.. doxygenfunction:: mp_units::pow -.. doxygenfunction:: units::sqrt +.. doxygenfunction:: mp_units::sqrt -.. doxygenfunction:: units::abs +.. doxygenfunction:: mp_units::abs -.. doxygenfunction:: units::epsilon +.. doxygenfunction:: mp_units::epsilon diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 6733348b..5741fc67 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -33,17 +33,40 @@ function(add_example target) target_link_libraries(${target} PRIVATE ${ARGN}) endfunction() +add_example(avg_speed mp-units::core-io mp-units::si mp-units::cgs mp-units::usc) +add_example(capacitor_time_curve mp-units::core-io mp-units::si mp-units::utility) +add_example( + clcpp_response + mp-units::core-fmt + mp-units::core-io + mp-units::si + mp-units::iau + mp-units::imperial + mp-units::international + mp-units::typographic + mp-units::usc +) add_example(conversion_factor mp-units::core-fmt mp-units::core-io mp-units::si) -add_example(custom_systems mp-units::core-io mp-units::si) -add_example(hello_units mp-units::core-fmt mp-units::core-io mp-units::si mp-units::si-international) +add_example(currency mp-units::core-io) +add_example(foot_pound_second mp-units::core-fmt mp-units::international mp-units::imperial) +add_example(glide_computer mp-units::core-fmt mp-units::international mp-units::utility glide_computer_lib) +add_example(hello_units mp-units::core-fmt mp-units::core-io mp-units::si mp-units::usc) add_example(measurement mp-units::core-io mp-units::si) add_example(si_constants mp-units::core-fmt mp-units::si) +add_example(storage_tank mp-units::core-fmt mp-units::si) +add_example( + strong_angular_quantities mp-units::core-fmt mp-units::core-io mp-units::si mp-units::isq_angle mp-units::utility +) +add_example(total_energy mp-units::core-io mp-units::si mp-units::natural mp-units::utility) +add_example( + unmanned_aerial_vehicle + mp-units::core-fmt + mp-units::core-io + mp-units::si + mp-units::international + mp-units::utility + example_utils +) -if(NOT ${projectPrefix}LIBCXX) - add_subdirectory(glide_computer) -endif() - -add_subdirectory(aliases) +add_subdirectory(glide_computer) add_subdirectory(kalman_filter) -add_subdirectory(literals) -add_subdirectory(references) diff --git a/example/aliases/CMakeLists.txt b/example/aliases/CMakeLists.txt deleted file mode 100644 index 1d40e9c5..00000000 --- a/example/aliases/CMakeLists.txt +++ /dev/null @@ -1,65 +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) - -# -# add_example(target ...) -# -function(add_example target) - add_executable(${target}-aliases ${target}.cpp) - target_link_libraries(${target}-aliases PRIVATE ${ARGN}) - target_compile_definitions(${target}-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES) -endfunction() - -add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international) -add_example(box_example mp-units::core-fmt mp-units::si) -add_example(capacitor_time_curve mp-units::core-io mp-units::si) -add_example( - clcpp_response - mp-units::core-fmt - mp-units::core-io - mp-units::si - mp-units::si-iau - mp-units::si-imperial - mp-units::si-international - mp-units::si-typographic - mp-units::si-uscs -) -add_example(experimental_angle mp-units::core-fmt mp-units::core-io mp-units::si) -add_example(foot_pound_second mp-units::core-fmt mp-units::si-fps) -add_example(measurement mp-units::core-io mp-units::si) -add_example(total_energy mp-units::core-io mp-units::si mp-units::isq-natural) -add_example(unknown_dimension mp-units::core-io mp-units::si) - -if(NOT ${projectPrefix}LIBCXX) - add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer) - target_compile_definitions( - glide_computer_example-aliases PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_REFERENCES - ) - - if(${projectPrefix}BUILD_LA) - find_package(wg21_linear_algebra CONFIG REQUIRED) - add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) - target_link_libraries(linear_algebra-aliases PRIVATE wg21_linear_algebra::wg21_linear_algebra) - endif() -endif() diff --git a/example/aliases/avg_speed.cpp b/example/aliases/avg_speed.cpp deleted file mode 100644 index d09b2571..00000000 --- a/example/aliases/avg_speed.cpp +++ /dev/null @@ -1,192 +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. - -#include -#include // IWYU pragma: keep -#include -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include -#include -#include -#include -#include - -namespace { - -using namespace units::isq; - -constexpr si::speed fixed_int_si_avg_speed(si::length d, - si::time t) -{ - return d / t; -} - -constexpr si::speed fixed_double_si_avg_speed(si::length d, si::time t) -{ - return d / t; -} - -template -constexpr Speed auto si_avg_speed(si::length d, si::time t) -{ - return d / t; -} - -constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } - -template -void print_result(D distance, T duration, V speed) -{ - const auto result_in_kmph = units::quantity_cast>(speed); - std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph - << ".\n"; -} - -void example() -{ - // SI (int) - { - using namespace units::aliases::isq::si; - constexpr auto distance = km(220); - constexpr auto duration = h(2); - - std::cout << "SI units with 'int' as representation\n"; - - print_result(distance, duration, fixed_int_si_avg_speed(distance, duration)); - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // SI (double) - { - using namespace units::aliases::isq::si; - constexpr auto distance = km(220.); - constexpr auto duration = h(2.); - - std::cout << "\nSI units with 'double' as representation\n"; - - // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - print_result(distance, duration, - fixed_int_si_avg_speed(quantity_cast(distance), quantity_cast(duration))); - - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // Customary Units (int) - { - using namespace units::aliases::isq::si::international; - using namespace units::aliases::isq::si; - constexpr auto distance = mi(140); - constexpr auto duration = h(2); - - std::cout << "\nUS Customary Units with 'int' as representation\n"; - - // it is not possible to make a lossless conversion of miles to meters on an integral type - // (explicit cast needed) - print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast(distance), duration)); - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // Customary Units (double) - { - using namespace units::aliases::isq::si::international; - using namespace units::aliases::isq::si; - constexpr auto distance = mi(140.); - constexpr auto duration = h(2.); - - std::cout << "\nUS Customary Units with 'double' as representation\n"; - - // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - // also it is not possible to make a lossless conversion of miles to meters on an integral type - // (explicit cast needed) - print_result( - distance, duration, - fixed_int_si_avg_speed(quantity_cast>(distance), quantity_cast(duration))); - - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // CGS (int) - { - using namespace units::aliases::isq::si::cgs; - using namespace units::aliases::isq::si::time; - constexpr auto distance = cm(22'000'000); - constexpr auto duration = h(2); - - std::cout << "\nCGS units with 'int' as representation\n"; - - // it is not possible to make a lossless conversion of centimeters to meters on an integral type - // (explicit cast needed) - print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast(distance), duration)); - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - - // not possible to convert both a dimension and a unit with implicit cast - print_result(distance, duration, si_avg_speed(quantity_cast(distance), duration)); - - print_result(distance, duration, avg_speed(distance, duration)); - } - - // CGS (double) - { - using namespace units::aliases::isq::si::cgs; - using namespace units::aliases::isq::si::time; - constexpr auto distance = cm(22'000'000.); - constexpr auto duration = h(2.); - - std::cout << "\nCGS units with 'double' as representation\n"; - - // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - // it is not possible to make a lossless conversion of centimeters to meters on an integral type - // (explicit cast needed) - print_result( - distance, duration, - fixed_int_si_avg_speed(quantity_cast>(distance), quantity_cast(duration))); - - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - - // not possible to convert both a dimension and a unit with implicit cast - print_result(distance, duration, si_avg_speed(quantity_cast(distance), duration)); - - print_result(distance, duration, avg_speed(distance, duration)); - } -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/aliases/box_example.cpp b/example/aliases/box_example.cpp deleted file mode 100644 index 11e56330..00000000 --- a/example/aliases/box_example.cpp +++ /dev/null @@ -1,108 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include -#include - -namespace { - -using namespace units::aliases::isq::si; - -inline constexpr auto g = units::isq::si::standard_gravity<>; // NOLINT(readability-identifier-length) -inline constexpr auto air_density = kg_per_m3<>(1.225); - -class Box { - area::m2<> base_; - length::m<> height_; - density::kg_per_m3<> density_ = air_density; -public: - constexpr Box(const length::m<>& length, const length::m<>& width, length::m<> height) : - base_(length * width), height_(std::move(height)) - { - } - - [[nodiscard]] constexpr force::N<> filled_weight() const - { - const volume::m3<> volume = base_ * height_; - const mass::kg<> mass = density_ * volume; - return mass * g; - } - - [[nodiscard]] constexpr length::m<> fill_level(const mass::kg<>& measured_mass) const - { - return height_ * measured_mass * g / filled_weight(); - } - - [[nodiscard]] constexpr volume::m3<> spare_capacity(const mass::kg<>& measured_mass) const - { - return (height_ - fill_level(measured_mass)) * base_; - } - - constexpr void set_contents_density(const density::kg_per_m3<>& density_in) - { - assert(density_in > air_density); - density_ = density_in; - } -}; - -} // namespace - - -int main() -{ - using namespace units; - using namespace units::isq; - - const length::m<> height(mm<>(200.0)); - auto box = Box(mm<>(1000.0), mm<>(500.0), height); - box.set_contents_density(kg_per_m3<>(1000.0)); - - const auto fill_time = s<>(200.0); // time since starting fill - const auto measured_mass = kg<>(20.0); // measured mass at fill_time - - const Length auto fill_level = box.fill_level(measured_mass); - const Dimensionless auto fill_percent = quantity_cast(fill_level / height); - const Volume auto spare_capacity = box.spare_capacity(measured_mass); - const auto input_flow_rate = measured_mass / fill_time; // unknown dimension - const Speed auto float_rise_rate = fill_level / fill_time; - const Time auto fill_time_left = (height / fill_level - 1) * fill_time; - - std::cout << "mp-units box example...\n"; - std::cout << UNITS_STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent); - std::cout << UNITS_STD_FMT::format("spare_capacity at {} = {}\n", fill_time, spare_capacity); - std::cout << UNITS_STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate); - std::cout << UNITS_STD_FMT::format("float rise rate = {}\n", float_rise_rate); - std::cout << UNITS_STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left); -} diff --git a/example/aliases/capacitor_time_curve.cpp b/example/aliases/capacitor_time_curve.cpp deleted file mode 100644 index ab20cf78..00000000 --- a/example/aliases/capacitor_time_curve.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (c) 2003-2020 Andy Little. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses./ -*/ - -/* - capacitor discharge curve using compile_time - physical_quantities -*/ - -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include - -int main() -{ - using namespace units::isq; - using namespace units::aliases::isq::si; - - std::cout << "mp-units capacitor time curve example...\n"; - std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield); - std::cout.precision(3); - - constexpr auto C = capacitance::uF<>(0.47); - constexpr auto V0 = voltage::V<>(5.0); - constexpr auto R = resistance::kR<>(4.7); - - for (auto t = ms(0); t <= ms(50); ++t) { - const Voltage auto Vt = V0 * units::exp(-t / (R * C)); - - std::cout << "at " << t << " voltage is "; - - if (Vt >= V<>(1)) - std::cout << Vt; - else if (Vt >= mV<>(1)) - std::cout << mV<>(Vt); - else if (Vt >= uV<>(1)) - std::cout << uV<>(Vt); - else if (Vt >= nV<>(1)) - std::cout << nV<>(Vt); - else - std::cout << pV<>(Vt); - std::cout << "\n"; - } -} diff --git a/example/aliases/clcpp_response.cpp b/example/aliases/clcpp_response.cpp deleted file mode 100644 index 4bfde79f..00000000 --- a/example/aliases/clcpp_response.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - Copyright (c) 2003-2019 Andy Little. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses./ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -using namespace units; - -void simple_quantities() -{ - using namespace units::aliases::isq; - using namespace units::aliases::isq::si; - using namespace units::aliases::isq::si::international; - - using distance = si::length::m<>; - using duration = time::s<>; - - constexpr distance km = si::length::km<>(1.0); - constexpr distance miles = mi<>(1.0); - - constexpr duration sec = s<>(1); - constexpr duration min = time::min<>(1); - constexpr duration hr = h<>(1); - - std::cout << "A physical quantities library can choose the simple\n"; - std::cout << "option to provide output using a single type for each base unit:\n\n"; - std::cout << km << '\n'; - std::cout << miles << '\n'; - std::cout << sec << '\n'; - std::cout << min << '\n'; - std::cout << hr << "\n\n"; -} - -void quantities_with_typed_units() -{ - using namespace units::aliases::isq; - using namespace units::aliases::isq::si; - using namespace units::aliases::isq::si::international; - - constexpr si::length::km<> km = si::km<>(1.0); - constexpr si::international::length::mi<> miles = mi<>(1.0); - - std::cout.precision(6); - - constexpr time::s<> sec = s<>(1); - constexpr time::min<> min = si::min<>(1); - constexpr time::h<> hr = h<>(1); - - std::cout << "A more flexible option is to provide separate types for each unit,\n\n"; - std::cout << km << '\n'; - std::cout << miles << '\n'; - std::cout << sec << '\n'; - std::cout << min << '\n'; - std::cout << hr << "\n\n"; - - constexpr si::length::m<> meter = m<>(1); - std::cout << "then a wide range of pre-defined units can be defined and converted,\n" - " for consistency and repeatability across applications:\n\n"; - - std::cout << meter << '\n'; - - std::cout << " = " << au<>(meter) << '\n'; - std::cout << " = " << iau::angstrom<>(meter) << '\n'; - std::cout << " = " << imperial::ch<>(meter) << '\n'; - std::cout << " = " << international::fathom<>(meter) << '\n'; - std::cout << " = " << uscs::fathom<>(meter) << '\n'; - std::cout << " = " << international::ft<>(meter) << '\n'; - std::cout << " = " << uscs::ft<>(meter) << '\n'; - std::cout << " = " << international::in<>(meter) << '\n'; - std::cout << " = " << iau::ly<>(meter) << '\n'; - std::cout << " = " << international::mi<>(meter) << '\n'; - std::cout << " = " << international::mi_naut<>(meter) << '\n'; - std::cout << " = " << iau::pc<>(meter) << '\n'; - std::cout << " = " << typographic::pica_comp<>(meter) << '\n'; - std::cout << " = " << typographic::pica_prn<>(meter) << '\n'; - std::cout << " = " << typographic::point_comp<>(meter) << '\n'; - std::cout << " = " << typographic::point_prn<>(meter) << '\n'; - std::cout << " = " << imperial::rd<>(meter) << '\n'; - std::cout << " = " << international::yd<>(meter) << '\n'; -} - -void calcs_comparison() -{ - using namespace units::aliases::isq::si; - - std::cout << "\nA distinct unit for each type is efficient and accurate\n" - "when adding two values of the same very big\n" - "or very small type:\n\n"; - - length::fm L1A = fm<>(2.f); - length::fm L2A = fm<>(3.f); - length::fm LrA = L1A + L2A; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA); - - std::cout << "The single unit method must convert large\n" - "or small values in other units to the base unit.\n" - "This is both inefficient and inaccurate\n\n"; - - length::m L1B = L1A; - length::m L2B = L2A; - length::m LrB = L1B + L2B; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, LrB); - - std::cout << "In multiplication and division:\n\n"; - - area::fm2 ArA = L1A * L2A; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA); - - std::cout << "similar problems arise\n\n"; - - area::m2 ArB = L1B * L2B; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, ArB); -} - -} // namespace - -int main() -{ - std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n"; - std::cout << "http://compgroups.net/comp.lang.c++.moderated/dimensional-analysis-units/51712\n"; - std::cout << "Here converted to use mp-units library.\n\n"; - - simple_quantities(); - quantities_with_typed_units(); - calcs_comparison(); -} diff --git a/example/aliases/experimental_angle.cpp b/example/aliases/experimental_angle.cpp deleted file mode 100644 index 15ab817c..00000000 --- a/example/aliases/experimental_angle.cpp +++ /dev/null @@ -1,45 +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. - -#include -#include -#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"; -} diff --git a/example/aliases/foot_pound_second.cpp b/example/aliases/foot_pound_second.cpp deleted file mode 100644 index 81a1e584..00000000 --- a/example/aliases/foot_pound_second.cpp +++ /dev/null @@ -1,129 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace units::aliases::isq; - -// Some basic specs for the warship -struct Ship { - si::fps::length::ft<> length; - si::fps::length::ft<> draft; - si::fps::length::ft<> beam; - - si::fps::speed::ft_per_s<> speed; - si::fps::mass::lb<> mass; - - si::fps::length::in<> mainGuns; - si::fps::mass::lb<> shellMass; - si::fps::speed::ft_per_s<> shellSpeed; - si::fps::power::ft_pdl_per_s<> power; -}; - -// Print 'a' in its current units and print its value cast to the units in each of Args -template -auto fmt_line(const Q a) -{ - return UNITS_STD_FMT::format("{:22}", a) + (UNITS_STD_FMT::format(",{:20}", units::quantity_cast(a)) + ...); -} - -// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI -void print_details(std::string_view description, const Ship& ship) -{ - const auto waterDensity = si::fps::density::lb_per_ft3<>(62.4); - std::cout << UNITS_STD_FMT::format("{}\n", description); - std::cout - << UNITS_STD_FMT::format("{:20} : {}\n", "length", fmt_line, si::length::m<>>(ship.length)) - << UNITS_STD_FMT::format("{:20} : {}\n", "draft", fmt_line, si::length::m<>>(ship.draft)) - << UNITS_STD_FMT::format("{:20} : {}\n", "beam", fmt_line, si::length::m<>>(ship.beam)) - << UNITS_STD_FMT::format("{:20} : {}\n", "mass", fmt_line, si::mass::t<>>(ship.mass)) - << UNITS_STD_FMT::format("{:20} : {}\n", "speed", - fmt_line, si::speed::km_per_h<>>(ship.speed)) - << UNITS_STD_FMT::format("{:20} : {}\n", "power", fmt_line, si::power::kW<>>(ship.power)) - << UNITS_STD_FMT::format("{:20} : {}\n", "main guns", - fmt_line, si::length::mm<>>(ship.mainGuns)) - << UNITS_STD_FMT::format("{:20} : {}\n", "fire shells weighing", - fmt_line, si::mass::kg<>>(ship.shellMass)) - << UNITS_STD_FMT::format("{:20} : {}\n", "fire shells at", - fmt_line, si::speed::km_per_h<>>(ship.shellSpeed)) - << UNITS_STD_FMT::format("{:20} : {}\n", "volume underwater", - fmt_line, si::volume::l<>>(ship.mass / waterDensity)); -} - -int main() -{ - using namespace units::aliases::isq::si; - using namespace units::aliases::isq::si::fps; - using units::aliases::isq::si::fps::length::ft; // to disambiguate from si::femptotonne - - // KMS Bismark, using the units the Germans would use, taken from Wiki - auto bismark = Ship{.length{m<>(251.)}, - .draft{m<>(9.3)}, - .beam{m<>(36)}, - .speed{km_per_h<>(56)}, - .mass{t<>(50'300)}, - .mainGuns{mm<>(380)}, - .shellMass{kg<>(800)}, - .shellSpeed{m_per_s<>(820.)}, - .power{kW<>(110.45)}}; - - // USS Iowa, using units from the foot-pound-second system - auto iowa = Ship{.length{ft<>(860.)}, - .draft{ft<>(37.) + in<>(2.)}, - .beam{ft<>(108.) + in<>(2.)}, - .speed{international::kn<>(33)}, - .mass{lton<>(57'540)}, - .mainGuns{in<>(16)}, - .shellMass{lb<>(2700)}, - .shellSpeed{ft_per_s<>(2690.)}, - .power{hp<>(212'000)}}; - - // HMS King George V, using units from the foot-pound-second system - auto kgv = Ship{.length{ft<>(745.1)}, - .draft{ft<>(33.) + in<>(7.5)}, - .beam{ft<>(103.2) + in<>(2.5)}, - .speed{international::kn<>(28.3)}, - .mass{lton<>(42'245)}, - .mainGuns{in<>(14)}, - .shellMass{lb<>(1'590)}, - .shellSpeed{ft_per_s<>(2483)}, - .power{hp<>(110'000)}}; - - print_details("KMS Bismark, defined in appropriate units from the SI system", bismark); - std::cout << "\n\n"; - print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa); - std::cout << "\n\n"; - print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv); -} diff --git a/example/aliases/linear_algebra.cpp b/example/aliases/linear_algebra.cpp deleted file mode 100644 index fcd8c622..00000000 --- a/example/aliases/linear_algebra.cpp +++ /dev/null @@ -1,232 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include // IWYU pragma: keep -#include -#include -#include - -template -using vector = STD_LA::fixed_size_column_vector; - -template -using matrix = STD_LA::fixed_size_matrix; - -namespace STD_LA { - -template -std::ostream& operator<<(std::ostream& os, const ::vector& v) -{ - os << "|"; - for (auto i = 0U; i < v.size(); ++i) { - os << UNITS_STD_FMT::format(" {:>9}", v(i)); - } - os << " |"; - return os; -} - -template -std::ostream& operator<<(std::ostream& os, const ::matrix& v) -{ - for (auto i = 0U; i < v.rows(); ++i) { - os << "|"; - for (auto j = 0U; j < v.columns(); ++j) { - os << UNITS_STD_FMT::format(" {:>9}", v(i, j)); - } - os << (i != v.rows() - 1U ? " |\n" : " |"); - } - return os; -} - -} // namespace STD_LA - -namespace { - -using namespace units::aliases::isq::si; - -void vector_of_quantity_add() -{ - std::cout << "\nvector_of_quantity_add:\n"; - - vector> v = {m<>(4), m<>(8), m<>(12)}; - vector> u = {m<>(3), m<>(2), m<>(1)}; - vector> t = {km<>(3), km<>(2), km<>(1)}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - std::cout << "t = " << t << "\n"; - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << vector>(t) << "\n"; -} - -void vector_of_quantity_divide_by_scalar() -{ - std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; - - vector> v = {m<>(4), m<>(8), m<>(12)}; - - std::cout << "v = " << v << "\n"; - - std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; - std::cout << "v / 2 = " << v / 2 << "\n"; -} - -void vector_of_quantity_tests() -{ - vector_of_quantity_add(); - vector_of_quantity_divide_by_scalar(); -} - -void matrix_of_quantity_add() -{ - std::cout << "\nmatrix_of_quantity_add:\n"; - - matrix> v = {{m<>(1), m<>(2), m<>(3)}, {m<>(4), m<>(5), m<>(6)}, {m<>(7), m<>(8), m<>(9)}}; - matrix> u = {{m<>(3), m<>(2), m<>(1)}, {m<>(3), m<>(2), m<>(1)}, {m<>(3), m<>(2), m<>(1)}}; - matrix> t = {{mm<>(3), mm<>(2), mm<>(1)}, {mm<>(3), mm<>(2), mm<>(1)}, {mm<>(3), mm<>(2), mm<>(1)}}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - std::cout << "t =\n" << t << "\n"; - - std::cout << "v + u =\n" << v + u << "\n"; - std::cout << "v + t =\n" << v + t << "\n"; - - std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void matrix_of_quantity_divide_by_scalar() -{ - std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n"; - - matrix> v = {{m<>(2), m<>(4), m<>(6)}, {m<>(4), m<>(6), m<>(8)}, {m<>(8), m<>(4), m<>(2)}}; - - std::cout << "v =\n" << v << "\n"; - - std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; - std::cout << "v / 2 =\n" << v / 2 << "\n"; -} - -void matrix_of_quantity_tests() -{ - matrix_of_quantity_add(); - matrix_of_quantity_divide_by_scalar(); -} - -using namespace units::isq; - -template -using length_v = si::length>; - -template -using force_v = si::force>; - -void quantity_of_vector_add() -{ - std::cout << "\nquantity_of_vector_add:\n"; - - length_v<> v(vector<>{4, 8, 12}); - length_v<> u(vector<>{3, 2, 1}); - length_v t(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - std::cout << "t = " << t << "\n"; - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << quantity_cast(t) << "\n"; -} - -void quantity_of_vector_divide_by_scalar() -{ - std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; - - length_v<> v(vector<>{4, 8, 12}); - - std::cout << "v = " << v << "\n"; - - std::cout << "v / s<>(2) = " << v / s<>(2) << "\n"; - std::cout << "v / 2 = " << v / 2 << "\n"; -} - -void quantity_of_vector_tests() -{ - quantity_of_vector_add(); - quantity_of_vector_divide_by_scalar(); -} - -template -using length_m = si::length>; - -void quantity_of_matrix_add() -{ - std::cout << "\nquantity_of_matrix_add:\n"; - - length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}}); - length_m t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - std::cout << "t =\n" << t << "\n"; - - std::cout << "v + u =\n" << v + u << "\n"; - std::cout << "v + t =\n" << v + t << "\n"; - - // TODO Fix it - // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void quantity_of_matrix_divide_by_scalar() -{ - std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; - - length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}}); - - std::cout << "v =\n" << v << "\n"; - - std::cout << "v / s<>(2) =\n" << v / s<>(2) << "\n"; - std::cout << "v / 2 =\n" << v / 2 << "\n"; -} - -void quantity_of_matrix_tests() -{ - quantity_of_matrix_add(); - quantity_of_matrix_divide_by_scalar(); -} - -} // namespace - -int main() -{ - vector_of_quantity_tests(); - matrix_of_quantity_tests(); - quantity_of_vector_tests(); - quantity_of_matrix_tests(); -} diff --git a/example/aliases/measurement.cpp b/example/aliases/measurement.cpp deleted file mode 100644 index c952387b..00000000 --- a/example/aliases/measurement.cpp +++ /dev/null @@ -1,156 +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. - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -template -class measurement { -public: - using value_type = T; - - measurement() = default; - - constexpr explicit measurement(const value_type& val, const value_type& err = {}) : value_(val) - { - // it sucks that using declaration cannot be provided for a constructor initializer list - using namespace std; - uncertainty_ = abs(err); - } - - constexpr const value_type& value() const { return value_; } - constexpr const value_type& uncertainty() const { return uncertainty_; } - - constexpr value_type relative_uncertainty() const { return uncertainty() / value(); } - constexpr value_type lower_bound() const { return value() - uncertainty(); } - constexpr value_type upper_bound() const { return value() + uncertainty(); } - - [[nodiscard]] constexpr measurement operator-() const { return measurement(-value(), uncertainty()); } - - [[nodiscard]] friend constexpr measurement operator+(const measurement& lhs, const measurement& rhs) - { - using namespace std; - return measurement(lhs.value() + rhs.value(), hypot(lhs.uncertainty(), rhs.uncertainty())); - } - - [[nodiscard]] friend constexpr measurement operator-(const measurement& lhs, const measurement& rhs) - { - using namespace std; - return measurement(lhs.value() - rhs.value(), hypot(lhs.uncertainty(), rhs.uncertainty())); - } - - [[nodiscard]] friend constexpr measurement operator*(const measurement& lhs, const measurement& rhs) - { - const auto val = lhs.value() * rhs.value(); - using namespace std; - return measurement(val, val * hypot(lhs.relative_uncertainty(), rhs.relative_uncertainty())); - } - - [[nodiscard]] friend constexpr measurement operator*(const measurement& lhs, const value_type& value) - { - const auto val = lhs.value() * value; - return measurement(val, val * lhs.relative_uncertainty()); - } - - [[nodiscard]] friend constexpr measurement operator*(const value_type& value, const measurement& rhs) - { - const auto val = rhs.value() * value; - return measurement(val, val * rhs.relative_uncertainty()); - } - - [[nodiscard]] friend constexpr measurement operator/(const measurement& lhs, const measurement& rhs) - { - const auto val = lhs.value() / rhs.value(); - using namespace std; - return measurement(val, val * hypot(lhs.relative_uncertainty(), rhs.relative_uncertainty())); - } - - [[nodiscard]] friend constexpr measurement operator/(const measurement& lhs, const value_type& value) - { - const auto val = lhs.value() / value; - return measurement(val, val * lhs.relative_uncertainty()); - } - - [[nodiscard]] friend constexpr measurement operator/(const value_type& value, const measurement& rhs) - { - const auto val = value / rhs.value(); - return measurement(val, val * rhs.relative_uncertainty()); - } - - [[nodiscard]] constexpr auto operator<=>(const measurement&) const = default; - - friend std::ostream& operator<<(std::ostream& os, const measurement& v) - { - return os << v.value() << " ± " << v.uncertainty(); - } - -private: - value_type value_{}; - value_type uncertainty_{}; -}; - -} // namespace - - -namespace { - -static_assert(units::Representation>); - -void example() -{ - using namespace units::isq; - using namespace units::aliases::isq::si; - - const auto a = acceleration::m_per_s2>(measurement(9.8, 0.1)); - const auto t = time::s>(measurement(1.2, 0.1)); - - const Speed auto v1 = a * t; -#if UNITS_DOWNCAST_MODE == 0 - std::cout << a << " * " << t << " = " << v1 << " = " << km_per_h>(v1) << '\n'; -#else - std::cout << a << " * " << t << " = " << v1 << " = " << km_per_h>(v1) << '\n'; -#endif - - length::m> length(measurement(123., 1.)); - std::cout << "10 * " << length << " = " << 10 * length << '\n'; -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/aliases/total_energy.cpp b/example/aliases/total_energy.cpp deleted file mode 100644 index 0ad4c132..00000000 --- a/example/aliases/total_energy.cpp +++ /dev/null @@ -1,100 +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. - -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -namespace { - -using namespace units::isq; - -Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c) -{ - return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c))); -} - -void si_example() -{ - using namespace units::aliases::isq::si; - - constexpr Speed auto c = units::isq::si::si2019::speed_of_light<>; - - std::cout << "\n*** SI units (c = " << c << ") ***\n"; - - const Momentum auto p = GeV<>(4.) / c; - const Mass auto m = GeV<>(3.) / pow<2>(c); - const Energy auto E = total_energy(p, m, c); - - std::cout << "[in GeV]\n" - << "p = " << p << "\n" - << "m = " << m << "\n" - << "E = " << E << "\n"; - - const momentum::kg_m_per_s<> p_si = p; - const mass::kg<> m_si = m; - const energy::J<> E_si = total_energy(p_si, m_si, c); - - std::cout << "\n[in SI units]\n" - << "p = " << p_si << "\n" - << "m = " << m_si << "\n" - << "E = " << E_si << "\n"; - - std::cout << "\n[converted from SI units back to GeV]\n" - << "E = " << GeV<>(E_si) << "\n"; -} - -void natural_example() -{ - using namespace units::aliases::isq::natural; - - constexpr Speed auto c = units::isq::natural::speed_of_light<>; - const momentum::GeV<> p(4); - const mass::GeV<> m(3); - const Energy auto E = total_energy(p, m, c); - - std::cout << "\n*** Natural units (c = " << c << ") ***\n" - << "p = " << p << "\n" - << "m = " << m << "\n" - << "E = " << E << "\n"; -} - -} // namespace - -int main() -{ - try { - si_example(); - natural_example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/aliases/unknown_dimension.cpp b/example/aliases/unknown_dimension.cpp deleted file mode 100644 index 5256abe8..00000000 --- a/example/aliases/unknown_dimension.cpp +++ /dev/null @@ -1,71 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -namespace { - -template -constexpr units::isq::Speed auto avg_speed(D d, T t) -{ - return d / t; -} - -void example() -{ - using namespace units::isq; - using namespace units::aliases::isq::si; - - Length auto d1 = m<>(123); - Time auto t1 = s<>(10); - Speed auto v1 = avg_speed(d1, t1); - - auto temp1 = - v1 * m<>(50); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit' - Speed auto v2 = temp1 / m<>(100); // back to known dimensions again - Length auto d2 = v2 * s<>(60); - - std::cout << "d1 = " << d1 << '\n'; - std::cout << "t1 = " << t1 << '\n'; - std::cout << "v1 = " << v1 << '\n'; - std::cout << "temp1 = " << temp1 << '\n'; - std::cout << "v2 = " << v2 << '\n'; - std::cout << "d2 = " << d2 << '\n'; -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/references/avg_speed.cpp b/example/avg_speed.cpp similarity index 60% rename from example/references/avg_speed.cpp rename to example/avg_speed.cpp index 3c9cecca..1dd64dda 100644 --- a/example/references/avg_speed.cpp +++ b/example/avg_speed.cpp @@ -20,53 +20,49 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include // IWYU pragma: keep -#include -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include -#include -#include +#include +#include +#include +#include +#include #include #include namespace { -using namespace units::isq; +using namespace mp_units; -constexpr si::speed fixed_int_si_avg_speed(si::length d, - si::time t) +constexpr quantity fixed_int_si_avg_speed(quantity d, + quantity t) { return d / t; } -constexpr si::speed fixed_double_si_avg_speed(si::length d, si::time t) +constexpr quantity fixed_double_si_avg_speed(quantity d, quantity t) { return d / t; } -template -constexpr Speed auto si_avg_speed(si::length d, si::time t) +constexpr QuantityOf auto avg_speed(QuantityOf auto d, QuantityOf auto t) { return d / t; } -constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } - -template +template D, QuantityOf T, QuantityOf V> void print_result(D distance, T duration, V speed) { - const auto result_in_kmph = units::quantity_cast>(speed); + using namespace mp_units::si::unit_symbols; + const auto result_in_kmph = value_cast(speed); std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph << ".\n"; } void example() { + using namespace mp_units::si::unit_symbols; + // SI (int) { - using namespace units::isq::si::references; constexpr auto distance = 220 * km; constexpr auto duration = 2 * h; @@ -74,31 +70,26 @@ void example() print_result(distance, duration, fixed_int_si_avg_speed(distance, duration)); print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); print_result(distance, duration, avg_speed(distance, duration)); } // SI (double) { - using namespace units::isq::si::references; constexpr auto distance = 220. * km; constexpr auto duration = 2. * h; std::cout << "\nSI units with 'double' as representation\n"; // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - print_result(distance, duration, - fixed_int_si_avg_speed(quantity_cast(distance), quantity_cast(duration))); - + print_result(distance, duration, fixed_int_si_avg_speed(value_cast(distance), value_cast(duration))); print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); print_result(distance, duration, avg_speed(distance, duration)); } // Customary Units (int) { - using namespace units::isq::si::time_references; - using namespace units::isq::si::international::length_references; + using namespace mp_units::international::unit_symbols; + constexpr auto distance = 140 * mi; constexpr auto duration = 2 * h; @@ -106,16 +97,15 @@ void example() // it is not possible to make a lossless conversion of miles to meters on an integral type // (explicit cast needed) - print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast(distance), duration)); + print_result(distance, duration, fixed_int_si_avg_speed(value_cast(distance), duration)); print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); print_result(distance, duration, avg_speed(distance, duration)); } // Customary Units (double) { - using namespace units::isq::si::time_references; - using namespace units::isq::si::international::length_references; + using namespace mp_units::international::unit_symbols; + constexpr auto distance = 140. * mi; constexpr auto duration = 2. * h; @@ -124,56 +114,40 @@ void example() // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed // also it is not possible to make a lossless conversion of miles to meters on an integral type // (explicit cast needed) - print_result( - distance, duration, - fixed_int_si_avg_speed(quantity_cast>(distance), quantity_cast(duration))); - + print_result(distance, duration, + fixed_int_si_avg_speed(value_cast(value_cast(distance)), value_cast(duration))); print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); print_result(distance, duration, avg_speed(distance, duration)); } // CGS (int) { - using namespace units::isq::si::time_references; - using namespace units::isq::si::cgs::length_references; - constexpr auto distance = 22'000'000 * cm; - constexpr auto duration = 2 * h; + constexpr auto distance = 22'000'000 * cgs::centimetre; + constexpr auto duration = 7200 * cgs::second; std::cout << "\nCGS units with 'int' as representation\n"; // it is not possible to make a lossless conversion of centimeters to meters on an integral type // (explicit cast needed) - print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast(distance), duration)); + print_result(distance, duration, fixed_int_si_avg_speed(value_cast(distance), duration)); print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - - // not possible to convert both a dimension and a unit with implicit cast - print_result(distance, duration, si_avg_speed(quantity_cast(distance), duration)); - print_result(distance, duration, avg_speed(distance, duration)); } // CGS (double) { - using namespace units::isq::si::time_references; - using namespace units::isq::si::cgs::length_references; - constexpr auto distance = 22'000'000. * cm; - constexpr auto duration = 2. * h; + constexpr auto distance = 22'000'000. * cgs::centimetre; + constexpr auto duration = 7200. * cgs::second; std::cout << "\nCGS units with 'double' as representation\n"; // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed // it is not possible to make a lossless conversion of centimeters to meters on an integral type // (explicit cast needed) - print_result( - distance, duration, - fixed_int_si_avg_speed(quantity_cast>(distance), quantity_cast(duration))); + print_result(distance, duration, + fixed_int_si_avg_speed(value_cast(value_cast(distance)), value_cast(duration))); print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - - // not possible to convert both a dimension and a unit with implicit cast - print_result(distance, duration, si_avg_speed(quantity_cast(distance), duration)); - print_result(distance, duration, avg_speed(distance, duration)); } } diff --git a/example/references/capacitor_time_curve.cpp b/example/capacitor_time_curve.cpp similarity index 54% rename from example/references/capacitor_time_curve.cpp rename to example/capacitor_time_curve.cpp index 45e1c45b..7612f0e6 100644 --- a/example/references/capacitor_time_curve.cpp +++ b/example/capacitor_time_curve.cpp @@ -20,47 +20,42 @@ physical_quantities */ -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include +#include +#include // IWYU pragma: keep +#include +#include #include int main() { - using namespace units::isq; - using namespace units::isq::si::capacitance_references; - using namespace units::isq::si::voltage_references; - using namespace units::isq::si::resistance_references; - using namespace units::isq::si::time_references; + using namespace mp_units; + using namespace mp_units::si::unit_symbols; std::cout << "mp-units capacitor time curve example...\n"; std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield); std::cout.precision(3); - constexpr auto C = 0.47 * uF; - constexpr auto V0 = 5.0 * V; - constexpr auto RR = 4.7 * kR; // cannot use just 'R' here + constexpr auto C = isq::capacitance(0.47 * uF); + constexpr auto V0 = isq::voltage(5.0 * V); + constexpr auto R = isq::resistance(4.7 * si::kilo); for (auto t = 0 * ms; t <= 50 * ms; ++t) { - const Voltage auto Vt = V0 * units::exp(-t / (RR * C)); + const QuantityOf auto Vt = V0 * exp(dimensionless(-t / (R * C))); + // TODO try to make the below work instead + // const QuantityOf auto Vt = V0 * exp(-t / (R * C)); std::cout << "at " << t << " voltage is "; if (Vt >= 1 * V) - std::cout << Vt; + std::cout << Vt[V]; else if (Vt >= 1 * mV) - std::cout << quantity_cast(Vt); + std::cout << Vt[mV]; else if (Vt >= 1 * uV) - std::cout << quantity_cast(Vt); + std::cout << Vt[uV]; else if (Vt >= 1 * nV) - std::cout << quantity_cast(Vt); + std::cout << Vt[nV]; else - std::cout << quantity_cast(Vt); + std::cout << Vt[pV]; std::cout << "\n"; } } diff --git a/example/clcpp_response.cpp b/example/clcpp_response.cpp new file mode 100644 index 00000000..643a7c37 --- /dev/null +++ b/example/clcpp_response.cpp @@ -0,0 +1,149 @@ +/* + Copyright (c) 2003-2019 Andy Little. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses./ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +void simple_quantities() +{ + using namespace mp_units; + using namespace mp_units::si; + using namespace mp_units::international; + + using distance = quantity]>; + using duration = quantity; + + constexpr distance km = 1. * kilo; + constexpr distance miles = 1. * mile; + + constexpr duration sec = 1 * second; + constexpr duration min = 1 * minute; + constexpr duration hr = 1 * hour; + + std::cout << "A physical quantities library can choose the simple\n"; + std::cout << "option to provide output using a single type for each base unit:\n\n"; + std::cout << km << '\n'; + std::cout << miles << '\n'; + std::cout << sec << '\n'; + std::cout << min << '\n'; + std::cout << hr << "\n\n"; +} + +void quantities_with_typed_units() +{ + using namespace mp_units; + using namespace mp_units::si; + using namespace mp_units::international; + + constexpr auto km = 1.0 * kilo; + constexpr auto miles = 1.0 * mile; + + std::cout.precision(6); + + constexpr auto sec = 1 * second; + constexpr auto min = 1 * minute; + constexpr auto hr = 1 * hour; + + std::cout << "A more flexible option is to provide separate types for each unit,\n\n"; + std::cout << km << '\n'; + std::cout << miles << '\n'; + std::cout << sec << '\n'; + std::cout << min << '\n'; + std::cout << hr << "\n\n"; + + constexpr auto meter = 1. * metre; + std::cout << "then a wide range of pre-defined units can be defined and converted,\n" + " for consistency and repeatability across applications:\n\n"; + + std::cout << meter << '\n'; + + std::cout << " = " << meter[astronomical_unit] << '\n'; + std::cout << " = " << meter[iau::angstrom] << '\n'; + std::cout << " = " << meter[imperial::chain] << '\n'; + std::cout << " = " << meter[imperial::fathom] << '\n'; + std::cout << " = " << meter[usc::fathom] << '\n'; + std::cout << " = " << meter[international::foot] << '\n'; + std::cout << " = " << meter[usc::survey1893::us_survey_foot] << '\n'; + std::cout << " = " << meter[international::inch] << '\n'; + std::cout << " = " << meter[iau::light_year] << '\n'; + std::cout << " = " << meter[international::mile] << '\n'; + std::cout << " = " << meter[international::nautical_mile] << '\n'; + std::cout << " = " << meter[iau::parsec] << '\n'; + std::cout << " = " << meter[typographic::pica_dtp] << '\n'; + std::cout << " = " << meter[typographic::pica_us] << '\n'; + std::cout << " = " << meter[typographic::point_dtp] << '\n'; + std::cout << " = " << meter[typographic::point_us] << '\n'; + std::cout << " = " << meter[imperial::rod] << '\n'; + std::cout << " = " << meter[international::yard] << '\n'; +} + +void calcs_comparison() +{ + using namespace mp_units; + using namespace mp_units::si::unit_symbols; + + std::cout << "\nA distinct unit for each type is efficient and accurate\n" + "when adding two values of the same very big\n" + "or very small type:\n\n"; + + const auto L1A = 2.f * fm; + const auto L2A = 3.f * fm; + const auto LrA = L1A + L2A; + std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA); + + std::cout << "The single unit method must convert large\n" + "or small values in other units to the base unit.\n" + "This is both inefficient and inaccurate\n\n"; + + const auto L1B = L1A[m]; + const auto L2B = L2A[m]; + const auto LrB = L1B + L2B; + std::cout << UNITS_STD_FMT::format("{:%.30eQ %q}\n + {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, LrB); + + std::cout << "In multiplication and division:\n\n"; + + const quantity ArA = L1A * L2A; + std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA); + + std::cout << "similar problems arise\n\n"; + + const quantity ArB = L1B * L2B; + std::cout << UNITS_STD_FMT::format("{:%.30eQ %q}\n * {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, ArB); +} + +} // namespace + +int main() +{ + std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n"; + std::cout << "https://groups.google.com/g/comp.lang.c++.moderated/c/upv7hZExtf4/m/XruKUk8LhXYJ\n"; + std::cout << "Here converted to use mp-units library.\n\n"; + + simple_quantities(); + quantities_with_typed_units(); + calcs_comparison(); +} diff --git a/example/conversion_factor.cpp b/example/conversion_factor.cpp index 11980c46..dbb39cab 100644 --- a/example/conversion_factor.cpp +++ b/example/conversion_factor.cpp @@ -15,8 +15,10 @@ along with this program. If not, see http://www.gnu.org/licenses./ */ -#include -#include +#include +#include +#include +#include #include #include @@ -27,27 +29,24 @@ namespace { -template - requires units::equivalent -inline constexpr std::common_type_t conversion_factor(Target, Source) +template + requires std::constructible_from +inline constexpr double conversion_factor(Target, Source) { - // get quantities looking like inputs but with Q::rep that doesn't have narrowing conversion - typedef std::common_type_t rep; - typedef units::quantity source; - typedef units::quantity target; - return target{source{1}}.number(); + return value_cast(1. * Source::reference).number(); } } // namespace int main() { - using namespace units::isq::si; + using namespace mp_units; + using namespace mp_units::si::unit_symbols; std::cout << "conversion factor in mp-units...\n\n"; - constexpr length lengthA(2.0); - constexpr length lengthB = lengthA; + constexpr auto lengthA = 2.0 * m; + constexpr auto lengthB = lengthA[mm]; std::cout << UNITS_STD_FMT::format("lengthA( {} ) and lengthB( {} )\n", lengthA, lengthB) << "represent the same length in different units.\n\n"; diff --git a/example/currency.cpp b/example/currency.cpp new file mode 100644 index 00000000..51d6e386 --- /dev/null +++ b/example/currency.cpp @@ -0,0 +1,91 @@ +// 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. + +#include +#include +#include +#include +#include + +using namespace mp_units; + +// clang-format off +inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency; + +QUANTITY_SPEC(currency, dim_currency); + +inline constexpr struct euro : named_unit<"EUR", kind_of> {} euro; +inline constexpr struct us_dollar : named_unit<"USD", kind_of> {} us_dollar; +inline constexpr struct great_british_pound : named_unit<"GBP", kind_of> {} great_british_pound; +inline constexpr struct japanese_jen : named_unit<"JPY", kind_of> {} japanese_jen; +// clang-format on + +static_assert(!std::equality_comparable_with, quantity>); + +#if 0 + +// if you have only a few currencies to handle +template +[[nodiscard]] double exchange_rate() +{ + if constexpr (From == us_dollar && To == euro) return 0.9215; + else if constexpr (From == euro && To == us_dollar) return 1.0848; + // ... +} + +#else + +[[nodiscard]] std::string_view to_string_view(Unit auto u) { return u.symbol.ascii().c_str(); } + +template +[[nodiscard]] double exchange_rate() +{ + static std::map, double> rates = { + {{"USD", "EUR"}, 0.9215}, {{"EUR", "USD"}, 1.0848}, + // ... + }; + + return rates[std::make_pair(to_string_view(From), to_string_view(To))]; +} + +#endif + +template auto To, ReferenceOf auto From, typename Rep> +quantity exchange_to(quantity q) +{ + return static_cast(exchange_rate() * q.number()) * To; +} + +template auto To, ReferenceOf auto From, auto PO, typename Rep> +quantity_point exchange_to(quantity_point q) +{ + return quantity_point{static_cast(exchange_rate() * q.absolute().number()) * To}; +} + +int main() +{ + auto price_usd = quantity_point{100 * us_dollar}; + auto price_euro = quantity_point{exchange_to(price_usd)}; + + std::cout << price_usd.absolute() << " -> " << price_euro.absolute() << "\n"; + // std::cout << price_usd.absolute() + price_euro.absolute() << "\n"; // does not compile +} diff --git a/example/custom_systems.cpp b/example/custom_systems.cpp deleted file mode 100644 index c708bf0f..00000000 --- a/example/custom_systems.cpp +++ /dev/null @@ -1,117 +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. - -#include -#include -#include -#include -#include -#include -#include - -using namespace units; - -namespace fps { - -struct foot : named_unit {}; -struct yard : named_scaled_unit(), foot> {}; - -struct dim_length : base_dimension<"L", foot> {}; - -template U, Representation Rep = double> -using length = quantity; - -} // namespace fps - -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(), metre> {}; -struct yard : named_scaled_unit(), foot> {}; - -struct dim_length : base_dimension<"L", foot> {}; - -template U, Representation Rep = double> -using length = quantity; - -} // namespace fps -} // namespace si - -template -concept castable_to = Quantity && Unit && requires(Q q) { quantity_cast(q); }; - -void conversions() -{ - // fps::yard is not defined in terms of SI units (or vice-versa) - // so the conversion between FPS and SI is not possible - static_assert(!castable_to, si::kilometre>); - - // si::fps::yard is defined in terms of SI units - // so the conversion between FPS and SI is possible - static_assert(castable_to, si::kilometre>); - constexpr auto si_fps_yard = si::fps::length(1.); - std::cout << quantity_cast(si_fps_yard) << "\n"; -} - -void unknown_dimensions() -{ - constexpr auto fps_yard = fps::length(1.); - constexpr auto fps_area = fps_yard * fps_yard; - std::cout << fps_yard << "\n"; - std::cout << quantity_cast(fps_area) << "\n"; - - 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"; - std::cout << quantity_cast(si_fps_area) << "\n"; -} - -std::ostream& operator<<(std::ostream& os, const ratio& r) { return os << "ratio{" << r.num << ", " << r.den << "}"; } - -template -std::ostream& operator<<(std::ostream& os, const U& u) -{ - using unit_type = std::remove_cvref_t; - return os << as_ratio(unit_type::mag) << " x " << unit_type::reference::symbol.standard(); -} - -void what_is_your_ratio() -{ - std::cout << "fps: " << fps::yard() << "\n"; - std::cout << "si::fps: " << si::fps::yard() << "\n"; -} - -int main() -{ - conversions(); - unknown_dimensions(); - what_is_your_ratio(); -} diff --git a/example/foot_pound_second.cpp b/example/foot_pound_second.cpp new file mode 100644 index 00000000..0c06f4e1 --- /dev/null +++ b/example/foot_pound_second.cpp @@ -0,0 +1,118 @@ +// 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. + +#include +#include +#include +#include +#include +#include +#include + +using namespace mp_units; +using namespace mp_units::international::unit_symbols; +using namespace mp_units::si::unit_symbols; + + +// Some basic specs for the warship +struct Ship { + quantity length; + quantity draft; + quantity beam; + + quantity speed; + quantity mass; + + quantity mainGuns; + quantity shellMass; + quantity shellSpeed; + quantity power; +}; + +// Print 'q' in its current units and print its value cast to the units in each of Us +template +auto fmt_line(const Q& q) +{ + return UNITS_STD_FMT::format("{:22}", q) + (UNITS_STD_FMT::format(",{:20}", value_cast(q)) + ...); +} + +// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI +void print_details(std::string_view description, const Ship& ship) +{ + const auto waterDensity = 62.4 * isq::density[lb / cubic(ft)]; + std::cout << UNITS_STD_FMT::format("{}\n", description); + std::cout << UNITS_STD_FMT::format("{:20} : {}\n", "length", fmt_line(ship.length)) + << UNITS_STD_FMT::format("{:20} : {}\n", "draft", fmt_line(ship.draft)) + << UNITS_STD_FMT::format("{:20} : {}\n", "beam", fmt_line(ship.beam)) + << UNITS_STD_FMT::format("{:20} : {}\n", "mass", fmt_line(ship.mass)) + << UNITS_STD_FMT::format("{:20} : {}\n", "speed", fmt_line(ship.speed)) + << UNITS_STD_FMT::format("{:20} : {}\n", "power", fmt_line(ship.power)) + << UNITS_STD_FMT::format("{:20} : {}\n", "main guns", fmt_line(ship.mainGuns)) + << UNITS_STD_FMT::format("{:20} : {}\n", "fire shells weighing", + fmt_line(ship.shellMass)) + << UNITS_STD_FMT::format("{:20} : {}\n", "fire shells at", fmt_line(ship.shellSpeed)) + << UNITS_STD_FMT::format("{:20} : {}\n", "volume underwater", fmt_line(ship.mass / waterDensity)); +} + +int main() +{ + using mp_units::international::unit_symbols::ft; // collides with si::femto + + // KMS Bismark, using the units the Germans would use, taken from Wiki + auto bismark = Ship{.length{251. * m}, + .draft{9.3 * m}, + .beam{36 * m}, + .speed{56 * (km / h)}, + .mass{50'300 * t}, + .mainGuns{380 * mm}, + .shellMass{800 * kg}, + .shellSpeed{820. * (m / s)}, + .power{110.45 * kW}}; + + // USS Iowa, using units from the foot-pound-second system + auto iowa = Ship{.length{860. * ft}, + .draft{37. * ft + 2. * in}, + .beam{108. * ft + 2. * in}, + .speed{33 * kt}, + .mass{57'540 * imperial::long_ton}, + .mainGuns{16 * in}, + .shellMass{2700 * lb}, + .shellSpeed{2690. * (ft / s)}, + .power{212'000 * hp}}; + + // HMS King George V, using units from the foot-pound-second system + auto kgv = Ship{.length{745.1 * ft}, + .draft{33. * ft + 7.5 * in}, + .beam{103.2 * ft + 2.5 * in}, + .speed{28.3 * kt}, + .mass{42'245 * imperial::long_ton}, + .mainGuns{14 * in}, + .shellMass{1590 * lb}, + .shellSpeed{2483. * (ft / s)}, + .power{110'000 * hp}}; + + print_details("KMS Bismark, defined in appropriate units from the SI system", bismark); + std::cout << "\n\n"; + print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa); + std::cout << "\n\n"; + print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv); +} diff --git a/example/aliases/glide_computer_example.cpp b/example/glide_computer.cpp similarity index 72% rename from example/aliases/glide_computer_example.cpp rename to example/glide_computer.cpp index 75346469..16fc2f5b 100644 --- a/example/aliases/glide_computer_example.cpp +++ b/example/glide_computer.cpp @@ -21,11 +21,11 @@ // SOFTWARE. #include "glide_computer.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include @@ -36,41 +36,39 @@ namespace { +using namespace geographic; using namespace glide_computer; - -using namespace units::isq; +using namespace mp_units; auto get_gliders() { - using namespace units::aliases::isq::si; + using namespace mp_units::si::unit_symbols; UNITS_DIAGNOSTIC_PUSH UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES - static const std::array gliders = { - glider{"SZD-30 Pirat", {velocity(km_per_h<>(83)), rate_of_climb(m_per_s<>(-0.7389))}}, - glider{"SZD-51 Junior", {velocity(km_per_h<>(80)), rate_of_climb(m_per_s<>(-0.6349))}}, - glider{"SZD-48 Jantar Std 3", {velocity(km_per_h<>(110)), rate_of_climb(m_per_s<>(-0.77355))}}, - glider{"SZD-56 Diana", {velocity(km_per_h<>(110)), rate_of_climb(m_per_s<>(-0.63657))}}}; + static const std::array gliders = {glider{"SZD-30 Pirat", {83 * (km / h), -0.7389 * (m / s)}}, + glider{"SZD-51 Junior", {80 * (km / h), -0.6349 * (m / s)}}, + glider{"SZD-48 Jantar Std 3", {110 * (km / h), -0.77355 * (m / s)}}, + glider{"SZD-56 Diana", {110 * (km / h), -0.63657 * (m / s)}}}; UNITS_DIAGNOSTIC_POP return gliders; } auto get_weather_conditions() { - using namespace units::aliases::isq::si; - static const std::array weather_conditions = { - std::pair("Good", weather{height(m<>(1900)), rate_of_climb(m_per_s<>(4.3))}), - std::pair("Medium", weather{height(m<>(1550)), rate_of_climb(m_per_s<>(2.8))}), - std::pair("Bad", weather{height(m<>(850)), rate_of_climb(m_per_s<>(1.8))})}; + using namespace mp_units::si::unit_symbols; + static const std::array weather_conditions = {std::pair{"Good", weather{1900 * m, 4.3 * (m / s)}}, + std::pair{"Medium", weather{1550 * m, 2.8 * (m / s)}}, + std::pair{"Bad", weather{850 * m, 1.8 * (m / s)}}}; return weather_conditions; } auto get_waypoints() { using namespace geographic::literals; - using namespace units::aliases::isq::si::international; + using namespace mp_units::international::unit_symbols; static const std::array waypoints = { - waypoint{"EPPR", {54.24772_N, 18.6745_E}, altitude(ft<>(16))}, // N54°14'51.8" E18°40'28.2" - waypoint{"EPGI", {53.52442_N, 18.84947_E}, altitude(ft<>(115))} // N53°31'27.9" E18°50'58.1" + waypoint{"EPPR", {54.24772_N, 18.6745_E}, msl_altitude{16. * ft}}, // N54°14'51.8" E18°40'28.2" + waypoint{"EPGI", {53.52442_N, 18.84947_E}, msl_altitude{115. * ft}} // N53°31'27.9" E18°50'58.1" }; return waypoints; } @@ -85,9 +83,12 @@ void print(const R& gliders) std::cout << "- Name: " << g.name << "\n"; std::cout << "- Polar:\n"; for (const auto& p : g.polar) { - const auto ratio = units::quantity_cast(glide_ratio(g.polar[0])); + const auto ratio = value_cast(glide_ratio(g.polar[0])); std::cout << UNITS_STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, - ratio, units::quantity_cast(asin(1 / ratio))); + ratio, + // TODO is it possible to make ADL work below (we need another set of trig + // functions for strong angle in a different namespace) + value_cast(isq::asin(1 / ratio))); } std::cout << "\n"; } @@ -126,12 +127,12 @@ void print(const task& t) std::cout << "- Start: " << t.get_start().name << "\n"; std::cout << "- Finish: " << t.get_finish().name << "\n"; - std::cout << "- Length: " << UNITS_STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n"; + std::cout << "- Length: " << UNITS_STD_FMT::format("{:%.1Q %q}", t.get_distance()) << "\n"; std::cout << "- Legs: " << "\n"; for (const auto& l : t.get_legs()) - std::cout << UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length()); + std::cout << UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_distance()); std::cout << "\n"; } @@ -155,14 +156,14 @@ void print(const aircraft_tow& tow) void example() { - using namespace units::aliases::isq::si; + using namespace mp_units::si::unit_symbols; - const safety sfty = {height(m<>(300))}; + const safety sfty = {300 * m}; const auto gliders = get_gliders(); const auto waypoints = get_waypoints(); const auto weather_conditions = get_weather_conditions(); const task t = {waypoints[0], waypoints[1], waypoints[0]}; - const aircraft_tow tow = {height(m<>(400)), rate_of_climb(m_per_s<>(1.6))}; + const aircraft_tow tow = {400 * m, 1.6 * (m / s)}; // TODO use C++20 date library when available // set `start_time` to 11:00 am today const timestamp start_time(std::chrono::system_clock::now()); diff --git a/example/glide_computer/CMakeLists.txt b/example/glide_computer/CMakeLists.txt index 7c19f4db..9587ef37 100644 --- a/example/glide_computer/CMakeLists.txt +++ b/example/glide_computer/CMakeLists.txt @@ -22,6 +22,6 @@ cmake_minimum_required(VERSION 3.2) -add_library(glide_computer STATIC include/geographic.h glide_computer.cpp include/glide_computer.h) -target_link_libraries(glide_computer PRIVATE mp-units::core-fmt PUBLIC mp-units::si example_utils) -target_include_directories(glide_computer PUBLIC include) +add_library(glide_computer_lib STATIC glide_computer.cpp include/glide_computer.h) +target_link_libraries(glide_computer_lib PRIVATE mp-units::core-fmt PUBLIC mp-units::si mp-units::utility example_utils) +target_include_directories(glide_computer_lib PUBLIC include) diff --git a/example/glide_computer/glide_computer.cpp b/example/glide_computer/glide_computer.cpp index 3428448d..b6d3a881 100644 --- a/example/glide_computer/glide_computer.cpp +++ b/example/glide_computer/glide_computer.cpp @@ -21,13 +21,14 @@ // SOFTWARE. #include "glide_computer.h" +#include #include #include #include namespace glide_computer { -using namespace units::isq; +using namespace mp_units; task::legs task::make_legs(const waypoints& wpts) { @@ -43,26 +44,27 @@ std::vector task::make_leg_total_distances(const legs& legs) { std::vector res; res.reserve(legs.size()); - auto to_length = [](const leg& l) { return l.get_length(); }; + auto to_length = [](const leg& l) { return l.get_distance(); }; std::transform_inclusive_scan(legs.cbegin(), legs.cend(), std::back_inserter(res), std::plus(), to_length); return res; } -altitude terrain_level_alt(const task& t, const flight_point& pos) +geographic::msl_altitude terrain_level_alt(const task& t, const flight_point& pos) { const task::leg& l = t.get_legs()[pos.leg_idx]; const height alt_diff = l.end().alt - l.begin().alt; - return l.begin().alt + alt_diff * ((pos.dist - t.get_leg_dist_offset(pos.leg_idx)) / l.get_length()).common(); + return l.begin().alt + alt_diff * ((pos.dist - t.get_leg_dist_offset(pos.leg_idx)) / l.get_distance()); } // Returns `x` of the intersection of a glide line and a terrain line. // y = -x / glide_ratio + pos.alt; // y = (finish_alt - ground_alt) / dist_to_finish * x + ground_alt + min_agl_height; -distance glide_distance(const flight_point& pos, const glider& g, const task& t, const safety& s, altitude ground_alt) +distance glide_distance(const flight_point& pos, const glider& g, const task& t, const safety& s, + geographic::msl_altitude ground_alt) { - const auto dist_to_finish = t.get_length() - pos.dist; - return distance((ground_alt + s.min_agl_height - pos.alt).common() / - ((ground_alt - t.get_finish().alt) / dist_to_finish - 1 / glide_ratio(g.polar[0]))); + const auto dist_to_finish = t.get_distance() - pos.dist; + return quantity_cast(ground_alt + s.min_agl_height - pos.alt) / + ((ground_alt - t.get_finish().alt) / dist_to_finish - 1 / glide_ratio(g.polar[0])); } } // namespace glide_computer @@ -77,7 +79,7 @@ void print(std::string_view phase_name, timestamp start_ts, const glide_computer std::cout << UNITS_STD_FMT::format( "| {:<12} | {:>9%.1Q %q} (Total: {:>9%.1Q %q}) | {:>8%.1Q %q} (Total: {:>8%.1Q %q}) | {:>7%.0Q %q} ({:>6%.0Q %q}) " "|\n", - phase_name, quantity_cast(new_point.ts - point.ts), quantity_cast(new_point.ts - start_ts), + phase_name, value_cast(new_point.ts - point.ts), value_cast(new_point.ts - start_ts), new_point.dist - point.dist, new_point.dist, new_point.alt - point.alt, new_point.alt); } @@ -85,7 +87,7 @@ flight_point takeoff(timestamp start_ts, const task& t) { return {start_ts, t.ge flight_point tow(timestamp start_ts, const flight_point& pos, const aircraft_tow& at) { - const duration d = (at.height_agl / at.performance).common(); + const duration d = (at.height_agl / at.performance); const flight_point new_pos{pos.ts + d, pos.alt + at.height_agl, pos.leg_idx, pos.dist}; print("Tow", start_ts, pos, new_pos); @@ -98,7 +100,7 @@ flight_point circle(timestamp start_ts, const flight_point& pos, const glider& g const height h_agl = agl(pos.alt, terrain_level_alt(t, pos)); const height circling_height = std::min(w.cloud_base - h_agl, height_to_gain); const rate_of_climb circling_rate = w.thermal_strength + g.polar[0].climb; - const duration d = (circling_height / circling_rate).common(); + const duration d = (circling_height / circling_rate); const flight_point new_pos{pos.ts + d, pos.alt + circling_height, pos.leg_idx, pos.dist}; height_to_gain -= circling_height; @@ -114,7 +116,7 @@ flight_point glide(timestamp start_ts, const flight_point& pos, const glider& g, const auto new_distance = pos.dist + dist; const auto alt = ground_alt + s.min_agl_height; const auto l3d = length_3d(dist, pos.alt - alt); - const duration d = l3d / g.polar[0].v.common(); + const duration d = l3d / g.polar[0].v; const flight_point new_pos{pos.ts + d, terrain_level_alt(t, pos) + s.min_agl_height, t.get_leg_index(new_distance), new_distance}; @@ -124,9 +126,9 @@ flight_point glide(timestamp start_ts, const flight_point& pos, const glider& g, flight_point final_glide(timestamp start_ts, const flight_point& pos, const glider& g, const task& t) { - const auto dist = t.get_length() - pos.dist; + const auto dist = t.get_distance() - pos.dist; const auto l3d = length_3d(dist, pos.alt - t.get_finish().alt); - const duration d = l3d / g.polar[0].v.common(); + const duration d = l3d / g.polar[0].v; const flight_point new_pos{pos.ts + d, t.get_finish().alt, t.get_legs().size() - 1, pos.dist + dist}; print("Final Glide", start_ts, pos, new_pos); @@ -150,8 +152,9 @@ void estimate(timestamp start_ts, const glider& g, const weather& w, const task& // estimate aircraft towing pos = tow(start_ts, pos, at); - // estimate the altitude needed to reach the finish line from this place - const altitude final_glide_alt = t.get_finish().alt + height(t.get_length().common() / glide_ratio(g.polar[0])); + // estimate the msl_altitude needed to reach the finish line from this place + const geographic::msl_altitude final_glide_alt = + t.get_finish().alt + quantity_cast(t.get_distance() / glide_ratio(g.polar[0])); // how much height we still need to gain in the thermalls to reach the destination? height height_to_gain = final_glide_alt - pos.alt; diff --git a/example/glide_computer/include/glide_computer.h b/example/glide_computer/include/glide_computer.h index 6f54810a..8503cc3b 100644 --- a/example/glide_computer/include/glide_computer.h +++ b/example/glide_computer/include/glide_computer.h @@ -22,17 +22,11 @@ #pragma once -// IWYU pragma: begin_exports #include "geographic.h" -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include // IWYU pragma: keep +#include +#include // IWYU pragma: keep +#include +#include #include #include #include @@ -56,67 +50,25 @@ // - no ground obstacles (i.e. mountains) to pass // - flight path exactly on a shortest possible line to destination -template -struct UNITS_STD_FMT::formatter : formatter { - template - auto format(const QK& v, FormatContext& ctx) - { - return formatter::format(v.common(), ctx); - } -}; - namespace glide_computer { -template -constexpr units::Dimensionless auto operator/(const QK1& lhs, const QK2& rhs) - requires(!units::QuantityKindRelatedTo) && requires { lhs.common() / rhs.common(); } -{ - return lhs.common() / rhs.common(); -} - -// kinds -using horizontal_kind = geographic::horizontal_kind; -struct vertical_kind : units::kind {}; -struct vertical_point_kind : units::point_kind {}; -struct velocity_kind : units::derived_kind {}; -struct rate_of_climb_kind : units::derived_kind {}; - // https://en.wikipedia.org/wiki/Flight_planning#Units_of_measurement +QUANTITY_SPEC(rate_of_climb_speed, mp_units::isq::speed, mp_units::isq::height / mp_units::isq::time); + // length -using distance = units::quantity_kind; -using height = units::quantity_kind; -using altitude = units::quantity_point_kind; +using distance = mp_units::quantity]>; +using height = mp_units::quantity; // time -using duration = units::isq::si::time; -using timestamp = units::quantity_point, units::isq::si::second>; +using duration = mp_units::quantity; +using timestamp = mp_units::quantity_point>; // speed -using velocity = units::quantity_kind; -using rate_of_climb = units::quantity_kind; - -// text output -template -std::basic_ostream& operator<<(std::basic_ostream& os, const altitude& a) -{ - return os << a.relative().common() << " AMSL"; -} - -} // namespace glide_computer - -template<> -struct UNITS_STD_FMT::formatter : formatter> { - template - auto format(glide_computer::altitude a, FormatContext& ctx) - { - formatter>::format(a.relative().common(), ctx); - return UNITS_STD_FMT::format_to(ctx.out(), " AMSL"); - } -}; +using velocity = mp_units::quantity / mp_units::si::hour]>; +using rate_of_climb = mp_units::quantity; // definition of glide computer databases and utilities -namespace glide_computer { - struct glider { struct polar_point { velocity v; @@ -127,7 +79,10 @@ struct glider { std::array polar; }; -constexpr units::Dimensionless auto glide_ratio(const glider::polar_point& polar) { return polar.v / -polar.climb; } +constexpr mp_units::QuantityOf auto glide_ratio(const glider::polar_point& polar) +{ + return polar.v / -polar.climb; +} struct weather { height cloud_base; @@ -137,7 +92,7 @@ struct weather { struct waypoint { std::string name; geographic::position pos; - altitude alt; + geographic::msl_altitude alt; }; class task { @@ -152,7 +107,7 @@ public: leg(const waypoint& b, const waypoint& e) noexcept : begin_(&b), end_(&e) {} constexpr const waypoint& begin() const { return *begin_; }; constexpr const waypoint& end() const { return *end_; } - constexpr const distance get_length() const { return length_; } + constexpr distance get_distance() const { return length_; } }; using legs = std::vector; @@ -170,7 +125,7 @@ public: const waypoint& get_start() const { return waypoints_.front(); } const waypoint& get_finish() const { return waypoints_.back(); } - distance get_length() const { return length_; } + distance get_distance() const { return length_; } distance get_leg_dist_offset(std::size_t leg_index) const { @@ -203,21 +158,26 @@ struct aircraft_tow { struct flight_point { timestamp ts; - altitude alt; + geographic::msl_altitude alt; std::size_t leg_idx = 0; distance dist{}; }; -altitude terrain_level_alt(const task& t, const flight_point& pos); +geographic::msl_altitude terrain_level_alt(const task& t, const flight_point& pos); -constexpr height agl(altitude glider_alt, altitude terrain_level) { return glider_alt - terrain_level; } - -inline units::isq::si::length length_3d(distance dist, height h) +constexpr height agl(geographic::msl_altitude glider_alt, geographic::msl_altitude terrain_level) { - return hypot(dist.common(), h.common()); + return glider_alt - terrain_level; } -distance glide_distance(const flight_point& pos, const glider& g, const task& t, const safety& s, altitude ground_alt); +inline mp_units::quantity]> length_3d(distance dist, + height h) +{ + return hypot(dist, h); +} + +distance glide_distance(const flight_point& pos, const glider& g, const task& t, const safety& s, + geographic::msl_altitude ground_alt); void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s, const aircraft_tow& at); diff --git a/example/hello_units.cpp b/example/hello_units.cpp index 27481e91..c6b7445d 100644 --- a/example/hello_units.cpp +++ b/example/hello_units.cpp @@ -20,37 +20,32 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include -#include // IWYU pragma: keep -#include -#include // IWYU pragma: keep -#include -#include +#include +#include +#include +#include +#include #include -using namespace units::isq; +using namespace mp_units; -constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } +constexpr QuantityOf auto avg_speed(QuantityOf auto d, QuantityOf 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; + using namespace mp_units::si::unit_symbols; + using namespace mp_units::international::unit_symbols; - 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)); -#if UNITS_DOWNCAST_MODE == 0 - constexpr Speed auto v5 = quantity_cast>(v3); - constexpr Speed auto v6 = quantity_cast(v4); -#else - constexpr Speed auto v5 = quantity_cast>(v3); - constexpr Speed auto v6 = quantity_cast(v4); -#endif - constexpr Speed auto v7 = quantity_cast(v6); + 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 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 diff --git a/example/glide_computer/include/geographic.h b/example/include/geographic.h similarity index 58% rename from example/glide_computer/include/geographic.h rename to example/include/geographic.h index 45e2f7f5..d303f0a1 100644 --- a/example/glide_computer/include/geographic.h +++ b/example/include/geographic.h @@ -23,26 +23,54 @@ #pragma once #include "ranged_representation.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports +namespace geographic { + +inline constexpr struct mean_sea_level : mp_units::absolute_point_origin { + using mp_units::absolute_point_origin::absolute_point_origin; +} mean_sea_level; + +using msl_altitude = mp_units::quantity_point; + +// text output +template +std::basic_ostream& operator<<(std::basic_ostream& os, const msl_altitude& a) +{ + return os << a.absolute() << " AMSL"; +} + +} // namespace geographic + +template<> +struct UNITS_STD_FMT::formatter : formatter { + template + auto format(const geographic::msl_altitude& a, FormatContext& ctx) + { + formatter::format(a.absolute(), ctx); + return UNITS_STD_FMT::format_to(ctx.out(), " AMSL"); + } +}; namespace geographic { template -using latitude = units::angle>; +using latitude = + mp_units::quantity>; template -using longitude = units::angle>; +using longitude = + mp_units::quantity>; template std::basic_ostream& operator<<(std::basic_ostream& os, const latitude& lat) @@ -64,29 +92,18 @@ std::basic_ostream& operator<<(std::basic_ostream& inline namespace literals { -constexpr auto operator"" _N(long double v) { return latitude(latitude::rep(v)); } -constexpr auto operator"" _S(long double v) { return latitude(latitude::rep(v)); } -constexpr auto operator"" _E(long double v) { return longitude(longitude::rep(v)); } -constexpr auto operator"" _W(long double v) { return longitude(longitude::rep(v)); } -constexpr auto operator"" _N(unsigned long long v) +constexpr latitude operator"" _N(long double v) { return latitude{v * mp_units::si::degree}; } +constexpr latitude operator"" _S(long double v) { - gsl_ExpectsAudit(std::in_range(v)); - return latitude(latitude::rep(static_cast(v))); + return latitude{-v * mp_units::si::degree}; } -constexpr auto operator"" _S(unsigned long long v) +constexpr longitude operator"" _E(long double v) { - gsl_ExpectsAudit(std::in_range(v)); - return latitude(-latitude::rep(static_cast(v))); + return longitude{v * mp_units::si::degree}; } -constexpr auto operator"" _E(unsigned long long v) +constexpr longitude operator"" _W(long double v) { - gsl_ExpectsAudit(std::in_range(v)); - return longitude(longitude::rep(static_cast(v))); -} -constexpr auto operator"" _W(unsigned long long v) -{ - gsl_ExpectsAudit(std::in_range(v)); - return longitude(-longitude::rep(static_cast(v))); + return longitude{-v * mp_units::si::degree}; } } // namespace literals @@ -129,8 +146,7 @@ struct UNITS_STD_FMT::formatter> : formatter { namespace geographic { -struct horizontal_kind : units::kind {}; -using distance = units::quantity_kind; +using distance = mp_units::quantity]>; template struct position { @@ -141,31 +157,26 @@ struct position { template distance spherical_distance(position from, position to) { - using namespace units::isq::si; - constexpr length earth_radius(6371); + using namespace mp_units; + constexpr auto earth_radius = 6'371 * isq::radius[si::kilo]; - constexpr auto p = std::numbers::pi_v / 180; - const auto lat1_rad = from.lat.number() * p; - const auto lon1_rad = from.lon.number() * p; - const auto lat2_rad = to.lat.number() * p; - const auto lon2_rad = to.lon.number() * p; - - using std::sin, std::cos, std::asin, std::acos, std::sqrt; + using isq::sin, isq::cos, isq::asin, isq::acos; // https://en.wikipedia.org/wiki/Great-circle_distance#Formulae if constexpr (sizeof(T) >= 8) { // spherical law of cosines - const auto central_angle = - acos(sin(lat1_rad) * sin(lat2_rad) + cos(lat1_rad) * cos(lat2_rad) * cos(lon2_rad - lon1_rad)); - // const auto central_angle = 2 * asin(sqrt(0.5 - cos(lat2_rad - lat1_rad) / 2 + cos(lat1_rad) * cos(lat2_rad) * (1 - // - cos(lon2_rad - lon1_rad)) / 2)); - return distance(earth_radius * central_angle); + const auto central_angle = acos(sin(from.lat) * sin(to.lat) + cos(from.lat) * cos(to.lat) * cos(to.lon - from.lon)); + // const auto central_angle = 2 * asin(sqrt(0.5 - cos(to.lat - from.lat) / 2 + cos(from.lat) * cos(to.lat) * (1 + // - cos(lon2_rad - from.lon)) / 2)); + + return quantity_cast(earth_radius * central_angle); } else { // the haversine formula - const auto sin_lat = sin((lat2_rad - lat1_rad) / 2); - const auto sin_lon = sin((lon2_rad - lon1_rad) / 2); - const auto central_angle = 2 * asin(sqrt(sin_lat * sin_lat + cos(lat1_rad) * cos(lat2_rad) * sin_lon * sin_lon)); - return distance(earth_radius * central_angle); + const auto sin_lat = sin((to.lat - from.lat) / 2); + const auto sin_lon = sin((to.lon - from.lon) / 2); + const auto central_angle = 2 * asin(sqrt(sin_lat * sin_lat + cos(from.lat) * cos(to.lat) * sin_lon * sin_lon)); + + return quantity_cast(earth_radius * central_angle); } } diff --git a/example/include/ranged_representation.h b/example/include/ranged_representation.h index 6b0448f1..a6c3ecfc 100644 --- a/example/include/ranged_representation.h +++ b/example/include/ranged_representation.h @@ -23,7 +23,8 @@ #pragma once #include "validated_type.h" -#include +#include +#include #include #include #include @@ -51,9 +52,4 @@ public: }; template -struct std::common_type> : - std::type_identity, Min, Max>> {}; - -template -struct std::common_type, std::intmax_t> : - std::type_identity, Min, Max>> {}; +inline constexpr bool mp_units::is_scalar> = mp_units::is_scalar; diff --git a/example/include/validated_type.h b/example/include/validated_type.h index 08b08d82..a99b43b5 100644 --- a/example/include/validated_type.h +++ b/example/include/validated_type.h @@ -23,7 +23,7 @@ #pragma once #include -#include +#include #include inline constexpr struct validated_tag { diff --git a/example/kalman_filter/CMakeLists.txt b/example/kalman_filter/CMakeLists.txt index d2f62243..f1370018 100644 --- a/example/kalman_filter/CMakeLists.txt +++ b/example/kalman_filter/CMakeLists.txt @@ -28,17 +28,13 @@ cmake_minimum_required(VERSION 3.2) function(add_example target) add_executable(${target} ${target}.cpp) target_link_libraries(${target} PRIVATE ${ARGN}) - target_compile_definitions(${target} PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES) endfunction() -add_example(kalman_filter-example_1 mp-units::core-fmt mp-units::si) -add_example(kalman_filter-example_2 mp-units::core-fmt mp-units::si) -add_example(kalman_filter-example_3 mp-units::core-fmt mp-units::si) -add_example(kalman_filter-example_4 mp-units::core-fmt mp-units::si) -add_example(kalman_filter-example_5 mp-units::core-fmt mp-units::si) - -if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - add_example(kalman_filter-example_6 mp-units::core-fmt mp-units::si) - add_example(kalman_filter-example_7 mp-units::core-fmt mp-units::si) - add_example(kalman_filter-example_8 mp-units::core-fmt mp-units::si) -endif() +add_example(kalman_filter-example_1 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_2 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_3 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_4 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_5 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_6 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_7 mp-units::core-fmt mp-units::si mp-units::utility) +add_example(kalman_filter-example_8 mp-units::core-fmt mp-units::si mp-units::utility) diff --git a/example/kalman_filter/kalman.h b/example/kalman_filter/kalman.h index 6bbe7066..fe84c498 100644 --- a/example/kalman_filter/kalman.h +++ b/example/kalman_filter/kalman.h @@ -22,43 +22,39 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include namespace kalman { template -concept QuantityOrQuantityPoint = - units::Quantity || units::QuantityPoint; // TODO Should it also account for `kinds`? +concept QuantityOrQuantityPoint = mp_units::Quantity || mp_units::QuantityPoint; -template +template inline constexpr bool are_time_derivatives = false; -template -inline constexpr bool are_time_derivatives = true; +template +inline constexpr bool are_time_derivatives = true; -template -inline constexpr bool are_time_derivatives = - units::DimensionOfT && // TODO Think on how to simplify this - are_time_derivatives; +template +inline constexpr bool are_time_derivatives = + (D1 / D2 == mp_units::isq::dim_time) && are_time_derivatives; // state template - requires(sizeof...(QQPs) > 0) && (sizeof...(QQPs) <= 3) && are_time_derivatives + requires(sizeof...(QQPs) > 0) && (sizeof...(QQPs) <= 3) && are_time_derivatives struct state { std::tuple variables_; constexpr state(QQPs... qqps) : variables_(std::move(qqps)...) {} }; template -concept State = units::is_specialization_of; +concept State = mp_units::is_specialization_of; template constexpr auto& get(state& s) @@ -76,38 +72,35 @@ constexpr const auto& get(const state& s) template struct estimation { private: - using uncertainty_ref = decltype(QQP::reference * QQP::reference); - using uncertainty_type = - units::quantity; + static constexpr auto uncertainty_ref = QQP::reference * QQP::reference; + using uncertainty_type = mp_units::quantity; public: - kalman::state state; // TODO extend kalman functions to work with this variadic patermater list + kalman::state state; // TODO extend kalman functions to work with this variadic parameter list uncertainty_type uncertainty; }; -#if UNITS_COMP_MSVC || (UNITS_COMP_CLANG && UNITS_COMP_CLANG <= 16) - -template +template estimation(state, U) -> estimation; -#endif - // kalman gain -template -constexpr units::dimensionless kalman_gain(Q estimate_uncertainty, Q measurement_uncertainty) +template +constexpr mp_units::quantity kalman_gain(Q estimate_uncertainty, + Q measurement_uncertainty) { return estimate_uncertainty / (estimate_uncertainty + measurement_uncertainty); } // state update -template - requires units::equivalent +template K> + requires(Q::quantity_spec == QM::quantity_spec) constexpr state state_update(const state& predicted, QM measured, K gain) { return {get<0>(predicted) + gain * (measured - get<0>(predicted))}; } -template - requires units::equivalent +template K, + mp_units::QuantityOf T> + requires(Q1::quantity_spec == QM::quantity_spec) constexpr state state_update(const state& predicted, QM measured, std::array gain, T interval) { const auto q1 = get<0>(predicted) + get<0>(gain) * (measured - get<0>(predicted)); @@ -115,8 +108,9 @@ constexpr state state_update(const state& predicted, QM measured return {q1, q2}; } -template - requires units::equivalent +template K, mp_units::QuantityOf T> + requires(Q1::quantity_spec == QM::quantity_spec) constexpr state state_update(const state& predicted, QM measured, std::array gain, T interval) { @@ -127,14 +121,14 @@ constexpr state state_update(const state& predicted, QM } // covariance update -template +template K> constexpr Q covariance_update(Q uncertainty, K gain) { return (1 - gain) * uncertainty; } // state extrapolation -template +template T> constexpr state state_extrapolation(const state& estimated, T interval) { const auto q1 = get<0>(estimated) + get<1>(estimated) * interval; @@ -142,7 +136,7 @@ constexpr state state_extrapolation(const state& estimated, T in return {q1, q2}; } -template +template T> constexpr state state_extrapolation(const state& estimated, T interval) { const auto q1 = get<0>(estimated) + get<1>(estimated) * interval + get<2>(estimated) * pow<2>(interval) / 2; @@ -152,7 +146,7 @@ constexpr state state_extrapolation(const state& estimat } // covariance extrapolation -template +template constexpr Q covariance_extrapolation(Q uncertainty, Q process_noise_variance) { return uncertainty + process_noise_variance; @@ -164,8 +158,8 @@ template struct UNITS_STD_FMT::formatter> { constexpr auto parse(format_parse_context& ctx) { - units::detail::dynamic_specs_handler handler(specs, ctx); - return units::detail::parse_format_specs(ctx.begin(), ctx.end(), handler); + mp_units::detail::dynamic_specs_handler handler(specs, ctx); + return mp_units::detail::parse_format_specs(ctx.begin(), ctx.end(), handler); } template @@ -193,28 +187,28 @@ struct UNITS_STD_FMT::formatter> { } std::string global_format_buffer; - units::detail::quantity_global_format_specs global_specs = {specs.fill, specs.align, specs.width}; - units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs); + mp_units::detail::quantity_global_format_specs global_specs = {specs.fill, specs.align, specs.width}; + mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs); return UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer, UNITS_STD_FMT::make_format_args(value_buffer)); } private: - units::detail::dynamic_format_specs specs; + mp_units::detail::dynamic_format_specs specs; }; template struct UNITS_STD_FMT::formatter> { constexpr auto parse(format_parse_context& ctx) { - units::detail::dynamic_specs_handler handler(specs, ctx); - return units::detail::parse_format_specs(ctx.begin(), ctx.end(), handler); + mp_units::detail::dynamic_specs_handler handler(specs, ctx); + return mp_units::detail::parse_format_specs(ctx.begin(), ctx.end(), handler); } template auto format(kalman::estimation e, FormatContext& ctx) { - units::Quantity auto q = [](const Q& t) { - if constexpr (units::Quantity) + mp_units::Quantity auto q = [](const Q& t) { + if constexpr (mp_units::Quantity) return t; else return t.relative(); @@ -230,11 +224,11 @@ struct UNITS_STD_FMT::formatter> { } std::string global_format_buffer; - units::detail::quantity_global_format_specs global_specs = {specs.fill, specs.align, specs.width}; - units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs); + mp_units::detail::quantity_global_format_specs global_specs = {specs.fill, specs.align, specs.width}; + mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs); return UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer, UNITS_STD_FMT::make_format_args(value_buffer)); } private: - units::detail::dynamic_format_specs specs; + mp_units::detail::dynamic_format_specs specs; }; diff --git a/example/kalman_filter/kalman_filter-example_1.cpp b/example/kalman_filter/kalman_filter-example_1.cpp index bd122099..5c73a441 100644 --- a/example/kalman_filter/kalman_filter-example_1.cpp +++ b/example/kalman_filter/kalman_filter-example_1.cpp @@ -21,15 +21,15 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include +#include +#include +#include #include #include // Based on: https://www.kalmanfilter.net/alphabeta.html#ex1 -using namespace units; +using namespace mp_units; void print_header(const kalman::State auto& initial) { @@ -38,27 +38,26 @@ void print_header(const kalman::State auto& initial) "Curr. Estimate", "Next Estimate"); } -void print(auto iteration, Dimensionless auto gain, Quantity auto measured, const kalman::State auto& current, - const kalman::State auto& next) +void print(auto iteration, QuantityOf auto gain, Quantity auto measured, + const kalman::State auto& current, const kalman::State auto& next) { std::cout << UNITS_STD_FMT::format("{:2} | {:9} | {:8} | {:14} | {:14}\n", iteration, gain, measured, current, next); } int main() { - using namespace units::isq; - using namespace units::isq::si::references; - using state = kalman::state>; + using namespace mp_units::si::unit_symbols; + using state = kalman::state>; const state initial = {1 * kg}; - const std::array measurements = {1030 * g, 989 * g, 1017 * g, 1009 * g, 1013 * g, - 979 * g, 1008 * g, 1042 * g, 1012 * g, 1011 * g}; + const std::array measurements = {1'030 * g, 989 * g, 1'017 * g, 1'009 * g, 1'013 * g, + 979 * g, 1'008 * g, 1'042 * g, 1'012 * g, 1'011 * g}; print_header(initial); state next = initial; for (int index = 1; const auto& m : measurements) { const auto& previous = next; - const dimensionless gain = 1. / index; + const auto gain = 1. / index * one; const auto current = state_update(previous, m, gain); next = current; print(index++, gain, m, current, next); diff --git a/example/kalman_filter/kalman_filter-example_2.cpp b/example/kalman_filter/kalman_filter-example_2.cpp index 29485c31..b3cfabc0 100644 --- a/example/kalman_filter/kalman_filter-example_2.cpp +++ b/example/kalman_filter/kalman_filter-example_2.cpp @@ -21,17 +21,19 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include -#include -#include +#include +#include +#include #include #include // Based on: https://www.kalmanfilter.net/alphabeta.html#ex2 -using namespace units; +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +using namespace mp_units; void print_header(const kalman::State auto& initial) { @@ -47,15 +49,15 @@ void print(auto iteration, Quantity auto measured, const kalman::State auto& cur int main() { - using namespace units::isq; - using namespace units::isq::si::references; - using state = kalman::state, si::speed>; + using namespace mp_units::si::unit_symbols; + using state = kalman::state, quantity>; - const auto interval = 5 * s; + const auto interval = isq::duration(5 * s); const state initial = {30 * km, 40 * (m / s)}; - const std::array measurements = {30110 * m, 30265 * m, 30740 * m, 30750 * m, 31135 * m, - 31015 * m, 31180 * m, 31610 * m, 31960 * m, 31865 * m}; - std::array gain = {dimensionless(0.2), dimensionless(0.1)}; + const quantity measurements[] = {30'110 * m, 30'265 * m, 30'740 * m, 30'750 * m, + 31'135 * m, 31'015 * m, 31'180 * m, 31'610 * m, + 31'960 * m, 31'865 * m}; + std::array gain = {0.2 * one, 0.1 * one}; print_header(initial); state next = state_extrapolation(initial, interval); diff --git a/example/kalman_filter/kalman_filter-example_3.cpp b/example/kalman_filter/kalman_filter-example_3.cpp index adbf5c70..018742b8 100644 --- a/example/kalman_filter/kalman_filter-example_3.cpp +++ b/example/kalman_filter/kalman_filter-example_3.cpp @@ -21,17 +21,19 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include -#include -#include +#include +#include +#include #include #include // Based on: https://www.kalmanfilter.net/alphabeta.html#ex3 -using namespace units; +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +using namespace mp_units; void print_header(const kalman::State auto& initial) { @@ -47,15 +49,15 @@ void print(auto iteration, Quantity auto measured, const kalman::State auto& cur int main() { - using namespace units::isq; - using namespace units::isq::si::references; - using state = kalman::state, si::speed>; + using namespace mp_units::si::unit_symbols; + using state = kalman::state, quantity>; - const auto interval = 5 * s; + const auto interval = isq::duration(5 * s); const state initial = {30 * km, 50 * (m / s)}; - const std::array measurements = {30160 * m, 30365 * m, 30890 * m, 31050 * m, 31785 * m, - 32215 * m, 33130 * m, 34510 * m, 36010 * m, 37265 * m}; - std::array gain = {dimensionless(0.2), dimensionless(0.1)}; + const quantity measurements[] = {30'160 * m, 30'365 * m, 30'890 * m, 31'050 * m, + 31'785 * m, 32'215 * m, 33'130 * m, 34'510 * m, + 36'010 * m, 37'265 * m}; + std::array gain = {0.2 * one, 0.1 * one}; print_header(initial); state next = state_extrapolation(initial, interval); diff --git a/example/kalman_filter/kalman_filter-example_4.cpp b/example/kalman_filter/kalman_filter-example_4.cpp index bbb4ab35..fd676b54 100644 --- a/example/kalman_filter/kalman_filter-example_4.cpp +++ b/example/kalman_filter/kalman_filter-example_4.cpp @@ -21,18 +21,19 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include // Based on: https://www.kalmanfilter.net/alphabeta.html#ex4 -using namespace units; +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +using namespace mp_units; void print_header(const kalman::State auto& initial) { @@ -48,18 +49,16 @@ void print(auto iteration, Quantity auto measured, const kalman::State auto& cur int main() { - using namespace units::isq; - using namespace units::isq::si::references; - using state = - kalman::state, si::speed, si::acceleration>; - constexpr auto mps = m / s; - constexpr auto mps2 = mps / s; + using namespace mp_units::si::unit_symbols; + using state = kalman::state, quantity, + quantity>; + const auto interval = isq::duration(5. * s); + const state initial = {30 * km, 50 * (m / s), 0 * (m / s2)}; - const auto interval = 5. * s; - const state initial = {30 * km, 50 * mps, 0 * mps2}; - const std::array measurements = {30160 * m, 30365 * m, 30890 * m, 31050 * m, 31785 * m, - 32215 * m, 33130 * m, 34510 * m, 36010 * m, 37265 * m}; - std::array gain = {dimensionless(0.5), dimensionless(0.4), dimensionless(0.1)}; + const quantity measurements[] = {30'160 * m, 30'365 * m, 30'890 * m, 31'050 * m, + 31'785 * m, 32'215 * m, 33'130 * m, 34'510 * m, + 36'010 * m, 37'265 * m}; + std::array gain = {0.5 * one, 0.4 * one, 0.1 * one}; print_header(initial); state next = state_extrapolation(initial, interval); diff --git a/example/kalman_filter/kalman_filter-example_5.cpp b/example/kalman_filter/kalman_filter-example_5.cpp index d899736d..de74ec33 100644 --- a/example/kalman_filter/kalman_filter-example_5.cpp +++ b/example/kalman_filter/kalman_filter-example_5.cpp @@ -21,15 +21,16 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include +#include +#include +#include +#include #include #include // Based on: https://www.kalmanfilter.net/kalman1d.html#ex5 -using namespace units; +using namespace mp_units; template void print_header(kalman::estimation initial) @@ -39,7 +40,7 @@ void print_header(kalman::estimation initial) "Curr. Estimate", "Next Estimate"); } -template +template K> void print(auto iteration, K gain, Q measured, kalman::estimation current, kalman::estimation next) { std::cout << UNITS_STD_FMT::format("{:2} | {:5%.2Q} | {:8} | {:>16.2} | {:>16.2}\n", iteration, gain, measured, @@ -49,16 +50,16 @@ void print(auto iteration, K gain, Q measured, kalman::estimation current, ka int main() { using namespace kalman; - using namespace units::isq; - using namespace units::isq::si::references; + using namespace mp_units::si::unit_symbols; - const estimation initial = {state{60. * m}, pow<2>(15. * m)}; - const std::array measurements = {48.54 * m, 47.11 * m, 55.01 * m, 55.15 * m, 49.89 * m, - 40.85 * m, 46.72 * m, 50.05 * m, 51.27 * m, 49.95 * m}; - const auto measurement_uncertainty = pow<2>(5. * m); + const estimation initial = {state{isq::height(60. * m)}, pow<2>(isq::height(15. * m))}; + const quantity measurements[] = {48.54 * m, 47.11 * m, 55.01 * m, 55.15 * m, 49.89 * m, + 40.85 * m, 46.72 * m, 50.05 * m, 51.27 * m, 49.95 * m}; + const auto measurement_uncertainty = pow<2>(isq::height(5. * m)); - auto update = [=](const estimation& previous, const Q& meassurement, Dimensionless auto gain) { - return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)}; + auto update = [=](const estimation& previous, const Q& measurement, + QuantityOf auto gain) { + return estimation{state_update(previous.state, measurement, gain), covariance_update(previous.uncertainty, gain)}; }; auto predict = [](const estimation& current) { return current; }; diff --git a/example/kalman_filter/kalman_filter-example_6.cpp b/example/kalman_filter/kalman_filter-example_6.cpp index 4293b5f3..18e2ef11 100644 --- a/example/kalman_filter/kalman_filter-example_6.cpp +++ b/example/kalman_filter/kalman_filter-example_6.cpp @@ -21,36 +21,17 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -// TODO Fix when Celsius is properly supported (#232) -namespace units::isq::si { - -struct degree_celsius : alias_unit {}; - -namespace thermodynamic_temperature_references { - -inline constexpr auto deg_C = reference{}; - -} // namespace thermodynamic_temperature_references - -namespace references { - -using namespace thermodynamic_temperature_references; - -} // namespace references - -} // namespace units::isq::si - // Based on: https://www.kalmanfilter.net/kalman1d.html#ex6 -using namespace units; +using namespace mp_units; template void print_header(kalman::estimation initial) @@ -60,7 +41,7 @@ void print_header(kalman::estimation initial) "Curr. Estimate", "Next Estimate"); } -template +template K> void print(auto iteration, K gain, QP measured, kalman::estimation current, kalman::estimation next) { std::cout << UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, @@ -69,20 +50,21 @@ void print(auto iteration, K gain, QP measured, kalman::estimation current, int main() { + constexpr auto deg_C = isq::Celsius_temperature[si::degree_Celsius]; + using namespace kalman; - using namespace units::isq; - using namespace units::isq::si::references; const auto process_noise_variance = 0.0001 * (deg_C * deg_C); - const estimation initial = {state{quantity_point(10. * deg_C)}, pow<2>(100. * deg_C)}; - const std::array measurements = {quantity_point(49.95 * deg_C), quantity_point(49.967 * deg_C), - quantity_point(50.1 * deg_C), quantity_point(50.106 * deg_C), - quantity_point(49.992 * deg_C), quantity_point(49.819 * deg_C), - quantity_point(49.933 * deg_C), quantity_point(50.007 * deg_C), - quantity_point(50.023 * deg_C), quantity_point(49.99 * deg_C)}; + const estimation initial = {state{quantity_point{10. * deg_C}}, pow<2>(100. * deg_C)}; + const std::array measurements = {quantity_point{49.95 * deg_C}, quantity_point{49.967 * deg_C}, + quantity_point{50.1 * deg_C}, quantity_point{50.106 * deg_C}, + quantity_point{49.992 * deg_C}, quantity_point{49.819 * deg_C}, + quantity_point{49.933 * deg_C}, quantity_point{50.007 * deg_C}, + quantity_point{50.023 * deg_C}, quantity_point{49.99 * deg_C}}; const auto measurement_uncertainty = pow<2>(0.1 * deg_C); - auto update = [=](const estimation& previous, const QP& meassurement, Dimensionless auto gain) { + auto update = [=](const estimation& previous, const QP& meassurement, + QuantityOf auto gain) { return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)}; }; diff --git a/example/kalman_filter/kalman_filter-example_7.cpp b/example/kalman_filter/kalman_filter-example_7.cpp index b44b0c78..567014b5 100644 --- a/example/kalman_filter/kalman_filter-example_7.cpp +++ b/example/kalman_filter/kalman_filter-example_7.cpp @@ -21,36 +21,17 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -// TODO Fix when Celsius is properly supported (#232) -namespace units::isq::si { - -struct degree_celsius : alias_unit {}; - -namespace thermodynamic_temperature_references { - -inline constexpr auto deg_C = reference{}; - -} // namespace thermodynamic_temperature_references - -namespace references { - -using namespace thermodynamic_temperature_references; - -} // namespace references - -} // namespace units::isq::si - // Based on: https://www.kalmanfilter.net/kalman1d.html#ex7 -using namespace units; +using namespace mp_units; template void print_header(kalman::estimation initial) @@ -60,7 +41,7 @@ void print_header(kalman::estimation initial) "Curr. Estimate", "Next Estimate"); } -template +template K> void print(auto iteration, K gain, QP measured, kalman::estimation current, kalman::estimation next) { std::cout << UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, @@ -69,20 +50,21 @@ void print(auto iteration, K gain, QP measured, kalman::estimation current, int main() { + constexpr auto deg_C = isq::Celsius_temperature[si::degree_Celsius]; + using namespace kalman; - using namespace units::isq; - using namespace units::isq::si::references; const auto process_noise_variance = 0.0001 * (deg_C * deg_C); - const estimation initial = {state{quantity_point(10. * deg_C)}, pow<2>(100. * deg_C)}; - const std::array measurements = {quantity_point(50.45 * deg_C), quantity_point(50.967 * deg_C), - quantity_point(51.6 * deg_C), quantity_point(52.106 * deg_C), - quantity_point(52.492 * deg_C), quantity_point(52.819 * deg_C), - quantity_point(53.433 * deg_C), quantity_point(54.007 * deg_C), - quantity_point(54.523 * deg_C), quantity_point(54.99 * deg_C)}; + const estimation initial = {state{quantity_point{10. * deg_C}}, pow<2>(100. * deg_C)}; + const std::array measurements = {quantity_point{50.45 * deg_C}, quantity_point{50.967 * deg_C}, + quantity_point{51.6 * deg_C}, quantity_point{52.106 * deg_C}, + quantity_point{52.492 * deg_C}, quantity_point{52.819 * deg_C}, + quantity_point{53.433 * deg_C}, quantity_point{54.007 * deg_C}, + quantity_point{54.523 * deg_C}, quantity_point{54.99 * deg_C}}; const auto measurement_uncertainty = pow<2>(0.1 * deg_C); - auto update = [=](const estimation& previous, const QP& meassurement, Dimensionless auto gain) { + auto update = [=](const estimation& previous, const QP& meassurement, + QuantityOf auto gain) { return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)}; }; diff --git a/example/kalman_filter/kalman_filter-example_8.cpp b/example/kalman_filter/kalman_filter-example_8.cpp index f0d0b103..65fe47d0 100644 --- a/example/kalman_filter/kalman_filter-example_8.cpp +++ b/example/kalman_filter/kalman_filter-example_8.cpp @@ -21,36 +21,17 @@ // SOFTWARE. #include "kalman.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -// TODO Fix when Celsius is properly supported (#232) -namespace units::isq::si { - -struct degree_celsius : alias_unit {}; - -namespace thermodynamic_temperature_references { - -inline constexpr auto deg_C = reference{}; - -} // namespace thermodynamic_temperature_references - -namespace references { - -using namespace thermodynamic_temperature_references; - -} // namespace references - -} // namespace units::isq::si - // Based on: https://www.kalmanfilter.net/kalman1d.html#ex8 -using namespace units; +using namespace mp_units; template void print_header(kalman::estimation initial) @@ -60,7 +41,7 @@ void print_header(kalman::estimation initial) "Curr. Estimate", "Next Estimate"); } -template +template K> void print(auto iteration, K gain, QP measured, kalman::estimation current, kalman::estimation next) { std::cout << UNITS_STD_FMT::format("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain, @@ -69,20 +50,21 @@ void print(auto iteration, K gain, QP measured, kalman::estimation current, int main() { + constexpr auto deg_C = isq::Celsius_temperature[si::degree_Celsius]; + using namespace kalman; - using namespace units::isq; - using namespace units::isq::si::references; const auto process_noise_variance = 0.15 * (deg_C * deg_C); - const estimation initial = {state{quantity_point(10. * deg_C)}, pow<2>(100. * deg_C)}; - const std::array measurements = {quantity_point(50.45 * deg_C), quantity_point(50.967 * deg_C), - quantity_point(51.6 * deg_C), quantity_point(52.106 * deg_C), - quantity_point(52.492 * deg_C), quantity_point(52.819 * deg_C), - quantity_point(53.433 * deg_C), quantity_point(54.007 * deg_C), - quantity_point(54.523 * deg_C), quantity_point(54.99 * deg_C)}; + const estimation initial = {state{quantity_point{10. * deg_C}}, pow<2>(100. * deg_C)}; + const std::array measurements = {quantity_point{50.45 * deg_C}, quantity_point{50.967 * deg_C}, + quantity_point{51.6 * deg_C}, quantity_point{52.106 * deg_C}, + quantity_point{52.492 * deg_C}, quantity_point{52.819 * deg_C}, + quantity_point{53.433 * deg_C}, quantity_point{54.007 * deg_C}, + quantity_point{54.523 * deg_C}, quantity_point{54.99 * deg_C}}; const auto measurement_uncertainty = pow<2>(0.1 * deg_C); - auto update = [=](const estimation& previous, const QP& meassurement, Dimensionless auto gain) { + auto update = [=](const estimation& previous, const QP& meassurement, + QuantityOf auto gain) { return estimation{state_update(previous.state, meassurement, gain), covariance_update(previous.uncertainty, gain)}; }; diff --git a/example/literals/CMakeLists.txt b/example/literals/CMakeLists.txt deleted file mode 100644 index 0db4de8a..00000000 --- a/example/literals/CMakeLists.txt +++ /dev/null @@ -1,64 +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) - -# -# add_example(target ...) -# -function(add_example target) - add_executable(${target}-literals ${target}.cpp) - target_link_libraries(${target}-literals PRIVATE ${ARGN}) - target_compile_definitions(${target}-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES) -endfunction() - -add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international) -add_example(box_example mp-units::core-fmt mp-units::si) -add_example(capacitor_time_curve mp-units::core-io mp-units::si) -add_example( - clcpp_response - mp-units::core-fmt - mp-units::core-io - mp-units::si - mp-units::si-iau - mp-units::si-imperial - mp-units::si-international - mp-units::si-typographic - mp-units::si-uscs -) -add_example(experimental_angle mp-units::core-fmt mp-units::core-io mp-units::si) -add_example(foot_pound_second mp-units::core-fmt mp-units::si-fps) -add_example(total_energy mp-units::core-io mp-units::si mp-units::isq-natural) -add_example(unknown_dimension mp-units::core-io mp-units::si) - -if(NOT ${projectPrefix}LIBCXX) - add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer) - target_compile_definitions( - glide_computer_example-literals PRIVATE ${projectPrefix}NO_REFERENCES ${projectPrefix}NO_ALIASES - ) - - if(${projectPrefix}BUILD_LA) - find_package(wg21_linear_algebra CONFIG REQUIRED) - add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) - target_link_libraries(linear_algebra-literals PRIVATE wg21_linear_algebra::wg21_linear_algebra) - endif() -endif() diff --git a/example/literals/avg_speed.cpp b/example/literals/avg_speed.cpp deleted file mode 100644 index 5a3f3e05..00000000 --- a/example/literals/avg_speed.cpp +++ /dev/null @@ -1,190 +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. - -#include -#include // IWYU pragma: keep -#include -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include -#include -#include -#include -#include - -namespace { - -using namespace units::isq; - -constexpr si::speed fixed_int_si_avg_speed(si::length d, - si::time t) -{ - return d / t; -} - -constexpr si::speed fixed_double_si_avg_speed(si::length d, si::time t) -{ - return d / t; -} - -template -constexpr Speed auto si_avg_speed(si::length d, si::time t) -{ - return d / t; -} - -constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } - -template -void print_result(D distance, T duration, V speed) -{ - const auto result_in_kmph = units::quantity_cast>(speed); - std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph - << ".\n"; -} - -void example() -{ - // SI (int) - { - using namespace units::isq::si::literals; - constexpr auto distance = 220_q_km; - constexpr auto duration = 2_q_h; - - std::cout << "SI units with 'int' as representation\n"; - - print_result(distance, duration, fixed_int_si_avg_speed(distance, duration)); - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // SI (double) - { - using namespace units::isq::si::literals; - constexpr auto distance = 220._q_km; - constexpr auto duration = 2._q_h; - - std::cout << "\nSI units with 'double' as representation\n"; - - // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - print_result(distance, duration, - fixed_int_si_avg_speed(quantity_cast(distance), quantity_cast(duration))); - - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // Customary Units (int) - { - using namespace units::isq::si::international::literals; - using namespace units::isq::si::literals; - constexpr auto distance = 140_q_mi; - constexpr auto duration = 2_q_h; - - std::cout << "\nUS Customary Units with 'int' as representation\n"; - - // it is not possible to make a lossless conversion of miles to meters on an integral type - // (explicit cast needed) - print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast(distance), duration)); - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // Customary Units (double) - { - using namespace units::isq::si::international::literals; - using namespace units::isq::si::literals; - constexpr auto distance = 140._q_mi; - constexpr auto duration = 2._q_h; - - std::cout << "\nUS Customary Units with 'double' as representation\n"; - - // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - // also it is not possible to make a lossless conversion of miles to meters on an integral type - // (explicit cast needed) - print_result( - distance, duration, - fixed_int_si_avg_speed(quantity_cast>(distance), quantity_cast(duration))); - - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - print_result(distance, duration, si_avg_speed(distance, duration)); - print_result(distance, duration, avg_speed(distance, duration)); - } - - // CGS (int) - { - using namespace units::isq::si::cgs::literals; - constexpr auto distance = 22'000'000_q_cm; - constexpr si::cgs::time duration(2); // cannot use an SI literal here - - std::cout << "\nCGS units with 'int' as representation\n"; - - // it is not possible to make a lossless conversion of centimeters to meters on an integral type - // (explicit cast needed) - print_result(distance, duration, fixed_int_si_avg_speed(quantity_cast(distance), duration)); - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - - // not possible to convert both a dimension and a unit with implicit cast - print_result(distance, duration, si_avg_speed(quantity_cast(distance), duration)); - - print_result(distance, duration, avg_speed(distance, duration)); - } - - // CGS (double) - { - using namespace units::isq::si::cgs::literals; - constexpr auto distance = 22'000'000._q_cm; - constexpr si::cgs::time duration(2); // cannot use an SI literal here - - std::cout << "\nCGS units with 'double' as representation\n"; - - // conversion from a floating-point to an integral type is a truncating one so an explicit cast is needed - // it is not possible to make a lossless conversion of centimeters to meters on an integral type - // (explicit cast needed) - print_result( - distance, duration, - fixed_int_si_avg_speed(quantity_cast>(distance), quantity_cast(duration))); - - print_result(distance, duration, fixed_double_si_avg_speed(distance, duration)); - - // not possible to convert both a dimension and a unit with implicit cast - print_result(distance, duration, si_avg_speed(quantity_cast(distance), duration)); - - print_result(distance, duration, avg_speed(distance, duration)); - } -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/literals/box_example.cpp b/example/literals/box_example.cpp deleted file mode 100644 index 52759cfa..00000000 --- a/example/literals/box_example.cpp +++ /dev/null @@ -1,116 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include -#include - -namespace { - -using namespace units::isq; - -using m = si::metre; -using m2 = si::square_metre; -using m3 = si::cubic_metre; -using kg = si::kilogram; -using N = si::newton; -using kgpm3 = si::kilogram_per_metre_cub; - -inline constexpr auto g = si::standard_gravity<>; -inline constexpr si::density air_density(1.225); - - -class Box { - si::area base_; - si::length height_; - si::density density_ = air_density; -public: - constexpr Box(const si::length& length, const si::length& width, si::length height) : - base_(length * width), height_(std::move(height)) - { - } - - [[nodiscard]] constexpr si::force filled_weight() const - { - const si::volume volume = base_ * height_; - const si::mass mass = density_ * volume; - return mass * g; - } - - [[nodiscard]] constexpr si::length fill_level(const si::mass& measured_mass) const - { - return height_ * measured_mass * g / filled_weight(); - } - - [[nodiscard]] constexpr si::volume spare_capacity(const si::mass& measured_mass) const - { - return (height_ - fill_level(measured_mass)) * base_; - } - - constexpr void set_contents_density(const si::density& density_in) - { - assert(density_in > air_density); - density_ = density_in; - } -}; - -} // namespace - - -int main() -{ - using namespace units; - using namespace si::literals; - - const si::length height(200.0_q_mm); - auto box = Box(1000.0_q_mm, 500.0_q_mm, height); - box.set_contents_density(1000.0_q_kg_per_m3); - - const auto fill_time = 200.0_q_s; // time since starting fill - const auto measured_mass = 20.0_q_kg; // measured mass at fill_time - - const Length auto fill_level = box.fill_level(measured_mass); - const Dimensionless auto fill_percent = quantity_cast(fill_level / height); - const Volume auto spare_capacity = box.spare_capacity(measured_mass); - const auto input_flow_rate = measured_mass / fill_time; // unknown dimension - const Speed auto float_rise_rate = fill_level / fill_time; - const Time auto fill_time_left = (height / fill_level - 1) * fill_time; - - std::cout << "mp-units box example...\n"; - std::cout << UNITS_STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent); - std::cout << UNITS_STD_FMT::format("spare_capacity at {} = {}\n", fill_time, spare_capacity); - std::cout << UNITS_STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate); - std::cout << UNITS_STD_FMT::format("float rise rate = {}\n", float_rise_rate); - std::cout << UNITS_STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left); -} diff --git a/example/literals/capacitor_time_curve.cpp b/example/literals/capacitor_time_curve.cpp deleted file mode 100644 index e844f359..00000000 --- a/example/literals/capacitor_time_curve.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (c) 2003-2020 Andy Little. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses./ -*/ - -/* - capacitor discharge curve using compile_time - physical_quantities -*/ - -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include - -int main() -{ - using namespace units::isq; - using namespace units::isq::si; - - std::cout << "mp-units capacitor time curve example...\n"; - std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield); - std::cout.precision(3); - - constexpr auto C = 0.47_q_uF; - constexpr auto V0 = 5.0_q_V; - constexpr auto R = 4.7_q_kR; - - for (auto t = 0_q_ms; t <= 50_q_ms; ++t) { - const Voltage auto Vt = V0 * units::exp(-t / (R * C)); - - std::cout << "at " << t << " voltage is "; - - if (Vt >= 1_q_V) - std::cout << Vt; - else if (Vt >= 1_q_mV) - std::cout << quantity_cast(Vt); - else if (Vt >= 1_q_uV) - std::cout << quantity_cast(Vt); - else if (Vt >= 1_q_nV) - std::cout << quantity_cast(Vt); - else - std::cout << quantity_cast(Vt); - std::cout << "\n"; - } -} diff --git a/example/literals/clcpp_response.cpp b/example/literals/clcpp_response.cpp deleted file mode 100644 index b0b2d921..00000000 --- a/example/literals/clcpp_response.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright (c) 2003-2019 Andy Little. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses./ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -using namespace units; - -void simple_quantities() -{ - using namespace units::isq::si; - using namespace units::isq::si::international; - - using distance = length; - using duration = isq::si::time; - - constexpr distance km = 1.0_q_km; - constexpr distance miles = 1.0_q_mi; - - constexpr duration sec = 1_q_s; - constexpr duration min = 1_q_min; - constexpr duration hr = 1_q_h; - - std::cout << "A physical quantities library can choose the simple\n"; - std::cout << "option to provide output using a single type for each base unit:\n\n"; - std::cout << km << '\n'; - std::cout << miles << '\n'; - std::cout << sec << '\n'; - std::cout << min << '\n'; - std::cout << hr << "\n\n"; -} - -void quantities_with_typed_units() -{ - using namespace units::isq; - using namespace units::isq::si; - using namespace units::isq::si::international; - - constexpr length km = 1.0_q_km; - constexpr length miles = 1.0_q_mi; - - std::cout.precision(6); - - constexpr si::time sec = 1_q_s; - constexpr si::time min = 1_q_min; - constexpr si::time hr = 1_q_h; - - std::cout << "A more flexible option is to provide separate types for each unit,\n\n"; - std::cout << km << '\n'; - std::cout << miles << '\n'; - std::cout << sec << '\n'; - std::cout << min << '\n'; - std::cout << hr << "\n\n"; - - constexpr length meter = 1_q_m; - std::cout << "then a wide range of pre-defined units can be defined and converted,\n" - " for consistency and repeatability across applications:\n\n"; - - std::cout << meter << '\n'; - - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; -} - -void calcs_comparison() -{ - using namespace units::isq::si; - - std::cout << "\nA distinct unit for each type is efficient and accurate\n" - "when adding two values of the same very big\n" - "or very small type:\n\n"; - - const length L1A = 2._q_fm; - const length L2A = 3._q_fm; - const length LrA = L1A + L2A; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA); - - std::cout << "The single unit method must convert large\n" - "or small values in other units to the base unit.\n" - "This is both inefficient and inaccurate\n\n"; - - const length L1B = L1A; - const length L2B = L2A; - const length LrB = L1B + L2B; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, LrB); - - std::cout << "In multiplication and division:\n\n"; - - const area ArA = L1A * L2A; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA); - - std::cout << "similar problems arise\n\n"; - - const area ArB = L1B * L2B; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, ArB); -} - -} // namespace - -int main() -{ - std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n"; - std::cout << "http://compgroups.net/comp.lang.c++.moderated/dimensional-analysis-units/51712\n"; - std::cout << "Here converted to use mp-units library.\n\n"; - - simple_quantities(); - quantities_with_typed_units(); - calcs_comparison(); -} diff --git a/example/literals/experimental_angle.cpp b/example/literals/experimental_angle.cpp deleted file mode 100644 index 55e4b6eb..00000000 --- a/example/literals/experimental_angle.cpp +++ /dev/null @@ -1,44 +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. - -#include -#include -#include -#include -#include -#include -#include - -int main() -{ - using namespace units; - using namespace units::isq; - using namespace units::isq::si::literals; - - const Length auto lever = 20_q_cm; - const Force auto force = 500_q_N; - const Angle auto angle = 90._q_deg; - 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"; -} diff --git a/example/literals/foot_pound_second.cpp b/example/literals/foot_pound_second.cpp deleted file mode 100644 index 40f1be0f..00000000 --- a/example/literals/foot_pound_second.cpp +++ /dev/null @@ -1,137 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace units::isq; - - -// Some basic specs for the warship -struct Ship { - si::fps::length length; - si::fps::length draft; - si::fps::length beam; - - si::fps::speed speed; - si::fps::mass mass; - - si::fps::length mainGuns; - si::fps::mass shellMass; - si::fps::speed shellSpeed; - si::fps::power power; -}; - -// Print 'a' in its current units and print its value cast to the units in each of Args -template -auto fmt_line(const Q a) -{ - return UNITS_STD_FMT::format("{:22}", a) + (UNITS_STD_FMT::format(",{:20}", units::quantity_cast(a)) + ...); -} - -// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI -void print_details(std::string_view description, const Ship& ship) -{ - using namespace units::isq::si::fps::literals; - const auto waterDensity = 62.4_q_lb_per_ft3; - std::cout << UNITS_STD_FMT::format("{}\n", description); - std::cout - << UNITS_STD_FMT::format("{:20} : {}\n", "length", - fmt_line, si::length>(ship.length)) - << UNITS_STD_FMT::format("{:20} : {}\n", "draft", - fmt_line, si::length>(ship.draft)) - << UNITS_STD_FMT::format("{:20} : {}\n", "beam", - fmt_line, si::length>(ship.beam)) - << UNITS_STD_FMT::format("{:20} : {}\n", "mass", - fmt_line, si::mass>(ship.mass)) - << UNITS_STD_FMT::format( - "{:20} : {}\n", "speed", - fmt_line, si::speed>(ship.speed)) - << UNITS_STD_FMT::format("{:20} : {}\n", "power", - fmt_line, si::power>(ship.power)) - << UNITS_STD_FMT::format("{:20} : {}\n", "main guns", - fmt_line, si::length>(ship.mainGuns)) - << UNITS_STD_FMT::format("{:20} : {}\n", "fire shells weighing", - fmt_line, si::mass>(ship.shellMass)) - << UNITS_STD_FMT::format( - "{:20} : {}\n", "fire shells at", - fmt_line, si::speed>(ship.shellSpeed)) - << UNITS_STD_FMT::format("{:20} : {}\n", "volume underwater", - fmt_line, si::volume>(ship.mass / waterDensity)); -} - -int main() -{ - using namespace units::isq::si::literals; - using namespace units::isq::si::fps::literals; - - // KMS Bismark, using the units the Germans would use, taken from Wiki - auto bismark = Ship{.length{251._q_m}, - .draft{9.3_q_m}, - .beam{36_q_m}, - .speed{56_q_km_per_h}, - .mass{50'300_q_t}, - .mainGuns{380_q_mm}, - .shellMass{800_q_kg}, - .shellSpeed{820._q_m_per_s}, - .power{110.45_q_kW}}; - - // USS Iowa, using units from the foot-pound-second system - auto iowa = Ship{.length{860._q_ft}, - .draft{37._q_ft + 2._q_in}, - .beam{108._q_ft + 2._q_in}, - .speed{si::speed{33}}, - .mass{57'540_q_lton}, - .mainGuns{16_q_in}, - .shellMass{2700_q_lb}, - .shellSpeed{2690._q_ft_per_s}, - .power{212'000_q_hp}}; - - // HMS King George V, using units from the foot-pound-second system - auto kgv = Ship{.length{745.1_q_ft}, - .draft{33._q_ft + 7.5_q_in}, - .beam{103.2_q_ft + 2.5_q_in}, - .speed{si::speed{28.3}}, - .mass{42'245_q_lton}, - .mainGuns{14_q_in}, - .shellMass{1'590_q_lb}, - .shellSpeed{2483._q_ft_per_s}, - .power{110'000_q_hp}}; - - print_details("KMS Bismark, defined in appropriate units from the SI system", bismark); - std::cout << "\n\n"; - print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa); - std::cout << "\n\n"; - print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv); -} diff --git a/example/literals/glide_computer_example.cpp b/example/literals/glide_computer_example.cpp deleted file mode 100644 index 10e36f13..00000000 --- a/example/literals/glide_computer_example.cpp +++ /dev/null @@ -1,201 +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. - -#include "glide_computer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -using namespace glide_computer; - -using namespace units::isq; - -auto get_gliders() -{ - using namespace si::literals; - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES - static const std::array gliders = { - glider{"SZD-30 Pirat", {velocity(83_q_km_per_h), rate_of_climb(-0.7389_q_m_per_s)}}, - glider{"SZD-51 Junior", {velocity(80_q_km_per_h), rate_of_climb(-0.6349_q_m_per_s)}}, - glider{"SZD-48 Jantar Std 3", {velocity(110_q_km_per_h), rate_of_climb(-0.77355_q_m_per_s)}}, - glider{"SZD-56 Diana", {velocity(110_q_km_per_h), rate_of_climb(-0.63657_q_m_per_s)}}}; - UNITS_DIAGNOSTIC_POP - return gliders; -} - -auto get_weather_conditions() -{ - using namespace si::literals; - static const std::array weather_conditions = { - std::pair("Good", weather{height(1900_q_m), rate_of_climb(4.3_q_m_per_s)}), - std::pair("Medium", weather{height(1550_q_m), rate_of_climb(2.8_q_m_per_s)}), - std::pair("Bad", weather{height(850_q_m), rate_of_climb(1.8_q_m_per_s)})}; - return weather_conditions; -} - -auto get_waypoints() -{ - using namespace geographic::literals; - using namespace units::isq::si::international::literals; - static const std::array waypoints = { - waypoint{"EPPR", {54.24772_N, 18.6745_E}, altitude(16_q_ft)}, // N54°14'51.8" E18°40'28.2" - waypoint{"EPGI", {53.52442_N, 18.84947_E}, altitude(115_q_ft)} // N53°31'27.9" E18°50'58.1" - }; - return waypoints; -} - -template - requires(std::same_as, glider>) -void print(const R& gliders) -{ - std::cout << "Gliders:\n"; - std::cout << "========\n"; - for (const auto& g : gliders) { - std::cout << "- Name: " << g.name << "\n"; - std::cout << "- Polar:\n"; - for (const auto& p : g.polar) { - const auto ratio = units::quantity_cast(glide_ratio(g.polar[0])); - std::cout << UNITS_STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, - ratio, units::quantity_cast(asin(1 / ratio))); - } - std::cout << "\n"; - } -} - -template - requires(std::same_as, std::pair>) -void print(const R& conditions) -{ - std::cout << "Weather:\n"; - std::cout << "========\n"; - for (const auto& c : conditions) { - std::cout << "- " << c.first << "\n"; - const auto& w = c.second; - std::cout << " * Cloud base: " << UNITS_STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n"; - std::cout << " * Thermals strength: " << UNITS_STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n"; - std::cout << "\n"; - } -} - -template - requires(std::same_as, waypoint>) -void print(const R& waypoints) -{ - std::cout << "Waypoints:\n"; - std::cout << "==========\n"; - for (const auto& w : waypoints) - std::cout << UNITS_STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt); - std::cout << "\n"; -} - -void print(const task& t) -{ - std::cout << "Task:\n"; - std::cout << "=====\n"; - - std::cout << "- Start: " << t.get_start().name << "\n"; - std::cout << "- Finish: " << t.get_finish().name << "\n"; - std::cout << "- Length: " << UNITS_STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n"; - - std::cout << "- Legs: " - << "\n"; - for (const auto& l : t.get_legs()) - std::cout << UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length()); - std::cout << "\n"; -} - -void print(const safety& s) -{ - std::cout << "Safety:\n"; - std::cout << "=======\n"; - std::cout << "- Min AGL separation: " << UNITS_STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n"; - std::cout << "\n"; -} - -void print(const aircraft_tow& tow) -{ - std::cout << "Tow:\n"; - std::cout << "====\n"; - std::cout << "- Type: aircraft\n"; - std::cout << "- Height: " << UNITS_STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n"; - std::cout << "- Performance: " << UNITS_STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n"; - std::cout << "\n"; -} - -void example() -{ - using namespace si::literals; - - const safety sfty = {height(300_q_m)}; - const auto gliders = get_gliders(); - const auto waypoints = get_waypoints(); - const auto weather_conditions = get_weather_conditions(); - const task t = {waypoints[0], waypoints[1], waypoints[0]}; - const aircraft_tow tow = {height(400_q_m), rate_of_climb(1.6_q_m_per_s)}; - // TODO use C++20 date library when available - // set `start_time` to 11:00 am today - const timestamp start_time(std::chrono::system_clock::now()); - - print(sfty); - print(gliders); - print(waypoints); - print(weather_conditions); - print(t); - print(tow); - - for (const auto& g : gliders) { - for (const auto& c : weather_conditions) { - std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first; - std::cout << txt << "\n"; - std::cout << UNITS_STD_FMT::format("{0:=^{1}}\n\n", "", txt.size()); - - estimate(start_time, g, c.second, t, sfty, tow); - - std::cout << "\n\n"; - } - } -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/literals/linear_algebra.cpp b/example/literals/linear_algebra.cpp deleted file mode 100644 index afef901d..00000000 --- a/example/literals/linear_algebra.cpp +++ /dev/null @@ -1,231 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include // IWYU pragma: keep -#include -#include -#include - -template -using vector = STD_LA::fixed_size_column_vector; - -template -using matrix = STD_LA::fixed_size_matrix; - -namespace STD_LA { - -template -std::ostream& operator<<(std::ostream& os, const ::vector& v) -{ - os << "|"; - for (auto i = 0U; i < v.size(); ++i) { - os << UNITS_STD_FMT::format(" {:>9}", v(i)); - } - os << " |"; - return os; -} - -template -std::ostream& operator<<(std::ostream& os, const ::matrix& v) -{ - for (auto i = 0U; i < v.rows(); ++i) { - os << "|"; - for (auto j = 0U; j < v.columns(); ++j) { - os << UNITS_STD_FMT::format(" {:>9}", v(i, j)); - } - os << (i != v.rows() - 1U ? " |\n" : " |"); - } - return os; -} - -} // namespace STD_LA - -namespace { - -using namespace units::isq; -using namespace units::isq::si::literals; - -void vector_of_quantity_add() -{ - std::cout << "\nvector_of_quantity_add:\n"; - - vector> v = {4_q_m, 8_q_m, 12_q_m}; - vector> u = {3_q_m, 2_q_m, 1_q_m}; - vector> t = {3_q_km, 2_q_km, 1_q_km}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - std::cout << "t = " << t << "\n"; - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << vector>(t) << "\n"; -} - -void vector_of_quantity_divide_by_scalar() -{ - std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; - - vector> v = {4_q_m, 8_q_m, 12_q_m}; - - std::cout << "v = " << v << "\n"; - - std::cout << "v / 2_q_s = " << v / quantity_cast(2_q_s) << "\n"; - std::cout << "v / 2 = " << v / 2 << "\n"; -} - -void vector_of_quantity_tests() -{ - vector_of_quantity_add(); - vector_of_quantity_divide_by_scalar(); -} - -void matrix_of_quantity_add() -{ - std::cout << "\nmatrix_of_quantity_add:\n"; - - matrix> v = {{1_q_m, 2_q_m, 3_q_m}, {4_q_m, 5_q_m, 6_q_m}, {7_q_m, 8_q_m, 9_q_m}}; - matrix> u = {{3_q_m, 2_q_m, 1_q_m}, {3_q_m, 2_q_m, 1_q_m}, {3_q_m, 2_q_m, 1_q_m}}; - matrix> t = {{3_q_mm, 2_q_mm, 1_q_mm}, {3_q_mm, 2_q_mm, 1_q_mm}, {3_q_mm, 2_q_mm, 1_q_mm}}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - std::cout << "t =\n" << t << "\n"; - - std::cout << "v + u =\n" << v + u << "\n"; - std::cout << "v + t =\n" << v + t << "\n"; - - std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void matrix_of_quantity_divide_by_scalar() -{ - std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n"; - - matrix> v = {{2_q_m, 4_q_m, 6_q_m}, {4_q_m, 6_q_m, 8_q_m}, {8_q_m, 4_q_m, 2_q_m}}; - - std::cout << "v =\n" << v << "\n"; - - std::cout << "v / 2_q_s =\n" << v / quantity_cast(2_q_s) << "\n"; - std::cout << "v / 2 =\n" << v / 2 << "\n"; -} - -void matrix_of_quantity_tests() -{ - matrix_of_quantity_add(); - matrix_of_quantity_divide_by_scalar(); -} - -template -using length_v = si::length>; - -template -using force_v = si::force>; - -void quantity_of_vector_add() -{ - std::cout << "\nquantity_of_vector_add:\n"; - - length_v<> v(vector<>{4, 8, 12}); - length_v<> u(vector<>{3, 2, 1}); - length_v t(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - std::cout << "t = " << t << "\n"; - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << quantity_cast(t) << "\n"; -} - -void quantity_of_vector_divide_by_scalar() -{ - std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; - - length_v<> v(vector<>{4, 8, 12}); - - std::cout << "v = " << v << "\n"; - - std::cout << "v / 2_q_s = " << v / 2_q_s << "\n"; - std::cout << "v / 2 = " << v / 2 << "\n"; -} - -void quantity_of_vector_tests() -{ - quantity_of_vector_add(); - quantity_of_vector_divide_by_scalar(); -} - -template -using length_m = si::length>; - -void quantity_of_matrix_add() -{ - std::cout << "\nquantity_of_matrix_add:\n"; - - length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}}); - length_m t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - std::cout << "t =\n" << t << "\n"; - - std::cout << "v + u =\n" << v + u << "\n"; - std::cout << "v + t =\n" << v + t << "\n"; - - // TODO Fix it - // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void quantity_of_matrix_divide_by_scalar() -{ - std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; - - length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}}); - - std::cout << "v =\n" << v << "\n"; - - std::cout << "v / 2_q_s =\n" << v / 2_q_s << "\n"; - std::cout << "v / 2 =\n" << v / 2 << "\n"; -} - -void quantity_of_matrix_tests() -{ - quantity_of_matrix_add(); - quantity_of_matrix_divide_by_scalar(); -} - -} // namespace - -int main() -{ - vector_of_quantity_tests(); - matrix_of_quantity_tests(); - quantity_of_vector_tests(); - quantity_of_matrix_tests(); -} diff --git a/example/literals/total_energy.cpp b/example/literals/total_energy.cpp deleted file mode 100644 index 0cda3706..00000000 --- a/example/literals/total_energy.cpp +++ /dev/null @@ -1,103 +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. - -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -namespace { - -using namespace units::isq; - -Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c) -{ - return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c))); -} - -void si_example() -{ - using namespace units::isq::si; - - constexpr Speed auto c = si2019::speed_of_light<>; - - std::cout << "\n*** SI units (c = " << c << ") ***\n"; - - const Momentum auto p = 4._q_GeV / c; - const Mass auto m = 3._q_GeV / pow<2>(c); - const Energy auto E = total_energy(p, m, c); - - std::cout << "[in GeV]\n" - << "p = " << p << "\n" - << "m = " << m << "\n" - << "E = " << E << "\n"; - - const momentum p_si = p; - const mass m_si = m; - const energy E_si = total_energy(p_si, m_si, c); - - std::cout << "\n[in SI units]\n" - << "p = " << p_si << "\n" - << "m = " << m_si << "\n" - << "E = " << E_si << "\n"; - - std::cout << "\n[converted from SI units back to GeV]\n" - << "E = " << quantity_cast(E_si) << "\n"; -} - -void natural_example() -{ - using namespace units::isq::natural; - - // TODO Typical UDLs will not work here as the same units are reused by many quantities. - // Should we define some strange ones (i.e. _q_mass_GeV)? - - constexpr Speed auto c = speed_of_light<>; - const momentum p(4); - const mass m(3); - const Energy auto E = total_energy(p, m, c); - - std::cout << "\n*** Natural units (c = " << c << ") ***\n" - << "p = " << p << "\n" - << "m = " << m << "\n" - << "E = " << E << "\n"; -} - -} // namespace - -int main() -{ - try { - si_example(); - natural_example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/literals/unknown_dimension.cpp b/example/literals/unknown_dimension.cpp deleted file mode 100644 index fd26ee92..00000000 --- a/example/literals/unknown_dimension.cpp +++ /dev/null @@ -1,71 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -namespace { - -template -constexpr units::isq::Speed auto avg_speed(D d, T t) -{ - return d / t; -} - -void example() -{ - using namespace units::isq; - using namespace units::isq::si::literals; - - Length auto d1 = 123_q_m; - Time auto t1 = 10_q_s; - Speed auto v1 = avg_speed(d1, t1); - - auto temp1 = - v1 * 50_q_m; // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit' - Speed auto v2 = temp1 / 100_q_m; // back to known dimensions again - Length auto d2 = v2 * 60_q_s; - - std::cout << "d1 = " << d1 << '\n'; - std::cout << "t1 = " << t1 << '\n'; - std::cout << "v1 = " << v1 << '\n'; - std::cout << "temp1 = " << temp1 << '\n'; - std::cout << "v2 = " << v2 << '\n'; - std::cout << "d2 = " << d2 << '\n'; -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/measurement.cpp b/example/measurement.cpp index ca7df2f3..a312f4cc 100644 --- a/example/measurement.cpp +++ b/example/measurement.cpp @@ -20,37 +20,36 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include namespace { -template +template class measurement { public: using value_type = T; measurement() = default; - constexpr explicit measurement(const value_type& val, const value_type& err = {}) : value_(val) + constexpr explicit measurement(value_type val, const value_type& err = {}) : value_(std::move(val)) { // it sucks that using declaration cannot be provided for a constructor initializer list using namespace std; uncertainty_ = abs(err); } - constexpr const value_type& value() const { return value_; } - constexpr const value_type& uncertainty() const { return uncertainty_; } + [[nodiscard]] constexpr const value_type& value() const { return value_; } + [[nodiscard]] constexpr const value_type& uncertainty() const { return uncertainty_; } - constexpr value_type relative_uncertainty() const { return uncertainty() / value(); } - constexpr value_type lower_bound() const { return value() - uncertainty(); } - constexpr value_type upper_bound() const { return value() + uncertainty(); } + [[nodiscard]] constexpr value_type relative_uncertainty() const { return uncertainty() / value(); } + [[nodiscard]] constexpr value_type lower_bound() const { return value() - uncertainty(); } + [[nodiscard]] constexpr value_type upper_bound() const { return value() + uncertainty(); } [[nodiscard]] constexpr measurement operator-() const { return measurement(-value(), uncertainty()); } @@ -118,27 +117,27 @@ private: } // namespace +template +inline constexpr bool mp_units::is_scalar> = true; +template +inline constexpr bool mp_units::is_vector> = true; + +static_assert(mp_units::RepresentationOf, mp_units::quantity_character::scalar>); namespace { -static_assert(units::Representation>); - void example() { - using namespace units::isq; + using namespace mp_units; + using namespace mp_units::si::unit_symbols; - const auto a = si::acceleration>(measurement(9.8, 0.1)); - const auto t = si::time>(measurement(1.2, 0.1)); + const auto a = isq::acceleration(measurement{9.8, 0.1} * (m / s2)); + const auto t = measurement{1.2, 0.1} * s; - const Speed auto v1 = a * t; -#if UNITS_DOWNCAST_MODE == 0 - std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast(v1) - << '\n'; -#else - std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast(v1) << '\n'; -#endif + const QuantityOf auto v = a * t; + std::cout << a << " * " << t << " = " << v << " = " << v[km / h] << '\n'; - si::length> length(measurement(123., 1.)); + const auto length = measurement{123., 1.} * m; std::cout << "10 * " << length << " = " << 10 * length << '\n'; } diff --git a/example/references/CMakeLists.txt b/example/references/CMakeLists.txt deleted file mode 100644 index de614d91..00000000 --- a/example/references/CMakeLists.txt +++ /dev/null @@ -1,64 +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) - -# -# add_example(target ...) -# -function(add_example target) - add_executable(${target}-references ${target}.cpp) - target_link_libraries(${target}-references PRIVATE ${ARGN}) - target_compile_definitions(${target}-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES) -endfunction() - -add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international) -add_example(box_example mp-units::core-fmt mp-units::si) -add_example(capacitor_time_curve mp-units::core-io mp-units::si) -add_example( - clcpp_response - mp-units::core-fmt - mp-units::core-io - mp-units::si - mp-units::si-iau - mp-units::si-imperial - mp-units::si-international - mp-units::si-typographic - mp-units::si-uscs -) -add_example(experimental_angle mp-units::core-fmt mp-units::core-io mp-units::si) -add_example(foot_pound_second mp-units::core-fmt mp-units::si-fps) -add_example(total_energy mp-units::core-io mp-units::si mp-units::isq-natural) -add_example(unknown_dimension mp-units::core-io mp-units::si) - -if(NOT ${projectPrefix}LIBCXX) - add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer) - target_compile_definitions( - glide_computer_example-references PRIVATE ${projectPrefix}NO_LITERALS ${projectPrefix}NO_ALIASES - ) - - if(${projectPrefix}BUILD_LA) - find_package(wg21_linear_algebra CONFIG REQUIRED) - add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) - target_link_libraries(linear_algebra-references PRIVATE wg21_linear_algebra::wg21_linear_algebra) - endif() -endif() diff --git a/example/references/box_example.cpp b/example/references/box_example.cpp deleted file mode 100644 index e5dc73b2..00000000 --- a/example/references/box_example.cpp +++ /dev/null @@ -1,112 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include -#include - -namespace { - -using namespace units::isq; -using namespace si::mass_references; -using namespace si::volume_references; - -inline constexpr Acceleration auto g = si::standard_gravity<>; -inline constexpr Density auto air_density = 1.225 * (kg / m3); - -class Box { - si::area base_; - si::length height_; - si::density density_ = air_density; -public: - constexpr Box(const si::length& length, const si::length& width, si::length height) : - base_(length * width), height_(std::move(height)) - { - } - - [[nodiscard]] constexpr si::force filled_weight() const - { - const Volume auto volume = base_ * height_; - const Mass auto mass = density_ * volume; - return mass * g; - } - - [[nodiscard]] constexpr si::length fill_level(const si::mass& measured_mass) const - { - return height_ * measured_mass * g / filled_weight(); - } - - [[nodiscard]] constexpr si::volume spare_capacity(const si::mass& measured_mass) const - { - return (height_ - fill_level(measured_mass)) * base_; - } - - constexpr void set_contents_density(const si::density& density_in) - { - assert(density_in > air_density); - density_ = density_in; - } -}; - -} // namespace - - -int main() -{ - using namespace units; - using namespace units::isq::si; - using namespace length_references; - using namespace time_references; - - const auto height = quantity_cast(200.0 * mm); - auto box = Box(1000.0 * mm, 500.0 * mm, height); - box.set_contents_density(1000.0 * (kg / m3)); - - const auto fill_time = 200.0 * s; // time since starting fill - const auto measured_mass = 20.0 * kg; // measured mass at fill_time - - const Length auto fill_level = box.fill_level(measured_mass); - const Dimensionless auto fill_percent = quantity_cast(fill_level / height); - const Volume auto spare_capacity = box.spare_capacity(measured_mass); - const auto input_flow_rate = measured_mass / fill_time; // unknown dimension - const Speed auto float_rise_rate = fill_level / fill_time; - const Time auto fill_time_left = (height / fill_level - 1) * fill_time; - - std::cout << "mp-units box example...\n"; - std::cout << UNITS_STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_percent); - std::cout << UNITS_STD_FMT::format("spare_capacity at {} = {}\n", fill_time, spare_capacity); - std::cout << UNITS_STD_FMT::format("input flow rate after {} = {}\n", fill_time, input_flow_rate); - std::cout << UNITS_STD_FMT::format("float rise rate = {}\n", float_rise_rate); - std::cout << UNITS_STD_FMT::format("box full E.T.A. at current flow rate = {}\n", fill_time_left); -} diff --git a/example/references/clcpp_response.cpp b/example/references/clcpp_response.cpp deleted file mode 100644 index 705f45c7..00000000 --- a/example/references/clcpp_response.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (c) 2003-2019 Andy Little. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses./ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -void simple_quantities() -{ - using namespace units::isq; - using namespace units::isq::si; - using namespace units::isq::si::references; - using namespace units::isq::si::international::references; - - using distance = si::length; - using duration = si::time; - - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_SHADOW - constexpr distance km = 1.0 * references::km; - constexpr distance miles = 1.0 * mi; - - constexpr duration sec = 1 * s; - constexpr duration min = 1 * references::min; - constexpr duration hr = 1 * h; - UNITS_DIAGNOSTIC_POP - - std::cout << "A physical quantities library can choose the simple\n"; - std::cout << "option to provide output using a single type for each base unit:\n\n"; - std::cout << km << '\n'; - std::cout << miles << '\n'; - std::cout << sec << '\n'; - std::cout << min << '\n'; - std::cout << hr << "\n\n"; -} - -void quantities_with_typed_units() -{ - using namespace units::isq; - using namespace units::isq::si; - using namespace units::isq::si::references; - using namespace units::isq::si::international; - using namespace units::isq::si::international::references; - - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_SHADOW - constexpr length km = 1.0 * si::references::km; - constexpr length miles = 1.0 * mi; - - std::cout.precision(6); - - constexpr si::time sec = 1 * s; - constexpr si::time min = 1 * si::references::min; - constexpr si::time hr = 1 * h; - UNITS_DIAGNOSTIC_POP - - std::cout << "A more flexible option is to provide separate types for each unit,\n\n"; - std::cout << km << '\n'; - std::cout << miles << '\n'; - std::cout << sec << '\n'; - std::cout << min << '\n'; - std::cout << hr << "\n\n"; - - constexpr auto meter = 1 * m; - std::cout << "then a wide range of pre-defined units can be defined and converted,\n" - " for consistency and repeatability across applications:\n\n"; - - std::cout << meter << '\n'; - - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; - std::cout << " = " << quantity_cast(meter) << '\n'; -} - -void calcs_comparison() -{ - using namespace units::isq::si; - using namespace units::isq::si::references; - - std::cout << "\nA distinct unit for each type is efficient and accurate\n" - "when adding two values of the same very big\n" - "or very small type:\n\n"; - - const length L1A = 2.f * fm; - const length L2A = 3.f * fm; - const length LrA = L1A + L2A; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA); - - std::cout << "The single unit method must convert large\n" - "or small values in other units to the base unit.\n" - "This is both inefficient and inaccurate\n\n"; - - const length L1B = L1A; - const length L2B = L2A; - const length LrB = L1B + L2B; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, LrB); - - std::cout << "In multiplication and division:\n\n"; - - const area ArA = L1A * L2A; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA); - - std::cout << "similar problems arise\n\n"; - - const area ArB = L1B * L2B; - std::cout << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1B, L2B, ArB); -} - -} // namespace - -int main() -{ - std::cout << "This demo was originally posted on com.lang.c++.moderated in 2006\n"; - std::cout << "http://compgroups.net/comp.lang.c++.moderated/dimensional-analysis-units/51712\n"; - std::cout << "Here converted to use mp-units library.\n\n"; - - simple_quantities(); - quantities_with_typed_units(); - calcs_comparison(); -} diff --git a/example/references/foot_pound_second.cpp b/example/references/foot_pound_second.cpp deleted file mode 100644 index 13498382..00000000 --- a/example/references/foot_pound_second.cpp +++ /dev/null @@ -1,141 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace units::isq; - - -// Some basic specs for the warship -struct Ship { - si::fps::length length; - si::fps::length draft; - si::fps::length beam; - - si::fps::speed speed; - si::fps::mass mass; - - si::fps::length mainGuns; - si::fps::mass shellMass; - si::fps::speed shellSpeed; - si::fps::power power; -}; - -// Print 'a' in its current units and print its value cast to the units in each of Args -template -auto fmt_line(const Q a) -{ - return UNITS_STD_FMT::format("{:22}", a) + (UNITS_STD_FMT::format(",{:20}", units::quantity_cast(a)) + ...); -} - -// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI -void print_details(std::string_view description, const Ship& ship) -{ - using namespace units::isq::si::fps::references; - const auto waterDensity = 62.4 * (lb / ft3); - std::cout << UNITS_STD_FMT::format("{}\n", description); - std::cout - << UNITS_STD_FMT::format("{:20} : {}\n", "length", - fmt_line, si::length>(ship.length)) - << UNITS_STD_FMT::format("{:20} : {}\n", "draft", - fmt_line, si::length>(ship.draft)) - << UNITS_STD_FMT::format("{:20} : {}\n", "beam", - fmt_line, si::length>(ship.beam)) - << UNITS_STD_FMT::format("{:20} : {}\n", "mass", - fmt_line, si::mass>(ship.mass)) - << UNITS_STD_FMT::format( - "{:20} : {}\n", "speed", - fmt_line, si::speed>(ship.speed)) - << UNITS_STD_FMT::format("{:20} : {}\n", "power", - fmt_line, si::power>(ship.power)) - << UNITS_STD_FMT::format("{:20} : {}\n", "main guns", - fmt_line, si::length>(ship.mainGuns)) - << UNITS_STD_FMT::format("{:20} : {}\n", "fire shells weighing", - fmt_line, si::mass>(ship.shellMass)) - << UNITS_STD_FMT::format( - "{:20} : {}\n", "fire shells at", - fmt_line, si::speed>(ship.shellSpeed)) - << UNITS_STD_FMT::format("{:20} : {}\n", "volume underwater", - fmt_line, si::volume>(ship.mass / waterDensity)); -} - -int main() -{ - using namespace units::isq::si::references; - using namespace units::isq::si::fps::references; - using units::isq::si::fps::references::ft; // collides with si::femtotonne (alias unit of mass) - - // KMS Bismark, using the units the Germans would use, taken from Wiki - auto bismark = Ship{.length{251. * m}, - .draft{9.3 * m}, - .beam{36 * m}, - .speed{56 * (km / h)}, - .mass{50'300 * t}, - .mainGuns{380 * mm}, - .shellMass{800 * kg}, - .shellSpeed{820. * (m / s)}, - .power{110.45 * kW}}; - - // USS Iowa, using units from the foot-pound-second system - auto iowa = Ship{.length{860. * ft}, - .draft{37. * ft + 2. * in}, - .beam{108. * ft + 2. * in}, - .speed{33 * units::isq::si::international::references::kn}, - .mass{57'540 * lton}, - .mainGuns{16 * in}, - .shellMass{2700 * lb}, - .shellSpeed{2690. * (ft / s)}, - .power{212'000 * hp}}; - - // HMS King George V, using units from the foot-pound-second system - auto kgv = Ship{.length{745.1 * ft}, - .draft{33. * ft + 7.5 * in}, - .beam{103.2 * ft + 2.5 * in}, - .speed{28.3 * units::isq::si::international::references::kn}, - .mass{42'245 * lton}, - .mainGuns{14 * in}, - .shellMass{1'590 * lb}, - .shellSpeed{2483. * (ft / s)}, - .power{110'000 * hp}}; - - print_details("KMS Bismark, defined in appropriate units from the SI system", bismark); - std::cout << "\n\n"; - print_details("USS Iowa, defined in appropriate units foot-pound-second system", iowa); - std::cout << "\n\n"; - print_details("HMS King George V, defined in appropriate units foot-pound-second system", kgv); -} diff --git a/example/references/glide_computer_example.cpp b/example/references/glide_computer_example.cpp deleted file mode 100644 index f79981fb..00000000 --- a/example/references/glide_computer_example.cpp +++ /dev/null @@ -1,201 +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. - -#include "glide_computer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -using namespace glide_computer; - -using namespace units::isq; - -auto get_gliders() -{ - using namespace si::references; - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES - static const std::array gliders = { - glider{"SZD-30 Pirat", {velocity(83 * (km / h)), rate_of_climb(-0.7389 * (m / s))}}, - glider{"SZD-51 Junior", {velocity(80 * (km / h)), rate_of_climb(-0.6349 * (m / s))}}, - glider{"SZD-48 Jantar Std 3", {velocity(110 * (km / h)), rate_of_climb(-0.77355 * (m / s))}}, - glider{"SZD-56 Diana", {velocity(110 * (km / h)), rate_of_climb(-0.63657 * (m / s))}}}; - UNITS_DIAGNOSTIC_POP - return gliders; -} - -auto get_weather_conditions() -{ - using namespace si::references; - static const std::array weather_conditions = { - std::pair("Good", weather{height(1900 * m), rate_of_climb(4.3 * (m / s))}), - std::pair("Medium", weather{height(1550 * m), rate_of_climb(2.8 * (m / s))}), - std::pair("Bad", weather{height(850 * m), rate_of_climb(1.8 * (m / s))})}; - return weather_conditions; -} - -auto get_waypoints() -{ - using namespace geographic::literals; - using namespace units::isq::si::international::references; - static const std::array waypoints = { - waypoint{"EPPR", {54.24772_N, 18.6745_E}, altitude(16 * ft)}, // N54°14'51.8" E18°40'28.2" - waypoint{"EPGI", {53.52442_N, 18.84947_E}, altitude(115 * ft)} // N53°31'27.9" E18°50'58.1" - }; - return waypoints; -} - -template - requires(std::same_as, glider>) -void print(const R& gliders) -{ - std::cout << "Gliders:\n"; - std::cout << "========\n"; - for (const auto& g : gliders) { - std::cout << "- Name: " << g.name << "\n"; - std::cout << "- Polar:\n"; - for (const auto& p : g.polar) { - const auto ratio = units::quantity_cast(glide_ratio(g.polar[0])); - std::cout << UNITS_STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, - ratio, units::quantity_cast(asin(1 / ratio))); - } - std::cout << "\n"; - } -} - -template - requires(std::same_as, std::pair>) -void print(const R& conditions) -{ - std::cout << "Weather:\n"; - std::cout << "========\n"; - for (const auto& c : conditions) { - std::cout << "- " << c.first << "\n"; - const auto& w = c.second; - std::cout << " * Cloud base: " << UNITS_STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n"; - std::cout << " * Thermals strength: " << UNITS_STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n"; - std::cout << "\n"; - } -} - -template - requires(std::same_as, waypoint>) -void print(const R& waypoints) -{ - std::cout << "Waypoints:\n"; - std::cout << "==========\n"; - for (const auto& w : waypoints) - std::cout << UNITS_STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt); - std::cout << "\n"; -} - -void print(const task& t) -{ - std::cout << "Task:\n"; - std::cout << "=====\n"; - - std::cout << "- Start: " << t.get_start().name << "\n"; - std::cout << "- Finish: " << t.get_finish().name << "\n"; - std::cout << "- Length: " << UNITS_STD_FMT::format("{:%.1Q %q}", t.get_length()) << "\n"; - - std::cout << "- Legs: " - << "\n"; - for (const auto& l : t.get_legs()) - std::cout << UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_length()); - std::cout << "\n"; -} - -void print(const safety& s) -{ - std::cout << "Safety:\n"; - std::cout << "=======\n"; - std::cout << "- Min AGL separation: " << UNITS_STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n"; - std::cout << "\n"; -} - -void print(const aircraft_tow& tow) -{ - std::cout << "Tow:\n"; - std::cout << "====\n"; - std::cout << "- Type: aircraft\n"; - std::cout << "- Height: " << UNITS_STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n"; - std::cout << "- Performance: " << UNITS_STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n"; - std::cout << "\n"; -} - -void example() -{ - using namespace si::references; - - const safety sfty = {height(300 * m)}; - const auto gliders = get_gliders(); - const auto waypoints = get_waypoints(); - const auto weather_conditions = get_weather_conditions(); - const task t = {waypoints[0], waypoints[1], waypoints[0]}; - const aircraft_tow tow = {height(400 * m), rate_of_climb(1.6 * (m / s))}; - // TODO use C++20 date library when available - // set `start_time` to 11:00 am today - const timestamp start_time(std::chrono::system_clock::now()); - - print(sfty); - print(gliders); - print(waypoints); - print(weather_conditions); - print(t); - print(tow); - - for (const auto& g : gliders) { - for (const auto& c : weather_conditions) { - std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first; - std::cout << txt << "\n"; - std::cout << UNITS_STD_FMT::format("{0:=^{1}}\n\n", "", txt.size()); - - estimate(start_time, g, c.second, t, sfty, tow); - - std::cout << "\n\n"; - } - } -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/references/linear_algebra.cpp b/example/references/linear_algebra.cpp deleted file mode 100644 index adf0de38..00000000 --- a/example/references/linear_algebra.cpp +++ /dev/null @@ -1,232 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include // IWYU pragma: keep -#include -#include -#include - -template -using vector = STD_LA::fixed_size_column_vector; - -template -using matrix = STD_LA::fixed_size_matrix; - -namespace STD_LA { - -template -std::ostream& operator<<(std::ostream& os, const ::vector& v) -{ - os << "|"; - for (auto i = 0U; i < v.size(); ++i) { - os << UNITS_STD_FMT::format(" {:>9}", v(i)); - } - os << " |"; - return os; -} - -template -std::ostream& operator<<(std::ostream& os, const ::matrix& v) -{ - for (auto i = 0U; i < v.rows(); ++i) { - os << "|"; - for (auto j = 0U; j < v.columns(); ++j) { - os << UNITS_STD_FMT::format(" {:>9}", v(i, j)); - } - os << (i != v.rows() - 1U ? " |\n" : " |"); - } - return os; -} - -} // namespace STD_LA - -namespace { - -using namespace units::isq; -using namespace units::isq::si::length_references; -using namespace units::isq::si::time_references; - -void vector_of_quantity_add() -{ - std::cout << "\nvector_of_quantity_add:\n"; - - vector> v = {4 * m, 8 * m, 12 * m}; - vector> u = {3 * m, 2 * m, 1 * m}; - vector> t = {3 * km, 2 * km, 1 * km}; - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - std::cout << "t = " << t << "\n"; - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << vector>(t) << "\n"; -} - -void vector_of_quantity_divide_by_scalar() -{ - std::cout << "\nvector_of_quantity_divide_by_scalar:\n"; - - vector> v = {4 * m, 8 * m, 12 * m}; - - std::cout << "v = " << v << "\n"; - - std::cout << "v / (2 * s) = " << v / (2 * s) << "\n"; - std::cout << "v / 2 = " << v / 2 << "\n"; -} - -void vector_of_quantity_tests() -{ - vector_of_quantity_add(); - vector_of_quantity_divide_by_scalar(); -} - -void matrix_of_quantity_add() -{ - std::cout << "\nmatrix_of_quantity_add:\n"; - - matrix> v = {{1 * m, 2 * m, 3 * m}, {4 * m, 5 * m, 6 * m}, {7 * m, 8 * m, 9 * m}}; - matrix> u = {{3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}, {3 * m, 2 * m, 1 * m}}; - matrix> t = {{3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}, {3 * mm, 2 * mm, 1 * mm}}; - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - std::cout << "t =\n" << t << "\n"; - - std::cout << "v + u =\n" << v + u << "\n"; - std::cout << "v + t =\n" << v + t << "\n"; - - std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void matrix_of_quantity_divide_by_scalar() -{ - std::cout << "\nmatrix_of_quantity_divide_by_scalar:\n"; - - matrix> v = {{2 * m, 4 * m, 6 * m}, {4 * m, 6 * m, 8 * m}, {8 * m, 4 * m, 2 * m}}; - - std::cout << "v =\n" << v << "\n"; - - std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; - std::cout << "v / 2 =\n" << v / 2 << "\n"; -} - -void matrix_of_quantity_tests() -{ - matrix_of_quantity_add(); - matrix_of_quantity_divide_by_scalar(); -} - -template -using length_v = si::length>; - -template -using force_v = si::force>; - -void quantity_of_vector_add() -{ - std::cout << "\nquantity_of_vector_add:\n"; - - length_v<> v(vector<>{4, 8, 12}); - length_v<> u(vector<>{3, 2, 1}); - length_v t(vector<>{3, 2, 1}); - - std::cout << "v = " << v << "\n"; - std::cout << "u = " << u << "\n"; - std::cout << "t = " << t << "\n"; - - std::cout << "v + u = " << v + u << "\n"; - std::cout << "v + t = " << v + t << "\n"; - std::cout << "t[m] = " << quantity_cast(t) << "\n"; -} - -void quantity_of_vector_divide_by_scalar() -{ - std::cout << "\nquantity_of_vector_divide_by_scalar:\n"; - - length_v<> v(vector<>{4, 8, 12}); - - std::cout << "v = " << v << "\n"; - - std::cout << "v / (2 * s) = " << v / (2 * s) << "\n"; - std::cout << "v / 2 = " << v / 2 << "\n"; -} - -void quantity_of_vector_tests() -{ - quantity_of_vector_add(); - quantity_of_vector_divide_by_scalar(); -} - -template -using length_m = si::length>; - -void quantity_of_matrix_add() -{ - std::cout << "\nquantity_of_matrix_add:\n"; - - length_m<> v(matrix<>{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); - length_m<> u(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}}); - length_m t(matrix<>{{3, 2, 1}, {3, 2, 1}, {3, 2, 1}}); - - std::cout << "v =\n" << v << "\n"; - std::cout << "u =\n" << u << "\n"; - std::cout << "t =\n" << t << "\n"; - - std::cout << "v + u =\n" << v + u << "\n"; - std::cout << "v + t =\n" << v + t << "\n"; - - // TODO Fix it - // std::cout << "v[mm] =\n" << matrix>(v) << "\n"; -} - -void quantity_of_matrix_divide_by_scalar() -{ - std::cout << "\nquantity_of_matrix_divide_by_scalar:\n"; - - length_m<> v(matrix<>{{2, 4, 6}, {4, 6, 8}, {8, 4, 2}}); - - std::cout << "v =\n" << v << "\n"; - - std::cout << "v / (2 * s) =\n" << v / (2 * s) << "\n"; - std::cout << "v / 2 =\n" << v / 2 << "\n"; -} - -void quantity_of_matrix_tests() -{ - quantity_of_matrix_add(); - quantity_of_matrix_divide_by_scalar(); -} - -} // namespace - -int main() -{ - vector_of_quantity_tests(); - matrix_of_quantity_tests(); - quantity_of_vector_tests(); - quantity_of_matrix_tests(); -} diff --git a/example/references/total_energy.cpp b/example/references/total_energy.cpp deleted file mode 100644 index ec6e8f3e..00000000 --- a/example/references/total_energy.cpp +++ /dev/null @@ -1,102 +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. - -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -namespace { - -using namespace units::isq; - -Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c) -{ - return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c))); -} - -void si_example() -{ - using namespace units::isq::si; - using namespace units::isq::si::energy_references; - - constexpr Speed auto c = si2019::speed_of_light<>; - - std::cout << "\n*** SI units (c = " << c << ") ***\n"; - - const Momentum auto p = 4. * GeV / c; - const Mass auto m = 3. * GeV / pow<2>(c); - const Energy auto E = total_energy(p, m, c); - - std::cout << "[in GeV]\n" - << "p = " << p << "\n" - << "m = " << m << "\n" - << "E = " << E << "\n"; - - const momentum p_si = p; - const mass m_si = m; - const energy E_si = total_energy(p_si, m_si, c); - - std::cout << "\n[in SI units]\n" - << "p = " << p_si << "\n" - << "m = " << m_si << "\n" - << "E = " << E_si << "\n"; - - std::cout << "\n[converted from SI units back to GeV]\n" - << "E = " << quantity_cast(E_si) << "\n"; -} - -void natural_example() -{ - using namespace units::isq::natural; - using namespace units::isq::natural::references; - - constexpr Speed auto c = speed_of_light<>; - const auto p = 4. * momentum_references::GeV; - const auto m = 3. * mass_references::GeV; - const Energy auto E = total_energy(p, m, c); - - std::cout << "\n*** Natural units (c = " << c << ") ***\n" - << "p = " << p << "\n" - << "m = " << m << "\n" - << "E = " << E << "\n"; -} - -} // namespace - -int main() -{ - try { - si_example(); - natural_example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/references/unknown_dimension.cpp b/example/references/unknown_dimension.cpp deleted file mode 100644 index d2ea9c47..00000000 --- a/example/references/unknown_dimension.cpp +++ /dev/null @@ -1,71 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -namespace { - -template -constexpr units::isq::Speed auto avg_speed(D d, T t) -{ - return d / t; -} - -void example() -{ - using namespace units::isq; - using namespace units::isq::si::references; - - Length auto d1 = 123 * m; - Time auto t1 = 10 * s; - Speed auto v1 = avg_speed(d1, t1); - - auto temp1 = - v1 * (50 * m); // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit' - Speed auto v2 = temp1 / (100 * m); // back to known dimensions again - Length auto d2 = v2 * (60 * s); - - std::cout << "d1 = " << d1 << '\n'; - std::cout << "t1 = " << t1 << '\n'; - std::cout << "v1 = " << v1 << '\n'; - std::cout << "temp1 = " << temp1 << '\n'; - std::cout << "v2 = " << v2 << '\n'; - std::cout << "d2 = " << d2 << '\n'; -} - -} // namespace - -int main() -{ - try { - example(); - } catch (const std::exception& ex) { - std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; - } catch (...) { - std::cerr << "Unhandled unknown exception caught\n"; - } -} diff --git a/example/si_constants.cpp b/example/si_constants.cpp index dc0a203d..462ea44f 100644 --- a/example/si_constants.cpp +++ b/example/si_constants.cpp @@ -20,21 +20,37 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include +#include +#include +#include #include +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + int main() { - using namespace units::isq::si::si2019; + using namespace mp_units::si; + using namespace mp_units::si::unit_symbols; std::cout << "The seven defining constants of the SI and the seven corresponding units they define:\n"; - std::cout << UNITS_STD_FMT::format("- hyperfine transition frequency of Cs: {:%.0Q %q}\n", - hyperfine_structure_transition_frequency<>); - std::cout << UNITS_STD_FMT::format("- speed of light in vacuum: {:%.0Q %q}\n", speed_of_light<>); - std::cout << UNITS_STD_FMT::format("- Planck constant: {}\n", planck_constant<>); - std::cout << UNITS_STD_FMT::format("- elementary charge: {}\n", elementary_charge<>); - std::cout << UNITS_STD_FMT::format("- Boltzmann constant: {}\n", boltzmann_constant<>); - std::cout << UNITS_STD_FMT::format("- Avogadro constant: {}\n", avogadro_constant<>); - std::cout << UNITS_STD_FMT::format("- luminous efficacy: {}\n", luminous_efficacy<>); + std::cout << UNITS_STD_FMT::format("- hyperfine transition frequency of Cs: {} = {:%.0Q %q}\n", + 1. * si2019::hyperfine_structure_transition_frequency_of_cs, + (1. * si2019::hyperfine_structure_transition_frequency_of_cs)[Hz]); + std::cout << UNITS_STD_FMT::format("- speed of light in vacuum: {} = {:%.0Q %q}\n", + 1. * si2019::speed_of_light_in_vacuum, + (1. * si2019::speed_of_light_in_vacuum)[m / s]); + std::cout << UNITS_STD_FMT::format("- Planck constant: {} = {:%.8eQ %q}\n", + 1. * si2019::planck_constant, (1. * si2019::planck_constant)[J * s]); + std::cout << UNITS_STD_FMT::format("- elementary charge: {} = {:%.9eQ %q}\n", + 1. * si2019::elementary_charge, (1. * si2019::elementary_charge)[C]); + std::cout << UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n", + 1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant)[J / K]); + std::cout << UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n", + 1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant)[1 / mol]); + // TODO uncomment the below when ISQ is done + // std::cout << UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n", + // si2019::luminous_efficacy(1.), + // si2019::luminous_efficacy(1.)[lm / W]); } diff --git a/example/storage_tank.cpp b/example/storage_tank.cpp new file mode 100644 index 00000000..0acddd2d --- /dev/null +++ b/example/storage_tank.cpp @@ -0,0 +1,128 @@ +// 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. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +namespace { + +using namespace mp_units; +using namespace mp_units::si::unit_symbols; + +inline constexpr auto g = 1 * si::standard_gravity; +inline constexpr auto air_density = isq::mass_density(1.225 * (kg / m3)); + +class StorageTank { + quantity base_; + quantity height_; + quantity density_ = air_density; +public: + constexpr StorageTank(const quantity& base, const quantity& height) : + base_(base), height_(height) + { + } + + constexpr void set_contents_density(const quantity& density) + { + assert(density > air_density); + density_ = density; + } + + [[nodiscard]] constexpr QuantityOf auto filled_weight() const + { + const auto volume = isq::volume(base_ * height_); // TODO check if we can remove that cast + const QuantityOf auto mass = density_ * volume; + return isq::weight(mass * g); + } + + [[nodiscard]] constexpr quantity fill_level(const quantity& measured_mass) const + { + return height_ * measured_mass * g / filled_weight(); + } + + [[nodiscard]] constexpr quantity spare_capacity(const quantity& measured_mass) const + { + return (height_ - fill_level(measured_mass)) * base_; + } +}; + + +class CylindricalStorageTank : public StorageTank { +public: + constexpr CylindricalStorageTank(const quantity& radius, const quantity& height) : + StorageTank(std::numbers::pi * radius * radius, height) + { + } +}; + +class RectangularStorageTank : public StorageTank { +public: + constexpr RectangularStorageTank(const quantity& length, const quantity& width, + const quantity& height) : + StorageTank(length * width, height) + { + } +}; + +} // namespace + + +int main() +{ + using namespace mp_units; + using namespace mp_units::si::unit_symbols; + + const auto height = isq::height(200 * mm); + auto tank = RectangularStorageTank(isq::length(1'000 * mm), isq::width(500 * mm), height); + tank.set_contents_density(1'000 * isq::mass_density[kg / m3]); + + const auto fill_time = 200 * s; // time since starting fill + const auto measured_mass = 20. * kg; // measured mass at fill_time + + const auto fill_level = tank.fill_level(measured_mass); + const auto spare_capacity = tank.spare_capacity(measured_mass); + const auto filled_weight = tank.filled_weight(); + + const QuantityOf auto input_flow_rate = measured_mass / fill_time; + const QuantityOf auto float_rise_rate = fill_level / fill_time; + const QuantityOf auto fill_time_left = (height / fill_level - 1) * fill_time; + + const auto fill_ratio = fill_level / height; + + std::cout << UNITS_STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_ratio[percent]); + std::cout << UNITS_STD_FMT::format("fill weight at {} = {} ({})\n", fill_time, filled_weight, filled_weight[N]); + std::cout << UNITS_STD_FMT::format("spare capacity at {} = {}\n", fill_time, spare_capacity); + std::cout << UNITS_STD_FMT::format("input flow rate = {}\n", input_flow_rate); + std::cout << UNITS_STD_FMT::format("float rise rate = {}\n", float_rise_rate); + std::cout << UNITS_STD_FMT::format("tank full E.T.A. at current flow rate = {}\n", fill_time_left[s]); +} diff --git a/example/references/experimental_angle.cpp b/example/strong_angular_quantities.cpp similarity index 61% rename from example/references/experimental_angle.cpp rename to example/strong_angular_quantities.cpp index f307d98e..04d41b5e 100644 --- a/example/references/experimental_angle.cpp +++ b/example/strong_angular_quantities.cpp @@ -20,31 +20,29 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include - -UNITS_DIAGNOSTIC_PUSH -UNITS_DIAGNOSTIC_IGNORE_SHADOW -#include // 'N' (Newton) shadows a template parameter traditionally used as a size of the array -UNITS_DIAGNOSTIC_POP - -#include -#include -#include -#include +#include +#include +#include +#include #include +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + int main() { - using namespace units; - using namespace units::isq; - using namespace units::isq::si::references; - using namespace units::references; + using namespace mp_units; + using namespace mp_units::si::unit_symbols; + using namespace mp_units::angular::unit_symbols; + using mp_units::angular::unit_symbols::deg; + using mp_units::angular::unit_symbols::rad; - const Length auto lever = 20 * cm; - const Force auto force = 500 * N; - const Angle auto angle = 90. * deg; - const Torque auto torque = lever * force * sin(angle) / cotes_angle<>; + const auto lever = isq_angle::position_vector(20 * cm); + const auto force = isq_angle::force(500 * N); + const auto angle = isq_angle::angular_measure(90. * deg); + const auto torque = isq_angle::torque(lever * force * angular::sin(angle) / (1 * isq_angle::cotes_angle)); std::cout << "Applying a perpendicular force of " << force << " to a " << lever << " long lever results in " - << quantity_cast(torque) << " of torque.\n"; + << torque[N * m / rad] << " of torque.\n"; } diff --git a/example/total_energy.cpp b/example/total_energy.cpp new file mode 100644 index 00000000..321b487f --- /dev/null +++ b/example/total_energy.cpp @@ -0,0 +1,114 @@ +// 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. + +#include +#include +#include +#include +#include +#include +#include +#include + +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +namespace { + +using namespace mp_units; + +QuantityOf auto total_energy(QuantityOf auto p, QuantityOf auto m, + QuantityOf auto c) +{ + return isq::mechanical_energy(sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c)))); +} + +void si_example() +{ + using namespace mp_units::si::unit_symbols; + constexpr auto GeV = si::giga; + constexpr QuantityOf auto c = 1. * si::si2019::speed_of_light_in_vacuum; + auto c2 = pow<2>(c); + + const auto p1 = isq::momentum(4. * GeV / c); + const QuantityOf auto m1 = 3. * GeV / c2; + const auto E = total_energy(p1, m1, c); + + std::cout << "\n*** SI units (c = " << c << " = " << c[si::metre / s] << ") ***\n"; + + std::cout << "\n[in `GeV` and `c`]\n" + << "p = " << p1 << "\n" + << "m = " << m1 << "\n" + << "E = " << E << "\n"; + + const auto p2 = p1[GeV / (m / s)]; + const auto m2 = m1[GeV / pow<2>(m / s)]; + const auto E2 = total_energy(p2, m2, c)[GeV]; + + std::cout << "\n[in `GeV`]\n" + << "p = " << p2 << "\n" + << "m = " << m2 << "\n" + << "E = " << E2 << "\n"; + + const auto p3 = p1[kg * m / s]; + const auto m3 = m1[kg]; + const auto E3 = total_energy(p3, m3, c)[J]; + + std::cout << "\n[in SI base units]\n" + << "p = " << p3 << "\n" + << "m = " << m3 << "\n" + << "E = " << E3 << "\n"; + + std::cout << "\n[converted from SI units back to GeV]\n" + << "E = " << value_cast(E3) << "\n"; +} + +void natural_example() +{ + using namespace mp_units::natural; + using namespace mp_units::natural::unit_symbols; + + constexpr auto c = 1. * speed_of_light; + const auto p = 4. * momentum[GeV]; + const auto m = 3. * mass[GeV]; + const auto E = total_energy(p, m, c); + + std::cout << "\n*** Natural units (c = " << c << ") ***\n" + << "p = " << p << "\n" + << "m = " << m << "\n" + << "E = " << E << "\n"; +} + +} // namespace + +int main() +{ + try { + si_example(); + natural_example(); + } catch (const std::exception& ex) { + std::cerr << "Unhandled std exception caught: " << ex.what() << '\n'; + } catch (...) { + std::cerr << "Unhandled unknown exception caught\n"; + } +} diff --git a/example/unmanned_aerial_vehicle.cpp b/example/unmanned_aerial_vehicle.cpp new file mode 100644 index 00000000..ac065610 --- /dev/null +++ b/example/unmanned_aerial_vehicle.cpp @@ -0,0 +1,167 @@ +// 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. + +#include "geographic.h" +#include +#include +#include +#include +#include +#include + +using namespace mp_units; +using namespace geographic; + +// **** HAE **** + +enum class earth_gravity_model { egm84_15, egm95_5, egm2008_1 }; + +template +struct height_above_ellipsoid_t : absolute_point_origin { + static constexpr earth_gravity_model egm = M; + using absolute_point_origin::absolute_point_origin; +}; +template +inline constexpr height_above_ellipsoid_t height_above_ellipsoid; + +template +using hae_altitude = quantity_point>; + +constexpr const char* to_text(earth_gravity_model m) +{ + switch (m) { + using enum earth_gravity_model; + case egm84_15: + return "EGM84-15"; + case egm95_5: + return "EGM95-5"; + case egm2008_1: + return "EGM2008-1"; + } +} + +template +[[nodiscard]] consteval bool is_hae(height_above_ellipsoid_t) +{ + return true; +} +[[nodiscard]] consteval bool is_hae(...) { return false; } + +template + requires(is_hae(QP::absolute_point_origin)) +std::basic_ostream& operator<<(std::basic_ostream& os, const QP& a) +{ + return os << a.absolute() << " HAE(" << to_text(a.absolute_point_origin.egm) << ")"; +} + +template + requires(is_hae(QP::absolute_point_origin)) +struct UNITS_STD_FMT::formatter : formatter { + template + auto format(const QP& a, FormatContext& ctx) + { + formatter::format(a.absolute(), ctx); + return UNITS_STD_FMT::format_to(ctx.out(), " HAE({})", to_text(QP::absolute_point_origin.egm)); + } +}; + +double GeographicLibWhatsMyOffset(long double /* lat */, long double /* lon */) +{ + // for example use GeographicLib for that: + // - https://geographiclib.sourceforge.io/C++/doc/geoid.html + // - https://conan.io/center/geographiclib + return 29.49; +} + +template +hae_altitude to_hae(msl_altitude msl, position pos) +{ + const auto geoid_undulation = + isq::height(GeographicLibWhatsMyOffset(pos.lat.number_in(si::degree), pos.lon.number_in(si::degree)) * si::metre); + return hae_altitude{msl.absolute() - geoid_undulation}; +} + + +// **** HAL **** + +// clang-format off +inline constexpr struct height_above_launch : absolute_point_origin {} height_above_launch; +// clang-format on + +using hal_altitude = quantity_point; + +template +std::basic_ostream& operator<<(std::basic_ostream& os, const hal_altitude& a) +{ + return os << a.absolute() << " HAL"; +} + +template<> +struct UNITS_STD_FMT::formatter : formatter { + template + auto format(const hal_altitude& a, FormatContext& ctx) + { + formatter::format(a.absolute(), ctx); + return UNITS_STD_FMT::format_to(ctx.out(), " HAL"); + } +}; + + +// **** UAV **** + +class unmanned_aerial_vehicle { + msl_altitude current_{0 * si::metre}; + msl_altitude launch_ = current_; +public: + void take_off(msl_altitude alt) { launch_ = alt; } + msl_altitude take_off() const { return launch_; } + + void current(msl_altitude alt) { current_ = alt; } + msl_altitude current() const { return current_; } + + hal_altitude hal() const { return hal_altitude{current_ - launch_}; } +}; + + +int main() +{ + using namespace mp_units::si::unit_symbols; + using namespace mp_units::international::unit_symbols; + + unmanned_aerial_vehicle uav; + uav.take_off(msl_altitude{6'000 * ft}); + uav.current(msl_altitude{10'000 * ft}); + std::cout << UNITS_STD_FMT::format("hal = {}\n", uav.hal()); + + msl_altitude ground_level{123 * m}; + std::cout << UNITS_STD_FMT::format("agl = {}\n", uav.current() - ground_level); + + struct waypoint { + std::string name; + geographic::position pos; + msl_altitude msl_alt; + }; + + waypoint wpt = {"EPPR", {54.24772_N, 18.6745_E}, msl_altitude{16. * ft}}; + std::cout << UNITS_STD_FMT::format("{}: {} {}, {:%.2Q %q}, {:%.2Q %q}\n", wpt.name, wpt.pos.lat, wpt.pos.lon, + wpt.msl_alt, to_hae(wpt.msl_alt, wpt.pos)); +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d81062f6..cc27e30d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ # SOFTWARE. cmake_minimum_required(VERSION 3.19) -project(mp-units VERSION 0.8.0 LANGUAGES CXX) +project(mp-units VERSION 2.0.0 LANGUAGES CXX) set(projectPrefix UNITS_) @@ -44,10 +44,13 @@ add_subdirectory(core) add_subdirectory(core-fmt) add_subdirectory(core-io) add_subdirectory(systems) +add_subdirectory(utility) # project-wide wrapper add_library(mp-units INTERFACE) -target_link_libraries(mp-units INTERFACE mp-units::core mp-units::core-io mp-units::core-fmt mp-units::systems) +target_link_libraries( + mp-units INTERFACE mp-units::core mp-units::core-io mp-units::core-fmt mp-units::systems mp-units::utility +) add_library(mp-units::mp-units ALIAS mp-units) install(TARGETS mp-units EXPORT mp-unitsTargets) diff --git a/src/cmake/AddUnitsModule.cmake b/src/cmake/AddUnitsModule.cmake index 7e52697b..de89f1af 100644 --- a/src/cmake/AddUnitsModule.cmake +++ b/src/cmake/AddUnitsModule.cmake @@ -65,5 +65,5 @@ function(add_units_module name) add_library(mp-units::${name} ALIAS mp-units-${name}) install(TARGETS mp-units-${name} EXPORT mp-unitsTargets) - install(DIRECTORY include/units TYPE INCLUDE) + install(DIRECTORY include/mp-units TYPE INCLUDE) endfunction() diff --git a/src/core-fmt/CMakeLists.txt b/src/core-fmt/CMakeLists.txt index 96c6dded..99f2ce04 100644 --- a/src/core-fmt/CMakeLists.txt +++ b/src/core-fmt/CMakeLists.txt @@ -25,7 +25,7 @@ cmake_minimum_required(VERSION 3.19) option(${projectPrefix}USE_LIBFMT "Enables usage of libfmt instead of the one from 'std'" ON) message(STATUS "${projectPrefix}USE_LIBFMT: ${${projectPrefix}USE_LIBFMT}") -add_units_module(core-fmt DEPENDENCIES mp-units::core HEADERS include/units/format.h) +add_units_module(core-fmt DEPENDENCIES mp-units::core HEADERS include/mp-units/format.h) target_compile_definitions(mp-units-core-fmt INTERFACE ${projectPrefix}USE_LIBFMT=$) if(${projectPrefix}USE_LIBFMT) diff --git a/src/core-fmt/include/units/bits/fmt.h b/src/core-fmt/include/mp-units/bits/fmt.h similarity index 97% rename from src/core-fmt/include/units/bits/fmt.h rename to src/core-fmt/include/mp-units/bits/fmt.h index 0f6a492b..5c76d991 100644 --- a/src/core-fmt/include/units/bits/fmt.h +++ b/src/core-fmt/include/mp-units/bits/fmt.h @@ -28,14 +28,14 @@ // For the license information refer to format.h. #include -#include +#include #include #include #include // most of the below code is based on/copied from libfmt -namespace units::detail { +namespace mp_units::detail { struct auto_id {}; @@ -382,11 +382,11 @@ template S, typename SpecHandler> if (begin == end) return begin; - begin = ::units::detail::parse_align(begin, end, handler); + begin = ::mp_units::detail::parse_align(begin, end, handler); if (begin == end) return begin; // Parse sign. - begin = ::units::detail::parse_sign(begin, end, handler); + begin = ::mp_units::detail::parse_sign(begin, end, handler); if (begin == end) return begin; if (*begin == '#') { @@ -400,12 +400,12 @@ template S, typename SpecHandler> if (++begin == end) return begin; } - begin = ::units::detail::parse_width(begin, end, handler); + begin = ::mp_units::detail::parse_width(begin, end, handler); if (begin == end) return begin; // Parse precision. if (*begin == '.') { - begin = ::units::detail::parse_precision(begin, end, handler); + begin = ::mp_units::detail::parse_precision(begin, end, handler); if (begin == end) return begin; } @@ -465,4 +465,4 @@ private: ParseContext& context_; }; -} // namespace units::detail +} // namespace mp_units::detail diff --git a/src/core-fmt/include/units/bits/fmt_hacks.h b/src/core-fmt/include/mp-units/bits/fmt_hacks.h similarity index 98% rename from src/core-fmt/include/units/bits/fmt_hacks.h rename to src/core-fmt/include/mp-units/bits/fmt_hacks.h index 5b24c6a7..bbfc2adc 100644 --- a/src/core-fmt/include/units/bits/fmt_hacks.h +++ b/src/core-fmt/include/mp-units/bits/fmt_hacks.h @@ -27,7 +27,7 @@ // // For the license information refer to format.h. -#include +#include #ifndef UNITS_USE_LIBFMT #define UNITS_USE_LIBFMT 1 diff --git a/src/core-fmt/include/units/format.h b/src/core-fmt/include/mp-units/format.h similarity index 64% rename from src/core-fmt/include/units/format.h rename to src/core-fmt/include/mp-units/format.h index 372f6447..1234296c 100644 --- a/src/core-fmt/include/units/format.h +++ b/src/core-fmt/include/mp-units/format.h @@ -22,16 +22,13 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports - // Grammar // // units-format-spec ::= [fill-and-align] [width] [units-specs] @@ -42,39 +39,14 @@ // 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' +// units-unit-modifier ::= [units-text-encoding, units-unit-symbol-denominator, units-unit-symbol-separator] +// units-text-encoding ::= one of "UA" +// units-unit-symbol-solidus ::= one of "oan" +// units-unit-symbol-separator ::= one of "sd" -// Guide for editing -// -// If you want to add a new `units-type` terminal character (e.g. 'Q', 'q'): -// - If needed, write a new `specs` class (e.g. `global_format_specs`) -// - Add the new symbol in the `units_types` variable in the `parse_units_format` function -// - Add a new case in the `if` following the format_error in `parse_units_format` function; -// this should invoke `handler.on_[...]` -// - Edit `UNITS_STD_FMT::formatter`: -// - Add a new field for the flag/specs -// - Add to the `UNITS_STD_FMT::formatter::spec_handler` a `on_[...]` function that set the flag/specs if needed -// - Edit `quantity_formatter`: -// - Add a new field for the flag/specs -// - write a `on_[...]` function that writes to the `out` iterator the correct output -// -// If you want to add a new `units-rep-type`: -// - Add the new symbol in the `valid_rep_types` variable (which is in the -// UNITS_STD_FMT::formatter::spec_handler::on_type member function) -// NB: currently this function forward the modifier to the value that must be formatted; -// if the symbol has no meaning for UNITS_STD_FMT::formatter, this behavior should be disabled manually -// (as is done for '\0') -// - Implement the effect of the new flag in `format_units_quantity_value` -// -// If you want to add a new `units-unit-modifier`: -// - Add the new symbol in the `valid_modifiers` variable (which is in the -// UNITS_STD_FMT::formatter::spec_handler::on_unit_modifier member function) -// - Implement the effect of the new flag in the `quantity_formatter::on_quantity_unit` member function - -namespace units::detail { +namespace mp_units::detail { // Holds specs about the whole object template @@ -96,9 +68,7 @@ struct quantity_rep_format_specs { }; // Holds specs about the unit (%[specs]q) -struct quantity_unit_format_specs { - bool ascii_only = false; -}; +struct quantity_unit_format_specs : unit_symbol_formatting {}; template struct quantity_format_specs { @@ -109,7 +79,7 @@ struct quantity_format_specs { // Parse a `units-rep-modifier` template S, typename Handler> -constexpr const It parse_units_rep(It begin, S end, Handler&& handler, bool treat_as_floating_point) +constexpr It parse_units_rep(It begin, S end, Handler&& handler, bool treat_as_floating_point) { // parse sign begin = parse_sign(begin, end, handler); @@ -126,7 +96,7 @@ constexpr const It parse_units_rep(It begin, S end, Handler&& handler, bool trea if (treat_as_floating_point) { begin = parse_precision(begin, end, handler); } else - UNITS_THROW(UNITS_STD_FMT::format_error("precision not allowed for integral quantity representation")); + throw UNITS_STD_FMT::format_error("precision not allowed for integral quantity representation"); if (begin == end) return begin; } @@ -156,35 +126,18 @@ constexpr It parse_units_format(It begin, S end, Handler&& handler) } if (begin != ptr) handler.on_text(begin, ptr); begin = ++ptr; // consume '%' - if (ptr == end) UNITS_THROW(UNITS_STD_FMT::format_error("invalid format")); + if (ptr == end) throw UNITS_STD_FMT::format_error("invalid format"); c = *ptr++; - switch (c) { - // units-type - case '%': - handler.on_text(ptr - 1, ptr); - break; - case 'n': { - const char newline[] = "\n"; - handler.on_text(newline, newline + 1); - break; - } - case 't': { - const char tab[] = "\t"; - handler.on_text(tab, tab + 1); - break; - } - default: - constexpr auto units_types = std::string_view{"Qq"}; - const auto new_end = std::find_first_of(begin, end, units_types.begin(), units_types.end()); - if (new_end == end) UNITS_THROW(UNITS_STD_FMT::format_error("invalid format")); - if (*new_end == 'Q') { - handler.on_quantity_value(begin, new_end); // Edit `on_quantity_value` to add rep modifiers - } else { - handler.on_quantity_unit(*begin); // Edit `on_quantity_unit` to add an unit modifier - } - ptr = new_end + 1; + constexpr auto units_types = std::string_view{"Qq"}; + const auto new_end = find_first_of(begin, end, units_types.begin(), units_types.end()); + if (new_end == end) throw UNITS_STD_FMT::format_error("invalid format"); + if (*new_end == 'Q') { + handler.on_quantity_value(begin, new_end); // Edit `on_quantity_value` to add rep modifiers + } else { + handler.on_quantity_unit(begin, new_end); // Edit `on_quantity_unit` to add an unit modifier } + ptr = new_end + 1; begin = ptr; } if (begin != ptr) handler.on_text(begin, ptr); @@ -264,14 +217,14 @@ OutputIt format_global_buffer(OutputIt out, const quantity_global_format_specs +template struct quantity_formatter { OutputIt out; Rep val; const quantity_format_specs& specs; Locale loc; - explicit quantity_formatter(OutputIt o, quantity q, const quantity_format_specs& fspecs, + explicit quantity_formatter(OutputIt o, quantity q, const quantity_format_specs& fspecs, Locale lc) : out(o), val(std::move(q).number()), specs(fspecs), loc(std::move(lc)) { @@ -289,28 +242,34 @@ struct quantity_formatter { out = format_units_quantity_value(out, val, specs.rep, loc); } - void on_quantity_unit([[maybe_unused]] CharT) + template S> + void on_quantity_unit(It, S) { - auto txt = unit_text(); - if (specs.unit.ascii_only) { - UNITS_STD_FMT::format_to(out, "{}", txt.ascii().c_str()); - } else { - UNITS_STD_FMT::format_to(out, "{}", txt.standard().c_str()); - } + out = unit_symbol_to(out, get_unit(Reference), specs.unit); } }; -} // namespace units::detail +template S> +[[nodiscard]] constexpr It at_most_one_of(It begin, S end, std::string_view modifiers) +{ + auto it = find_first_of(begin, end, modifiers.begin(), modifiers.end()); + if (it != end && find_first_of(it + 1, end, modifiers.begin(), modifiers.end()) != end) + throw UNITS_STD_FMT::format_error("only one of '" + std::string(modifiers) + + "' unit modifiers may be used in the format spec"); + return it; +} -template -struct UNITS_STD_FMT::formatter, CharT> { +} // namespace mp_units::detail + +template +struct UNITS_STD_FMT::formatter, CharT> { private: - using quantity = units::quantity; + using quantity = mp_units::quantity; using iterator = TYPENAME UNITS_STD_FMT::basic_format_parse_context::iterator; bool quantity_value = false; bool quantity_unit = false; - units::detail::quantity_format_specs specs; + mp_units::detail::quantity_format_specs specs; std::basic_string_view format_str; struct spec_handler { @@ -318,9 +277,9 @@ private: UNITS_STD_FMT::basic_format_parse_context& context; constexpr void on_fill(std::basic_string_view fill) { f.specs.global.fill = fill; } - constexpr void on_align(units::detail::fmt_align align) { f.specs.global.align = align; } + constexpr void on_align(mp_units::detail::fmt_align align) { f.specs.global.align = align; } constexpr void on_width(int width) { f.specs.global.width = width; } - constexpr void on_sign(units::detail::fmt_sign sign) { f.specs.rep.sign = sign; } + constexpr void on_sign(mp_units::detail::fmt_sign sign) { f.specs.rep.sign = sign; } constexpr void on_hash() { f.specs.rep.alt = true; } constexpr void on_precision(int precision) { f.specs.rep.precision = precision; } constexpr void on_localized() { f.specs.rep.localized = true; } @@ -331,30 +290,20 @@ private: if (valid_rep_types.find(type) != std::string_view::npos) { f.specs.rep.type = type; } else { - UNITS_THROW(UNITS_STD_FMT::format_error("invalid quantity type specifier")); - } - } - - constexpr void on_unit_modifier(char mod) - { - constexpr auto valid_modifiers = std::string_view{"A"}; - if (valid_modifiers.find(mod) != std::string_view::npos) { - f.specs.unit.ascii_only = true; - } else { - UNITS_THROW(UNITS_STD_FMT::format_error("invalid unit modifier specified")); + throw UNITS_STD_FMT::format_error("invalid quantity type specifier"); } } template constexpr void on_dynamic_width(T t) { - f.specs.global.dynamic_width_index = units::detail::on_dynamic_arg(t, context); + f.specs.global.dynamic_width_index = mp_units::detail::on_dynamic_arg(t, context); } template constexpr void on_dynamic_precision(T t) { - f.specs.rep.dynamic_precision_index = units::detail::on_dynamic_arg(t, context); + f.specs.rep.dynamic_precision_index = mp_units::detail::on_dynamic_arg(t, context); } template S> @@ -365,13 +314,47 @@ private: template S> constexpr void on_quantity_value(It begin, S end) { - if (begin != end) units::detail::parse_units_rep(begin, end, *this, units::treat_as_floating_point); + if (begin != end) mp_units::detail::parse_units_rep(begin, end, *this, mp_units::treat_as_floating_point); f.quantity_value = true; } - constexpr void on_quantity_unit(CharT mod) + template S> + constexpr void on_quantity_unit(It begin, S end) { - if (mod != 'q') on_unit_modifier(mod); + if (begin == end) return; + + constexpr auto valid_modifiers = std::string_view{"UAoansd"}; + for (auto it = begin; it != end; ++it) { + if (valid_modifiers.find(*it) == std::string_view::npos) + throw UNITS_STD_FMT::format_error("invalid unit modifier specified"); + } + + if (auto it = mp_units::detail::at_most_one_of(begin, end, "UA"); it != end) { + if (*it == 'U') + f.specs.unit.encoding = mp_units::text_encoding::unicode; + else + f.specs.unit.encoding = mp_units::text_encoding::ascii; + } + + if (auto it = mp_units::detail::at_most_one_of(begin, end, "oan"); it != end) { + if (*it == 'o') + f.specs.unit.solidus = mp_units::unit_symbol_solidus::one_denominator; + else if (*it == 'a') + f.specs.unit.solidus = mp_units::unit_symbol_solidus::always; + else + f.specs.unit.solidus = mp_units::unit_symbol_solidus::never; + } + + if (auto it = mp_units::detail::at_most_one_of(begin, end, "sd"); it != end) { + if (*it == 's') + f.specs.unit.separator = mp_units::unit_symbol_separator::space; + else { + if (f.specs.unit.encoding == mp_units::text_encoding::ascii) + throw UNITS_STD_FMT::format_error("dot unit separator allowed only for Unicode encoding"); + f.specs.unit.separator = mp_units::unit_symbol_separator::dot; + } + } + f.quantity_unit = true; } }; @@ -387,19 +370,19 @@ private: spec_handler handler{*this, ctx}; // parse alignment - begin = units::detail::parse_align(begin, end, handler); + begin = mp_units::detail::parse_align(begin, end, handler); if (begin == end) return {begin, begin}; // parse width - begin = units::detail::parse_width(begin, end, handler); + begin = mp_units::detail::parse_width(begin, end, handler); if (begin == end) return {begin, begin}; // parse units-specific specification - end = units::detail::parse_units_format(begin, end, handler); + end = mp_units::detail::parse_units_format(begin, end, handler); - if (specs.global.align == units::detail::fmt_align::none && (!quantity_unit || quantity_value)) + if (specs.global.align == mp_units::detail::fmt_align::none && (!quantity_unit || quantity_value)) // quantity values should behave like numbers (by default aligned to right) - specs.global.align = units::detail::fmt_align::right; + specs.global.align = mp_units::detail::fmt_align::right; return {begin, end}; } @@ -412,16 +395,15 @@ private: if (begin == end || *begin == '}') { // default format should print value followed by the unit separated with 1 space - out = units::detail::format_units_quantity_value(out, q.number(), specs.rep, ctx.locale()); - constexpr auto symbol = units::detail::unit_text(); - if constexpr (symbol.standard().size() > 0) { + out = mp_units::detail::format_units_quantity_value(out, q.number(), specs.rep, ctx.locale()); + if constexpr (mp_units::detail::has_unit_symbol(get_unit(Reference))) { *out++ = CharT(' '); - UNITS_STD_FMT::format_to(out, "{}", symbol.standard().c_str()); + out = unit_symbol_to(out, get_unit(Reference)); } } else { // user provided format - units::detail::quantity_formatter f(out, q, specs, ctx.locale()); - units::detail::parse_units_format(begin, end, f); + mp_units::detail::quantity_formatter f(out, q, specs, ctx.locale()); + mp_units::detail::parse_units_format(begin, end, f); } return out; } @@ -441,10 +423,10 @@ public: // process dynamic width and precision if (specs.global.dynamic_width_index >= 0) specs.global.width = - units::detail::get_dynamic_spec(specs.global.dynamic_width_index, ctx); + mp_units::detail::get_dynamic_spec(specs.global.dynamic_width_index, ctx); if (specs.rep.dynamic_precision_index >= 0) specs.rep.precision = - units::detail::get_dynamic_spec(specs.rep.dynamic_precision_index, ctx); + mp_units::detail::get_dynamic_spec(specs.rep.dynamic_precision_index, ctx); if (specs.global.width == 0) { // Avoid extra copying if width is not specified @@ -461,7 +443,7 @@ public: // In `global_format_buffer` we will create a global format string // e.g. "{:*^10%.1Q_%q}, 1.23_q_m" => "{:*^10}" std::basic_string global_format_buffer; - units::detail::format_global_buffer(std::back_inserter(global_format_buffer), specs.global); + mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), specs.global); // Format the `quantity buffer` using specs from `global_format_buffer` // In the example, equivalent to UNITS_STD_FMT::format("{:*^10}", "1.2_m") diff --git a/src/core-io/CMakeLists.txt b/src/core-io/CMakeLists.txt index de797acf..5d79bd07 100644 --- a/src/core-io/CMakeLists.txt +++ b/src/core-io/CMakeLists.txt @@ -22,4 +22,4 @@ cmake_minimum_required(VERSION 3.19) -add_units_module(core-io DEPENDENCIES mp-units::core HEADERS include/units/quantity_io.h) +add_units_module(core-io DEPENDENCIES mp-units::core HEADERS include/mp-units/iostream.h) diff --git a/src/core-io/include/units/quantity_io.h b/src/core-io/include/mp-units/iostream.h similarity index 75% rename from src/core-io/include/units/quantity_io.h rename to src/core-io/include/mp-units/iostream.h index cb93f686..d9958fae 100644 --- a/src/core-io/include/units/quantity_io.h +++ b/src/core-io/include/mp-units/iostream.h @@ -23,32 +23,28 @@ #pragma once -#include - -// IWYU pragma: begin_exports -#include -#include +#include +#include #include -// IWYU pragma: end_exports -namespace units { +namespace mp_units { namespace detail { -template -void to_stream(std::basic_ostream& os, const quantity& q) +template +void to_stream(std::basic_ostream& os, const quantity& q) { os << q.number(); - constexpr auto symbol = detail::unit_text(); - if constexpr (!symbol.standard().empty()) { - os << " " << symbol.standard(); + if constexpr (has_unit_symbol(get_unit(R))) { + os << " "; + unit_symbol_to(std::ostream_iterator(os), get_unit(R)); } } } // namespace detail -template -std::basic_ostream& operator<<(std::basic_ostream& os, const quantity& q) +template +std::basic_ostream& operator<<(std::basic_ostream& os, const quantity& q) requires requires { os << q.number(); } { if (os.width()) { @@ -65,4 +61,4 @@ std::basic_ostream& operator<<(std::basic_ostream& return os; } -} // namespace units +} // namespace mp_units diff --git a/src/core-io/include/units/bits/external/fixed_string_io.h b/src/core-io/include/units/bits/external/fixed_string_io.h deleted file mode 100644 index d06cc5cc..00000000 --- a/src/core-io/include/units/bits/external/fixed_string_io.h +++ /dev/null @@ -1,37 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units { - -template -std::basic_ostream& operator<<(std::basic_ostream& os, - const basic_fixed_string& txt) -{ - return os << txt.c_str(); -} - -} // namespace units diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 04576b2b..49e52bcd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -22,10 +22,6 @@ cmake_minimum_required(VERSION 3.19) -# core library options -set(${projectPrefix}DOWNCAST_MODE ON CACHE STRING "Select downcasting mode") -set_property(CACHE ${projectPrefix}DOWNCAST_MODE PROPERTY STRINGS AUTO ON OFF) - # find dependencies if(NOT TARGET gsl::gsl-lite) find_package(gsl-lite CONFIG REQUIRED) @@ -39,30 +35,41 @@ check_libcxx_in_use(${projectPrefix}LIBCXX) add_library( mp-units-core INTERFACE - include/units/base_dimension.h - include/units/chrono.h - include/units/concepts.h - include/units/customization_points.h - include/units/derived_dimension.h - include/units/exponent.h - include/units/generic/angle.h - include/units/generic/dimensionless.h - include/units/generic/solid_angle.h - include/units/kind.h - include/units/magnitude.h - include/units/math.h - include/units/point_origin.h - include/units/prefix.h - include/units/quantity.h - include/units/quantity_cast.h - include/units/quantity_kind.h - include/units/quantity_point.h - include/units/quantity_point_kind.h - include/units/random.h - include/units/ratio.h - include/units/reference.h - include/units/symbol_text.h - include/units/unit.h + include/mp-units/bits/external/fixed_string.h + include/mp-units/bits/external/hacks.h + include/mp-units/bits/external/type_list.h + include/mp-units/bits/external/type_name.h + include/mp-units/bits/external/type_traits.h + include/mp-units/bits/algorithm.h + include/mp-units/bits/dimension_concepts.h + include/mp-units/bits/expression_template.h + include/mp-units/bits/get_associated_quantity.h + include/mp-units/bits/get_common_base.h + include/mp-units/bits/magnitude.h + include/mp-units/bits/math_concepts.h + include/mp-units/bits/prime.h + include/mp-units/bits/quantity_cast.h + include/mp-units/bits/quantity_concepts.h + include/mp-units/bits/quantity_point_concepts.h + include/mp-units/bits/quantity_spec_concepts.h + include/mp-units/bits/ratio.h + include/mp-units/bits/reference_concepts.h + include/mp-units/bits/representation_concepts.h + include/mp-units/bits/sudo_cast.h + include/mp-units/bits/symbol_text.h + include/mp-units/bits/text_tools.h + include/mp-units/bits/unit_concepts.h + include/mp-units/bits/value_cast.h + include/mp-units/concepts.h + include/mp-units/core.h + include/mp-units/customization_points.h + include/mp-units/dimension.h + include/mp-units/quantity.h + include/mp-units/quantity_point.h + include/mp-units/quantity_spec.h + include/mp-units/reference.h + include/mp-units/system_reference.h + include/mp-units/unit.h ) target_compile_features(mp-units-core INTERFACE cxx_std_20) target_link_libraries(mp-units-core INTERFACE gsl::gsl-lite) @@ -85,23 +92,9 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") ) endif() -if(DEFINED ${projectPrefix}DOWNCAST_MODE) - set(downcast_mode_options OFF ON AUTO) - list(FIND downcast_mode_options "${${projectPrefix}DOWNCAST_MODE}" downcast_mode) - - if(downcast_mode EQUAL -1) - message(FATAL_ERROR - "'${projectPrefix}DOWNCAST_MODE' should be one of ${downcast_mode_options} ('${${projectPrefix}DOWNCAST_MODE}' received)" - ) - else() - message(STATUS "${projectPrefix}DOWNCAST_MODE: ${${projectPrefix}DOWNCAST_MODE}") - target_compile_definitions(mp-units-core INTERFACE ${projectPrefix}DOWNCAST_MODE=${downcast_mode}) - endif() -endif() - set_target_properties(mp-units-core PROPERTIES EXPORT_NAME core) add_library(mp-units::core ALIAS mp-units-core) # installation install(TARGETS mp-units-core EXPORT mp-unitsTargets) -install(DIRECTORY include/units TYPE INCLUDE) +install(DIRECTORY include/mp-units TYPE INCLUDE) diff --git a/src/core/include/units/bits/algorithm.h b/src/core/include/mp-units/bits/algorithm.h similarity index 62% rename from src/core/include/units/bits/algorithm.h rename to src/core/include/mp-units/bits/algorithm.h index 1ac80362..477290f7 100644 --- a/src/core/include/units/bits/algorithm.h +++ b/src/core/include/mp-units/bits/algorithm.h @@ -22,11 +22,13 @@ #pragma once -#include // IWYU pragma: keep +#include // IWYU pragma: keep #include +#include #include +#include -namespace units::detail { +namespace mp_units::detail { // TODO refactor two below functions with std::ranges when moved to modules @@ -59,6 +61,19 @@ constexpr auto get_first_of(const Rng& rng, UnaryFunction f) } // TODO remove all the below and use std when moved to modules +template +constexpr InputIt find_first_of(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last) +{ + for (; first != last; ++first) { + for (ForwardIt it = s_first; it != s_last; ++it) { + if (*first == *it) { + return first; + } + } + } + return last; +} + template constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) { @@ -94,7 +109,68 @@ constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp template constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2) { - return ::units::detail::lexicographical_compare_three_way(f1, l1, f2, l2, std::compare_three_way()); + return ::mp_units::detail::lexicographical_compare_three_way(f1, l1, f2, l2, std::compare_three_way()); } -} // namespace units::detail +template +constexpr ForwardIt max_element(ForwardIt first, ForwardIt last) +{ + if (first == last) return last; + + ForwardIt largest = first; + ++first; + + for (; first != last; ++first) + if (*largest < *first) largest = first; + + return largest; +} + +template +constexpr T max(std::initializer_list ilist) +{ + return *max_element(ilist.begin(), ilist.end()); +} + +template +struct in_out_result { + [[no_unique_address]] I in; + [[no_unique_address]] O out; + + template + requires std::convertible_to && std::convertible_to + constexpr operator in_out_result() const& + { + return {in, out}; + } + + template + requires std::convertible_to && std::convertible_to + constexpr operator in_out_result() && + { + return {std::move(in), std::move(out)}; + } +}; + +template +using copy_result = in_out_result; + +template S, std::weakly_incrementable O> + requires std::indirectly_copyable +constexpr copy_result copy(I first, S last, O result) +{ + for (; first != last; ++first, (void)++result) { + *result = *first; + } + return {std::move(first), std::move(result)}; +} + +template + requires std::indirectly_copyable, O> +constexpr copy_result, O> copy(R&& r, O result) +{ + return ::mp_units::detail::copy(std::ranges::begin(r), std::ranges::end(r), std::move(result)); +} + + +} // namespace mp_units::detail diff --git a/src/core/include/mp-units/bits/dimension_concepts.h b/src/core/include/mp-units/bits/dimension_concepts.h new file mode 100644 index 00000000..cd8b2b9d --- /dev/null +++ b/src/core/include/mp-units/bits/dimension_concepts.h @@ -0,0 +1,104 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units { + +template +struct base_dimension; + +namespace detail { + +template +void to_base_specialization_of_base_dimension(const volatile base_dimension*); + +template +inline constexpr bool is_derived_from_specialization_of_base_dimension = + requires(T* t) { to_base_specialization_of_base_dimension(t); }; + +template +inline constexpr bool is_specialization_of_base_dimension = false; + +template +inline constexpr bool is_specialization_of_base_dimension> = true; + +/** + * @brief A concept matching all named base dimensions in the library. + * + * Satisfied by all dimension types derived from a specialization of `base_dimension`. + */ +template +concept BaseDimension = + is_derived_from_specialization_of_base_dimension && (!is_specialization_of_base_dimension); + +template +struct is_dimension_one : std::false_type {}; + +template +inline constexpr bool is_power_of_dim = requires { + requires is_specialization_of_power && + (BaseDimension || is_dimension_one::value); +}; + +template +inline constexpr bool is_per_of_dims = false; + +template +inline constexpr bool is_per_of_dims> = + (... && (BaseDimension || is_dimension_one::value || is_power_of_dim)); + +template +concept DerivedDimensionExpr = + BaseDimension || is_dimension_one::value || is_power_of_dim || is_per_of_dims; + +} // namespace detail + +template +struct derived_dimension; + +namespace detail { + +/** + * @brief A concept matching all derived dimensions in the library. + * + * Satisfied by all dimension types either being a specialization of `derived_dimension` + * or derived from it (inheritance needed to properly handle `dimension_one`). + */ +template +concept DerivedDimension = is_derived_from_specialization_of; + +} // namespace detail + +/** + * @brief A concept matching all dimensions in the library. + * + * Satisfied by all dimension types for which either `BaseDimension` or `DerivedDimension` is `true`. + */ +template +concept Dimension = detail::BaseDimension || detail::DerivedDimension; + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/expression_template.h b/src/core/include/mp-units/bits/expression_template.h new file mode 100644 index 00000000..ab98a5e8 --- /dev/null +++ b/src/core/include/mp-units/bits/expression_template.h @@ -0,0 +1,557 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +/** + * @brief Type list type used by the expression template framework + * + * @tparam Ts The list of types + */ +template +struct type_list {}; + +/** + * @brief Type list type storing the list of components with negative exponents + * + * @note Can't be empty + */ +template +struct per {}; + +namespace detail { + +template +inline constexpr bool is_specialization_of_per = false; + +template +inline constexpr bool is_specialization_of_per> = true; + +template +inline constexpr bool valid_ratio = true; + +template +inline constexpr bool valid_ratio<0, Den...> = false; + +template +inline constexpr bool valid_ratio = false; + +template<> +inline constexpr bool valid_ratio<0, 0> = false; + +template +inline constexpr bool positive_ratio = gt_zero; + +template +inline constexpr bool positive_ratio = gt_zero; + +template +inline constexpr bool ratio_one = false; + +template<> +inline constexpr bool ratio_one<1> = true; + +template +inline constexpr bool ratio_one = true; + +} // namespace detail + + +/** + * @brief Type container for exponents with ratio different than `1` + * + * Ratio must be mathematically valid and non-negative. Negative exponents are passed to + * `per<...>` with inverted sign (as positive exponents). + * + * @tparam F factor to be raised to specified power + * @tparam Num Power ratio numerator + * @tparam Den [optional] Power ration denominator + * + * @note @p Den is an optional parameter to shorten the types presented to the user in the case when @p Den equals `1`. + */ +template + requires(detail::valid_ratio && detail::positive_ratio && !detail::ratio_one) +struct power { + using factor = F; + static constexpr ratio exponent{Num, Den...}; +}; + +namespace detail { + +template +struct expr_type_impl : std::type_identity {}; + +template +struct expr_type_impl> : std::type_identity {}; + +} // namespace detail + +template +using expr_type = TYPENAME detail::expr_type_impl::type; + +namespace detail { + +template +inline constexpr bool is_specialization_of_power = false; + +template +inline constexpr bool is_specialization_of_power> = true; + +template +consteval auto power_or_T_impl() +{ + if constexpr (is_specialization_of_power) { + return power_or_T_impl(); + } else { + if constexpr (R.den == 1) { + if constexpr (R.num == 1) + return T{}; + else + return power{}; + } else { + return power{}; + } + } +} + +template +// template // TODO ICE gcc 12 +using power_or_T = decltype(power_or_T_impl()); + + +/** + * @brief Consolidates contiguous ranges of exponents of the same type + * + * If there is more than one exponent with the same type they are aggregated into one type by adding + * their powers. + */ +template +struct expr_consolidate_impl; + +template<> +struct expr_consolidate_impl> { + using type = type_list<>; +}; + +template +struct expr_consolidate_impl> { + using type = type_list; +}; + +template +struct expr_consolidate_impl> { + using type = type_list_push_front>::type, T>; +}; + +// replaces two instances of a type with one having the power of `2` +template + requires(!is_specialization_of_power) +struct expr_consolidate_impl> { + using type = TYPENAME expr_consolidate_impl, Rest...>>::type; +}; + +// replaces the instance of a type and a power of it with one with incremented power +template +struct expr_consolidate_impl, Rest...>> { + using type = TYPENAME expr_consolidate_impl::exponent + 1>, Rest...>>::type; +}; + +// accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`) +template +struct expr_consolidate_impl, power, Rest...>> { + static constexpr ratio r = power::exponent + power::exponent; + using type = TYPENAME expr_consolidate_impl, Rest...>>::type; +}; + +template +using expr_consolidate = TYPENAME expr_consolidate_impl::type; + + +/** + * @brief Simplifies the expression template + * + * Analyzes provided numerator and denominator type lists and simplifies elements with the same type. + * If the same power exists in both list, this elements gets omitted. Otherwise, the power of its + * exponent gets subtracted according to numerator and denominator elements powers. + * + * @tparam NumList type list for expression numerator + * @tparam DenList type list for expression denominator + * @tparam Pred predicate to be used for elements comparisons + */ +template typename Pred> +struct expr_simplify; + +// when one of the lists is empty there is nothing to do +template typename Pred> + requires(type_list_size == 0) || (type_list_size == 0) +struct expr_simplify { + using num = NumList; + using den = DenList; +}; + +// in case when front elements are different progress to the next element +template typename Pred> +struct expr_simplify, type_list, Pred> { + using impl = conditional::value, expr_simplify, type_list, Pred>, + expr_simplify, type_list, Pred>>; + using num = conditional::value, type_list_push_front, typename impl::num>; + using den = conditional::value, typename impl::den, type_list_push_front>; +}; + +// in case two elements are of the same power such element gets omitted +template typename Pred> +struct expr_simplify, type_list, Pred> : + expr_simplify, type_list, Pred> {}; + +template +struct expr_simplify_power { + static constexpr ratio r = Num - Den; + using type = power_or_T; + using num = conditional<(r > 0), type_list, type_list<>>; + using den = conditional<(r < 0), type_list, type_list<>>; +}; + +// in case there are different powers for the same element simplify the power +template typename Pred> +struct expr_simplify, NRest...>, type_list, Pred> { + using impl = expr_simplify, type_list, Pred>; + using type = expr_simplify_power::exponent, ratio{1}>; + using num = type_list_join; + using den = type_list_join; +}; + +// in case there are different powers for the same element simplify the power +template typename Pred> +struct expr_simplify, type_list, DRest...>, Pred> { + using impl = expr_simplify, type_list, Pred>; + using type = expr_simplify_power::exponent>; + using num = type_list_join; + using den = type_list_join; +}; + +// in case there are different powers for the same element simplify the power +template typename Pred> + requires(!std::same_as, power>) +struct expr_simplify, NRest...>, type_list, DRest...>, Pred> { + using impl = expr_simplify, type_list, Pred>; + using type = expr_simplify_power::exponent, power::exponent>; + using num = type_list_join; + using den = type_list_join; +}; + + +// expr_less +template typename Pred> +struct expr_less_impl : Pred, expr_type> {}; + +template typename Pred> +struct expr_less_impl, Pred> : std::true_type {}; + +/** + * @brief Compares two types with a given predicate + * + * Algorithm accounts not only for explicit types but also for the case when they + * are wrapped within `power`. + */ +template typename Pred> +using expr_less = expr_less_impl; + + +// expr_fractions +template, typename Den = type_list<>> +struct expr_fractions_result { + using _num_ = Num; // exposition only + using _den_ = Den; // exposition only +}; + +template typename OneType, typename List> +[[nodiscard]] consteval auto expr_fractions_impl() +{ + constexpr std::size_t size = type_list_size; + + if constexpr (size == 0) + return expr_fractions_result<>{}; + else if constexpr (size == 1) + return expr_fractions_result{}; + else { + using last_element = type_list_back; + + if constexpr (is_specialization_of_per) { + if constexpr (size == 2 && OneType>::value) + return expr_fractions_result, type_list_map>{}; + else { + using split = type_list_split; + return expr_fractions_result>{}; + } + } else { + return expr_fractions_result{}; + } + } +} + +/** + * @brief Divides expression template spec to numerator and denominator parts + */ +template typename OneType, typename... Ts> +struct expr_fractions : decltype(expr_fractions_impl>()) {}; + +// expr_make_spec +template typename To> +[[nodiscard]] consteval auto expr_make_spec_impl() +{ + constexpr std::size_t num = type_list_size; + constexpr std::size_t den = type_list_size; + + if constexpr (num == 0 && den == 0) { + return OneType{}; + } else if constexpr (num > 0 && den > 0) { + return type_list_map>, To>{}; + } else if constexpr (den > 0) { + return To>{}; + } else { + if constexpr (num == 1 && !is_specialization_of_power>) + // temporary derived type not needed -> just return the original one + return type_list_front{}; + else + return type_list_map{}; + } +} + +/** + * @brief Creates an expression template spec based on provided numerator and denominator parts + */ +template typename To> +using expr_make_spec = decltype(expr_make_spec_impl()); + +template typename Pred, + template typename To> +[[nodiscard]] consteval auto get_optimized_expression() +{ + using num_list = expr_consolidate; + using den_list = expr_consolidate; + using simple = expr_simplify; + using expr = expr_make_spec; + return expr{}; +} + +/** + * @brief Multiplies two sorted expression template specs + * + * @tparam To destination type list to put the result to + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam Lhs lhs of the operation + * @tparam Rhs rhs of the operation + */ +template typename To, typename OneType, template typename Pred, typename Lhs, + typename Rhs> +[[nodiscard]] consteval auto expr_multiply(Lhs, Rhs) +{ + if constexpr (is_same_v) { + return Rhs{}; + } else if constexpr (is_same_v) { + return Lhs{}; + } else if constexpr (is_specialization_of && is_specialization_of) { + // two derived dimensions + return get_optimized_expression, + type_list_merge_sorted, OneType, + Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + typename Lhs::_den_, OneType, Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + typename Rhs::_den_, OneType, Pred, To>(); + } else { + // two base dimensions + return get_optimized_expression, type_list, Pred>, type_list<>, OneType, + Pred, To>(); + } +} + +/** + * @brief Divides two sorted expression template specs + * + * @tparam To destination type list to put the result to + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam Lhs lhs of the operation + * @tparam Rhs rhs of the operation + */ +template typename To, typename OneType, template typename Pred, typename Lhs, + typename Rhs> +[[nodiscard]] consteval auto expr_divide(Lhs lhs, Rhs rhs) +{ + if constexpr (is_same_v) { + return OneType{}; + } else if constexpr (is_same_v) { + return lhs; + } else if constexpr (is_same_v) { + return expr_divide(To<>{}, rhs); + } else if constexpr (is_specialization_of && is_specialization_of) { + // two derived entities + return get_optimized_expression, + type_list_merge_sorted, OneType, + Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression< + typename Lhs::_num_, type_list_merge_sorted, Pred>, OneType, Pred, To>(); + } else if constexpr (is_specialization_of) { + return get_optimized_expression, Pred>, + typename Rhs::_num_, OneType, Pred, To>(); + } else { + // two named entities + return To>{}; + } +} + +/** + * @brief Inverts the expression template spec + * + * @tparam T expression template spec to invert + * @tparam OneType type that represents the value `1` + * @tparam To destination type list to put the result to + */ +template typename To, typename OneType, typename T> +[[nodiscard]] consteval auto expr_invert(T) +{ + if constexpr (is_specialization_of) + return expr_make_spec{}; + else + return To>{}; +} + + +template typename To, typename OneType, + template typename Pred, typename... Nums, typename... Dens> + requires detail::non_zero +[[nodiscard]] consteval auto expr_pow_impl(type_list, type_list) +{ + return detail::get_optimized_expression...>, + type_list...>, OneType, Pred, To>(); +} + + +/** + * @brief Computes the value of an expression raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @tparam To destination type list to put the result to + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam T Expression being the base of the operation + */ +template typename To, typename OneType, + template typename Pred, typename T> + requires detail::non_zero +[[nodiscard]] consteval auto expr_pow(T) +{ + return expr_pow_impl(typename T::_num_{}, typename T::_den_{}); +} + + +// expr_map +template typename Proj> +struct expr_type_map; + +template typename Proj> + requires requires { typename Proj; } +struct expr_type_map { + using type = Proj; +}; + +template typename Proj> + requires requires { typename Proj; } +struct expr_type_map, Proj> { + using type = power, Ints...>; +}; + +template typename Proj> +concept expr_type_projectable = (requires { typename Proj; } || + (is_specialization_of_power && requires { typename Proj; })); + +template typename Proj> +inline constexpr bool expr_projectable_impl = false; + +template typename Proj> +inline constexpr bool expr_projectable_impl, Proj> = (... && expr_type_projectable); + +template typename Proj> +concept expr_projectable = requires { + typename T::_num_; + typename T::_den_; + requires expr_projectable_impl; + requires expr_projectable_impl; +}; + +template +[[nodiscard]] consteval auto map_power(T t) +{ + return t; +} + +template +[[nodiscard]] consteval auto map_power(power) +{ + return pow(T{}); +} + +template typename Proj, template typename To, typename OneType, + template typename Pred, expr_type_projectable... Nums, + expr_type_projectable... Dens> +[[nodiscard]] consteval auto expr_map_impl(type_list, type_list) +{ + return (OneType{} * ... * map_power(typename expr_type_map, Proj>::type{})) / + (OneType{} * ... * map_power(typename expr_type_map, Proj>::type{})); +} + +/** + * @brief Maps contents of one expression template to another resulting in a different type list + * + * @tparam Proj Projection to be used for mapping + * @tparam To destination type list to put the result to + * @tparam OneType type that represents the value `1` + * @tparam Pred binary less then predicate + * @tparam T expression template to map from + */ +template typename Proj, template typename To, typename OneType, + template typename Pred, expr_projectable T> +[[nodiscard]] consteval auto expr_map(T) +{ + if constexpr (type_list_size + type_list_size == 0) + return OneType{}; + else + return expr_map_impl(typename T::_num_{}, typename T::_den_{}); +} + +} // namespace detail + +} // namespace mp_units diff --git a/src/core/include/units/bits/external/fixed_string.h b/src/core/include/mp-units/bits/external/fixed_string.h similarity index 96% rename from src/core/include/units/bits/external/fixed_string.h rename to src/core/include/mp-units/bits/external/fixed_string.h index 25a7369a..2d0da7ec 100644 --- a/src/core/include/units/bits/external/fixed_string.h +++ b/src/core/include/mp-units/bits/external/fixed_string.h @@ -22,9 +22,9 @@ #pragma once -#include // IWYU pragma: keep +#include // IWYU pragma: keep // TODO use when moved to C++20 modules (parsing takes too long for each translation unit) -#include +#include // IWYU pragma: begin_exports #include @@ -34,7 +34,7 @@ #include -namespace units { +namespace mp_units { /** * @brief A compile-time fixed string @@ -111,4 +111,4 @@ basic_fixed_string(CharT) -> basic_fixed_string; template using fixed_string = basic_fixed_string; -} // namespace units +} // namespace mp_units diff --git a/src/core/include/units/bits/external/hacks.h b/src/core/include/mp-units/bits/external/hacks.h similarity index 98% rename from src/core/include/units/bits/external/hacks.h rename to src/core/include/mp-units/bits/external/hacks.h index 0f9b54dc..3eabdaed 100644 --- a/src/core/include/units/bits/external/hacks.h +++ b/src/core/include/mp-units/bits/external/hacks.h @@ -52,6 +52,7 @@ #define UNITS_DIAGNOSTIC_IGNORE_SHADOW UNITS_DIAGNOSTIC_IGNORE("-Wshadow") #define UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE #define UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT UNITS_DIAGNOSTIC_IGNORE("-Wzero-as-nullpointer-constant") +#define UNITS_DIAGNOSTIC_IGNORE_DEPRECATED UNITS_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations") #else #define UNITS_DIAGNOSTIC_PUSH UNITS_PRAGMA(warning(push)) #define UNITS_DIAGNOSTIC_POP UNITS_PRAGMA(warning(pop)) @@ -65,6 +66,7 @@ #define UNITS_DIAGNOSTIC_IGNORE_SHADOW UNITS_DIAGNOSTIC_IGNORE(4459) #define UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE UNITS_DIAGNOSTIC_IGNORE(4702) #define UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT +#define UNITS_DIAGNOSTIC_IGNORE_DEPRECATED #endif #if _LIBCPP_VERSION diff --git a/src/core/include/units/bits/external/type_list.h b/src/core/include/mp-units/bits/external/type_list.h similarity index 67% rename from src/core/include/units/bits/external/type_list.h rename to src/core/include/mp-units/bits/external/type_list.h index b6b6e7ec..b0ca737a 100644 --- a/src/core/include/units/bits/external/type_list.h +++ b/src/core/include/mp-units/bits/external/type_list.h @@ -22,12 +22,14 @@ #pragma once +#include // IWYU pragma: keep #include +#include UNITS_DIAGNOSTIC_PUSH UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF -namespace units { +namespace mp_units { namespace detail { @@ -42,6 +44,94 @@ inline constexpr bool is_type_list> = true; template concept TypeList = detail::is_type_list; +// size + +namespace detail { + +template +struct type_list_size_impl; + +template typename List, typename... Types> +struct type_list_size_impl> : std::integral_constant {}; + +} // namespace detail + +template +inline constexpr std::size_t type_list_size = detail::type_list_size_impl::value; + + +// map + +namespace detail { + +template typename To> +struct type_list_map_impl; + +template typename From, template typename To, typename... Args> +struct type_list_map_impl, To> { + using type = To; +}; + +} // namespace detail + +template typename To> +using type_list_map = TYPENAME detail::type_list_map_impl::type; + + +// element + +namespace detail { + +template +struct type_list_leaf { + using type = T; +}; + +template +struct indexed_type_list_impl; + +template +struct indexed_type_list_impl, Ts...> : type_list_leaf... {}; + +template +std::type_identity type_list_element_func(const type_list_leaf&); + +} // namespace detail + +template +struct indexed_type_list : detail::indexed_type_list_impl, Ts...> {}; + +template +using type_list_element_indexed = typename decltype(detail::type_list_element_func(std::declval()))::type; + +template +using type_list_element = type_list_element_indexed, I>; + + +// front + +namespace detail { + +template +struct type_list_front_impl; + +template typename List, typename T, typename... Ts> +struct type_list_front_impl> { + using type = T; +}; + +} // namespace detail + +template +using type_list_front = TYPENAME detail::type_list_front_impl::type; + + +// back + +template +using type_list_back = type_list_element - 1>; + + // push_front namespace detail { @@ -59,6 +149,7 @@ struct type_list_push_front_impl, NewTypes...> { template using type_list_push_front = TYPENAME detail::type_list_push_front_impl::type; + // push_back namespace detail { @@ -76,6 +167,7 @@ struct type_list_push_back_impl, NewTypes...> { template using type_list_push_back = TYPENAME detail::type_list_push_back_impl::type; + // join namespace detail { @@ -95,46 +187,29 @@ struct type_list_join_impl, List, Rest...> { template using type_list_join = TYPENAME detail::type_list_join_impl::type; + // split namespace detail { -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; +template +struct type_list_split_impl; -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> - requires(Idx < N) -struct split_impl : split_impl { - using base = split_impl; - using first_list = TYPENAME type_list_push_front_impl::type; - using second_list = TYPENAME base::second_list; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = TYPENAME base::first_list; - using second_list = TYPENAME type_list_push_front_impl::type; +template typename List, typename... Args, std::size_t... First, std::size_t... Second> +struct type_list_split_impl, std::index_sequence, std::index_sequence> { + using indexed_list = indexed_type_list; + using first_list = List...>; + using second_list = List...>; }; } // namespace detail template -struct type_list_split; + requires(N <= type_list_size) +struct type_list_split : + detail::type_list_split_impl, + std::make_index_sequence - N>> {}; -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = TYPENAME split::first_list; - using second_list = TYPENAME split::second_list; -}; // split_half @@ -144,6 +219,7 @@ struct type_list_split_half; template typename List, typename... Types> struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; + // merge_sorted namespace detail { @@ -166,7 +242,6 @@ struct type_list_merge_sorted_impl, List, Pred> { using type = List; }; - template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, template typename Pred> requires Pred::value @@ -187,6 +262,7 @@ struct type_list_merge_sorted_impl, List typename Pred> using type_list_merge_sorted = TYPENAME detail::type_list_merge_sorted_impl::type; + // sort namespace detail { @@ -218,6 +294,6 @@ struct type_list_sort_impl, Pred> { template typename Pred> using type_list_sort = TYPENAME detail::type_list_sort_impl::type; -} // namespace units +} // namespace mp_units UNITS_DIAGNOSTIC_POP diff --git a/src/core/include/mp-units/bits/external/type_name.h b/src/core/include/mp-units/bits/external/type_name.h new file mode 100644 index 00000000..e8fb007f --- /dev/null +++ b/src/core/include/mp-units/bits/external/type_name.h @@ -0,0 +1,40 @@ +// https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c/56766138#56766138 + +#pragma once + +#include + +template +[[nodiscard]] consteval std::string_view type_name() +{ + std::string_view name, prefix, suffix; +#ifdef __clang__ + name = __PRETTY_FUNCTION__; + prefix = "auto type_name() [T = "; + suffix = "]"; +#elif defined(__GNUC__) + name = __PRETTY_FUNCTION__; + prefix = "constexpr auto type_name() [with T = "; + suffix = "]"; +#elif defined(_MSC_VER) + name = __FUNCSIG__; + prefix = "auto __cdecl type_name<"; + suffix = ">(void)"; +#endif + name.remove_prefix(prefix.size()); + name.remove_suffix(suffix.size()); + return name; +} + +template +[[nodiscard]] consteval auto better_type_name(T1 v1, T2 v2) +{ + if constexpr (type_name().size() < type_name().size()) + return v1; + else if constexpr (type_name().size() < type_name().size()) + return v2; + else if constexpr (type_name() < type_name()) + return v1; + else + return v2; +} diff --git a/src/core/include/units/bits/external/type_traits.h b/src/core/include/mp-units/bits/external/type_traits.h similarity index 56% rename from src/core/include/units/bits/external/type_traits.h rename to src/core/include/mp-units/bits/external/type_traits.h index 286a713e..6c4f2d9a 100644 --- a/src/core/include/units/bits/external/type_traits.h +++ b/src/core/include/mp-units/bits/external/type_traits.h @@ -22,11 +22,11 @@ #pragma once -#include +#include #include #include -namespace units { +namespace mp_units { // conditional namespace detail { @@ -65,6 +65,12 @@ inline constexpr bool is_specialization_of = false; template typename Type> inline constexpr bool is_specialization_of, Type> = true; +template typename Type> +inline constexpr bool is_specialization_of_v = false; + +template typename Type> +inline constexpr bool is_specialization_of_v, Type> = true; + // is_derived_from_specialization_of namespace detail { @@ -77,4 +83,72 @@ template typename Type> // inline constexpr bool // TODO: Replace with concept when it works with MSVC concept is_derived_from_specialization_of = requires(T* t) { detail::to_base_specialization_of(t); }; -} // namespace units +template +concept one_of = (false || ... || std::same_as); + +template +[[nodiscard]] consteval bool contains() +{ + return (false || ... || is_same_v, T>); +} + +template typename T, typename... Ts> +[[nodiscard]] consteval bool contains() +{ + return (false || ... || is_specialization_of); +} + +template typename T, typename... Ts> +[[nodiscard]] consteval bool contains() +{ + return (false || ... || is_specialization_of_v); +} + +template auto V> +[[nodiscard]] consteval auto get() +{ + return V; +} + +template +[[nodiscard]] consteval auto get() +{ + if constexpr (is_same_v>) + return V1; + else + return get(); +} + +template typename T, typename T1> + requires is_specialization_of +[[nodiscard]] consteval auto get() +{ + return T1{}; +} + +template typename T, typename T1, typename T2, typename... Ts> +[[nodiscard]] consteval auto get() +{ + if constexpr (is_specialization_of) + return T1{}; + else + return get(); +} + +template typename T, typename T1> + requires is_specialization_of_v +[[nodiscard]] consteval auto get() +{ + return T1{}; +} + +template typename T, typename T1, typename T2, typename... Ts> +[[nodiscard]] consteval auto get() +{ + if constexpr (is_specialization_of_v) + return T1{}; + else + return get(); +} + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/get_associated_quantity.h b/src/core/include/mp-units/bits/get_associated_quantity.h new file mode 100644 index 00000000..abaee2a3 --- /dev/null +++ b/src/core/include/mp-units/bits/get_associated_quantity.h @@ -0,0 +1,86 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::detail { + +template +[[nodiscard]] consteval auto all_are_kinds(U); + +template +[[nodiscard]] consteval auto all_are_kinds(power) +{ + return all_are_kinds(U{}); +} + +template +[[nodiscard]] consteval bool all_are_kinds(type_list, type_list) +{ + return (... && all_are_kinds(Nums{})) && (... && all_are_kinds(Dens{})); +} + +template +[[nodiscard]] consteval auto all_are_kinds(U) +{ + if constexpr (requires { U::quantity_spec; }) + return QuantityKindSpec>; + else if constexpr (requires { U::reference_unit; }) + return all_are_kinds(U::reference_unit); + else if constexpr (requires { typename U::_num_; }) { + return all_are_kinds(typename U::_num_{}, typename U::_den_{}); + } +} + +template +[[nodiscard]] consteval auto get_associated_quantity_impl(U u); + +template +using to_quantity_spec = std::remove_const_t; + +template +[[nodiscard]] consteval auto get_associated_quantity_impl(U u) +{ + if constexpr (requires { U::quantity_spec; }) + return remove_kind(U::quantity_spec); + else if constexpr (requires { U::reference_unit; }) + return get_associated_quantity_impl(U::reference_unit); + else if constexpr (requires { typename U::_num_; }) { + return expr_map(u); + } +} + +template +[[nodiscard]] consteval auto get_associated_quantity(U u) +{ + constexpr bool all_kinds = all_are_kinds(u); + if constexpr (all_kinds) + return kind_of; + else + return get_associated_quantity_impl(u); +} + +} // namespace mp_units::detail diff --git a/src/core/include/mp-units/bits/get_common_base.h b/src/core/include/mp-units/bits/get_common_base.h new file mode 100644 index 00000000..0c232dc1 --- /dev/null +++ b/src/core/include/mp-units/bits/get_common_base.h @@ -0,0 +1,91 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include + +namespace mp_units::detail { + +[[nodiscard]] consteval std::size_t hierarchy_path_length(QuantitySpec auto q) +{ + if constexpr (requires { q._parent_; }) + return hierarchy_path_length(q._parent_) + 1; + else + return 1; +} + +template + requires(Offset >= 0) +[[nodiscard]] consteval QuantitySpec auto hierarchy_path_advance(QuantitySpec auto q) +{ + if constexpr (Offset == 0) + return q; + else if constexpr (requires { q._parent_; }) + return hierarchy_path_advance(q._parent_); +} + +template +[[nodiscard]] consteval bool have_common_base_in_hierarchy_of_equal_length(A a, B b) +{ + if constexpr (is_same_v) + return true; + else if constexpr (requires { a._parent_; }) + return have_common_base_in_hierarchy_of_equal_length(a._parent_, b._parent_); + else + return false; +} + +template +[[nodiscard]] consteval auto have_common_base(A a, B b) +{ + constexpr int a_length = hierarchy_path_length(A{}); + constexpr int b_length = hierarchy_path_length(B{}); + if constexpr (a_length > b_length) + return have_common_base_in_hierarchy_of_equal_length(hierarchy_path_advance(a), b); + else + return have_common_base_in_hierarchy_of_equal_length(a, hierarchy_path_advance(b)); +} + +template + requires(have_common_base_in_hierarchy_of_equal_length(A{}, B{})) +[[nodiscard]] consteval auto get_common_base_for_hierarchy_of_equal_length(A a, B b) +{ + if constexpr (is_same_v) + return a; + else + return get_common_base_for_hierarchy_of_equal_length(a._parent_, b._parent_); +} + +template + requires(have_common_base(A{}, B{})) +[[nodiscard]] consteval auto get_common_base(A a, B b) +{ + constexpr int a_length = hierarchy_path_length(A{}); + constexpr int b_length = hierarchy_path_length(B{}); + if constexpr (a_length > b_length) + return get_common_base_for_hierarchy_of_equal_length(hierarchy_path_advance(a), b); + else + return get_common_base_for_hierarchy_of_equal_length(a, hierarchy_path_advance(b)); +} + +} // namespace mp_units::detail diff --git a/src/core/include/units/magnitude.h b/src/core/include/mp-units/bits/magnitude.h similarity index 50% rename from src/core/include/units/magnitude.h rename to src/core/include/mp-units/bits/magnitude.h index f565e80d..c4d23b31 100644 --- a/src/core/include/units/magnitude.h +++ b/src/core/include/mp-units/bits/magnitude.h @@ -22,23 +22,74 @@ #pragma once -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include #include #include -namespace units { +namespace mp_units { + namespace detail { + // Higher numbers use fewer trial divisions, at the price of more storage space. using factorizer = wheel_factorizer<4>; + +} // namespace detail + +namespace detail { + +template +inline constexpr bool is_magnitude = false; + +template +inline constexpr bool is_specialization_of_magnitude = false; + } // namespace detail /** - * @brief Any type which can be used as a basis vector in a BasePower. + * @brief Concept to detect whether T is a valid Magnitude. + */ +template +concept Magnitude = detail::is_magnitude; + +/** + * @brief A type to represent a standalone constant value. + */ +// template +// struct constant { +// static constexpr auto value = V; +// }; + +// // is_derived_from_specialization_of_constant +// namespace detail { + +// template +// void to_base_specialization_of_constant(const volatile constant*); + +// template +// inline constexpr bool is_derived_from_specialization_of_constant = +// requires(T * t) { to_base_specialization_of_constant(t); }; + +// } // namespace detail + + +// template +// concept Constant = detail::is_derived_from_specialization_of_constant; + +// struct pi_v : constant> {}; + +/** + * @brief Any type which can be used as a basis vector in a PowerV. * * We have two categories. * @@ -52,9 +103,6 @@ using factorizer = wheel_factorizer<4>; * The reason we can't hold the value directly for floating point bases is so that we can support some compilers (e.g., * GCC 10) which don't yet permit floating point NTTPs. */ -template -concept BaseRep = - std::is_same_v || std::is_same_v, long double>; /** * @brief A basis vector in our magnitude representation, raised to some rational power. @@ -80,72 +128,119 @@ concept BaseRep = * _existing_ bases, including both prime numbers and any other irrational bases. For example, even though `sqrt(2)` is * irrational, we must not ever use it as a base; instead, we would use `base_power{2, ratio{1, 2}}`. */ -template -struct base_power { - // The rational power to which the base is raised. - ratio power{1}; - constexpr long double get_base() const { return T::value; } -}; - -/** - * @brief Specialization for prime number bases. - */ -template<> -struct base_power { - // The value of the basis "vector". Must be prime to be used with `magnitude` (below). - std::intmax_t base; - - // The rational power to which the base is raised. - ratio power{1}; - - constexpr std::intmax_t get_base() const { return base; } -}; - -/** - * @brief Deduction guides for base_power: only permit deducing integral bases. - */ -template U> -base_power(T, U) -> base_power; -template -base_power(T) -> base_power; - -// Implementation for BasePower concept (below). namespace detail { + template -inline constexpr bool is_base_power = false; -template -inline constexpr bool is_base_power> = true; +inline constexpr bool is_named_magnitude = Magnitude && !detail::is_specialization_of_magnitude; + +} + +template +concept PowerVBase = one_of || detail::is_named_magnitude; + +// TODO Unify with `power` if UTPs (P1985) are accepted by the Committee +template + requires(detail::valid_ratio && !detail::ratio_one) +struct power_v { + static constexpr auto base = V; + static constexpr ratio exponent{Num, Den...}; +}; + +namespace detail { + +template +inline constexpr bool is_specialization_of_power_v = false; + +template +inline constexpr bool is_specialization_of_power_v> = true; + } // namespace detail + +template +concept MagnitudeSpec = PowerVBase || detail::is_specialization_of_power_v; + +namespace detail { + +template +[[nodiscard]] consteval auto get_base(Element element) +{ + if constexpr (detail::is_specialization_of_power_v) + return Element::base; + else + return element; +} + +template +[[nodiscard]] consteval ratio get_exponent(Element) +{ + if constexpr (detail::is_specialization_of_power_v) + return Element::exponent; + else + return ratio{1}; +} + +} // namespace detail + + /** * @brief Concept to detect whether a _type_ is a valid base power. * * Note that this is somewhat incomplete. We must also detect whether a _value_ of that type is valid for use with * `magnitude<...>`. We will defer that second check to the constraints on the `magnitude` template. */ -template -concept BasePower = detail::is_base_power; - namespace detail { -constexpr auto inverse(BasePower auto bp) +// We do not want magnitude type to have the `l` literal after a value for a small integral number. +// For example this modifies `magnitude<3l>` to be `magnitude<3>` +template +[[nodiscard]] consteval auto shorten_T() { - bp.power.num *= -1; - return bp; + if constexpr (std::integral) { + if constexpr (V <= std::numeric_limits::max()) { + return static_cast(V); + } else { + return static_cast(V); + } + } else if constexpr (std::floating_point) { + return static_cast(V); + } else { + return V; + } +} + +template +[[nodiscard]] consteval auto power_v_or_T() +{ + constexpr auto shortT = shorten_T(); + + if constexpr (R.den == 1) { + if constexpr (R.num == 1) + return shortT; + else + return power_v{}; + } else { + return power_v{}; + } +} + +template +[[nodiscard]] consteval auto inverse(M) +{ + return power_v_or_T(); } // `widen_t` gives the widest arithmetic type in the same category, for intermediate computations. template -using widen_t = - std::conditional_t, - std::conditional_t, long double, - std::conditional_t, std::intmax_t, std::uintmax_t>>, - T>; +using widen_t = conditional, + conditional, long double, + conditional, std::intmax_t, std::uintmax_t>>, + T>; // Raise an arbitrary arithmetic type to a positive integer power at compile time. template -constexpr T int_power(T base, std::integral auto exp) +[[nodiscard]] consteval T int_power(T base, std::integral auto exp) { // As this function should only be called at compile time, the terminations herein function as // "parameter-compatible static_asserts", and should not result in terminations at runtime. @@ -182,27 +277,28 @@ constexpr T int_power(T base, std::integral auto exp) template -constexpr widen_t compute_base_power(BasePower auto bp) +[[nodiscard]] consteval widen_t compute_base_power(MagnitudeSpec auto el) { // This utility can only handle integer powers. To compute rational powers at compile time, we'll // need to write a custom function. // // Note that since this function should only be called at compile time, the point of these // terminations is to act as "static_assert substitutes", not to actually terminate at runtime. - if (bp.power.den != 1) { + const auto exp = get_exponent(el); + if (exp.den != 1) { std::terminate(); // Rational powers not yet supported } - if (bp.power.num < 0) { + if (exp.num < 0) { if constexpr (std::is_integral_v) { std::terminate(); // Cannot represent reciprocal as integer } else { - return T{1} / compute_base_power(inverse(bp)); + return T{1} / compute_base_power(inverse(el)); } } - auto power = bp.power.num; - return int_power(static_cast>(bp.get_base()), power); + auto power = exp.num; + return int_power(static_cast>(get_base(el)), power); } // A converter for the value member variable of magnitude (below). @@ -212,7 +308,7 @@ constexpr widen_t compute_base_power(BasePower auto bp) template // TODO(chogg): Migrate this to use `treat_as_floating_point`. requires(!std::is_integral_v || std::is_integral_v) -constexpr To checked_static_cast(From x) +[[nodiscard]] consteval To checked_static_cast(From x) { // This function should only ever be called at compile time. The purpose of these terminations is // to produce compiler errors, because we cannot `static_assert` on function arguments. @@ -224,31 +320,15 @@ constexpr To checked_static_cast(From x) return static_cast(x); } + } // namespace detail -/** - * @brief Equality detection for two base powers. - */ -template -constexpr bool operator==(T t, U u) -{ - return std::is_same_v && (t.get_base() == u.get_base()) && (t.power == u.power); -} - -/** - * @brief A BasePower, raised to a rational power E. - */ -constexpr auto pow(BasePower auto bp, ratio p) -{ - bp.power = bp.power * p; - return bp; -} // A variety of implementation detail helpers. namespace detail { // The exponent of `factor` in the prime factorization of `n`. -constexpr std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) +[[nodiscard]] consteval std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) { std::intmax_t m = 0; while (n % factor == 0) { @@ -261,7 +341,7 @@ constexpr std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n) // Divide a number by a given base raised to some power. // // Undefined unless base > 1, pow >= 0, and (base ^ pow) evenly divides n. -constexpr std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std::intmax_t n) +[[nodiscard]] consteval std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std::intmax_t n) { while (pow-- > 0) { n /= base; @@ -270,181 +350,216 @@ constexpr std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std: } // A way to check whether a number is prime at compile time. -constexpr bool is_prime(std::intmax_t n) { return (n >= 0) && factorizer::is_prime(static_cast(n)); } +// [[nodiscard]] consteval bool is_prime(std::intmax_t n) +// { +// return (n >= 0) && factorizer::is_prime(static_cast(n)); +// } -constexpr bool is_valid_base_power(const BasePower auto& bp) -{ - if (bp.power == 0) { - return false; - } +// template +// [[nodiscard]] consteval bool is_valid_element(Element element) +// { +// if (get_exponent(element) == 0) { +// return false; +// } +// if constexpr (std::integral) { +// // Some prime numbers are so big, that we can't check their primality without exhausting limits on constexpr +// steps +// // and/or iterations. We can still _perform_ the factorization for these by using the `known_first_factor` +// // workaround. However, we can't _check_ that they are prime, because this workaround depends on the input being +// // usable in a constexpr expression. This is true for `prime_factorization` (below), where the input `N` is a +// // template parameter, but is not true for our case, where the input `bp.get_base()` is a function parameter. +// (See +// // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html for some background reading on this +// // distinction.) +// // +// // In our case: we simply give up on excluding every possible ill-formed base power, and settle for catching the +// // most likely and common mistakes. +// if (const bool too_big_to_check = (get_base_value(element) > 1'000'000'000)) { +// return true; +// } - if constexpr (std::is_same_v) { - // Some prime numbers are so big, that we can't check their primality without exhausting limits on constexpr steps - // and/or iterations. We can still _perform_ the factorization for these by using the `known_first_factor` - // workaround. However, we can't _check_ that they are prime, because this workaround depends on the input being - // usable in a constexpr expression. This is true for `prime_factorization` (below), where the input `N` is a - // template parameter, but is not true for our case, where the input `bp.get_base()` is a function parameter. (See - // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html for some background reading on this - // distinction.) - // - // In our case: we simply give up on excluding every possible ill-formed base power, and settle for catching the - // most likely and common mistakes. - if (const bool too_big_to_check = (bp.get_base() > 1'000'000'000)) { - return true; - } - - return is_prime(bp.get_base()); - } else { - return bp.get_base() > 0; - } -} +// return is_prime(get_base_value(element)); +// } else { +// return get_base_value(element) > 0; +// } +// } // A function object to apply a predicate to all consecutive pairs of values in a sequence. -template -struct pairwise_all { - Predicate predicate; +// template +// struct pairwise_all { +// Predicate predicate; - template - constexpr bool operator()(Ts&&... ts) const - { - // Carefully handle different sizes, avoiding unsigned integer underflow. - constexpr auto num_comparisons = [](auto num_elements) { - return (num_elements > 1) ? (num_elements - 1) : 0; - }(sizeof...(Ts)); +// template +// [[nodiscard]] consteval bool operator()(Ts&&... ts) const +// { +// // Carefully handle different sizes, avoiding unsigned integer underflow. +// constexpr auto num_comparisons = [](auto num_elements) { +// return (num_elements > 1) ? (num_elements - 1) : 0; +// }(sizeof...(Ts)); - // Compare zero or more pairs of neighbours as needed. - return [this](std::tuple&& t, std::index_sequence) { - return (predicate(std::get(t), std::get(t)) && ...); - }(std::make_tuple(std::forward(ts)...), std::make_index_sequence()); - } -}; +// // Compare zero or more pairs of neighbours as needed. +// return [this](std::tuple && t, std::index_sequence) +// { +// return (predicate(std::get(t), std::get(t)) && ...); +// } +// (std::make_tuple(std::forward(ts)...), std::make_index_sequence()); +// } +// }; // Deduction guide: permit constructions such as `pairwise_all{std::less{}}`. -template -pairwise_all(T) -> pairwise_all; +// template +// pairwise_all(T) -> pairwise_all; // Check whether a sequence of (possibly heterogeneously typed) values are strictly increasing. -template - requires(std::is_signed_v && ...) -constexpr bool strictly_increasing(Ts&&... ts) +// template +// requires(std::is_signed_v && ...) +// [[nodiscard]] consteval bool strictly_increasing(Ts&&... ts) +// { +// return pairwise_all{std::less{}}(std::forward(ts)...); +// } + +// template +// inline constexpr bool all_elements_valid = (is_valid_element(Elements) && ...); + +// template +// inline constexpr bool all_elements_in_order = strictly_increasing(get_base_value(Elements)...); + +// template +// inline constexpr bool is_element_pack_valid = all_elements_valid && all_elements_in_order; + +[[nodiscard]] consteval bool is_rational(MagnitudeSpec auto element) { - return pairwise_all{std::less{}}(std::forward(ts)...); + static_assert(!Magnitude); // magnitudes are handles by another overload + return std::is_integral_v && (get_exponent(element).den == 1); } -template -inline constexpr bool all_base_powers_valid = (is_valid_base_power(BPs) && ...); - -template -inline constexpr bool all_bases_in_order = strictly_increasing(BPs.get_base()...); - -template -inline constexpr bool is_base_power_pack_valid = all_base_powers_valid && all_bases_in_order; - -constexpr bool is_rational(BasePower auto bp) +[[nodiscard]] consteval bool is_integral(MagnitudeSpec auto element) { - return std::is_integral_v && (bp.power.den == 1); + static_assert(!Magnitude); // magnitudes are handles by another overload + return is_rational(element) && get_exponent(element).num > 0; } -constexpr bool is_integral(BasePower auto bp) { return is_rational(bp) && bp.power.num > 0; } } // namespace detail + /** * @brief A representation for positive real numbers which optimizes taking products and rational powers. * * Magnitudes can be treated as values. Each type encodes exactly one value. Users can multiply, divide, raise to * rational powers, and compare for equality. */ -template - requires detail::is_base_power_pack_valid +template +// requires detail::is_element_pack_valid struct magnitude { - // Whether this magnitude represents an integer. - friend constexpr bool is_integral(const magnitude&) { return (detail::is_integral(BPs) && ...); } + [[nodiscard]] friend consteval bool is_integral(const magnitude&) + { + using namespace detail; // needed for recursive case when magnitudes are in the MagnitudeSpec + return (is_integral(Ms) && ...); + } - // Whether this magnitude represents a rational number. - friend constexpr bool is_rational(const magnitude&) { return (detail::is_rational(BPs) && ...); } + [[nodiscard]] friend consteval bool is_rational(const magnitude&) + { + using namespace detail; // needed for recursive case when magnitudes are in the MagnitudeSpec + return (is_rational(Ms) && ...); + } }; -// Implementation for Magnitude concept (below). + namespace detail { + +template +void to_base_specialization_of_magnitude(const volatile magnitude*); + template -inline constexpr bool is_magnitude = false; -template -inline constexpr bool is_magnitude> = true; +inline constexpr bool is_derived_from_specialization_of_magnitude = + requires(T* t) { to_base_specialization_of_magnitude(t); }; + +template + requires is_derived_from_specialization_of_magnitude +inline constexpr bool is_magnitude = true; + +template +inline constexpr bool is_specialization_of_magnitude> = true; + } // namespace detail -/** - * @brief Concept to detect whether T is a valid Magnitude. - */ -template -concept Magnitude = detail::is_magnitude; /** * @brief The value of a Magnitude in a desired type T. */ -template -// TODO(chogg): Migrate this to use `treat_as_floating_point`. - requires(!std::is_integral_v || is_integral(magnitude{})) -constexpr T get_value(const magnitude&) +template + requires(is_integral(magnitude{})) || treat_as_floating_point +constexpr T get_value(const magnitude&) { // Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow. - constexpr auto result = detail::checked_static_cast((detail::compute_base_power(BPs) * ... * T{1})); + constexpr auto result = detail::checked_static_cast((detail::compute_base_power(Ms) * ... * T{1})); return result; } -/** - * @brief A base to represent pi. - */ -struct pi_base { - static constexpr long double value = std::numbers::pi_v; -}; /** * @brief A convenient Magnitude constant for pi, which we can manipulate like a regular number. */ -inline constexpr Magnitude auto mag_pi = magnitude{}>{}; +inline constexpr struct mag_pi : magnitude> { +} mag_pi; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude equality implementation. -template -constexpr bool operator==(magnitude, magnitude) +template +[[nodiscard]] consteval bool operator==(M1, M2) { - if constexpr (sizeof...(LeftBPs) == sizeof...(RightBPs)) { - return ((LeftBPs == RightBPs) && ...); - } else { - return false; - } + return std::is_same_v; } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude rational powers implementation. -template -constexpr auto pow(magnitude) +template +[[nodiscard]] consteval auto pow(magnitude) { - if constexpr (E.num == 0) { + if constexpr (Num == 0) { return magnitude<>{}; } else { - return magnitude{}; + return magnitude()...>{}; } } -template -constexpr auto sqrt(magnitude m) +template +[[nodiscard]] consteval auto sqrt(magnitude m) { - return pow(m); + return pow<1, 2>(m); } -template -constexpr auto cbrt(magnitude m) +template +[[nodiscard]] consteval auto cbrt(magnitude m) { - return pow(m); + return pow<1, 3>(m); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude product implementation. +namespace detail { + +consteval bool less(MagnitudeSpec auto lhs, MagnitudeSpec auto rhs) +{ + using lhs_base_t = decltype(get_base(lhs)); + using rhs_base_t = decltype(get_base(rhs)); + + if constexpr (is_named_magnitude && is_named_magnitude) + return type_name() < type_name(); + else if constexpr (!is_named_magnitude && !is_named_magnitude) + return get_base(lhs) < get_base(rhs); + else + return is_named_magnitude; +} + +} // namespace detail + + // Base cases, for when either (or both) inputs are the identity. constexpr Magnitude auto operator*(magnitude<>, magnitude<>) { return magnitude<>{}; } constexpr Magnitude auto operator*(magnitude<>, Magnitude auto m) { return m; } @@ -452,37 +567,38 @@ constexpr Magnitude auto operator*(Magnitude auto m, magnitude<>) { return m; } // Recursive case for the product of any two non-identity Magnitudes. template -constexpr Magnitude auto operator*(magnitude, magnitude) +[[nodiscard]] consteval Magnitude auto operator*(magnitude, magnitude) { - // Case for when H1 has the smaller base. - if constexpr (H1.get_base() < H2.get_base()) { + using namespace detail; + + if constexpr (less(H1, H2)) { if constexpr (sizeof...(T1) == 0) { // Shortcut for the "pure prepend" case, which makes it easier to implement some of the other cases. return magnitude{}; } else { return magnitude

{} * (magnitude{} * magnitude{}); } - } - - // Case for when H2 has the smaller base. - if constexpr (H1.get_base() > H2.get_base()) { + } else if constexpr (less(H2, H1)) { return magnitude

{} * (magnitude{} * magnitude{}); - } + } else { + if constexpr (is_same_v) { + constexpr auto partial_product = magnitude{} * magnitude{}; + if constexpr (get_exponent(H1) + get_exponent(H2) == 0) { + return partial_product; + } else { + // Make a new power_v with the common base of H1 and H2, whose power is their powers' sum. + constexpr auto new_head = power_v_or_T(); - // "Same leading base" case. - if constexpr (H1.get_base() == H2.get_base()) { - constexpr auto partial_product = magnitude{} * magnitude{}; - - // Make a new base_power with the common base of H1 and H2, whose power is their powers' sum. - constexpr auto new_head = [&](auto head) { - head.power = H1.power + H2.power; - return head; - }(H1); - - if constexpr (new_head.power == 0) { - return partial_product; + if constexpr (get_exponent(new_head) == 0) { + return partial_product; + } else { + return magnitude{} * partial_product; + } + } + } else if constexpr (is_named_magnitude) { + return magnitude

{} * (magnitude{} * magnitude{}); } else { - return magnitude{} * partial_product; + return magnitude

{} * (magnitude{} * magnitude{}); } } } @@ -490,7 +606,7 @@ constexpr Magnitude auto operator*(magnitude, magnitude) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude quotient implementation. -constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1>(r); } +[[nodiscard]] consteval auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1>(r); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Magnitude numerator and denominator implementation. @@ -498,19 +614,15 @@ constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1 namespace detail { // The largest integer which can be extracted from any magnitude with only a single basis vector. -template -constexpr auto integer_part(magnitude) +template +[[nodiscard]] consteval auto integer_part(magnitude) { - constexpr auto power_num = BP.power.num; - constexpr auto power_den = BP.power.den; + constexpr auto power_num = get_exponent(M).num; + constexpr auto power_den = get_exponent(M).den; - if constexpr (std::is_integral_v && (power_num >= power_den)) { - constexpr auto largest_integer_power = [=](BasePower auto bp) { - bp.power = (power_num / power_den); // Note: integer division intended. - return bp; - }(BP); // Note: lambda is immediately invoked. - - return magnitude{}; + if constexpr (std::is_integral_v && (power_num >= power_den)) { + // largest integer power + return magnitude()>{}; // Note: integer division intended } else { return magnitude<>{}; } @@ -518,13 +630,13 @@ constexpr auto integer_part(magnitude) } // namespace detail -template -constexpr auto numerator(magnitude) +template +[[nodiscard]] consteval auto numerator(magnitude) { - return (detail::integer_part(magnitude{}) * ... * magnitude<>{}); + return (detail::integer_part(magnitude{}) * ... * magnitude<>{}); } -constexpr auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } +[[nodiscard]] consteval auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } // Implementation of conversion to ratio goes here, because it needs `numerator()` and `denominator()`. constexpr ratio as_ratio(Magnitude auto m) @@ -556,44 +668,50 @@ constexpr ratio as_ratio(Magnitude auto m) // minimum power for each base (where absent bases implicitly have a power of 0). namespace detail { -template -constexpr auto remove_positive_power(magnitude m) + +template +[[nodiscard]] consteval auto remove_positive_power(magnitude m) { - if constexpr (BP.power.num < 0) { + if constexpr (get_exponent(M).num < 0) { return m; } else { return magnitude<>{}; } } -template -constexpr auto remove_positive_powers(magnitude) +template +[[nodiscard]] consteval auto remove_positive_powers(magnitude) { - return (magnitude<>{} * ... * remove_positive_power(magnitude{})); + return (magnitude<>{} * ... * remove_positive_power(magnitude{})); } -} // namespace detail // Base cases, for when either (or both) inputs are the identity. -constexpr auto common_magnitude(magnitude<>, magnitude<>) { return magnitude<>{}; } -constexpr auto common_magnitude(magnitude<>, Magnitude auto m) { return detail::remove_positive_powers(m); } -constexpr auto common_magnitude(Magnitude auto m, magnitude<>) { return detail::remove_positive_powers(m); } +[[nodiscard]] consteval auto common_magnitude(magnitude<>, magnitude<>) { return magnitude<>{}; } +[[nodiscard]] consteval auto common_magnitude(magnitude<>, Magnitude auto m) +{ + return detail::remove_positive_powers(m); +} +[[nodiscard]] consteval auto common_magnitude(Magnitude auto m, magnitude<>) +{ + return detail::remove_positive_powers(m); +} // Recursive case for the common Magnitude of any two non-identity Magnitudes. template -constexpr auto common_magnitude(magnitude, magnitude) +[[nodiscard]] consteval auto common_magnitude(magnitude, magnitude) { using detail::remove_positive_power; - if constexpr (H1.get_base() < H2.get_base()) { + if constexpr (detail::get_base(H1) < detail::get_base(H2)) { // When H1 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); - } else if constexpr (H2.get_base() < H1.get_base()) { + } else if constexpr (detail::get_base(H2) < detail::get_base(H1)) { // When H2 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); } else { // When the bases are equal, pick whichever has the lower power. constexpr auto common_tail = common_magnitude(magnitude{}, magnitude{}); - if constexpr (H1.power < H2.power) { + if constexpr (detail::get_exponent(H1) < detail::get_exponent(H2)) { return magnitude

{} * common_tail; } else { return magnitude

{} * common_tail; @@ -601,6 +719,18 @@ constexpr auto common_magnitude(magnitude, magnitude) } } +template +[[nodiscard]] consteval auto common_magnitude_type_impl(magnitude) +{ + return (... * decltype(get_base(Ms)){}) * std::intmax_t{}; +} + +// Returns the most precise type to express the magnitude factor +template +using common_magnitude_type = decltype(common_magnitude_type_impl(M)); + +} // namespace detail + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // `mag()` implementation. @@ -614,11 +744,12 @@ template inline constexpr std::optional known_first_factor = std::nullopt; namespace detail { + // Helper to perform prime factorization at compile time. template - requires(N > 0) + requires gt_zero struct prime_factorization { - static constexpr std::intmax_t get_or_compute_first_factor() + [[nodiscard]] static consteval std::intmax_t get_or_compute_first_factor() { if constexpr (known_first_factor.has_value()) { return known_first_factor.value(); @@ -632,7 +763,7 @@ struct prime_factorization { static constexpr std::intmax_t remainder = remove_power(first_base, first_power, N); static constexpr auto value = - magnitude{} * prime_factorization::value; + magnitude()>{} * prime_factorization::value; }; // Specialization for the prime factorization of 1 (base case). @@ -643,6 +774,7 @@ struct prime_factorization<1> { template inline constexpr auto prime_factorization_v = prime_factorization::value; + } // namespace detail /** @@ -652,42 +784,74 @@ inline constexpr auto prime_factorization_v = prime_factorization::value; * manually adding base powers. */ template - requires(R.num > 0) -constexpr Magnitude auto mag() -{ - return detail::prime_factorization_v / detail::prime_factorization_v; -} + requires detail::gt_zero +inline constexpr Magnitude auto mag = detail::prime_factorization_v / detail::prime_factorization_v; /** * @brief Create a Magnitude which is some rational number raised to a rational power. */ template - requires(Base.num > 0) -constexpr Magnitude auto mag_power() -{ - return pow(mag()); -} + requires detail::gt_zero +inline constexpr Magnitude auto mag_power = pow(mag); namespace detail { -template -constexpr ratio get_power(T base, magnitude) + +template +[[nodiscard]] consteval ratio get_power(T base, magnitude) { - return ((BPs.get_base() == base ? BPs.power : ratio{0}) + ... + ratio{0}); + return ((get_base(Ms) == base ? get_exponent(Ms) : ratio{0}) + ... + ratio{0}); } -constexpr std::intmax_t integer_part(ratio r) { return r.num / r.den; } +[[nodiscard]] consteval std::intmax_t integer_part(ratio r) { return r.num / r.den; } -constexpr std::intmax_t extract_power_of_10(Magnitude auto m) +[[nodiscard]] consteval std::intmax_t extract_power_of_10(Magnitude auto m) { const auto power_of_2 = get_power(2, m); const auto power_of_5 = get_power(5, m); - if ((power_of_2 * power_of_5).num <= 0) { - return 0; - } + if ((power_of_2 * power_of_5).num <= 0) return 0; return integer_part((detail::abs(power_of_2) < detail::abs(power_of_5)) ? power_of_2 : power_of_5); } -} // namespace detail -} // namespace units +inline constexpr basic_symbol_text base_multiplier("× 10", "x 10"); + +template +[[nodiscard]] consteval auto magnitude_text() +{ + constexpr auto exp10 = extract_power_of_10(M); + + constexpr Magnitude auto base = M / mag_power<10, exp10>; + constexpr Magnitude auto num = numerator(base); + constexpr Magnitude auto den = denominator(base); + // TODO address the below + static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); + + constexpr auto num_value = get_value(num); + constexpr auto den_value = get_value(den); + + if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { + return base_multiplier + superscript(); + } else if constexpr (num_value != 1 || den_value != 1 || exp10 != 0) { + auto txt = basic_fixed_string("[") + regular(); + if constexpr (den_value == 1) { + if constexpr (exp10 == 0) { + return txt + basic_fixed_string("]"); + } else { + return txt + " " + base_multiplier + superscript() + basic_fixed_string("]"); + } + } else { + if constexpr (exp10 == 0) { + return txt + basic_fixed_string("/") + regular() + basic_fixed_string("]"); + } else { + return txt + basic_fixed_string("/") + regular() + " " + base_multiplier + superscript() + + basic_fixed_string("]"); + } + } + } else { + return basic_fixed_string(""); + } +} + +} // namespace detail +} // namespace mp_units diff --git a/src/core/include/units/bits/math_concepts.h b/src/core/include/mp-units/bits/math_concepts.h similarity index 91% rename from src/core/include/units/bits/math_concepts.h rename to src/core/include/mp-units/bits/math_concepts.h index e92acef1..80079220 100644 --- a/src/core/include/units/bits/math_concepts.h +++ b/src/core/include/mp-units/bits/math_concepts.h @@ -24,12 +24,12 @@ #include -namespace units::detail { +namespace mp_units::detail { -template +template concept gt_zero = (N > 0); -template +template concept non_zero = (N != 0); -} // namespace units::detail +} // namespace mp_units::detail diff --git a/src/core/include/units/bits/prime.h b/src/core/include/mp-units/bits/prime.h similarity index 84% rename from src/core/include/units/bits/prime.h rename to src/core/include/mp-units/bits/prime.h index 56a65168..b3365bdc 100644 --- a/src/core/include/units/bits/prime.h +++ b/src/core/include/mp-units/bits/prime.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include @@ -30,9 +30,9 @@ #include #include -namespace units::detail { +namespace mp_units::detail { -constexpr bool is_prime_by_trial_division(std::uintmax_t n) +[[nodiscard]] consteval bool is_prime_by_trial_division(std::uintmax_t n) { for (std::uintmax_t f = 2; f * f <= n; f += 1 + (f % 2)) { if (n % f == 0) { @@ -45,7 +45,7 @@ constexpr bool is_prime_by_trial_division(std::uintmax_t n) // Return the first factor of n, as long as it is either k or n. // // Precondition: no integer smaller than k evenly divides n. -constexpr std::optional first_factor_maybe(std::uintmax_t n, std::uintmax_t k) +[[nodiscard]] constexpr std::optional first_factor_maybe(std::uintmax_t n, std::uintmax_t k) { if (n % k == 0) { return k; @@ -57,7 +57,7 @@ constexpr std::optional first_factor_maybe(std::uintmax_t n, std } template -constexpr std::array first_n_primes() +[[nodiscard]] consteval std::array first_n_primes() { std::array primes; primes[0] = 2; @@ -71,7 +71,7 @@ constexpr std::array first_n_primes() } template -constexpr void call_for_coprimes_up_to(std::uintmax_t n, const std::array& basis, Callable&& call) +consteval void call_for_coprimes_up_to(std::uintmax_t n, const std::array& basis, Callable&& call) { for (std::uintmax_t i = 0u; i < n; ++i) { if (std::apply([&i](auto... primes) { return ((i % primes != 0) && ...); }, basis)) { @@ -81,7 +81,7 @@ constexpr void call_for_coprimes_up_to(std::uintmax_t n, const std::array -constexpr std::size_t num_coprimes_up_to(std::uintmax_t n, const std::array& basis) +[[nodiscard]] consteval std::size_t num_coprimes_up_to(std::uintmax_t n, const std::array& basis) { std::size_t count = 0u; call_for_coprimes_up_to(n, basis, [&count](auto) { ++count; }); @@ -89,7 +89,7 @@ constexpr std::size_t num_coprimes_up_to(std::uintmax_t n, const std::array -constexpr auto coprimes_up_to(std::size_t n, const std::array& basis) +[[nodiscard]] consteval auto coprimes_up_to(std::size_t n, const std::array& basis) { std::array coprimes; std::size_t i = 0u; @@ -100,7 +100,7 @@ constexpr auto coprimes_up_to(std::size_t n, const std::array } template -constexpr std::uintmax_t product(const std::array& values) +[[nodiscard]] consteval std::uintmax_t product(const std::array& values) { std::uintmax_t product = 1; for (const auto& v : values) { @@ -135,7 +135,7 @@ struct wheel_factorizer { static constexpr auto coprimes_in_first_wheel = coprimes_up_to(wheel_size, basis); - static constexpr std::uintmax_t find_first_factor(std::uintmax_t n) + [[nodiscard]] static consteval std::uintmax_t find_first_factor(std::uintmax_t n) { if (const auto k = detail::get_first_of(basis, [&](auto p) { return first_factor_maybe(n, p); })) return *k; @@ -150,7 +150,7 @@ struct wheel_factorizer { return n; } - static constexpr bool is_prime(std::size_t n) { return (n > 1) && find_first_factor(n) == n; } + [[nodiscard]] static consteval bool is_prime(std::size_t n) { return (n > 1) && find_first_factor(n) == n; } }; -} // namespace units::detail +} // namespace mp_units::detail diff --git a/test/metabench/make_dimension/downcasting_no_concepts.h b/src/core/include/mp-units/bits/quantity_cast.h similarity index 56% rename from test/metabench/make_dimension/downcasting_no_concepts.h rename to src/core/include/mp-units/bits/quantity_cast.h index 8b7bec8f..712ea041 100644 --- a/test/metabench/make_dimension/downcasting_no_concepts.h +++ b/src/core/include/mp-units/bits/quantity_cast.h @@ -22,23 +22,34 @@ #pragma once -#include "hacks.h" +#include +#include #include -namespace units { +namespace mp_units { -template -struct downcast_base { - using downcast_base_type = BaseType; -}; +/** + * @brief Explicit cast of a quantity type + * + * This cast converts only a quantity type. It might be used to force some quantity type + * conversions that are not implicitly allowed but are allowed explicitly. + * + * For example: + * + * @code{.cpp} + * auto length = isq::length(42 * m); + * auto distance = quantity_cast(length); + * @endcode + * + * @note This cast does not affect the underlying value of a number stored in a quantity. + * + * @tparam ToQS a quantity specification to use for a target quantity + */ +template +[[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q) + requires Quantity> && (castable(q.quantity_spec, ToQS)) +{ + return make_quantity{}>(std::forward(q).number()); +} -template -using downcast_base_t = T::downcast_base_type; - -template -struct downcast_traits : std::type_identity {}; - -template -using downcast_traits_t = downcast_traits::type; - -} // namespace units +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/quantity_concepts.h b/src/core/include/mp-units/bits/quantity_concepts.h new file mode 100644 index 00000000..a544be61 --- /dev/null +++ b/src/core/include/mp-units/bits/quantity_concepts.h @@ -0,0 +1,81 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +template Rep> +class quantity; + +namespace detail { + +template +void to_base_specialization_of_quantity(const volatile quantity*); + +template +inline constexpr bool is_derived_from_specialization_of_quantity = + requires(T* t) { to_base_specialization_of_quantity(t); }; + +} // namespace detail + +/** + * @brief A concept matching all quantities in the library + * + * Satisfied by all types being a either specialization or derived from `quantity` + */ +template +concept Quantity = detail::is_derived_from_specialization_of_quantity; + +/** + * @brief A concept matching all quantities with provided dimension or quantity spec + * + * Satisfied by all quantities with a dimension/quantity_spec being the instantiation derived from + * the provided dimension/quantity_spec type. + */ +template +concept QuantityOf = Quantity && ReferenceOf, V>; + +/** + * @brief A concept matching all external quantities like types + * + * Satisfied by all external types (not-defined in mp-units) that via a `quantity_like_traits` provide + * all quantity-specific information. + */ +template +concept QuantityLike = requires(T q) { + quantity_like_traits::reference; + typename quantity_like_traits::rep; + requires Reference::reference)>>; + requires RepresentationOf::rep, + get_quantity_spec(quantity_like_traits::reference).character>; + { + quantity_like_traits::number(q) + } -> std::convertible_to::rep>; +}; + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/quantity_point_concepts.h b/src/core/include/mp-units/bits/quantity_point_concepts.h new file mode 100644 index 00000000..184864c9 --- /dev/null +++ b/src/core/include/mp-units/bits/quantity_point_concepts.h @@ -0,0 +1,128 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +template +struct absolute_point_origin; + +namespace detail { + +template +inline constexpr bool is_quantity_point = false; + +template +void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin*); + +template +inline constexpr bool is_derived_from_specialization_of_absolute_point_origin = + requires(T* t) { to_base_specialization_of_absolute_point_origin(t); }; + +} // namespace detail + +/** + * @brief A concept matching all quantity points in the library + * + * Satisfied by all types being a either specialization or derived from `quantity_point` + */ +template +concept QuantityPoint = detail::is_quantity_point; + +/** + * @brief A concept matching all quantity point origins in the library + * + * Satisfied by either quantity points or by all types derived from `absolute_point_origin` class template. + */ +template +concept PointOrigin = QuantityPoint || detail::is_derived_from_specialization_of_absolute_point_origin; + +/** + * @brief A concept matching all quantity point origins for a specified quantity type in the library + * + * Satisfied by all quantity point origins that are defined using a provided quantity specification. + */ +template +concept PointOriginFor = + PointOrigin && QuantitySpec> && implicitly_convertible(Q, T::quantity_spec); + +template auto PO, + RepresentationOf Rep> +class quantity_point; + +namespace detail { + +template +void to_base_specialization_of_quantity_point(const volatile quantity_point*); + +template +inline constexpr bool is_derived_from_specialization_of_quantity_point = + requires(T* t) { to_base_specialization_of_quantity_point(t); }; + +template + requires is_derived_from_specialization_of_quantity_point +inline constexpr bool is_quantity_point = true; + +} // namespace detail + +/** + * @brief A concept matching all quantity points with provided dimension or quantity spec + * + * Satisfied by all quantity points with a dimension/quantity_spec being the instantiation derived from + * the provided dimension/quantity_spec type, or quantity points having the origin with the same + * `absolute_point_origin`. + */ +template +concept QuantityPointOf = + QuantityPoint && + (ReferenceOf, V> || + (PointOrigin> && + std::convertible_to, std::remove_const_t>)); + +/** + * @brief A concept matching all external quantity point like types + * + * Satisfied by all external types (not-defined in mp-units) that via a `quantity_point_like_traits` provide + * all quantity_point-specific information. + */ +template +concept QuantityPointLike = requires(T q) { + quantity_point_like_traits::reference; + quantity_point_like_traits::point_origin; + typename quantity_point_like_traits::rep; + requires Reference::reference)>>; + requires PointOrigin::point_origin)>>; + requires RepresentationOf::rep, + get_quantity_spec(quantity_point_like_traits::reference).character>; + requires std::constructible_from< + typename quantity_point::reference, quantity_point_like_traits::point_origin, + typename quantity_point_like_traits::rep>::quantity_type, + decltype(quantity_point_like_traits::relative(q))>; +}; + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/quantity_spec_concepts.h b/src/core/include/mp-units/bits/quantity_spec_concepts.h new file mode 100644 index 00000000..27838524 --- /dev/null +++ b/src/core/include/mp-units/bits/quantity_spec_concepts.h @@ -0,0 +1,167 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units { + +#ifdef __cpp_explicit_this_parameter +template +#else +template +#endif +struct quantity_spec; + +template +struct kind_of_; + +namespace detail { + +template +inline constexpr bool is_specialization_of_kind_of = false; + +template +inline constexpr bool is_specialization_of_kind_of> = true; + +template +concept QuantityKindSpec = is_specialization_of_kind_of; + +#ifdef __cpp_explicit_this_parameter +template +void to_base_specialization_of_quantity_spec(const volatile quantity_spec*); +#else +template +void to_base_specialization_of_quantity_spec(const volatile quantity_spec*); +#endif + +template +inline constexpr bool is_derived_from_specialization_of_quantity_spec = + requires(T* t) { to_base_specialization_of_quantity_spec(t); }; + +#ifdef __cpp_explicit_this_parameter +template +template +void to_base_specialization_of_base_quantity_spec(const volatile quantity_spec*); +#else +template +void to_base_specialization_of_base_quantity_spec(const volatile quantity_spec*); +#endif + +template +inline constexpr bool is_derived_from_specialization_of_base_quantity_spec = + requires(T* t) { to_base_specialization_of_base_quantity_spec(t); }; + +template +inline constexpr bool is_specialization_of_quantity_spec = false; + +#ifdef __cpp_explicit_this_parameter +template +inline constexpr bool is_specialization_of_quantity_spec> = true; +#else +template +inline constexpr bool is_specialization_of_quantity_spec> = true; +#endif + +/** + * @brief Concept matching all named quantity specification types + * + * Satisfied by all types that derive from `quantity_spec`. + */ +template +concept NamedQuantitySpec = is_derived_from_specialization_of_quantity_spec && + (!is_specialization_of_quantity_spec)&&(!QuantityKindSpec); + +/** + * @brief Concept matching all named base quantity specification types + * + * Satisfied by all types that derive from `quantity_spec` taking a base dimension + * as a template parameter. + */ +template +concept BaseQuantitySpec = NamedQuantitySpec && is_derived_from_specialization_of_base_quantity_spec; + +template +struct is_dimensionless : std::false_type {}; + +template +inline constexpr bool is_power_of_quantity_spec = requires { + requires is_specialization_of_power && + (NamedQuantitySpec || is_dimensionless::value); +}; + +template +inline constexpr bool is_per_of_quantity_specs = false; + +template +inline constexpr bool is_per_of_quantity_specs> = + (... && (NamedQuantitySpec || is_dimensionless::value || is_power_of_quantity_spec)); + +template +concept IntermediateDerivedQuantitySpecExpr = + detail::NamedQuantitySpec || detail::is_dimensionless::value || detail::is_power_of_quantity_spec || + detail::is_per_of_quantity_specs; + +} // namespace detail + +template +struct derived_quantity_spec; + +namespace detail { + +/** + * @brief Concept matching all derived quantity specification types + * + * Satisfied by all `derived_quantity_spec` specializations. + * + * @note Deriving a strong type from it is considered a logic error and thus is + * explicitly not supported here. + */ +template +concept IntermediateDerivedQuantitySpec = + is_specialization_of || + (QuantityKindSpec && + is_specialization_of, derived_quantity_spec>); + +} // namespace detail + + +template +concept QuantitySpec = + detail::NamedQuantitySpec || detail::IntermediateDerivedQuantitySpec || detail::QuantityKindSpec; + +template +[[nodiscard]] consteval QuantitySpec auto get_kind(Q q); + +namespace detail { + +template +concept DerivedFromQuantityKindSpecOf = + QuantitySpec> && QuantitySpec> && + get_kind(From) != get_kind(To) && + std::derived_from, std::remove_cvref_t>; + +} + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/ratio.h b/src/core/include/mp-units/bits/ratio.h new file mode 100644 index 00000000..2792fa18 --- /dev/null +++ b/src/core/include/mp-units/bits/ratio.h @@ -0,0 +1,121 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +namespace detail { + +template +[[nodiscard]] consteval T abs(T v) noexcept +{ + return v < 0 ? -v : v; +} + +[[nodiscard]] consteval std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs) +{ + constexpr std::intmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4); + + const std::intmax_t a0 = abs(lhs) % c; + const std::intmax_t a1 = abs(lhs) / c; + const std::intmax_t b0 = abs(rhs) % c; + const std::intmax_t b1 = abs(rhs) / c; + + gsl_Assert(a1 == 0 || b1 == 0); // overflow in multiplication + gsl_Assert(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication + gsl_Assert(b0 * a0 <= INTMAX_MAX); // overflow in multiplication + gsl_Assert((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication + + return lhs * rhs; +} + +} // namespace detail + +/** + * @brief Provides compile-time rational arithmetic support. + * + * This class is really similar to @c std::ratio. An important difference is the fact that the objects of that class + * are used as class NTTPs rather then a type template parameter kind. + */ +struct ratio { + std::intmax_t num; + std::intmax_t den; + + consteval explicit(false) ratio(std::intmax_t n, std::intmax_t d = 1) : num{n}, den{d} + { + gsl_Expects(den != 0); + if (num == 0) + den = 1; + else { + std::intmax_t gcd = std::gcd(num, den); + num = num * (den < 0 ? -1 : 1) / gcd; + den = detail::abs(den) / gcd; + } + } + + [[nodiscard]] friend consteval bool operator==(ratio, ratio) = default; + [[nodiscard]] friend consteval auto operator<=>(ratio lhs, ratio rhs) { return (lhs - rhs).num <=> 0; } + + [[nodiscard]] friend consteval ratio operator-(ratio r) { return ratio{-r.num, r.den}; } + + [[nodiscard]] friend consteval ratio operator+(ratio lhs, ratio rhs) + { + return ratio{lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den}; + } + + [[nodiscard]] friend consteval ratio operator-(ratio lhs, ratio rhs) { return lhs + (-rhs); } + + [[nodiscard]] friend consteval ratio operator*(ratio lhs, ratio rhs) + { + const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den); + const std::intmax_t gcd2 = std::gcd(rhs.num, lhs.den); + return ratio{detail::safe_multiply(lhs.num / gcd1, rhs.num / gcd2), + detail::safe_multiply(lhs.den / gcd2, rhs.den / gcd1)}; + } + + [[nodiscard]] friend consteval ratio operator/(ratio lhs, ratio rhs) { return lhs * ratio{rhs.den, rhs.num}; } +}; + +[[nodiscard]] consteval bool is_integral(ratio r) { return r.num % r.den == 0; } + +[[nodiscard]] consteval ratio common_ratio(ratio r1, ratio r2) +{ + if (r1.num == r2.num && r1.den == r2.den) return ratio{r1.num, r1.den}; + + // gcd(a/b,c/d) = gcd(a⋅d, c⋅b) / b⋅d + gsl_Assert(std::numeric_limits::max() / r1.num > r2.den); + gsl_Assert(std::numeric_limits::max() / r2.num > r1.den); + gsl_Assert(std::numeric_limits::max() / r1.den > r2.den); + + std::intmax_t num = std::gcd(r1.num * r2.den, r2.num * r1.den); + std::intmax_t den = r1.den * r2.den; + std::intmax_t gcd = std::gcd(num, den); + return ratio{num / gcd, den / gcd}; +} + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/reference_concepts.h b/src/core/include/mp-units/bits/reference_concepts.h new file mode 100644 index 00000000..c51d2d59 --- /dev/null +++ b/src/core/include/mp-units/bits/reference_concepts.h @@ -0,0 +1,82 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units { + +template +struct reference; + +namespace detail { + +template +inline constexpr bool is_specialization_of_reference = false; + +template +inline constexpr bool is_specialization_of_reference> = true; + +} // namespace detail + +/** + * @brief A concept matching all references in the library. + * + * Satisfied by all specializations of @c reference. + */ +template +concept Reference = AssociatedUnit || detail::is_specialization_of_reference; + +[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); + +template +[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(reference) +{ + return Q; +} + +[[nodiscard]] consteval Unit auto get_unit(AssociatedUnit auto u) { return u; } + +template +[[nodiscard]] consteval Unit auto get_unit(reference) +{ + return U; +} + +/** + * @brief A concept matching all references with provided dimension or quantity spec + * + * Satisfied by all references with a dimension/quantity_spec being the instantiation derived from + * the provided dimension/quantity_spec type. + */ +template +concept ReferenceOf = + Reference && + ((Dimension> && get_quantity_spec(T{}).dimension == V) || + (QuantitySpec> && implicitly_convertible(get_quantity_spec(T{}), V) && + !detail::DerivedFromQuantityKindSpecOf && + (detail::QuantityKindSpec> || + !detail::DerivedFromQuantityKindSpecOf))); + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/representation_concepts.h b/src/core/include/mp-units/bits/representation_concepts.h new file mode 100644 index 00000000..503182ba --- /dev/null +++ b/src/core/include/mp-units/bits/representation_concepts.h @@ -0,0 +1,85 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include + +namespace mp_units { + +/** + * @brief Quantity character + * + * Scalars, vectors and tensors are mathematical objects that can be used to + * denote certain physical quantities and their values. They are as such + * independent of the particular choice of a coordinate system, whereas + * each scalar component of a vector or a tensor and each component vector and + * component tensor depend on that choice. + * + * A scalar is a physical quantity that has magnitude but no direction. + * + * Vectors are physical quantities that possess both magnitude and direction + * and whose operations obey the axioms of a vector space. + * + * Tensors can be used to describe more general physical quantities. + * For example, the Cauchy stress tensor possess magnitude, direction, + * and orientation qualities. + */ +enum class quantity_character { scalar, vector, tensor }; + +namespace detail { + +template +concept CommonTypeWith = + std::same_as, std::common_type_t> && + std::constructible_from, T> && std::constructible_from, U>; + +template +concept ScalableNumber = + std::regular_invocable, T, U> && std::regular_invocable, T, U>; + +template +concept CastableNumber = CommonTypeWith && ScalableNumber>; + +// TODO Fix it according to sudo_cast implementation +template +concept Scalable = CastableNumber || + (requires { typename T::value_type; } && CastableNumber && + ScalableNumber>) || + (requires { typename T::element_type; } && CastableNumber && + ScalableNumber>); + +} // namespace detail + +template +concept Representation = (is_scalar || is_vector || is_tensor)&&std::regular && detail::Scalable; + +template +concept RepresentationOf = Representation && ((Ch == quantity_character::scalar && is_scalar) || + (Ch == quantity_character::vector && is_vector) || + (Ch == quantity_character::tensor && is_tensor)); + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/sudo_cast.h b/src/core/include/mp-units/bits/sudo_cast.h new file mode 100644 index 00000000..c60c6476 --- /dev/null +++ b/src/core/include/mp-units/bits/sudo_cast.h @@ -0,0 +1,86 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include + +namespace mp_units::detail { + +// determines the best available representation type +template +[[nodiscard]] consteval auto common_rep_type(From, To) +{ + if constexpr (requires { typename std::common_type_t; }) + // returns a common type of two representation types if available + // i.e. `double` and `int` will end up with `double` precision + return std::common_type_t{}; + else + return typename From::rep{}; +} + +/** + * @brief Explicit cast between different quantity types + * + * @note This is a low-level facility and is too powerful to be used by the users directly. They should either use + * `value_cast` or `quantity_cast`. + * + * @tparam To a target quantity type to cast to + */ +template + requires Quantity> && + (castable(std::remove_reference_t::quantity_spec, To::quantity_spec)) && + ((std::remove_reference_t::unit == To::unit && + std::constructible_from::rep>) || + (std::remove_reference_t::unit != To::unit)) // && scalable_with_)) +// TODO how to constrain the second part here? +[[nodiscard]] constexpr Quantity auto sudo_cast(From&& q) +{ + if constexpr (q.unit == To::unit) { + // no scaling of the number needed + return make_quantity( + static_cast(std::forward(q).number())); // this is the only (and recommended) way to do + // a truncating conversion on a number, so we are + // using static_cast to suppress all the compiler + // warnings on conversions + } else { + // scale the number + constexpr Magnitude auto c_mag = get_canonical_unit(q.unit).mag / get_canonical_unit(To::unit).mag; + constexpr Magnitude auto num = numerator(c_mag); + constexpr Magnitude auto den = denominator(c_mag); + constexpr Magnitude auto irr = c_mag * (den / num); + using c_rep_type = decltype(common_rep_type(q, To{})); + using c_mag_type = common_magnitude_type; + using multiplier_type = + conditional, std::common_type_t, c_mag_type>; + constexpr auto val = [](Magnitude auto m) { return get_value(m); }; + return static_cast(static_cast(std::forward(q).number()) * val(num) / val(den) * + val(irr)) * + To::reference; + } +} + +} // namespace mp_units::detail diff --git a/src/core/include/mp-units/bits/symbol_text.h b/src/core/include/mp-units/bits/symbol_text.h new file mode 100644 index 00000000..b34e1e95 --- /dev/null +++ b/src/core/include/mp-units/bits/symbol_text.h @@ -0,0 +1,188 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +// IWYU pragma: begin_exports +#include +#include +#include +#include +#include +// IWYU pragma: end_exports + +#include + +namespace mp_units { + +namespace detail { + +constexpr void validate_ascii_char([[maybe_unused]] char c) noexcept { gsl_Expects((c & 0x80) == 0); } + +template +constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[N + 1]) noexcept +{ +#ifndef NDEBUG + if constexpr (N != 0) + for (size_t i = 0; i < N; ++i) validate_ascii_char(s[i]); +#endif +} + +} // namespace detail + + +/** + * @brief A symbol text representation + * + * This class template is responsible for definition and handling of a symbol text + * representation. In the libary it is used to define symbols of units and prefixes. + * Each symbol can have two versions: Unicode and ASCI-only. + * + * @tparam UnicodeCharT Character type to be used for a Unicode representation + * @tparam N The size of a Unicode symbol + * @tparam M The size of the ASCII-only symbol + */ +template +struct basic_symbol_text { + basic_fixed_string unicode_; + basic_fixed_string ascii_; + + constexpr explicit(false) basic_symbol_text(char txt) noexcept : unicode_(txt), ascii_(txt) + { + detail::validate_ascii_char(txt); + } + constexpr basic_symbol_text(UnicodeCharT u, char a) noexcept : unicode_(u), ascii_(a) + { + detail::validate_ascii_char(a); + } + constexpr explicit(false) basic_symbol_text(const char (&txt)[N + 1]) noexcept : unicode_(txt), ascii_(txt) + { + detail::validate_ascii_string(txt); + } + constexpr explicit(false) basic_symbol_text(const basic_fixed_string& txt) noexcept : + unicode_(txt), ascii_(txt) + { + detail::validate_ascii_string(txt.data_); + } + constexpr basic_symbol_text(const UnicodeCharT (&u)[N + 1], const char (&a)[M + 1]) noexcept : unicode_(u), ascii_(a) + { + detail::validate_ascii_string(a); + } + constexpr basic_symbol_text(const basic_fixed_string& u, + const basic_fixed_string& a) noexcept : + unicode_(u), ascii_(a) + { + detail::validate_ascii_string(a.data_); + } + + [[nodiscard]] constexpr auto& unicode() { return unicode_; } + [[nodiscard]] constexpr const auto& unicode() const { return unicode_; } + [[nodiscard]] constexpr auto& ascii() { return ascii_; } + [[nodiscard]] constexpr const auto& ascii() const { return ascii_; } + + [[nodiscard]] constexpr bool empty() const { return unicode().empty() && ascii().empty(); } + + template + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept + { + return basic_symbol_text(lhs.unicode() + rhs.unicode(), lhs.ascii() + rhs.ascii()); + } + + template + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept + { + return lhs + basic_symbol_text(rhs); + } + + template + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_fixed_string& lhs, const basic_symbol_text& rhs) noexcept + { + return basic_symbol_text(lhs) + rhs; + } + + template + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const basic_symbol_text& lhs, const UnicodeCharT (&rhs)[N2]) noexcept + { + return lhs + basic_symbol_text(rhs); + } + + template + [[nodiscard]] constexpr friend basic_symbol_text operator+( + const UnicodeCharT (&lhs)[N2], const basic_symbol_text& rhs) noexcept + { + return basic_symbol_text(lhs) + rhs; + } + + [[nodiscard]] constexpr friend basic_symbol_text operator+(const basic_symbol_text& lhs, + UnicodeCharT rhs) noexcept + { + return lhs + basic_symbol_text(rhs); + } + + [[nodiscard]] constexpr friend basic_symbol_text operator+( + UnicodeCharT lhs, const basic_symbol_text& rhs) noexcept + { + return basic_symbol_text(lhs) + rhs; + } + + template + [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, + const basic_symbol_text& rhs) noexcept + { + UNITS_DIAGNOSTIC_PUSH + UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT + if (const auto cmp = lhs.unicode() <=> rhs.unicode(); cmp != 0) return cmp; + UNITS_DIAGNOSTIC_POP + return lhs.ascii() <=> rhs.ascii(); + } + + template + [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, + const basic_symbol_text& rhs) noexcept + { + return lhs.unicode() == rhs.unicode() && lhs.ascii() == rhs.ascii(); + } +}; + +basic_symbol_text(char) -> basic_symbol_text; + +template +basic_symbol_text(UnicodeCharT, char) -> basic_symbol_text; + +template +basic_symbol_text(const char (&)[N]) -> basic_symbol_text; + +template +basic_symbol_text(const basic_fixed_string&) -> basic_symbol_text; + +template +basic_symbol_text(const UnicodeCharT (&)[N], const char (&)[M]) -> basic_symbol_text; + +template +basic_symbol_text(const basic_fixed_string&, const basic_fixed_string&) + -> basic_symbol_text; + +} // namespace mp_units diff --git a/src/core/include/units/bits/external/text_tools.h b/src/core/include/mp-units/bits/text_tools.h similarity index 91% rename from src/core/include/units/bits/external/text_tools.h rename to src/core/include/mp-units/bits/text_tools.h index a70e5107..11fd2b51 100644 --- a/src/core/include/units/bits/external/text_tools.h +++ b/src/core/include/mp-units/bits/text_tools.h @@ -22,10 +22,10 @@ #pragma once -#include -#include +#include +#include -namespace units::detail { +namespace mp_units::detail { template requires(0 <= Value) && (Value < 10) @@ -57,7 +57,7 @@ inline constexpr basic_symbol_text superscript_minus("\u207b", "-"); inline constexpr basic_symbol_text superscript_prefix("", "^"); template -constexpr auto superscript_helper() +[[nodiscard]] consteval auto superscript_helper() { if constexpr (Value < 0) return superscript_minus + superscript_helper<-Value>(); @@ -68,13 +68,13 @@ constexpr auto superscript_helper() } template -constexpr auto superscript() +[[nodiscard]] consteval auto superscript() { return superscript_prefix + superscript_helper(); } template -constexpr auto regular() +[[nodiscard]] consteval auto regular() { if constexpr (Value < 0) return basic_fixed_string("-") + superscript_helper<-Value>(); @@ -84,4 +84,4 @@ constexpr auto regular() return regular() + regular(); } -} // namespace units::detail +} // namespace mp_units::detail diff --git a/src/core/include/mp-units/bits/unit_concepts.h b/src/core/include/mp-units/bits/unit_concepts.h new file mode 100644 index 00000000..9acbe189 --- /dev/null +++ b/src/core/include/mp-units/bits/unit_concepts.h @@ -0,0 +1,194 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +namespace detail { + +template +inline constexpr bool is_unit = false; + +} // namespace detail + +/** + * @brief A concept matching all unit types in the library + * + * Satisfied by all unit types provided by the library. + */ +template +concept Unit = detail::is_unit; + +template +struct scaled_unit; + +template +struct named_unit; + +namespace detail { + +template +void to_base_specialization_of_named_unit(const volatile named_unit*); + +template +inline constexpr bool is_derived_from_specialization_of_named_unit = + requires(T* t) { to_base_specialization_of_named_unit(t); }; + +template +inline constexpr bool is_specialization_of_named_unit = false; + +template +inline constexpr bool is_specialization_of_named_unit> = true; + +/** + * @brief A concept matching all units with special names + * + * Satisfied by all unit types derived from the specialization of `named_unit`. + */ +template +concept NamedUnit = + Unit && detail::is_derived_from_specialization_of_named_unit && (!detail::is_specialization_of_named_unit); + +} // namespace detail + +/** + * @brief Prevents assignment of a prefix to specific units + * + * By default all named units allow assigning a prefix for them. There are some notable exceptions like + * `hour` or `degree_Celsius`. For those a partial specialization with the value `false` should be + * provided. + */ +template +inline constexpr bool unit_can_be_prefixed = detail::NamedUnit>; + +/** + * @brief A concept to be used to define prefixes for a unit + */ +template +concept PrefixableUnit = detail::NamedUnit && unit_can_be_prefixed; + +namespace detail { + +template +inline constexpr bool is_power_of_unit = + requires { requires is_specialization_of_power && Unit; }; + +template +inline constexpr bool is_per_of_units = false; + +template +inline constexpr bool is_per_of_units> = (... && (Unit || is_power_of_unit)); + +template +concept DerivedUnitExpr = Unit || detail::is_power_of_unit || detail::is_per_of_units; + +} // namespace detail + +template +struct derived_unit; + +template + requires(!Symbol.empty()) +struct prefixed_unit; + +namespace detail { + +template +void is_unit_impl(const scaled_unit*); + +template +void is_unit_impl(const named_unit*); + +template +void is_unit_impl(const derived_unit*); + +template +inline constexpr bool is_specialization_of_unit = false; + +template +inline constexpr bool is_specialization_of_unit> = true; + +template +inline constexpr bool is_specialization_of_prefixed_unit = false; + +template +inline constexpr bool is_specialization_of_prefixed_unit> = true; + +template + requires requires(T* t) { is_unit_impl(t); } +inline constexpr bool is_unit = !is_specialization_of_named_unit && !is_specialization_of_prefixed_unit; + +template +[[nodiscard]] consteval bool has_associated_quantity(U); + +template +[[nodiscard]] consteval bool has_associated_quantity(power) +{ + return has_associated_quantity(U{}); +} + +template +[[nodiscard]] consteval bool has_associated_quantity(type_list) +{ + return (... && has_associated_quantity(Us{})); +} + +template +[[nodiscard]] consteval bool has_associated_quantity(U) +{ + if constexpr (requires { U::quantity_spec; }) return true; + if constexpr (requires { U::reference_unit; }) + return has_associated_quantity(U::reference_unit); + else if constexpr (requires { typename U::_num_; }) + return has_associated_quantity(typename U::_num_{}) && has_associated_quantity(typename U::_den_{}); + else + return false; +} + +} // namespace detail + +/** + * @brief A concept matching all units that can be used as quantity references + */ +template +concept AssociatedUnit = Unit && detail::has_associated_quantity(U{}); + +/** + * @brief A concept matching all units associated with the provided quantity spec + * + * Satisfied by all units associated with the quantity_spec being the instantiation derived from + * the provided quantity_spec type. + */ +template +concept UnitOf = AssociatedUnit && QuantitySpec> && + implicitly_convertible(get_quantity_spec(U{}), QS) && + // the below is to make `dimensionless[radian]` invalid + (get_kind(QS) == get_kind(get_quantity_spec(U{})) || + !detail::DerivedFromQuantityKindSpecOf); + +} // namespace mp_units diff --git a/src/core/include/mp-units/bits/value_cast.h b/src/core/include/mp-units/bits/value_cast.h new file mode 100644 index 00000000..92880e16 --- /dev/null +++ b/src/core/include/mp-units/bits/value_cast.h @@ -0,0 +1,77 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include + +namespace mp_units { + +/** + * @brief Explicit cast of a quantity's unit + * + * Implicit conversions between quantities of different types are allowed only for "safe" + * (i.e. non-truncating) conversion. In truncating cases an explicit cast have to be used. + * + * auto d = value_cast(1234 * ms); + * + * @tparam ToU a unit to use for a target quantity + */ +template +[[nodiscard]] constexpr Quantity auto value_cast(Q&& q) + requires Quantity> && (convertible(q.reference, ToU)) +{ + using q_type = std::remove_reference_t; + constexpr auto r = [] { + if constexpr (detail::is_specialization_of_reference> || + !AssociatedUnit>) + return reference{}; + else + return ToU; + }(); + return detail::sudo_cast>(std::forward(q)); +} + +/** + * @brief Explicit cast of a quantity's representation type + * + * Implicit conversions between quantities of different types are allowed only for "safe" + * (i.e. non-truncating) conversion. In truncating cases an explicit cast have to be used. + * + * auto q = value_cast(1.23 * ms); + * + * @tparam ToRep a representation type to use for a target quantity + */ +template + requires Quantity> && + RepresentationOf::quantity_spec.character> && + std::constructible_from::rep> +[[nodiscard]] constexpr quantity::reference, ToRep> value_cast(Q&& q) +{ + return detail::sudo_cast>(std::forward(q)); +} + +} // namespace mp_units diff --git a/src/core/include/units/concepts.h b/src/core/include/mp-units/concepts.h similarity index 77% rename from src/core/include/units/concepts.h rename to src/core/include/mp-units/concepts.h index edf5e4b0..1cd93c78 100644 --- a/src/core/include/units/concepts.h +++ b/src/core/include/mp-units/concepts.h @@ -22,7 +22,10 @@ #pragma once -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports +#include +#include +#include +#include +#include +#include +#include diff --git a/src/systems/isq/include/units/isq/dimensions/amount_of_substance.h b/src/core/include/mp-units/core.h similarity index 78% rename from src/systems/isq/include/units/isq/dimensions/amount_of_substance.h rename to src/core/include/mp-units/core.h index 099e516f..b6c3682d 100644 --- a/src/systems/isq/include/units/isq/dimensions/amount_of_substance.h +++ b/src/core/include/mp-units/core.h @@ -22,14 +22,12 @@ #pragma once -#include - -namespace units::isq { - -template -struct dim_amount_of_substance : base_dimension<"N", U> {}; - -template -concept AmountOfSubstance = QuantityOfT; - -} // namespace units::isq +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/src/core/include/units/customization_points.h b/src/core/include/mp-units/customization_points.h similarity index 60% rename from src/core/include/units/customization_points.h rename to src/core/include/mp-units/customization_points.h index 6eb7c0d0..192d2943 100644 --- a/src/core/include/units/customization_points.h +++ b/src/core/include/mp-units/customization_points.h @@ -22,11 +22,12 @@ #pragma once -#include +#include +#include #include #include -namespace units { +namespace mp_units { /** * @brief Specifies if a value of a type should be treated as a floating-point value @@ -40,9 +41,50 @@ namespace units { template inline constexpr bool treat_as_floating_point = std::is_floating_point_v; -template - requires requires { typename T::value_type; } -inline constexpr bool treat_as_floating_point = treat_as_floating_point; +template + requires requires { typename Rep::value_type; } +inline constexpr bool treat_as_floating_point = treat_as_floating_point; + +template + requires requires { typename Rep::element_type; } +inline constexpr bool treat_as_floating_point = treat_as_floating_point; + +/** + * @brief Specifies a type to have a scalar character + * + * A scalar is a physical quantity that has magnitude but no direction. + */ +template +inline constexpr bool is_scalar = std::is_floating_point_v || (std::is_integral_v && !is_same_v); + +/** + * @brief Specifies a type to have a vector character + * + * Vectors are physical quantities that possess both magnitude and direction + * and whose operations obey the axioms of a vector space. + * + * In specific cases a scalar can represent a vector with the default direction. + * If that is the intent, a user should provide a partial specialization: + * + * @code{.cpp} + * template + * requires mp_units::is_scalar + * inline constexpr bool mp_units::is_vector = true; + * @endcode + */ +template +inline constexpr bool is_vector = false; + +/** + * @brief Specifies a type to have a tensor character + * + * Tensors can be used to describe more general physical quantities. + * + * A vector is a tensor of the first order and a scalar is a tensor of order zero. + * Similarly to `is_vector` a partial specialization is needed in such cases. + */ +template +inline constexpr bool is_tensor = false; template requires requires { typename T::element_type; } @@ -51,7 +93,7 @@ inline constexpr bool treat_as_floating_point = treat_as_floating_point struct quantity_point_like_traits; -} // namespace units +} // namespace mp_units diff --git a/src/core/include/mp-units/dimension.h b/src/core/include/mp-units/dimension.h new file mode 100644 index 00000000..4c9c0796 --- /dev/null +++ b/src/core/include/mp-units/dimension.h @@ -0,0 +1,213 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +/** + * @brief A dimension of a base quantity + * + * Base quantity is a 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. They are referred to as + * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base + * quantities. + * + * `Symbol` template parameter is an unique identifier of the base dimension. The same identifiers can be multiplied + * and divided which will result with an adjustment of its factor in an exponent of a `derived_dimension` + * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). + * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct dim_length : base_dimension<"L"> {} dim_length; + * inline constexpr struct dim_time : base_dimension<"T"> {} dim_time; + * inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the dimension types in the source code. All operations + * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support + */ +template +struct base_dimension { + static constexpr auto symbol = Symbol; ///< Unique base dimension identifier +}; + +namespace detail { + +template +struct base_dimension_less : std::bool_constant<(Lhs::symbol < Rhs::symbol)> {}; + +template +using type_list_of_base_dimension_less = expr_less; + +} // namespace detail + +/** + * @brief A dimension of a derived quantity + * + * Derived dimension is an 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. + * + * Instead of using a raw list of exponents this library decided to use expression template syntax to make types + * more digestable for the user. The positive exponents are ordered first and all negative exponents are put as a list + * into the `per<...>` class template. If a power of exponent is different than `1` the dimension type is enclosed in + * `power` class template. Otherwise, it is just put directly in the list without any wrapper. There + * is also one special case. In case all of the exponents are negative than the `dimension_one` being a dimension of + * a dimensionless quantity is put in the front to increase the readability. + * + * For example: + * + * @code{.cpp} + * using frequency = decltype(1 / dim_time); + * using speed = decltype(dim_length / dim_time); + * using acceleration = decltype(dim_speed / dim_time); + * using force = decltype(dim_mass * dim_acceleration); + * using energy = decltype(dim_force * dim_length); + * using moment_of_force = decltype(dim_length * dim_force); + * using torque = decltype(dim_moment_of_force); + * @endcode + * + * - `frequency` will be derived from type `derived_dimension>` + * - `speed` will be derived from type `derived_dimension>` + * - `acceleration` will be derived from type `derived_dimension>>` + * - `force` will be derived from type `derived_dimension>>` + * - `energy` will be derived from type `derived_dimension, dim_mass, per>>` + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the dimension types in the source code. All operations + * are done on the objects. Contrarily, the dimension types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Ds a parameter pack consisting tokens allowed in the dimension specification + * (base dimensions, `dimension_one`, `power`, `per<...>`) + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the dimensional arithmetic equation provided by the user. + */ +template +struct derived_dimension : detail::expr_fractions {}; + +/** + * @brief Dimension one + * + * Dimension for which all the exponents of the factors corresponding to the base + * dimensions are zero. It is a dimension of a quantity of dimension one also known as + * "dimensionless". + */ +inline constexpr struct dimension_one : derived_dimension<> { +} dimension_one; + +namespace detail { + +template<> +struct is_dimension_one : std::true_type {}; + +} // namespace detail + +// Operators + +template +[[nodiscard]] consteval Dimension auto operator*(Lhs, Rhs) +{ + return detail::expr_multiply( + Lhs{}, Rhs{}); +} + +template +[[nodiscard]] consteval Dimension auto operator/(Lhs, Rhs) +{ + return detail::expr_divide(Lhs{}, + Rhs{}); +} + +template +[[nodiscard]] consteval Dimension auto operator/(int value, D) +{ + gsl_Expects(value == 1); + return detail::expr_invert(D{}); +} + +template +[[nodiscard]] consteval Dimension auto operator/(D, int) = delete; + +template +[[nodiscard]] consteval bool operator==(Lhs, Rhs) +{ + return is_same_v; +} + +/** + * @brief Computes the value of a dimension raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param d Dimension being the base of the operation + * + * @return Dimension The result of computation + */ +template + requires detail::non_zero +[[nodiscard]] consteval Dimension auto pow(D d) +{ + if constexpr (detail::BaseDimension) { + if constexpr (Den == 1) + return derived_dimension>{}; + else + return derived_dimension>{}; + } else + return detail::expr_pow(d); +} + +/** + * @brief Computes the square root of a dimension + * + * @param d Dimension being the base of the operation + * + * @return Dimension The result of computation + */ +[[nodiscard]] consteval Dimension auto sqrt(Dimension auto d) { return pow<1, 2>(d); } + +/** + * @brief Computes the cubic root of a dimension + * + * @param d Dimension being the base of the operation + * + * @return Dimension The result of computation + */ +[[nodiscard]] consteval Dimension auto cbrt(Dimension auto d) { return pow<1, 3>(d); } + + +// TODO consider adding the support for text output of the dimensional equation + +} // namespace mp_units diff --git a/src/core/include/mp-units/quantity.h b/src/core/include/mp-units/quantity.h new file mode 100644 index 00000000..f8f7f6de --- /dev/null +++ b/src/core/include/mp-units/quantity.h @@ -0,0 +1,534 @@ + +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// the below is not used in this header but should be exposed with it +#include +#include + +namespace mp_units { + +namespace detail { + +template +using quantity_like_type = quantity::reference, typename quantity_like_traits::rep>; + +template +concept RepSafeConstructibleFrom = Unit> && std::constructible_from && + (treat_as_floating_point || (!treat_as_floating_point> && + is_rational(get_canonical_unit(U).mag))); + +template +concept IntegralConversionFactor = Unit && Unit && + is_integral(get_canonical_unit(UFrom).mag / get_canonical_unit(UTo).mag); + +template +concept QuantityConvertibleTo = + Quantity && Quantity && implicitly_convertible(QFrom::quantity_spec, QTo::quantity_spec) && + convertible(QFrom::unit, QTo::unit) && + (treat_as_floating_point || + (!treat_as_floating_point && IntegralConversionFactor)) && + // TODO consider providing constraints of sudo_cast here rather than testing if it can be called (its return type is + // deduced thus the function is evaluated here and may emit truncating conversion or other warnings) + requires(QFrom q) { detail::sudo_cast(q); }; + +template +concept InvokeResultOf = std::regular_invocable && RepresentationOf, Ch>; + +template +concept InvocableQuantities = Quantity && Quantity && + InvokeResultOf && + requires { common_reference(Q1::reference, Q2::reference); }; + +template + requires detail::InvocableQuantities +using common_quantity_for = quantity>; + +} // namespace detail + +/** + * @brief A 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. + * + * @tparam R a reference of the quantity providing all information about quantity properties + * @tparam Rep a type to be used to represent values of a quantity + */ +template Rep = double> +class quantity { +public: + Rep number_; // needs to be public for a structural type + + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + using rep = Rep; + + // helper used to constrain `make_quantity()` and `operator*(Representation, Unit)` + static constexpr bool _rep_safe_constructible_ = detail::RepSafeConstructibleFrom; + + // static member functions + [[nodiscard]] static constexpr quantity zero() noexcept + requires requires { quantity_values::zero(); } + { + return quantity(quantity_values::zero()); + } + + [[nodiscard]] static constexpr quantity one() noexcept + requires requires { quantity_values::one(); } + { + return quantity(quantity_values::one()); + } + + [[nodiscard]] static constexpr quantity min() noexcept + requires requires { quantity_values::min(); } + { + return quantity(quantity_values::min()); + } + + [[nodiscard]] static constexpr quantity max() noexcept + requires requires { quantity_values::max(); } + { + return quantity(quantity_values::max()); + } + + // construction, assignment, destruction + quantity() = default; + quantity(const quantity&) = default; + quantity(quantity&&) = default; + + template Q> + constexpr explicit(!std::convertible_to) quantity(const Q& q) : + number_(detail::sudo_cast(q).number()) + { + } + + template + requires detail::QuantityConvertibleTo, quantity> + constexpr explicit quantity(const Q& q) : quantity(detail::quantity_like_type(quantity_like_traits::number(q))) + { + } + + template + requires(dimension == dimension_one) && + (unit == ::mp_units::one) && detail::RepSafeConstructibleFrom + constexpr explicit(!std::convertible_to) quantity(Value&& v) : number_(std::forward(v)) + { + } + + quantity& operator=(const quantity&) = default; + quantity& operator=(quantity&&) = default; + + // data access + [[nodiscard]] constexpr const rep& number() const& noexcept { return number_; } + [[nodiscard]] constexpr rep&& number() && noexcept { return std::move(number_); } + [[nodiscard]] constexpr const rep&& number() const&& noexcept { return std::move(number_); } + + template + requires requires(quantity q) { q[U{}]; } + [[nodiscard]] constexpr rep number_in(U) const noexcept + { + return (*this)[U{}].number(); + } + + template + requires detail::QuantityConvertibleTo{}, Rep>> + [[nodiscard]] constexpr quantity<::mp_units::reference{}, Rep> operator[](U) const + { + return quantity{*this}; + } + + // member unary operators + [[nodiscard]] constexpr Quantity auto operator+() const + requires requires(rep v) { + { + +v + } -> std::common_with; + } + { + return make_quantity(+number()); + } + + [[nodiscard]] constexpr Quantity auto operator-() const + requires requires(rep v) { + { + -v + } -> std::common_with; + } + { + return make_quantity(-number()); + } + + constexpr quantity& operator++() + requires requires(rep v) { + { + ++v + } -> std::same_as; + } + { + ++number_; + return *this; + } + + [[nodiscard]] constexpr Quantity auto operator++(int) + requires requires(rep v) { + { + v++ + } -> std::common_with; + } + { + return make_quantity(number_++); + } + + constexpr quantity& operator--() + requires requires(rep v) { + { + --v + } -> std::same_as; + } + { + --number_; + return *this; + } + + [[nodiscard]] constexpr Quantity auto operator--(int) + requires requires(rep v) { + { + v-- + } -> std::common_with; + } + { + return make_quantity(number_--); + } + + constexpr quantity& operator+=(const quantity& q) + requires requires(rep a, rep b) { + { + a += b + } -> std::same_as; + } + { + number_ += q.number(); + return *this; + } + + constexpr quantity& operator-=(const quantity& q) + requires requires(rep a, rep b) { + { + a -= b + } -> std::same_as; + } + { + number_ -= q.number(); + return *this; + } + + template + requires(!Quantity) && requires(rep a, const Value b) { + { + a *= b + } -> std::same_as; + } + constexpr quantity& operator*=(const Value& v) + { + number_ *= v; + return *this; + } + + template Q> + requires(Q::unit == ::mp_units::one) && requires(rep a, const typename Q::rep b) { + { + a *= b + } -> std::same_as; + } + constexpr quantity& operator*=(const Q& rhs) + { + number_ *= rhs.number(); + return *this; + } + + template + requires(!Quantity) && requires(rep a, const Value b) { + { + a /= b + } -> std::same_as; + } + constexpr quantity& operator/=(const Value& v) + { + gsl_ExpectsAudit(v != quantity_values::zero()); + number_ /= v; + return *this; + } + + template Q> + requires(Q::unit == ::mp_units::one) && requires(rep a, const typename Q::rep b) { + { + a /= b + } -> std::same_as; + } + constexpr quantity& operator/=(const Q& rhs) + { + gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); + number_ /= rhs.number(); + return *this; + } + + constexpr quantity& operator%=(const quantity& q) + requires(!treat_as_floating_point) && requires(rep a, rep b) { + { + a %= b + } -> std::same_as; + } + { + gsl_ExpectsAudit(q.number() != quantity_values::zero()); + number_ %= q.number(); + return *this; + } + +private: + template + requires quantity>::_rep_safe_constructible_ + friend constexpr quantity> make_quantity(Rep2&& v); + + template + requires detail::RepSafeConstructibleFrom + constexpr explicit quantity(Value&& v) : number_(std::forward(v)) + { + } +}; + +// CTAD +template +explicit quantity(Q) -> quantity::reference, typename quantity_like_traits::rep>; + +// binary operators on quantities +template + requires detail::InvocableQuantities, quantity, quantity> +[[nodiscard]] constexpr Quantity auto operator+(const quantity& lhs, const quantity& rhs) +{ + using ret = detail::common_quantity_for, quantity, quantity>; + return make_quantity(ret(lhs).number() + ret(rhs).number()); +} + +template + requires detail::InvocableQuantities, quantity, quantity> +[[nodiscard]] constexpr Quantity auto operator-(const quantity& lhs, const quantity& rhs) +{ + using ret = detail::common_quantity_for, quantity, quantity>; + return make_quantity(ret(lhs).number() - ret(rhs).number()); +} + +template + requires detail::InvokeResultOf<(get_quantity_spec(R1) * get_quantity_spec(R2)).character, std::multiplies<>, Rep1, + Rep2> +[[nodiscard]] constexpr Quantity auto operator*(const quantity& lhs, const quantity& rhs) +{ + return make_quantity(lhs.number() * rhs.number()); +} + +template + requires(!Quantity) && + detail::InvokeResultOf, Rep, const Value&> +[[nodiscard]] constexpr Quantity auto operator*(const quantity& q, const Value& v) +{ + return make_quantity(q.number() * v); +} + +template + requires(!Quantity) && + detail::InvokeResultOf, const Value&, Rep> +[[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity& q) +{ + return make_quantity(v * q.number()); +} + +template + requires detail::InvokeResultOf<(get_quantity_spec(R1) / get_quantity_spec(R2)).character, std::divides<>, Rep1, Rep2> +[[nodiscard]] constexpr Quantity auto operator/(const quantity& lhs, const quantity& rhs) +{ + gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); + return make_quantity(lhs.number() / rhs.number()); +} + +template + requires(!Quantity) && + detail::InvokeResultOf, Rep, const Value&> +[[nodiscard]] constexpr Quantity auto operator/(const quantity& q, const Value& v) +{ + gsl_ExpectsAudit(v != quantity_values::zero()); + return make_quantity(q.number() / v); +} + +template + requires(!Quantity) && + detail::InvokeResultOf, const Value&, Rep> +[[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity& q) +{ + return make_quantity<::mp_units::one / R>(v / q.number()); +} + +template + requires(!treat_as_floating_point) && (!treat_as_floating_point) && + detail::InvocableQuantities, quantity, quantity> +[[nodiscard]] constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) +{ + gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); + using ret = detail::common_quantity_for, quantity, quantity>; + return make_quantity(ret(lhs).number() % ret(rhs).number()); +} + +template + requires requires { typename std::common_type_t, quantity>; } && + std::equality_comparable, quantity>::rep> +[[nodiscard]] constexpr bool operator==(const quantity& lhs, const quantity& rhs) +{ + using ct = std::common_type_t, quantity>; + return ct(lhs).number() == ct(rhs).number(); +} + +template + requires requires { typename std::common_type_t, quantity>; } && + std::three_way_comparable, quantity>::rep> +[[nodiscard]] constexpr auto operator<=>(const quantity& lhs, const quantity& rhs) +{ + using ct = std::common_type_t, quantity>; + return ct(lhs).number() <=> ct(rhs).number(); +} + +// binary operators on dimensionless quantities +template + requires(!Quantity) && (quantity::dimension == dimension_one) && + detail::InvokeResultOf, Rep, Value> +[[nodiscard]] constexpr Quantity auto operator+(const quantity& q, const Value& v) +{ + return q + make_quantity<::mp_units::one>(v); +} + +template + requires(!Quantity) && (quantity::dimension == dimension_one) && + detail::InvokeResultOf, Value, Rep> +[[nodiscard]] constexpr Quantity auto operator+(const Value& v, const quantity& q) +{ + return make_quantity<::mp_units::one>(v) + q; +} + +template + requires(!Quantity) && (quantity::dimension == dimension_one) && + detail::InvokeResultOf, Rep, Value> +[[nodiscard]] constexpr Quantity auto operator-(const quantity& q, const Value& v) +{ + return q - make_quantity<::mp_units::one>(v); +} + +template + requires(!Quantity) && (quantity::dimension == dimension_one) && + detail::InvokeResultOf, Value, Rep> +[[nodiscard]] constexpr Quantity auto operator-(const Value& v, const quantity& q) +{ + return make_quantity<::mp_units::one>(v) - q; +} + +template + requires(!Quantity) && (quantity::dimension == dimension_one) && (get_unit(R) == ::mp_units::one) && + (!treat_as_floating_point) && (!treat_as_floating_point) && + detail::InvokeResultOf, Value, Rep> +[[nodiscard]] constexpr Quantity auto operator%(const Value& v, const quantity& q) +{ + gsl_ExpectsAudit(q.number() != quantity_values::zero()); + return make_quantity(v % q.number()); +} + +template + requires(!Quantity) && + (quantity::dimension == dimension_one) && std::equality_comparable_with +[[nodiscard]] constexpr bool operator==(const quantity& q, const Value& v) +{ + return q == make_quantity<::mp_units::one>(v); +} + +template + requires(!Quantity) && + (quantity::dimension == dimension_one) && std::three_way_comparable_with +[[nodiscard]] constexpr auto operator<=>(const quantity& q, const Value& v) +{ + return q <=> make_quantity<::mp_units::one>(v); +} + +// make_quantity +template + requires quantity>::_rep_safe_constructible_ +[[nodiscard]] constexpr quantity> make_quantity(Rep&& v) +{ + return quantity>(std::forward(v)); +} + +} // namespace mp_units + +namespace std { + +template + requires requires { + { + mp_units::common_reference(Q1::reference, Q2::reference) + } -> mp_units::Reference; + typename common_type_t; + } +struct common_type { +public: + using type = mp_units::quantity>; +}; + +// dimensionless quantities support for interacting with raw values +template + requires(!mp_units::Quantity) && (Q::dimension == mp_units::dimension_one) && (Q::unit == mp_units::one) && + requires { typename common_type_t; } +struct common_type { +public: + using type = mp_units::quantity>; +}; + +template + requires(!mp_units::Quantity) && (Q::dimension == mp_units::dimension_one) && (Q::unit == mp_units::one) && + requires { typename common_type_t; } +struct common_type : common_type {}; + +} // namespace std diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h new file mode 100644 index 00000000..5ef2f588 --- /dev/null +++ b/src/core/include/mp-units/quantity_point.h @@ -0,0 +1,257 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +template +struct absolute_point_origin { + static constexpr QuantitySpec auto quantity_spec = Q; + absolute_point_origin() = default; + template + requires(implicitly_convertible(Q2, Q)) + consteval absolute_point_origin(absolute_point_origin) + { + } +}; + +namespace detail { + +[[nodiscard]] consteval PointOrigin auto get_absolute_point_origin(PointOrigin auto po) +{ + if constexpr (requires { po.absolute_point_origin; }) + return po.absolute_point_origin; + else + return po; +} + +template +using quantity_point_like_type = + quantity_point::reference, quantity_point_like_traits::point_origin, + typename quantity_point_like_traits::rep>; + +} // namespace detail + +/** + * @brief A quantity point + * + * An absolute quantity measured from an origin. + * + * @tparam R a reference of the quantity point providing all information about quantity properties + * @tparam PO a type that represents the origin point from which the quantity point is measured from + * @tparam Rep a type to be used to represent values of a quantity point + */ +template auto PO = absolute_point_origin{}, + RepresentationOf Rep = double> +class quantity_point { +public: + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + static constexpr PointOrigin auto absolute_point_origin = detail::get_absolute_point_origin(PO); + static constexpr PointOrigin auto point_origin = PO; + using rep = Rep; + using quantity_type = quantity; + + quantity_type q_; // needs to be public for a structural type + + // static member functions + [[nodiscard]] static constexpr quantity_point min() noexcept + requires requires { quantity_type::min(); } + { + return quantity_point{quantity_type::min()}; + } + + [[nodiscard]] static constexpr quantity_point max() noexcept + requires requires { quantity_type::max(); } + { + return quantity_point{quantity_type::max()}; + } + + // construction, assignment, destruction + quantity_point() = default; + quantity_point(const quantity_point&) = default; + quantity_point(quantity_point&&) = default; + + template + requires std::constructible_from + constexpr explicit quantity_point(T&& v) : q_(std::forward(v)) + { + } + + template QP> + requires std::constructible_from + constexpr explicit(!std::convertible_to) quantity_point(const QP& qp) : + q_(qp.relative()) + { + } + + template + requires std::same_as::point_origin)>, + std::remove_const_t> && + std::convertible_to::quantity_type, quantity_type> + constexpr explicit quantity_point(const QP& qp) : + q_(typename detail::quantity_point_like_type::quantity_type{quantity_point_like_traits::relative(qp)}) + { + } + + quantity_point& operator=(const quantity_point&) = default; + quantity_point& operator=(quantity_point&&) = default; + + // data access + [[nodiscard]] constexpr const quantity_type& relative() const& noexcept { return q_; } + [[nodiscard]] constexpr quantity_type&& relative() && noexcept { return std::move(q_); } + [[nodiscard]] constexpr const quantity_type&& relative() const&& noexcept { return std::move(q_); } + + [[nodiscard]] constexpr Quantity auto absolute() const noexcept + { + if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin< + std::remove_const_t>) + return relative(); + else + return point_origin.absolute() + relative(); + } + + template + requires detail::QuantityConvertibleTo{}, Rep>> + [[nodiscard]] constexpr quantity_point<::mp_units::reference{}, PO, Rep> operator[](U) const + { + return quantity_point{*this}; + } + + // member unary operators + constexpr quantity_point& operator++() + requires requires { ++q_; } + { + ++q_; + return *this; + } + + [[nodiscard]] constexpr quantity_point operator++(int) + requires requires { q_++; } + { + return quantity_point(q_++); + } + + constexpr quantity_point& operator--() + requires requires { --q_; } + { + --q_; + return *this; + } + + [[nodiscard]] constexpr quantity_point operator--(int) + requires requires { q_--; } + { + return quantity_point(q_--); + } + + constexpr quantity_point& operator+=(const quantity_type& q) + requires requires { q_ += q; } + { + q_ += q; + return *this; + } + + constexpr quantity_point& operator-=(const quantity_type& q) + requires requires { q_ -= q; } + { + q_ -= q; + return *this; + } +}; + +// CTAD +template +explicit quantity_point(Rep) -> quantity_point{}, Rep>; + +template +explicit quantity_point(Q) -> quantity_point{}, typename Q::rep>; + +template +explicit quantity_point(Q) + -> quantity_point::reference, absolute_point_origin::quantity_spec>{}, + typename quantity_like_traits::rep>; + +template +explicit quantity_point(QP) + -> quantity_point::reference, quantity_point_like_traits::point_origin, + typename quantity_point_like_traits::rep>; + +template +[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity_point& lhs, + const quantity& rhs) + requires requires { lhs.relative() + rhs; } +{ + const auto q = lhs.relative() + rhs; + using q_type = decltype(q); + return quantity_point(q); +} + +template +[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity& lhs, + const quantity_point& rhs) + requires requires { rhs + lhs; } +{ + return rhs + lhs; +} + +template +[[nodiscard]] constexpr QuantityPoint auto operator-(const quantity_point& lhs, + const quantity& rhs) + requires requires { lhs.relative() - rhs; } +{ + const auto q = lhs.relative() - rhs; + using q_type = decltype(q); + return quantity_point(q); +} + +template QP2> +[[nodiscard]] constexpr Quantity auto operator-(const QP1& lhs, const QP2& rhs) + requires requires { lhs.absolute() - rhs.absolute(); } +{ + return lhs.absolute() - rhs.absolute(); +} + +template QP2> + requires std::three_way_comparable_with +[[nodiscard]] constexpr auto operator<=>(const QP1& lhs, const QP2& rhs) +{ + return lhs.relative() <=> rhs.relative(); +} + +template QP2> + requires std::equality_comparable_with +[[nodiscard]] constexpr bool operator==(const QP1& lhs, const QP2& rhs) +{ + return lhs.relative() == rhs.relative(); +} + +} // namespace mp_units diff --git a/src/core/include/mp-units/quantity_spec.h b/src/core/include/mp-units/quantity_spec.h new file mode 100644 index 00000000..c8386cdc --- /dev/null +++ b/src/core/include/mp-units/quantity_spec.h @@ -0,0 +1,1489 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mp_units { + +template + requires quantity>::_rep_safe_constructible_ +[[nodiscard]] constexpr quantity> make_quantity(Rep&& v); + +namespace detail { + +// TODO revise the note in the below comment +/** + * @brief Returns the most restrictive character from the list + * + * @note `vector * vector` returns vector (not tensor) + */ +template... Ts> +[[nodiscard]] consteval quantity_character common_quantity_character(Ts... args) +{ + return max({args...}); +} + +template +[[nodiscard]] consteval quantity_character derived_quantity_character(const type_list&, + const type_list&) +{ + constexpr quantity_character num = + common_quantity_character(quantity_character::scalar, expr_type::character...); + constexpr quantity_character den = + common_quantity_character(quantity_character::scalar, expr_type::character...); + if constexpr (num == den) + return quantity_character::scalar; + else + return common_quantity_character(num, den); +} + +/** + * @brief Initializes quantity character + * + * If a quantity character value is present in template parameters, this value will be used. + * Otherwise, an inherited/derived value provided through the function argument is returned. + */ +template +[[nodiscard]] consteval quantity_character quantity_character_init(quantity_character ch) +{ + if constexpr (contains()) + return get(); + else + return ch; +} + +template +struct quantity_spec_less : std::bool_constant() < type_name()> {}; + +template +using type_list_of_quantity_spec_less = expr_less; + +template + requires requires { Q::dimension; } +using to_dimension = std::remove_const_t; + +template +[[nodiscard]] consteval auto get_associated_quantity(U); + +#ifndef __cpp_explicit_this_parameter +template +#endif +struct quantity_spec_interface { +#ifdef __cpp_explicit_this_parameter + template U> + [[nodiscard]] consteval Reference auto operator[](this Self self, U u) const + { + return reference{}; + } + + template + [[nodiscard]] constexpr Quantity auto operator()(this Self self, Q&& q) const + requires Quantity> && + (explicitly_convertible(std::remove_reference_t::quantity_spec, self)) + { + return make_quantity::unit>{}>(std::forward(q).number()); + } +#else + template U> + [[nodiscard]] consteval Reference auto operator[](U u) const + { + return reference{}; + } + + template + requires Quantity> && + (explicitly_convertible(std::remove_reference_t::quantity_spec, Self{})) + [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const + { + return make_quantity::unit>{}>(std::forward(q).number()); + } +#endif +}; + +} // namespace detail + +/** + * @brief Quantity Specification + * + * This type specifies all the properties of a quantity and allow modeling most of the quantities in the ISO 80000. + * It serves to define base and derived quantities as well as quantity kinds. Each quantity specification + * provides an information on how this quantity relates to other quantities, specifies its dimension, and character. + * + * Quantity character can be derived from other quantities or explicitly overriden through a template parameter. + * + * Binding a proper unit to a quantity specification via an indexing operator (`operator[]`) results + * in a quantity reference. + * + * Call operator may be used to change the type of a provided quantity. + * + * Two quantity specifications are deemed equal when they are of the same type. With that, both strong + * types `speed` and `velocity` are considered not equal to `derived_dimension>` or + * to each other. + */ +#ifdef __cpp_explicit_this_parameter +template +#else +template +#endif +struct quantity_spec; + +inline constexpr struct is_kind { +} is_kind; + +/** + * @brief Specialization defining a base quantity + * + * Base quantity is a 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. They are referred to as + * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base + * quantities. + * + * This quantity serves as a root/kind for a new hierarchy of quantities of the same kind. + * + * Base quantities have scalar character by default. + * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct dim_length : base_dimension<"L"> {} dim_length; + * inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass; + * inline constexpr struct dim_time : base_dimension<"T"> {} dim_time; + * + * inline constexpr struct length : quantity_spec {} length; + * inline constexpr struct mass : quantity_spec {} mass; + * inline constexpr struct time : quantity_spec {} time; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the types in the source code. All operations + * are done on the objects. Contrarily, the types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam BaseDimension base dimension for which a base quantity is being defined + * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar + */ +#ifdef __cpp_explicit_this_parameter +template auto... Args> + requires(... && !QuantitySpec>) +struct quantity_spec : detail::quantity_spec_interface { +#else +template auto... Args> + requires(... && !QuantitySpec>) +struct quantity_spec : detail::quantity_spec_interface { +#endif + static constexpr detail::BaseDimension auto dimension = Dim; + static constexpr quantity_character character = detail::quantity_character_init(quantity_character::scalar); +}; + +/** + * @brief Specialization defining a named quantity being the result of a quantity calculus + * + * Derived quantity is a quantity, in a system of quantities, defined in terms of other quantities + * of that system. + * + * This quantity serves as a root/kind for a new hierarchy of quantities of the same kind. + * + * Such quantities by default derive the character from the derived quantity definition. + * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct area : quantity_spec(length)> {} area; + * inline constexpr struct volume : quantity_spec(length)> {} volume; + * inline constexpr struct velocity : quantity_spec {} velocity; + * inline constexpr struct speed : quantity_spec {} speed; + * inline constexpr struct force : quantity_spec {} force; + * inline constexpr struct power : quantity_spec {} power; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the types in the source code. All operations + * are done on the objects. Contrarily, the types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Eq quantity equation specification of a derived quantity + * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar + */ +#ifdef __cpp_explicit_this_parameter +template auto... Args> + requires(... && !QuantitySpec>) +struct quantity_spec : detail::quantity_spec_interface { +#else +template auto... Args> + requires(... && !QuantitySpec>) +struct quantity_spec : detail::quantity_spec_interface { +#endif + static constexpr auto _equation_ = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = detail::quantity_character_init(Eq.character); +}; + +/** + * @brief Specialization defining a leaf quantity in the hierarchy + * + * Quantities of the same kind form a hierarchy. This specialization adds new leaf to such a tree which + * can later be used as a parent by other quantities. + * + * The character of those quantities by default is derived from the parent quantity. + * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct width : quantity_spec {} width; + * inline constexpr struct height : quantity_spec {} height; + * inline constexpr struct diameter : quantity_spec {} diameter; + * inline constexpr struct position_vector : quantity_spec {} position_vector; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the types in the source code. All operations + * are done on the objects. Contrarily, the types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Q quantity specification of a parent quantity + * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar + * or `is_kind` in case the quantity starts a new hierarchy tree of a kind + */ +#ifdef __cpp_explicit_this_parameter +template auto... Args> + requires(... && !QuantitySpec>) +struct quantity_spec : std::remove_const_t { +#else +template auto... Args> + requires(... && !QuantitySpec>) +struct quantity_spec : std::remove_const_t { +#endif + static constexpr auto _parent_ = QS; + static constexpr quantity_character character = detail::quantity_character_init(QS.character); + +#ifndef __cpp_explicit_this_parameter + template U> + [[nodiscard]] consteval Reference auto operator[](U u) const + { + return reference{}; + } + + template + requires Quantity> && + (explicitly_convertible(std::remove_reference_t::quantity_spec, Self{})) + [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const + { + return make_quantity::unit>{}>(std::forward(q).number()); + } +#endif +}; + +/** + * @brief Specialization defining a leaf derived quantity in the hierarchy and refining paren't equation + * + * Quantities of the same kind form a hierarchy. This specialization adds new leaf to such a tree which + * can later be used as a parent by other quantities. Additionally, this defintion adds additional + * constraints on the derived quantity's equation. + * + * The character of those quantities by default is derived from the parent quantity. + * + * User should derive a strong type from this class template rather than use it directly in the source code. + * For example: + * + * @code{.cpp} + * inline constexpr struct angular_measure : quantity_spec {} + * angular_measure; inline constexpr struct velocity : quantity_spec {} velocity; + * inline constexpr struct weight : quantity_spec {} weight; + * inline constexpr struct kinetic_energy : quantity_spec(speed)> {} kinetic_energy; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the types in the source code. All operations + * are done on the objects. Contrarily, the types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Q quantity specification of a parent quantity + * @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar + * or `is_kind` in case the quantity starts a new hierarchy tree of a kind + */ +#ifdef __cpp_explicit_this_parameter +template auto... Args> + requires(!requires { QS._equation_; } || + (requires { QS._equation_; } && (explicitly_convertible(Eq, QS._equation_)))) && + (... && !QuantitySpec>) +struct quantity_spec : quantity_spec { +#else +template auto... Args> + requires(!requires { QS._equation_; } || + (requires { QS._equation_; } && (explicitly_convertible(Eq, QS._equation_)))) && + (... && !QuantitySpec>) +struct quantity_spec : quantity_spec { +#endif + static constexpr auto _equation_ = Eq; + static constexpr quantity_character character = detail::quantity_character_init(Eq.character); +}; + +#ifdef __cpp_explicit_this_parameter + +#define QUANTITY_SPEC(name, ...) \ + inline constexpr struct name : ::mp_units::quantity_spec<##__VA_ARGS__> { \ + } name + +#else + +#define QUANTITY_SPEC(name, ...) \ + inline constexpr struct name : ::mp_units::quantity_spec { \ + } name + +#endif + + +/** + * @brief A specification of a derived quantity + * + * Derived quantity is a quantity, in a system of quantities, defined in terms of other quantities of that system. + * Its dimension is an 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. + * + * Instead of using a raw list of exponents this library decided to use expression template syntax to make types + * more digestable for the user both for quantity specification and its dimension. The positive exponents are ordered + * first and all negative exponents are put as a list into the `per<...>` class template. If a power of exponent + * is different than `1` the quantity type is enclosed in `power` class template. Otherwise, it is + * just put directly in the list without any wrapper. In case all of the exponents are negative than the + * `dimensionless`/`dimension_one` is put in the front to increase the readability. + * + * The character of those quantities is derived from ingredients or overriden with a template parameter. + * + * For example: + * + * @code{.cpp} + * auto frequency = 1 / period_duration; + * auto area = pow<2>(length); + * auto speed = distance / duration; + * auto velocity = position_vector / duration; + * auto acceleration = velocity / duration; + * @endcode + * + * - the type of `frequency` is `derived_quantity_spec>` + * - the dimension type of `frequency` is `derived_dimension>` + * - the type of `area` is `derived_quantity_spec>` + * - the dimension type of `area` is `derived_dimension>` + * - the type of `speed` is `derived_quantity_spec>` + * - the dimension type of `speed` is `derived_dimension>` + * - the type of `velocity` is `derived_quantity_spec>` + * - the dimension type of `velocity` is `derived_dimension>` + * - the type of `acceleration` is `derived_quantity_spec>` + * - the dimension type of `acceleration` is `derived_dimension>>` + * + * @tparam Expr a parameter pack consisting tokens allowed in the quantity specification + * (named quantity specification, `dimensionless`, `power`, `per<...>`) + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the dimensional arithmetic equation provided by the user. + */ +template +struct derived_quantity_spec : + detail::quantity_spec_interface>, + detail::expr_fractions { + using _base_ = detail::expr_fractions; + + static constexpr Dimension auto dimension = + detail::expr_map(_base_{}); + static constexpr quantity_character character = + detail::derived_quantity_character(typename _base_::_num_{}, typename _base_::_den_{}); +}; + +/** + * @brief Quantity of dimension one + * + * Quantity of dimension one also commonly named as "dimensionless" is a quantity with a dimension + * for which all the exponents of the factors corresponding to the base dimensions are zero. + */ +QUANTITY_SPEC(dimensionless, derived_quantity_spec<>{}); + +/** + * @brief Quantity kind specifier + * + * Specifies that the provided `Q` should be treated as a quantity kind. + */ +template +struct kind_of_; + +namespace detail { + +template +concept QuantitySpecWithNoSpecifiers = detail::NamedQuantitySpec || detail::IntermediateDerivedQuantitySpec; + +} // namespace detail + +template + requires(get_kind(Q) == Q) +#ifdef __cpp_explicit_this_parameter +struct kind_of_ : Q { + static constexpr auto _quantity_spec_ = Q; +}; +#else +struct kind_of_ : quantity_spec, Q> { + static constexpr auto _quantity_spec_ = Q; +}; +#endif + +template + requires(get_kind(Q) == Q) +inline constexpr kind_of_ kind_of; + +namespace detail { + +template<> +struct is_dimensionless : std::true_type {}; + +template +[[nodiscard]] consteval QuantitySpec auto clone_kind_of(Q q) +{ + if constexpr ((... && QuantityKindSpec>)) + return kind_of; + else + return q; +} + +} // namespace detail + +// Operators + +[[nodiscard]] consteval QuantitySpec auto operator*(QuantitySpec auto lhs, QuantitySpec auto rhs) +{ + return clone_kind_of( + detail::expr_multiply( + remove_kind(lhs), remove_kind(rhs))); +} + +template +[[nodiscard]] consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs) +{ + return clone_kind_of( + detail::expr_divide( + remove_kind(lhs), remove_kind(rhs))); +} + +[[nodiscard]] consteval QuantitySpec auto operator/(int value, QuantitySpec auto q) +{ + gsl_Expects(value == 1); + return clone_kind_of(detail::expr_invert(q)); +} + +[[nodiscard]] consteval QuantitySpec auto operator/(QuantitySpec auto, int) = delete; + +template +[[nodiscard]] consteval bool operator==(Lhs, Rhs) +{ + return is_same_v; +} + +template +[[nodiscard]] consteval bool operator==(Lhs, Rhs) +{ + return is_same_v; +} + +template +[[nodiscard]] consteval bool operator==(Lhs, Rhs rhs) +{ + return is_same_v>; +} + + +/** + * @brief Computes the value of a quantity specification raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param q Quantity specification being the base of the operation + * + * @return QuantitySpec The result of computation + */ +template + requires detail::non_zero +[[nodiscard]] consteval QuantitySpec auto pow(Q q) +{ + // TODO Does the below make sense? + // `2 * 2` should compare to `4` + // `2 * one * (2 * one)` should compare to `4 * one` + // `2 * rad * (2 * rad)` should compare to `4 * rad^2` + // all are dimensionless quantities :-( + if constexpr (Num == 0 || q == dimensionless) + return dimensionless; + else if constexpr (ratio{Num, Den} == 1) + return q; + else if constexpr (detail::IntermediateDerivedQuantitySpec) + return detail::clone_kind_of( + detail::expr_pow( + remove_kind(q))); + else if constexpr (Den == 1) + return detail::clone_kind_of( + derived_quantity_spec, Num>>{}); + else + return detail::clone_kind_of( + derived_quantity_spec, Num, Den>>{}); +} + + +/** + * @brief Computes the square root of a quantity specification + * + * @param q Quantity specification being the base of the operation + * + * @return QuantitySpec The result of computation + */ +[[nodiscard]] consteval QuantitySpec auto sqrt(QuantitySpec auto q) { return pow<1, 2>(q); } + + +/** + * @brief Computes the cubic root of a quantity specification + * + * @param q Quantity specification being the base of the operation + * + * @return QuantitySpec The result of computation + */ +[[nodiscard]] consteval QuantitySpec auto cbrt(QuantitySpec auto q) { return pow<1, 3>(q); } + + +namespace detail { + +enum class specs_convertible_result { no, cast, explicit_conversion, yes }; + +template +[[nodiscard]] consteval int get_complexity(Q); + +template +[[nodiscard]] consteval int get_complexity(type_list) +{ + return (0 + ... + get_complexity(Ts{})); +} + +template +[[nodiscard]] consteval int get_complexity(power) +{ + return get_complexity(Q{}); +} + +template +[[nodiscard]] consteval int get_complexity(kind_of_) +{ + return get_complexity(Q); +} + +template +[[nodiscard]] consteval int get_complexity(Q) +{ + if constexpr (detail::IntermediateDerivedQuantitySpec) + return get_complexity(typename Q::_num_{}) + get_complexity(typename Q::_den_{}); + else if constexpr (requires { Q::_equation_; }) + return 1 + get_complexity(Q::_equation_); + else + return 1; +} + +// dimension_one is always the last one +// otherwise, sort by typename +template +[[nodiscard]] consteval bool ingredients_dimension_less(D1 lhs, D2 rhs) +{ + if constexpr (lhs == rhs) + return false; + else if constexpr (lhs == dimension_one) + return false; + else if constexpr (rhs == dimension_one) + return true; + else + return type_name() < type_name(); +} + +template +struct ingredients_less : + std::bool_constant<(lhs_compl > rhs_compl) || + (lhs_compl == rhs_compl && ingredients_dimension_less(Lhs::dimension, Rhs::dimension)) || + (lhs_compl == rhs_compl && Lhs::dimension == Rhs::dimension && + type_name() < type_name())> {}; + +template +using type_list_of_ingredients_less = expr_less; + +template + requires requires { Q::_equation_; } +[[nodiscard]] consteval bool defines_equation(Q) +{ + if constexpr (requires { Q::_parent_._equation_; }) + return Q::_parent_._equation_ != Q::_equation_; + else + return true; +} + +template +struct explode_to_equation_result { + Q equation; + specs_convertible_result result; +}; + +template + requires requires { Q::_equation_; } +[[nodiscard]] consteval auto explode_to_equation(Q q) +{ + return explode_to_equation_result{ + Q::_equation_, defines_equation(q) ? specs_convertible_result::yes : specs_convertible_result::explicit_conversion}; +} + +template + requires requires { Q::_equation_; } +[[nodiscard]] consteval auto explode_to_equation(power) +{ + constexpr ratio exp = power::exponent; + return explode_to_equation_result{ + pow(Q::_equation_), + defines_equation(Q{}) ? specs_convertible_result::yes : specs_convertible_result::explicit_conversion}; +} + +template +struct explode_result { + Q quantity; + specs_convertible_result result = specs_convertible_result::yes; + + template + [[nodiscard]] consteval explode_result common_convertibility_with(explode_to_equation_result res) const + { + return {quantity, std::min(result, res.result)}; + } +}; + +template +[[nodiscard]] consteval auto explode(Q q); + +template +[[nodiscard]] consteval auto explode(Q q); + +template +[[nodiscard]] consteval auto explode(Q, type_list, type_list) +{ + constexpr auto n = get_complexity(Num{}); + constexpr auto d = get_complexity(Den{}); + constexpr auto max = n > d ? n : d; + + if constexpr (max == Complexity || ((n >= d && !requires { explode_to_equation(Num{}); }) || + (n < d && !requires { explode_to_equation(Den{}); }))) + return explode_result{(map_power(Num{}) * ... * map_power(Nums{})) / (map_power(Den{}) * ... * map_power(Dens{}))}; + else { + if constexpr (n >= d) { + constexpr auto res = explode_to_equation(Num{}); + return explode((res.equation * ... * map_power(Nums{})) / + (map_power(Den{}) * ... * map_power(Dens{}))) + .common_convertibility_with(res); + } else { + constexpr auto res = explode_to_equation(Den{}); + return explode((map_power(Num{}) * ... * map_power(Nums{})) / + (res.equation * ... * map_power(Dens{}))) + .common_convertibility_with(res); + } + } +} + +template +[[nodiscard]] consteval auto explode(Q, type_list, type_list<>) +{ + constexpr auto n = get_complexity(Num{}); + if constexpr (n == Complexity || !requires { explode_to_equation(Num{}); }) + return explode_result{(map_power(Num{}) * ... * map_power(Nums{}))}; + else { + constexpr auto res = explode_to_equation(Num{}); + return explode((res.equation * ... * map_power(Nums{}))).common_convertibility_with(res); + } +} + +template +[[nodiscard]] consteval auto explode(Q, type_list<>, type_list) +{ + constexpr auto d = get_complexity(Den{}); + if constexpr (d == Complexity || !requires { explode_to_equation(Den{}); }) + return explode_result{dimensionless / (map_power(Den{}) * ... * map_power(Dens{}))}; + else { + constexpr auto res = explode_to_equation(Den{}); + return explode(dimensionless / (res.equation * ... * map_power(Dens{}))) + .common_convertibility_with(res); + } +} + +template +[[nodiscard]] consteval auto explode(Q, type_list<>, type_list<>) +{ + return explode_result{dimensionless}; +} + +template +[[nodiscard]] consteval auto explode(Q q) +{ + constexpr auto c = get_complexity(q); + if constexpr (c > Complexity) + return explode(q, type_list_sort{}, + type_list_sort{}); + else + return explode_result{q}; +} + +template +[[nodiscard]] consteval auto explode(Q q) +{ + constexpr auto c = get_complexity(q); + if constexpr (c > Complexity && requires { Q::_equation_; }) { + constexpr auto res = explode_to_equation(q); + return explode(res.equation).common_convertibility_with(res); + } else + return explode_result{q}; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list num_from, + type_list den_from, + type_list num_to, + type_list den_to); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, + type_list, + type_list, + type_list); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list<>, type_list, + type_list); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list, + type_list<>, type_list); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list, + type_list, type_list<>); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list<>, type_list, + type_list<>); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, + type_list, + type_list<>, type_list); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list, type_list<>, + type_list<>); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, + type_list, + type_list); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, type_list<>, + type_list<>, type_list<>); +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list, + type_list<>, type_list<>); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, + type_list, type_list<>); + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, type_list<>, + type_list); + +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, type_list<>, + type_list<>); + +enum class prepend_rest { no, first, second }; + +template +struct extract_results { + bool same_dimension; + From from{}; + To to{}; + prepend_rest prepend{}; + Elem elem{}; +}; + +template +[[nodiscard]] consteval auto extract_convertible_quantities(From from, To to) +{ + constexpr auto qfrom = map_power(from); + constexpr auto qto = map_power(to); + if constexpr (qfrom.dimension == qto.dimension) { + if constexpr (is_specialization_of_power && is_specialization_of_power) { + constexpr auto cr = common_ratio(From::exponent, To::exponent); + constexpr auto from_ratio = From::exponent / cr; + constexpr auto to_ratio = To::exponent / cr; + return extract_results{true, pow(typename From::factor{}), + pow(typename To::factor{}), prepend_rest::no}; + } else + return extract_results{true, qfrom, qto, prepend_rest::no}; + } else { + auto normalize = [](Q) { + if constexpr (is_specialization_of_power) + return std::tuple{typename Q::factor{}, Q::exponent}; + else + return std::tuple{Q{}, ratio{1}}; + }; + constexpr auto from_norm = normalize(from); + constexpr auto to_norm = normalize(to); + constexpr auto from_factor = std::get<0>(from_norm); + constexpr auto from_exp = std::get<1>(from_norm); + constexpr auto to_factor = std::get<0>(to_norm); + constexpr auto to_exp = std::get<1>(to_norm); + if constexpr (from_factor.dimension != to_factor.dimension) + return extract_results{false}; + else if constexpr (from_exp > to_exp) + return extract_results{true, pow(from_factor), pow(to_factor), + prepend_rest::first, + power_or_T, from_exp - to_exp>{}}; + else + return extract_results{true, pow(from_factor), + pow(to_factor), prepend_rest::second, + power_or_T, to_exp - from_exp>{}}; + } +} + +enum class process_entities { numerators, denominators, from, to }; + +template +[[nodiscard]] consteval specs_convertible_result process_extracted(NumFrom num_from, DenFrom den_from, NumTo num_to, + DenTo den_to) +{ + if constexpr (Entities == process_entities::numerators || Entities == process_entities::denominators) { + constexpr auto res = convertible_impl(Ext.from, Ext.to); + if constexpr (Ext.prepend == prepend_rest::no) + return std::min(res, are_ingredients_convertible(num_from, den_from, num_to, den_to)); + else { + using elem = std::remove_cvref_t; + if constexpr (Entities == process_entities::numerators) { + if constexpr (Ext.prepend == prepend_rest::first) + return std::min(res, + are_ingredients_convertible(type_list_push_front{}, den_from, num_to, den_to)); + else + return std::min(res, + are_ingredients_convertible(num_from, den_from, type_list_push_front{}, den_to)); + } else { + if constexpr (Ext.prepend == prepend_rest::first) + return std::min(res, + are_ingredients_convertible(num_from, type_list_push_front{}, num_to, den_to)); + else + return std::min(res, + are_ingredients_convertible(num_from, den_from, num_to, type_list_push_front{})); + } + } + } else { + if constexpr (Ext.prepend == prepend_rest::no) + return are_ingredients_convertible(num_from, den_from, num_to, den_to); + else { + using elem = std::remove_cvref_t; + if constexpr (Entities == process_entities::from) { + if constexpr (Ext.prepend == prepend_rest::first) + return are_ingredients_convertible(type_list_push_front{}, den_from, num_to, den_to); + else + return are_ingredients_convertible(num_from, type_list_push_front{}, num_to, den_to); + } else { + if constexpr (Ext.prepend == prepend_rest::first) + return are_ingredients_convertible(num_from, den_from, type_list_push_front{}, den_to); + else + return are_ingredients_convertible(num_from, den_from, num_to, type_list_push_front{}); + } + } + } +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list num_from, + type_list den_from, + type_list num_to, + type_list den_to) +{ + if constexpr (constexpr auto extN = extract_convertible_quantities(NumFrom{}, NumTo{}); extN.same_dimension) + return process_extracted(type_list{}, den_from, + type_list{}, den_to); + else if constexpr (constexpr auto extD = extract_convertible_quantities(DenFrom{}, DenTo{}); extD.same_dimension) + return process_extracted(num_from, type_list{}, num_to, + type_list{}); + else if constexpr (constexpr auto extF = extract_convertible_quantities(NumFrom{}, DenFrom{}); extF.same_dimension) + return process_extracted(type_list{}, type_list{}, num_to, + den_to); + else if constexpr (constexpr auto extT = extract_convertible_quantities(NumTo{}, DenTo{}); extT.same_dimension) + return process_extracted(num_from, den_from, type_list{}, + type_list{}); + else { + constexpr auto num_from_compl = get_complexity(NumFrom{}); + constexpr auto den_from_compl = get_complexity(DenFrom{}); + constexpr auto num_to_compl = get_complexity(NumTo{}); + constexpr auto den_to_compl = get_complexity(DenTo{}); + constexpr auto max = std::max({num_from_compl, num_to_compl, den_from_compl, den_to_compl}); + if constexpr (max > 1) { + if constexpr (num_from_compl == max) { + constexpr auto res = explode_to_equation(NumFrom{}); + return convertible_impl( + (res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else if constexpr (den_from_compl == max) { + constexpr auto res = explode_to_equation(DenFrom{}); + return convertible_impl( + (map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else if constexpr (num_to_compl == max) { + constexpr auto res = explode_to_equation(NumTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})) / + (map_power(DenTo{}) * ... * map_power(DensTo{})))); + } else { + constexpr auto res = explode_to_equation(DenTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / + (res.equation * ... * map_power(DensTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<> num_from, + type_list den_from, + type_list num_to, + type_list) +{ + if constexpr (constexpr auto extD = extract_convertible_quantities(DenFrom{}, DenTo{}); extD.same_dimension) + return process_extracted(num_from, type_list{}, num_to, + type_list{}); + else if constexpr (constexpr auto extT = extract_convertible_quantities(NumTo{}, DenTo{}); extT.same_dimension) + return process_extracted(num_from, den_from, type_list{}, + type_list{}); + else { + constexpr auto den_from_compl = get_complexity(DenFrom{}); + constexpr auto num_to_compl = get_complexity(NumTo{}); + constexpr auto den_to_compl = get_complexity(DenTo{}); + constexpr auto max = std::max({num_to_compl, den_from_compl, den_to_compl}); + if constexpr (max > 1) { + if constexpr (den_from_compl == max) { + constexpr auto res = explode_to_equation(DenFrom{}); + return convertible_impl( + dimensionless / (res.equation * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else if constexpr (num_to_compl == max) { + constexpr auto res = explode_to_equation(NumTo{}); + return std::min( + res.result, convertible_impl( + dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{})))); + } else { + constexpr auto res = explode_to_equation(DenTo{}); + return std::min( + res.result, convertible_impl( + dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (res.equation * ... * map_power(DensTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list num_from, + type_list<> den_from, + type_list, + type_list den_to) +{ + if constexpr (constexpr auto extN = extract_convertible_quantities(NumFrom{}, NumTo{}); extN.same_dimension) + return process_extracted(type_list{}, den_from, + type_list{}, den_to); + else if constexpr (constexpr auto extT = extract_convertible_quantities(NumTo{}, DenTo{}); extT.same_dimension) + return process_extracted(num_from, den_from, type_list{}, + type_list{}); + else { + constexpr auto num_from_compl = get_complexity(NumFrom{}); + constexpr auto num_to_compl = get_complexity(NumTo{}); + constexpr auto den_to_compl = get_complexity(DenTo{}); + constexpr auto max = std::max({num_from_compl, num_to_compl, den_to_compl}); + if constexpr (max > 1) { + if constexpr (num_from_compl == max) { + constexpr auto res = explode_to_equation(NumFrom{}); + return convertible_impl( + (res.equation * ... * map_power(NumsFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else if constexpr (num_to_compl == max) { + constexpr auto res = explode_to_equation(NumTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + (res.equation * ... * map_power(NumsTo{})) / + (map_power(DenTo{}) * ... * map_power(DensTo{})))); + } else { + constexpr auto res = explode_to_equation(DenTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / + (res.equation * ... * map_power(DensTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list num_from, + type_list, + type_list<> num_to, + type_list den_to) +{ + if constexpr (constexpr auto extD = extract_convertible_quantities(DenFrom{}, DenTo{}); extD.same_dimension) + return process_extracted(num_from, type_list{}, num_to, + type_list{}); + else if constexpr (constexpr auto extF = extract_convertible_quantities(NumFrom{}, DenFrom{}); extF.same_dimension) + return process_extracted(type_list{}, type_list{}, num_to, + den_to); + else { + constexpr auto num_from_compl = get_complexity(NumFrom{}); + constexpr auto den_from_compl = get_complexity(DenFrom{}); + constexpr auto den_to_compl = get_complexity(DenTo{}); + constexpr auto max = std::max({num_from_compl, den_from_compl, den_to_compl}); + if constexpr (max > 1) { + if constexpr (num_from_compl == max) { + constexpr auto res = explode_to_equation(NumFrom{}); + return convertible_impl( + (res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else if constexpr (den_from_compl == max) { + constexpr auto res = explode_to_equation(DenFrom{}); + return convertible_impl( + (map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})), + dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else { + constexpr auto res = explode_to_equation(DenTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + dimensionless / (res.equation * ... * map_power(DensTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list den_from, + type_list num_to, + type_list<> den_to) +{ + if constexpr (constexpr auto extN = extract_convertible_quantities(NumFrom{}, NumTo{}); extN.same_dimension) + return process_extracted(type_list{}, den_from, + type_list{}, den_to); + else if constexpr (constexpr auto extF = extract_convertible_quantities(NumFrom{}, DenFrom{}); extF.same_dimension) + return process_extracted(type_list{}, type_list{}, num_to, + den_to); + else { + constexpr auto num_from_compl = get_complexity(NumFrom{}); + constexpr auto den_from_compl = get_complexity(DenFrom{}); + constexpr auto num_to_compl = get_complexity(NumTo{}); + constexpr auto max = std::max({num_from_compl, num_to_compl, den_from_compl}); + if constexpr (max > 1) { + if constexpr (num_from_compl == max) { + constexpr auto res = explode_to_equation(NumFrom{}); + return convertible_impl( + (res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{}))); + } else if constexpr (den_from_compl == max) { + constexpr auto res = explode_to_equation(DenFrom{}); + return convertible_impl( + (map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{}))); + } else { + constexpr auto res = explode_to_equation(NumTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list<> den_from, + type_list, + type_list<> den_to) +{ + if constexpr (constexpr auto ext = extract_convertible_quantities(NumFrom{}, NumTo{}); ext.same_dimension) { + return process_extracted(type_list{}, den_from, + type_list{}, den_to); + } else { + constexpr auto num_from_compl = get_complexity(NumFrom{}); + constexpr auto num_to_compl = get_complexity(NumTo{}); + constexpr auto max = std::max({num_from_compl, num_to_compl}); + if constexpr (max > 1) { + if constexpr (num_from_compl == max) { + constexpr auto res = explode_to_equation(NumFrom{}); + return convertible_impl((res.equation * ... * map_power(NumsFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{}))); + } else { + constexpr auto res = explode_to_equation(NumTo{}); + return std::min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + (res.equation * ... * map_power(NumsTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<> num_from, + type_list, + type_list<> num_to, + type_list) +{ + if constexpr (constexpr auto ext = extract_convertible_quantities(DenFrom{}, DenTo{}); ext.same_dimension) + return process_extracted(num_from, type_list{}, num_to, + type_list{}); + else { + constexpr auto den_from_compl = get_complexity(DenFrom{}); + constexpr auto den_to_compl = get_complexity(DenTo{}); + constexpr auto max = std::max({den_from_compl, den_to_compl}); + if constexpr (max > 1) { + if constexpr (den_from_compl == max) { + constexpr auto res = explode_to_equation(DenFrom{}); + return convertible_impl(dimensionless / (res.equation * ... * map_power(DensFrom{})), + dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + } else { + constexpr auto res = explode_to_equation(DenTo{}); + return std::min(res.result, + convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + dimensionless / (res.equation * ... * map_power(DensTo{})))); + } + } + } + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, + type_list, type_list<>, + type_list<>) +{ + if constexpr (((... * map_power(NumsFrom{})) / (... * map_power(DensFrom{}))).dimension == dimension_one) + return specs_convertible_result::yes; + else + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, + type_list, type_list) +{ + if constexpr (((... * map_power(NumsTo{})) / (... * map_power(DensTo{}))).dimension == dimension_one) + return specs_convertible_result::yes; + else + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list, type_list<>, + type_list<>, type_list<>) +{ + if constexpr ((... * map_power(NumsFrom{})).dimension == dimension_one) + return specs_convertible_result::yes; + else + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list, + type_list<>, type_list<>) +{ + if constexpr ((... * map_power(DensFrom{})).dimension == dimension_one) + return specs_convertible_result::yes; + else + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, + type_list, type_list<>) +{ + if constexpr ((... * map_power(NumsTo{})).dimension == dimension_one) + return specs_convertible_result::yes; + else + return specs_convertible_result::no; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, type_list<>, + type_list) +{ + if constexpr ((... * map_power(DensFrom{})).dimension == dimension_one) + return specs_convertible_result::yes; + else + return specs_convertible_result::no; +} + +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<>, type_list<>, type_list<>, + type_list<>) +{ + return specs_convertible_result::yes; +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(From, To) +{ + return are_ingredients_convertible(type_list_sort{}, + type_list_sort{}, + type_list_sort{}, + type_list_sort{}); +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(From, To) +{ + return are_ingredients_convertible(type_list_sort{}, + type_list_sort{}, + type_list{}, type_list<>{}); +} + +template +[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(From, To) +{ + return are_ingredients_convertible(type_list{}, type_list<>{}, + type_list_sort{}, + type_list_sort{}); +} + +template +[[nodiscard]] consteval specs_convertible_result convertible_impl(From from, To to) +{ + using enum specs_convertible_result; + + if constexpr (From::dimension != To::dimension) + return no; + else if constexpr (from == to) + return yes; + else if constexpr (QuantityKindSpec || QuantityKindSpec) { + constexpr auto from_kind = get_kind(from); + constexpr auto to_kind = get_kind(to); + constexpr auto exploded_kind_result = [](specs_convertible_result res) { + using enum specs_convertible_result; + return res == no ? no : yes; + }; + if constexpr ((NamedQuantitySpec> && + NamedQuantitySpec>) || + get_complexity(from_kind) == get_complexity(to_kind)) + return convertible_impl(from_kind, to_kind); + else if constexpr (get_complexity(from_kind) > get_complexity(to_kind)) + return exploded_kind_result( + convertible_impl(get_kind(explode(from_kind).quantity), to_kind)); + else + return exploded_kind_result( + convertible_impl(from_kind, get_kind(explode(to_kind).quantity))); + } else if constexpr (DerivedFromQuantityKindSpecOf && get_kind(to) == to) + return yes; + else if constexpr (NamedQuantitySpec && NamedQuantitySpec) { + if constexpr (have_common_base(from, to)) { + if (std::derived_from) + return yes; + else + return std::derived_from ? explicit_conversion : (get_kind(from) == get_kind(to) ? cast : no); + } else if constexpr (get_kind(from) != get_kind(to)) + return no; + else if constexpr (get_complexity(from) != get_complexity(to)) { + if constexpr (get_complexity(from) > get_complexity(to)) + return convertible_impl(explode(from).quantity, to); + else { + constexpr auto res = explode(to); + return std::min(res.result, convertible_impl(from, res.quantity)); + } + } + } else if constexpr (IntermediateDerivedQuantitySpec && IntermediateDerivedQuantitySpec) { + return are_ingredients_convertible(from, to); + } else if constexpr (IntermediateDerivedQuantitySpec) { + auto res = explode(from); + if constexpr (NamedQuantitySpec>) + return convertible_impl(res.quantity, to); + else if constexpr (requires { to._equation_; }) { + constexpr auto eq = explode_to_equation(to); + return std::min(eq.result, convertible_impl(res.quantity, eq.equation)); + } else + return are_ingredients_convertible(from, to); + } else if constexpr (IntermediateDerivedQuantitySpec) { + auto res = explode(to); + if constexpr (NamedQuantitySpec>) + return std::min(res.result, convertible_impl(from, res.quantity)); + else if constexpr (requires { from._equation_; }) + return std::min(res.result, convertible_impl(from._equation_, res.quantity)); + else + return std::min(res.result, are_ingredients_convertible(from, to)); + } + return no; +} + +} // namespace detail + +template +[[nodiscard]] consteval bool implicitly_convertible(From from, To to) +{ + return detail::convertible_impl(from, to) == detail::specs_convertible_result::yes; +} + +template +[[nodiscard]] consteval bool explicitly_convertible(From from, To to) +{ + return detail::convertible_impl(from, to) >= detail::specs_convertible_result::explicit_conversion; +} + +template +[[nodiscard]] consteval bool castable(From from, To to) +{ + return detail::convertible_impl(from, to) >= detail::specs_convertible_result::cast; +} + +namespace detail { + +template + requires requires(Q q) { get_kind(q); } +using to_kind = std::remove_const_t; + +#ifdef __cpp_explicit_this_parameter +template +[[nodiscard]] consteval bool defined_as_kind(quantity_spec) +#else +template +[[nodiscard]] consteval bool defined_as_kind(quantity_spec) +#endif +{ + return contains(); +} + +} // namespace detail + +template +[[nodiscard]] consteval auto remove_kind(Q q) +{ + if constexpr (detail::QuantityKindSpec) { + if constexpr (requires { Q::_parent_; }) + return Q::_parent_; + else + return Q::_equation_; + } else + return q; +} + +template +[[nodiscard]] consteval QuantitySpec auto get_kind(Q q) +{ + auto defined_as_kind = [](auto qq) { + if constexpr (requires { detail::defined_as_kind(qq); }) + return detail::defined_as_kind(qq); + else + return false; + }; + + if constexpr (detail::QuantityKindSpec) { + return remove_kind(q); + } else if constexpr (defined_as_kind(q)) { + return q; + } else if constexpr (requires { Q::_parent_; }) { + return get_kind(Q::_parent_); + } else if constexpr (detail::IntermediateDerivedQuantitySpec) { + return detail::expr_map(q); + } else { + // root quantity + return q; + } +} + +[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q) { return q; } + +template +[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(Q1 q1, Q2 q2) + requires(implicitly_convertible(get_kind(q1), get_kind(q2)) || implicitly_convertible(get_kind(q2), get_kind(q1))) +{ + using QQ1 = std::remove_const_t; + using QQ2 = std::remove_const_t; + if constexpr (is_same_v) + return q1; + else if constexpr (detail::DerivedFromQuantityKindSpecOf) + return remove_kind(q1); + else if constexpr (detail::DerivedFromQuantityKindSpecOf) + return remove_kind(q2); + else if constexpr ((detail::QuantityKindSpec && !detail::QuantityKindSpec) || + (detail::IntermediateDerivedQuantitySpec && detail::NamedQuantitySpec && + implicitly_convertible(q1, q2))) + return q2; + else if constexpr ((!detail::QuantityKindSpec && detail::QuantityKindSpec) || + (detail::NamedQuantitySpec && detail::IntermediateDerivedQuantitySpec && + implicitly_convertible(q2, q1))) + return q1; + else if constexpr (detail::have_common_base(q1, q2)) + return detail::get_common_base(q1, q2); + else if constexpr (implicitly_convertible(q1, q2)) + return q2; + else if constexpr (implicitly_convertible(q2, q1)) + return q1; + else if constexpr (implicitly_convertible(get_kind(q1), get_kind(q2))) + return get_kind(q2); + else + return get_kind(q1); +} + +[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q1, QuantitySpec auto q2, + QuantitySpec auto q3, QuantitySpec auto... rest) + requires requires { common_quantity_spec(common_quantity_spec(q1, q2), q3, rest...); } +{ + return common_quantity_spec(common_quantity_spec(q1, q2), q3, rest...); +} + +} // namespace mp_units diff --git a/src/core/include/mp-units/reference.h b/src/core/include/mp-units/reference.h new file mode 100644 index 00000000..14ed6a6d --- /dev/null +++ b/src/core/include/mp-units/reference.h @@ -0,0 +1,219 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units { + +template + requires quantity>::_rep_safe_constructible_ +[[nodiscard]] constexpr quantity> make_quantity(Rep&& v); + +[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u) +{ + return detail::get_associated_quantity(u); +} + +/** + * @brief Quantity reference type + * + * Quantity reference describes all the properties of a quantity besides its + * representation type. + * + * In most cases this class template is not explicitly instantiated by the user. + * It is implicitly instantiated by the library's framework while binding a quantity + * specification with a compatible unit. + * + * @code{.cpp} + * Reference auto kmph = isq::speed[km / h]; + * QuantityOf auto speed = 90 * kmph; + * @endcode + * + * The following syntaxes are not allowed: + * `2 / kmph`, `kmph * 3`, `kmph / 4`, `70 * isq::length[km] / isq:time[h]`. + */ +template +struct reference { + template + [[nodiscard]] friend consteval bool operator==(reference, reference) + { + return Q == Q2 && U == U2; + } + + template + [[nodiscard]] friend consteval bool operator==(reference, U2 u2) + { + return Q == get_quantity_spec(u2) && U == u2; + } + + template + [[nodiscard]] friend consteval reference operator*(reference, reference) + { + return {}; + } + + template + [[nodiscard]] friend consteval reference operator*(reference, U2) + { + return {}; + } + + template + [[nodiscard]] friend consteval reference operator*(U1, reference) + { + return {}; + } + + template + [[nodiscard]] friend consteval reference operator/(reference, reference) + { + return {}; + } + + template + [[nodiscard]] friend consteval reference operator/(reference, U2) + { + return {}; + } + + template + [[nodiscard]] friend consteval reference operator/(U1, reference) + { + return {}; + } + + /** + * @brief Computes the value of a reference raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param r Reference being the base of the operation + * + * @return The result of computation + */ + template + requires detail::non_zero + [[nodiscard]] friend consteval reference(Q), pow(U)> pow(reference) + { + return {}; + } + + /** + * @brief Computes the square root of a reference + * + * @param r Reference being the base of the operation + * + * @return The result of computation + */ + [[nodiscard]] friend consteval reference sqrt(reference) { return {}; } + + /** + * @brief Computes the cubic root of a reference + * + * @param r Reference being the base of the operation + * + * @return The result of computation + */ + [[nodiscard]] friend consteval reference cbrt(reference) { return {}; } + + template + [[nodiscard]] friend consteval bool convertible(reference, reference) + { + return implicitly_convertible(Q, Q2) && convertible(U, U2); + } + + template + [[nodiscard]] friend consteval bool convertible(reference, U2 u2) + { + return implicitly_convertible(Q, get_quantity_spec(u2)) && convertible(U, u2); + } + + template + [[nodiscard]] friend consteval bool convertible(U1 u1, reference) + { + return implicitly_convertible(get_quantity_spec(u1), Q) && convertible(u1, U); + } +}; + +template Rep> +class quantity; + +template + requires quantity>::_rep_safe_constructible_ +[[nodiscard]] constexpr quantity> operator*(Rep&& lhs, R) +{ + return make_quantity(std::forward(lhs)); +} + +void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete; + +[[nodiscard]] consteval AssociatedUnit auto common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires requires { + { + common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), get_quantity_spec(rest)...) + } -> QuantitySpec; + { + common_unit(u1, u2, rest...) + } -> AssociatedUnit; + } +{ + return common_unit(u1, u2, rest...); +} + +template +[[nodiscard]] consteval Reference auto common_reference(R1 r1, R2 r2, Rest... rest) + requires(!(AssociatedUnit && AssociatedUnit && (... && AssociatedUnit))) && requires { + { + common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), get_quantity_spec(rest)...) + } -> QuantitySpec; + { + common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...) + } -> Unit; + } +{ + return reference{}; +} + +namespace detail { + +template +[[nodiscard]] consteval std::remove_const_t clone_reference_with(From) +{ + return {}; +} + +template +[[nodiscard]] consteval reference clone_reference_with(reference) +{ + return {}; +} + +} // namespace detail + +} // namespace mp_units diff --git a/src/core/include/mp-units/system_reference.h b/src/core/include/mp-units/system_reference.h new file mode 100644 index 00000000..32568569 --- /dev/null +++ b/src/core/include/mp-units/system_reference.h @@ -0,0 +1,72 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units { + +/** + * @brief System-specific reference + * + * This type is used in rare cases where more than one base quantity in a specific + * system of units uses the same unit. For example in a hypothetical system of natural units + * where constant for speed of light `c = 1`, length and time could be measured in seconds. + * In such cases `system_reference` has to be used to explicitly express such a binding. + * + * For example: + * + * @code{.cpp} + * // hypothetical natural system of units for c=1 + * + * inline constexpr struct second : named_unit<"s"> {} second; + * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; + * inline constexpr struct gram : named_unit<"g"> {} gram; + * inline constexpr struct kilogram : decltype(si::kilo) {} kilogram; + * + * inline constexpr struct time : system_reference {} time; + * inline constexpr struct length : system_reference {} length; + * inline constexpr struct speed : system_reference {} speed; + * inline constexpr struct force : system_reference {} force; + * @endcode + * + * @tparam Q quantity for which a unit is being assigned + * @tparam CoU coherent unit for a quantity in this system + */ +template + requires(!AssociatedUnit>) || (CoU == one) +struct system_reference { + static constexpr auto quantity_spec = Q; + static constexpr auto coherent_unit = CoU; + + template + requires(convertible(coherent_unit, U{})) + [[nodiscard]] constexpr reference operator[](U) const + { + return {}; + } +}; + +} // namespace mp_units diff --git a/src/core/include/mp-units/unit.h b/src/core/include/mp-units/unit.h new file mode 100644 index 00000000..ca433c39 --- /dev/null +++ b/src/core/include/mp-units/unit.h @@ -0,0 +1,817 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mp_units { + +/** + * @brief Unit being a scaled version of another unit + * + * @tparam M magnitude describing the scale factor + * @tparam U reference unit being scaled + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the unit arithmetic equation provided by the user. + */ +template +struct scaled_unit { + static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M; + static constexpr U reference_unit{}; +}; + +namespace detail { + +template +inline constexpr bool is_specialization_of_scaled_unit = false; + +template +inline constexpr bool is_specialization_of_scaled_unit> = true; + +} // namespace detail + +/** + * @brief A named unit + * + * Defines a unit with a special name. It may be used to provide a base unit in the system + * of units (i.e. `metre`) or a name assigned to another scaled or derived unit + * (i.e. `hour`, `joule`). + * Most of the named units may be composed with a prefix to create a `prefixed_unit`. + * + * For example: + * + * @code{.cpp} + * inline constexpr struct second : named_unit<"s", time> {} second; + * inline constexpr struct metre : named_unit<"m", length> {} metre; + * inline constexpr struct hertz : named_unit<"Hz", 1 / second> {} hertz; + * inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; + * inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; + * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; + * @endcode + * + * @note A common convention in this library is to assign the same name for a type and an object of this type. + * Besides defining them user never works with the unit types in the source code. All operations + * are done on the objects. Contrarily, the unit types are the only one visible in the compilation + * errors. Having them of the same names improves user experience and somehow blurs those separate domains. + * + * @tparam Symbol a short text representation of the unit + */ +template +struct named_unit; + +/** + * @brief Specialization for unit of a specified base quantity + * + * Associates a unit with a specified base quantity. + * For example `si::metre` is a unit to measure `isq::length` in the SI system. + * + * @note This is the preferred way to define a measurement unit for a specific base quantity. + * + * @note It does not have to (or sometimes even can't) be a proper system's base unit. For example + * a base unit of mass in the SI is `si::kilogram` but here you are about to provide an `si::gram` + * and it will work just fine as those two are convertible to each other. A similar case would be + * the `cgs::centimetre` that is a base unit for `isq::length` in the CGS system. + * + * @tparam Symbol a short text representation of the unit + * @tparam QuantitySpec a specification of a base quantity to be measured with this unit + */ +template + requires(!Symbol.empty()) && detail::BaseDimension> +struct named_unit { + static constexpr auto symbol = Symbol; ///< Unique base unit identifier + static constexpr auto quantity_spec = QS; +}; + +/** + * @brief Specialization for a unit that can be reused by several base quantities + * + * This specialization is used in rare cases where more than one base quantity in a specific + * system of units uses the same unit. For example in a hypothetical system of natural units + * where constant for speed of light `c = 1`, length and time could be measured in seconds. + * In such cases `system_reference` has to be used to explicitly express such a binding. + * + * @tparam Symbol a short text representation of the unit + */ +template + requires(!Symbol.empty()) +struct named_unit { + static constexpr auto symbol = Symbol; ///< Unique base unit identifier +}; + +/** + * @brief Specialization for a unit with special name + * + * Allows assigning a special name to another scaled or derived unit (i.e. `hour`, `joule`). + * + * @tparam Symbol a short text representation of the unit + * @tparam Unit a unit for which we provide a special name + */ +template + requires(!Symbol.empty()) +struct named_unit : std::remove_const_t { + static constexpr auto symbol = Symbol; ///< Unique unit identifier +}; + +/** + * @brief Specialization for a unit with special name valid only for a specific quantity + * + * The same as the above but additionally limits the usage of this unit to provided quantities. + * + * @tparam Symbol a short text representation of the unit + * @tparam Unit a unit for which we provide a special name + * @tparam QuantitySpec a specification of a quantity to be measured with this unit + */ +template + requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension) +struct named_unit : std::remove_const_t { + static constexpr auto symbol = Symbol; ///< Unique unit identifier + static constexpr auto quantity_spec = QS; +}; + +/** + * @brief A prefixed unit + * + * Defines a new unit that is a scaled version of another unit with the scaling + * factor specified by a predefined prefix. + * + * For example: + * + * @code{.cpp} + * template + * struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + * + * template + * inline constexpr kilo_ kilo; + * + * inline constexpr struct kilogram : decltype(si::kilo) {} kilogram; + * @endcode + * + * @tparam Symbol a prefix text to prepend to a unit symbol + * @tparam M scaling factor of the prefix + * @tparam U a named unit to be prefixed + */ +template + requires(!Symbol.empty()) +struct prefixed_unit : std::remove_const_t { + static constexpr auto symbol = Symbol + U.symbol; +}; + +namespace detail { + +template +struct is_one : std::false_type {}; + +} // namespace detail + +/** + * @brief Measurement unit for a derived quantity + * + * Derived units are defined as products of powers of the base units. + * + * Instead of using a raw list of exponents this library decided to use expression template syntax to make types + * more digestable for the user. The positive exponents are ordered first and all negative exponents are put as a list + * into the `per<...>` class template. If a power of exponent is different than `1` the unit type is enclosed in + * `power` class template. Otherwise, it is just put directly in the list without any wrapper. There + * is also one special case. In case all of the exponents are negative then the `one` being a coherent unit of + * a dimensionless quantity is put in the front to increase the readability. + * + * For example: + * + * @code{.cpp} + * static_assert(is_of_type<1 / second, derived_unit>>); + * static_assert(is_of_type<1 / (1 / second), second>); + * static_assert(is_of_type); + * static_assert(is_of_type>>); + * static_assert(is_of_type>); + * static_assert(is_of_type>>); + * static_assert(is_of_type>>>); + * static_assert(is_of_type>>); + * @endcode + * + * Every unit in the library has its internal canonical representation being the list of exponents of named base units + * (with the exception of `kilogram` which is represented as `gram` here) and a scaling ratio represented with a + * magnitude. + * + * Two units are deemed convertible if their canonical version has units of the same type. + * Two units are equivalent when they are convertible and their canonical versions have the same scaling ratios. + * + * The above means that: + * - `1/s` and `Hz` are both convertible and equal + * - `m` and `km` are convertible but not equal + * - `m` and `m²` ane not convertible and not equal + * + * @note This also means that units like `hertz` and `becquerel` are also considered convertible and equal. + * + * @tparam Us a parameter pack consisting tokens allowed in the unit specification + * (units, `power`, `per<...>`) + * + * @note User should not instantiate this type! It is not exported from the C++ module. The library will + * instantiate this type automatically based on the unit arithmetic equation provided by the user. + */ +template +struct derived_unit : detail::expr_fractions {}; + +/** + * @brief Unit one + * + * Unit of a dimensionless quantity. + */ +// clang-format off +inline constexpr struct one : derived_unit<> {} one; +// clang-format on + +namespace detail { + +template<> +struct is_one : std::true_type {}; + +/** + * @brief A canonical representation of a unit + * + * A canonical representation of a unit consists of a `reference_unit` and its scaling + * factor represented by the magnitude `mag`. + * + * `reference_unit` is a unit (possibly derived one) that consists only named base units. + * All of the intermediate derived units are extracted, prefixes and magnitudes of scaled + * units are stripped from them and accounted in the `mag`. + * + * All units having the same canonical unit are deemed equal. + * All units having the same `reference_unit` are convertible (their `mag` may differ + * and is the subject of conversion). + * + * @tparam U a unit to use as a `reference_unit` + * @tparam M a Magnitude representing an absolute scaling factor of this unit + */ +template +struct canonical_unit { + M mag; + U reference_unit; +}; + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const named_unit&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit&); + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit&) +{ + auto base = get_canonical_unit_impl(U{}, U{}); + return canonical_unit{M * base.mag, base.reference_unit}; +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&) +{ + return canonical_unit{mag<1>, t}; +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit&) +{ + return canonical_unit{mag<1>, t}; +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const named_unit&) +{ + return get_canonical_unit_impl(U, U); +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(const power&, const type_list&) +{ + auto mag = (mp_units::mag<1> * ... * pow(get_canonical_unit_impl(Us{}, Us{}).mag)); + auto u = (one * ... * pow(get_canonical_unit_impl(Us{}, Us{}).reference_unit)); + return canonical_unit{mag, u}; +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power&) +{ + auto base = get_canonical_unit_impl(F{}, F{}); + if constexpr (requires { typename decltype(base.reference_unit)::_num_; }) { + auto num = get_canonical_unit_impl(power{}, typename decltype(base.reference_unit)::_num_{}); + auto den = get_canonical_unit_impl(power{}, typename decltype(base.reference_unit)::_den_{}); + return canonical_unit{pow(base.mag) * num.mag / den.mag, num.reference_unit / den.reference_unit}; + } else { + return canonical_unit{pow(base.mag), + derived_unit, Num, Den...>>{}}; + } +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(const type_list&) +{ + auto mag = (mp_units::mag<1> * ... * get_canonical_unit_impl(Us{}, Us{}).mag); + auto u = (one * ... * get_canonical_unit_impl(Us{}, Us{}).reference_unit); + return canonical_unit{mag, u}; +} + +template +[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit&) +{ + auto num = get_canonical_unit_impl(typename derived_unit::_num_{}); + auto den = get_canonical_unit_impl(typename derived_unit::_den_{}); + return canonical_unit{num.mag / den.mag, num.reference_unit / den.reference_unit}; +} + +[[nodiscard]] consteval auto get_canonical_unit(Unit auto u) { return get_canonical_unit_impl(u, u); } + +template +[[nodiscard]] consteval bool less(Lhs, Rhs) +{ + if constexpr (requires { + Lhs::symbol; + Rhs::symbol; + }) + // prefer symbols comparison if possible as it gives typically better results + // i.e. it puts upper case in from so `N m` is correct + return Lhs::symbol < Rhs::symbol; + else + return type_name() < type_name(); +} + + +// TODO What if the same unit will have different types (i.e. user will inherit its own type from `metre`)? +// Is there a better way to sort units here? Some of them may not have symbol at all (like all units of +// dimensionless quantities). +template +struct unit_less : std::bool_constant {}; + +template +using type_list_of_unit_less = expr_less; + +} // namespace detail + + +// Operators + +/** + * Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned. + */ +template +[[nodiscard]] consteval Unit auto operator*(M mag, const U u) +{ + if constexpr (mag == mp_units::mag<1>) + return u; + else + return scaled_unit{}; +} + +[[nodiscard]] consteval Unit auto operator*(Unit auto, Magnitude auto) = delete; + +/** + * `scaled_unit` specializations have priority in this operation. This means that the library framework + * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed + * to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation. + */ +template +[[nodiscard]] consteval Unit auto operator*(Lhs lhs, Rhs rhs) +{ + if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) + return (Lhs::mag * Rhs::mag) * (Lhs::reference_unit * Rhs::reference_unit); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Lhs::mag * (Lhs::reference_unit * rhs); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Rhs::mag * (lhs * Rhs::reference_unit); + else + return detail::expr_multiply(lhs, rhs); +} + +/** + * `scaled_unit` specializations have priority in this operation. This means that the library framework + * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed + * to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation. + */ +template +[[nodiscard]] consteval Unit auto operator/(Lhs lhs, Rhs rhs) +{ + if constexpr (detail::is_specialization_of_scaled_unit && detail::is_specialization_of_scaled_unit) + return (Lhs::mag / Rhs::mag) * (Lhs::reference_unit / Rhs::reference_unit); + else if constexpr (detail::is_specialization_of_scaled_unit) + return Lhs::mag * (Lhs::reference_unit / rhs); + else if constexpr (detail::is_specialization_of_scaled_unit) + return mag<1> / Rhs::mag * (lhs / Rhs::reference_unit); + else + return detail::expr_divide(lhs, rhs); +} + +[[nodiscard]] consteval Unit auto operator/(int value, Unit auto u) +{ + gsl_Expects(value == 1); + return detail::expr_invert(u); +} + +[[nodiscard]] consteval Unit auto operator/(Unit auto, int) = delete; + +namespace detail { + +[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(...) { return false; } + +template +[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const named_unit&, + const named_unit&) +{ + return true; +} + +template +[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const power&, const power&) +{ + return have_same_canonical_reference_unit_impl(F1{}, F2{}); +} + +template + requires(sizeof...(Us1) == sizeof...(Us2)) +[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const type_list&, const type_list&) +{ + return (... && have_same_canonical_reference_unit_impl(Us1{}, Us2{})); +} + +template +[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const derived_unit&, + const derived_unit&) +{ + return have_same_canonical_reference_unit_impl(typename derived_unit::_num_{}, + typename derived_unit::_num_{}) && + have_same_canonical_reference_unit_impl(typename derived_unit::_den_{}, + typename derived_unit::_den_{}); +} + +[[nodiscard]] consteval bool have_same_canonical_reference_unit(Unit auto u1, Unit auto u2) +{ + auto canonical_lhs = detail::get_canonical_unit(u1); + auto canonical_rhs = detail::get_canonical_unit(u2); + return have_same_canonical_reference_unit_impl(canonical_lhs.reference_unit, canonical_rhs.reference_unit); +} + +} // namespace detail + + +[[nodiscard]] consteval bool operator==(Unit auto lhs, Unit auto rhs) +{ + auto canonical_lhs = detail::get_canonical_unit(lhs); + auto canonical_rhs = detail::get_canonical_unit(rhs); + return detail::have_same_canonical_reference_unit(canonical_lhs.reference_unit, canonical_rhs.reference_unit) && + canonical_lhs.mag == canonical_rhs.mag; +} + +namespace detail { + +template +inline constexpr bool is_specialization_of_derived_unit = false; + +template +inline constexpr bool is_specialization_of_derived_unit> = true; + +} // namespace detail + +/** + * @brief Computes the value of a unit raised to the `Num/Den` power + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param u Unit being the base of the operation + * + * @return Unit The result of computation + */ +template + requires detail::non_zero +[[nodiscard]] consteval Unit auto pow(U u) +{ + if constexpr (Num == 0 || is_same_v) + return one; + else if constexpr (ratio{Num, Den} == 1) + return u; + else if constexpr (detail::is_specialization_of_scaled_unit) + return scaled_unit(U::mag), std::remove_const_t(U::reference_unit))>>{}; + else if constexpr (detail::is_specialization_of_derived_unit) + return detail::expr_pow(u); + else if constexpr (Den == 1) + return derived_unit>{}; + else + return derived_unit>{}; +} + +/** + * @brief Computes the square root of a unit + * + * @param u Unit being the base of the operation + * + * @return Unit The result of computation + */ +[[nodiscard]] consteval Unit auto sqrt(Unit auto u) { return pow<1, 2>(u); } + +/** + * @brief Computes the cubic root of a unit + * + * @param u Unit being the base of the operation + * + * @return Unit The result of computation + */ +[[nodiscard]] consteval Unit auto cbrt(Unit auto u) { return pow<1, 3>(u); } + +/** + * @brief Computes the square power of a unit + * + * @param u Unit being the base of the operation + * + * @return Unit The result of computation + */ +[[nodiscard]] consteval Unit auto square(Unit auto u) { return pow<2>(u); } + +/** + * @brief Computes the cubic power of a unit + * + * @param u Unit being the base of the operation + * + * @return Unit The result of computation + */ +[[nodiscard]] consteval Unit auto cubic(Unit auto u) { return pow<3>(u); } + + +// common dimensionless units +// clang-format off +inline constexpr struct percent : named_unit<"%", mag * one> {} percent; +inline constexpr struct per_mille : named_unit * one> {} per_mille; +// clang-format on + + +// convertible_to +[[nodiscard]] consteval bool convertible(Unit auto from, Unit auto to) +{ + return detail::have_same_canonical_reference_unit(from, to); +} + +// Common unit +[[nodiscard]] consteval Unit auto common_unit(Unit auto u) { return u; } + +template +[[nodiscard]] consteval Unit auto common_unit(U1 u1, U2 u2) + requires(detail::have_same_canonical_reference_unit(u1, u2)) +{ + if constexpr (U1{} == U2{}) { + if constexpr (std::derived_from) + return u1; + else if constexpr (std::derived_from) + return u2; + else + // TODO Check if there is a better choice here + return better_type_name(u1, u2); + } else { + constexpr auto canonical_lhs = detail::get_canonical_unit(U1{}); + constexpr auto canonical_rhs = detail::get_canonical_unit(U2{}); + + if constexpr (is_integral(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is_integral(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + constexpr auto cm = detail::common_magnitude(canonical_lhs.mag, canonical_rhs.mag); + return scaled_unit>{}; + } + } +} + +[[nodiscard]] consteval Unit auto common_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest) + requires requires { common_unit(common_unit(u1, u2), u3, rest...); } +{ + return common_unit(common_unit(u1, u2), u3, rest...); +} + + +// get_unit_symbol + +enum class text_encoding { + unicode, // m³; µs + ascii, // m^3; us + default_encoding = unicode +}; + +enum class unit_symbol_solidus { + one_denominator, // m/s; kg m-1 s-1 + always, // m/s; kg/(m s) + never, // m s-1; kg m-1 s-1 + default_denominator = one_denominator +}; + +enum class unit_symbol_separator { + space, // kg m²/s² + dot, // kg⋅m²/s² (valid only for unicode encoding) + default_separator = space +}; + +struct unit_symbol_formatting { + text_encoding encoding = text_encoding::default_encoding; + unit_symbol_solidus solidus = unit_symbol_solidus::default_denominator; + unit_symbol_separator separator = unit_symbol_separator::default_separator; +}; + +namespace detail { + +// TODO Should `basic_symbol_text` be fixed to use `char` type for both encodings? +template Out> +constexpr Out copy(const basic_symbol_text& txt, text_encoding encoding, Out out) +{ + if (encoding == text_encoding::unicode) { + if (is_same_v) + return copy(txt.unicode(), out).out; + else + throw std::invalid_argument("Unicode text can't be copied to CharT output"); + } else { + if (is_same_v) + return copy(txt.ascii(), out).out; + else + throw std::invalid_argument("ASCII text can't be copied to CharT output"); + } +} + +template Out> +constexpr Out print_separator(Out out, unit_symbol_formatting fmt) +{ + if (fmt.separator == unit_symbol_separator::dot) { + if (fmt.encoding != text_encoding::unicode) + throw std::invalid_argument("'unit_symbol_separator::dot' can be only used with 'text_encoding::unicode'"); + copy(std::string_view("⋅"), out); + } else { + *out++ = ' '; + } + return out; +} + +template +[[nodiscard]] consteval bool has_unit_symbol(U) +{ + return !std::derived_from>; +} + +template Out, Unit U> + requires requires { U::symbol; } +constexpr Out unit_symbol_impl(Out out, U, unit_symbol_formatting fmt, bool negative_power) +{ + out = copy(U::symbol, fmt.encoding, out); + if (negative_power) { + constexpr auto txt = superscript<-1>(); + out = copy(txt, fmt.encoding, out); + } + return out; +} + +template Out, auto M, typename U> +constexpr Out unit_symbol_impl(Out out, const scaled_unit& u, unit_symbol_formatting fmt, bool negative_power) +{ + if constexpr (M == mag<1>) { + // no ratio/prefix + return unit_symbol_impl(out, u.reference_unit, fmt, negative_power); + } else { + constexpr auto mag_txt = magnitude_text(); + out = copy(mag_txt, fmt.encoding, out); + + if constexpr (has_unit_symbol(u.reference_unit)) { + *out++ = ' '; + return unit_symbol_impl(out, u.reference_unit, fmt, negative_power); + } else { + return out; + } + } +} + +template Out, typename F, int Num, int... Den> +constexpr auto unit_symbol_impl(Out out, const power&, unit_symbol_formatting fmt, bool negative_power) +{ + out = unit_symbol_impl(out, F{}, fmt, false); // negative power component will be added below if needed + + constexpr ratio r = power::exponent; + if constexpr (r.den != 1) { + // add root part + constexpr auto txt = basic_fixed_string("^(") + regular() + basic_fixed_string("/") + regular() + + basic_fixed_string(")"); + return copy(txt, fmt.encoding, out); + } else if constexpr (r.num != 1) { + // add exponent part + if (negative_power) { + constexpr auto txt = superscript<-r.num>(); + return copy(txt, fmt.encoding, out); + } else { + constexpr auto txt = superscript(); + return copy(txt, fmt.encoding, out); + } + } +} + +template Out, DerivedUnitExpr M> +constexpr Out unit_symbol_impl(Out out, M m, std::size_t Idx, unit_symbol_formatting fmt, bool negative_power) +{ + if (Idx > 0) out = print_separator(out, fmt); + return unit_symbol_impl(out, m, fmt, negative_power); +} + +template Out, DerivedUnitExpr... Ms, std::size_t... Idxs> +constexpr Out unit_symbol_impl(Out out, const type_list&, std::index_sequence, + unit_symbol_formatting fmt, bool negative_power) +{ + return (..., (out = unit_symbol_impl(out, Ms{}, Idxs, fmt, negative_power))); +} + +template Out, DerivedUnitExpr... Nums, DerivedUnitExpr... Dens> +constexpr Out unit_symbol_impl(Out out, const type_list& nums, const type_list& dens, + unit_symbol_formatting fmt) +{ + if constexpr (sizeof...(Nums) == 0 && sizeof...(Dens) == 0) { + // dimensionless quantity + return out; + } else if constexpr (sizeof...(Dens) == 0) { + // no denominator + return unit_symbol_impl(out, nums, std::index_sequence_for(), fmt, false); + } else { + using enum unit_symbol_solidus; + if constexpr (sizeof...(Nums) > 0) { + unit_symbol_impl(out, nums, std::index_sequence_for(), fmt, false); + } + + if (fmt.solidus == always || (fmt.solidus == one_denominator && sizeof...(Dens) == 1)) { + if constexpr (sizeof...(Nums) == 0) *out++ = '1'; + *out++ = '/'; + } else { + out = print_separator(out, fmt); + } + + if (fmt.solidus == always && sizeof...(Dens) > 1) *out++ = '('; + bool negative_power = fmt.solidus == never || (fmt.solidus == one_denominator && sizeof...(Dens) > 1); + out = unit_symbol_impl(out, dens, std::index_sequence_for(), fmt, negative_power); + if (fmt.solidus == always && sizeof...(Dens) > 1) *out++ = ')'; + return out; + } +} + +template Out, typename... Expr> +constexpr Out unit_symbol_impl(Out out, const derived_unit&, unit_symbol_formatting fmt, bool negative_power) +{ + gsl_Expects(negative_power == false); + return unit_symbol_impl(out, typename derived_unit::_num_{}, typename derived_unit::_den_{}, + fmt); +} + +} // namespace detail + + +template Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, unit_symbol_formatting fmt = unit_symbol_formatting{}) +{ + return detail::unit_symbol_impl(out, u, fmt, false); +} + +template +[[nodiscard]] constexpr std::basic_string unit_symbol(U u, unit_symbol_formatting fmt = unit_symbol_formatting{}) +{ + std::basic_string buffer; + unit_symbol_to(std::back_inserter(buffer), u, fmt); + return buffer; +} + +} // namespace mp_units diff --git a/src/core/include/units/base_dimension.h b/src/core/include/units/base_dimension.h deleted file mode 100644 index 5f1d3f48..00000000 --- a/src/core/include/units/base_dimension.h +++ /dev/null @@ -1,66 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -/** - * @brief A dimension of a base quantity - * - * Base quantity is a 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. They are referred to as - * being mutually independent since a base quantity cannot be expressed as a product of powers of the other base - * quantities. - * - * Base unit is a measurement unit that is adopted by convention for a base quantity in a specific system of units. - * - * Pair of Symbol and Unit template parameters form an unique identifier of the base dimension. The same identifiers can - * be multiplied and divided which will result with an adjustment of its factor in an Exponent of a DerivedDimension - * (in case of zero the dimension will be simplified and removed from further analysis of current expresion). In case - * the Symbol is the same but the Unit differs (i.e. mixing SI and CGS length), there is no automatic simplification but - * is possible to force it with a quantity_cast. - * - * @tparam Symbol an unique identifier of the base dimension used to provide dimensional analysis support - * @tparam U a base unit to be used for this base dimension - */ -template -struct base_dimension { - static constexpr auto symbol = Symbol; ///< Unique base dimension identifier - using base_unit = U; ///< Base unit adopted for this dimension - static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = magnitude{}; -}; - -// base_dimension_less -template -struct base_dimension_less : - std::bool_constant<(D1::symbol < D2::symbol) || - (D1::symbol == D2::symbol && D1::base_unit::symbol < D1::base_unit::symbol)> {}; - -} // namespace units diff --git a/src/core/include/units/bits/absolute_magnitude.h b/src/core/include/units/bits/absolute_magnitude.h deleted file mode 100644 index 0216313f..00000000 --- a/src/core/include/units/bits/absolute_magnitude.h +++ /dev/null @@ -1,48 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -namespace units::detail { - -/** - * @brief Calculates the "absolute" magnitude of the derived dimension defined by this list. - * - * "Absolute" magnitudes are not physically observable: only ratios of magnitudes are. For example: if we multiplied - * all magnitudes in the system by the same constant, no meaningful results would change. However, in practice, we need - * to make some global choice for the "absolute" values of magnitudes, so that we can compute their ratios. - * - * The point of this function is to compute the absolute magnitude of a derived dimension, in terms of the absolute - * magnitudes of its constituent dimensions. - */ -template -constexpr Magnitude auto absolute_magnitude(exponent_list) -{ - return (magnitude<>{} * ... * pow(Es::dimension::base_unit::mag)); -} - -} // namespace units::detail diff --git a/src/core/include/units/bits/basic_concepts.h b/src/core/include/units/bits/basic_concepts.h deleted file mode 100644 index 633ef880..00000000 --- a/src/core/include/units/bits/basic_concepts.h +++ /dev/null @@ -1,489 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units { - -// Prefix -namespace detail { - -template -struct prefix_base; - -template -void to_prefix_base(const volatile prefix_base*); - -} // namespace detail - -/** - * @brief A concept matching a symbol prefix - * - * Satisfied by all specializations of `prefix`. - */ -template -concept Prefix = requires(T* t) { detail::to_prefix_base(t); }; - -// Unit -template -struct scaled_unit; - -// TODO: Remove when P1985 accepted -namespace detail { - -template -void to_base_scaled_unit(const volatile scaled_unit*); - -} // namespace detail - -/** - * @brief A concept matching all unit types in the library - * - * Satisfied by all unit types derived from an specialization of :class:`scaled_unit`. - */ -template -concept Unit = requires(T* t) { detail::to_base_scaled_unit(t); }; - -namespace detail { - -template -inline constexpr bool is_named = false; - -} - -template -concept NamedUnit = Unit && detail::is_named; - -template -struct alias_unit; - -// TODO: Remove when P1985 accepted -namespace detail { - -template -void to_base_alias_unit(const volatile alias_unit*); - -} // namespace detail - -template -concept AliasUnit = requires(T* t) { detail::to_base_alias_unit(t); }; - -// BaseDimension -template -struct base_dimension; - -namespace detail { - -template -void to_base_base_dimension(const volatile base_dimension*); - -} // namespace detail - -/** - * @brief A concept matching all base dimensions in the library. - * - * Satisfied by all dimension types derived from an specialization of `base_dimension`. - */ -template -concept BaseDimension = requires(T* t) { detail::to_base_base_dimension(t); }; - -// Exponent -namespace detail { - -template -inline constexpr bool is_exponent = false; - -} // namespace detail - -/** - * @brief A concept matching dimension's exponents. - * - * Satisfied by all specializations of :class:`exponent`. - */ -template -concept Exponent = detail::is_exponent; - -// DerivedDimension -namespace detail { - -template - requires(BaseDimension && ...) -struct derived_dimension_base; - -} // namespace detail - -/** - * @brief A concept matching all derived dimensions in the library. - * - * Satisfied by all dimension types derived from an specialization of `detail::derived_dimension_base`. - */ -template -concept DerivedDimension = is_derived_from_specialization_of; - -// Dimension -/** - * @brief A concept matching all dimensions in the library. - * - * Satisfied by all dimension types for which either `BaseDimension` or `DerivedDimension` is `true`. - */ -template -concept Dimension = BaseDimension || DerivedDimension; - -// UnitOf -namespace detail { - -template -auto default_unit() -{ - if constexpr (BaseDimension) - return typename D::base_unit{}; - else - return typename D::coherent_unit{}; -} - -} // namespace detail - -/** - * @brief Returns a 'default' unit of the dimension - * - * Depending on the dimension type it returns a base unit (for base dimensions) - * or a coherent unit (in case of derived dimensions). - * - * @tparam D Dimension type to get the unit from. - */ -template -using dimension_unit = decltype(detail::default_unit()); -// TODO: replace with the below code when VS catches up -// decltype([]{ -// if constexpr (BaseDimension) -// return TYPENAME D::base_unit{}; -// else -// return TYPENAME D::coherent_unit{}; -// }()); - -/** - * @brief A concept matching only units of a specified dimension. - * - * Satisfied by all unit types that satisfy `Unit`, `Dimension`, and for which - * `U::reference` and @c dimension_unit::reference denote the same unit type. - * - * @tparam U Type to verify. - * @tparam D Dimension type to use for verification. - */ -template -concept UnitOf = Unit && Dimension && std::same_as::reference>; - -// PointOrigin - -template -struct point_origin; - -/** - * @brief A concept matching a point origin - * - * Satisfied by types derived from an specialization of @c point_origin. - */ -template -concept PointOrigin = is_derived_from_specialization_of && requires { - typename T::dimension; - requires Dimension; - typename T::point_origin; - requires std::same_as>; - requires !std::same_as>; -}; - -// RebindablePointOriginFor - -namespace detail { - -template -struct rebind_point_origin_dimension_impl { - using type = typename O::template rebind; -}; - -} // namespace detail - -template -using rebind_point_origin_dimension = typename conditional, std::type_identity, - detail::rebind_point_origin_dimension_impl>::type; - -/** - * @brief A concept predicating the possibility of changing an origin's dimension - * - * Satisfied by point origins whose dimension can be made to be `D`. - */ -template -concept RebindablePointOriginFor = - requires { typename rebind_point_origin_dimension; } && PointOrigin> && - std::same_as::dimension>; - -// Kind -namespace detail { - -template -struct _kind_base; - -} // namespace detail - -template typename Base> -concept kind_impl_ = is_derived_from_specialization_of && requires { - typename T::base_kind; - typename T::dimension; - requires Dimension; -}; - -/** - * @brief A concept matching all kind types - * - * Satisfied by all kind types derived from an specialization of @c kind. - */ -template -concept Kind = kind_impl_ && kind_impl_ && - std::same_as; - -// PointKind -namespace detail { - -template -struct _point_kind_base; - -} // namespace detail - -/** - * @brief A concept matching all point kind types - * - * Satisfied by all point kind types derived from an specialization of @c point_kind. - */ -template -concept PointKind = - kind_impl_ && requires { typename T::origin; } && PointOrigin && - std::same_as && - std::same_as; - -// Reference -namespace detail { - -template -inline constexpr bool is_reference = false; - -} // namespace detail - -/** - * @brief A concept matching all references in the library. - * - * Satisfied by all specializations of @c reference. - */ -template -concept Reference = detail::is_reference; - -// Quantity, QuantityPoint, QuantityKind, QuantityPointKind -namespace detail { - -template -inline constexpr bool is_quantity = false; - -template -inline constexpr bool is_quantity_point = false; - -template -inline constexpr bool is_quantity_kind = false; - -template -inline constexpr bool is_quantity_point_kind = false; - -template -inline constexpr bool is_quantity_like = false; - -template -inline constexpr bool is_quantity_point_like = false; - -} // namespace detail - -/** - * @brief A concept matching all quantities in the library. - * - * Satisfied by all specializations of @c quantity. - */ -template -concept Quantity = detail::is_quantity; - -/** - * @brief A concept matching all quantity points in the library. - * - * Satisfied by all specializations of @c quantity_point. - */ -template -concept QuantityPoint = detail::is_quantity_point; - -/** - * @brief A concept matching all quantity kinds in the library. - * - * Satisfied by all specializations of @c quantity_kind. - */ -template -concept QuantityKind = detail::is_quantity_kind; - -/** - * @brief A concept matching all quantity point kinds in the library. - * - * Satisfied by all specializations of @c quantity_point_kind. - */ -template -concept QuantityPointKind = detail::is_quantity_point_kind; - -// QuantityLike, QuantityPointLike - -/** - * @brief A concept matching all quantity-like types (other than specialization of @c quantity) - * - * Satisfied by all types for which a correct specialization of `quantity_like_traits` - * type trait is provided. - */ -template -concept QuantityLike = detail::is_quantity_like; - -/** - * @brief A concept matching all quantity point-like types (other than specialization of @c quantity_point) - * - * Satisfied by all types for which a correct specialization of `quantity_point_like_traits` - * type trait is provided. - */ -template -concept QuantityPointLike = detail::is_quantity_point_like; - -// Representation - -template -concept common_type_with_ = // exposition only - (std::same_as, std::common_type_t>)&&( - std::constructible_from, T>)&&(std::constructible_from, U>); - -template -concept scalable_number_ = // exposition only - (std::regular_invocable, T, U>)&&(std::regular_invocable, T, U>); - -template -concept castable_number_ = // exposition only - common_type_with_ && scalable_number_>; - -template -concept scalable_ = // exposition only - castable_number_ || - (requires { typename T::value_type; } && castable_number_ && - scalable_number_>) || - (requires { typename T::element_type; } && castable_number_ && - scalable_number_>); - -template -concept scalable_with_ = // exposition only - common_type_with_ && scalable_>; - -// WrappedQuantity -namespace detail { - -template -inline constexpr bool is_wrapped_quantity = false; - -template - requires requires { typename T::value_type; } -inline constexpr bool is_wrapped_quantity = - Quantity || QuantityLike || - is_wrapped_quantity; - -template - requires requires { typename T::element_type; } -inline constexpr bool is_wrapped_quantity = - Quantity || QuantityLike || - is_wrapped_quantity; - -template - requires requires { typename T::quantity_type; } -inline constexpr bool is_wrapped_quantity = Quantity; - -} // namespace detail - -/** - * @brief A concept matching types that wrap quantity objects. - * - * Satisfied by all wrapper types that satisfy `Quantity` or - * `Quantity` recursively - * (i.e. `std::optional>`). - */ -template -concept wrapped_quantity_ = // exposition only - detail::is_wrapped_quantity; - -/** - * @brief A concept matching non-Quantity types. - * - * Satisfied by types that satisfy `(!Quantity) && (!WrappedQuantity) && std::regular`. - */ -template -concept Representation = (!Quantity)&&(!QuantityLike)&&(!wrapped_quantity_)&&std::regular && scalable_; - -namespace detail { - -template - requires requires(T q) { - typename quantity_like_traits::dimension; - typename quantity_like_traits::unit; - typename quantity_like_traits::rep; - requires Dimension::dimension>; - requires Unit::unit>; - requires Representation::rep>; - { - quantity_like_traits::number(q) - } -> std::convertible_to::rep>; - } -inline constexpr bool is_quantity_like = true; - -template - requires requires(T q) { - typename quantity_point_like_traits::dimension; - typename quantity_point_like_traits::unit; - typename quantity_point_like_traits::rep; - requires Dimension::dimension>; - requires Unit::unit>; - requires Representation::rep>; - { - quantity_point_like_traits::relative(q) - } -> QuantityLike; - } -inline constexpr bool is_quantity_point_like = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/bits/common_type.h b/src/core/include/units/bits/common_type.h deleted file mode 100644 index 2b674adb..00000000 --- a/src/core/include/units/bits/common_type.h +++ /dev/null @@ -1,125 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units { - -template U> -struct reference; - -template U, Representation Rep> -class quantity; - -template U, Representation Rep> -class quantity_point; - -template U, Representation Rep> -class quantity_kind; - -template U, Representation Rep> -class quantity_point_kind; - -namespace detail { - -template -struct common_quantity_reference_impl; - -template -struct common_quantity_reference_impl, reference> { - using type = reference; -}; - -template -struct common_quantity_reference_impl, reference> { - using type = reference>; -}; - -template - requires(same_unit_reference, dimension_unit>::value) -struct common_quantity_reference_impl, reference> { - using type = reference>; -}; - -template -struct common_quantity_reference_impl, reference> { - static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = common_magnitude(reference::mag, - reference::mag); - using dimension = conditional, D2, D1>; - using unit = downcast_unit; - using type = reference; -}; - -template Q2> -using common_quantity_reference = - TYPENAME detail::common_quantity_reference_impl, - std::remove_const_t>::type; - -} // namespace detail -} // namespace units - -namespace std { - -template Q2> - requires requires { typename common_type_t; } -struct common_type { -private: - using ref = units::detail::common_quantity_reference; -public: - using type = - units::quantity>; -}; - -template QP2> - requires requires { typename common_type_t; } -struct common_type { - using type = - units::quantity_point::dimension>, - typename common_type_t::unit, - typename common_type_t::rep>; -}; - -template QK2> - requires requires { typename common_type_t; } -struct common_type { - using type = - units::quantity_kind::unit, - typename common_type_t::rep>; -}; - -template QPK2> - requires requires { typename common_type_t; } -struct common_type { - using type = units::quantity_point_kind< - typename QPK1::point_kind_type, - typename common_type_t::unit, - typename common_type_t::rep>; -}; - -} // namespace std diff --git a/src/core/include/units/bits/constexpr_math.h b/src/core/include/units/bits/constexpr_math.h deleted file mode 100644 index c675579b..00000000 --- a/src/core/include/units/bits/constexpr_math.h +++ /dev/null @@ -1,244 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -namespace units::detail { - -struct decimal_fp { - double significant; - std::intmax_t exponent; -}; - -[[nodiscard]] constexpr decimal_fp to_decimal(double v) noexcept -{ - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL - if (v == 0) { - return {.significant = 0.0, .exponent = 0}; - } - UNITS_DIAGNOSTIC_POP - - double significant = abs(v); - std::intmax_t exponent = 0; - - while (significant < 1) { - significant *= 10.0; - --exponent; - } - - while (significant >= 10) { - significant /= 10.0; - ++exponent; - } - - if (v < 0) { - significant = -significant; - } - - return {.significant = significant, .exponent = exponent}; -} - -/* approximate natural log as https://math.stackexchange.com/a/977836 - far slower than std::log but works at compile time with similar accuracy - */ -[[nodiscard]] constexpr double constexpr_log(double v) noexcept -{ - gsl_Expects(v > 0); - - // lookup table to speed up convergence for all significant values - // significant values of 7 and greater benefit mostly as they now converge in 5 terms compared to O(10)-O(100) - // required without the table - // - // using python: - // >>> import math - // >>> for i in range(1, 100): - // ... print(f"/* log({i:>2d}) = */ {math.log(i):.16f},") - constexpr std::array log_table{ - /* log( 1) = */ 0.0000000000000000, - /* log( 2) = */ 0.6931471805599453, - /* log( 3) = */ 1.0986122886681098, - /* log( 4) = */ 1.3862943611198906, - /* log( 5) = */ 1.6094379124341003, - /* log( 6) = */ 1.7917594692280550, - /* log( 7) = */ 1.9459101490553132, - /* log( 8) = */ 2.0794415416798357, - /* log( 9) = */ 2.1972245773362196, - /* log(10) = */ 2.3025850929940459, - /* log(11) = */ 2.3978952727983707, - /* log(12) = */ 2.4849066497880004, - /* log(13) = */ 2.5649493574615367, - /* log(14) = */ 2.6390573296152584, - /* log(15) = */ 2.7080502011022101, - /* log(16) = */ 2.7725887222397811, - /* log(17) = */ 2.8332133440562162, - /* log(18) = */ 2.8903717578961645, - /* log(19) = */ 2.9444389791664403, - /* log(20) = */ 2.9957322735539909, - /* log(21) = */ 3.0445224377234230, - /* log(22) = */ 3.0910424533583161, - /* log(23) = */ 3.1354942159291497, - /* log(24) = */ 3.1780538303479458, - /* log(25) = */ 3.2188758248682006, - /* log(26) = */ 3.2580965380214821, - /* log(27) = */ 3.2958368660043291, - /* log(28) = */ 3.3322045101752038, - /* log(29) = */ 3.3672958299864741, - /* log(30) = */ 3.4011973816621555, - /* log(31) = */ 3.4339872044851463, - /* log(32) = */ 3.4657359027997265, - /* log(33) = */ 3.4965075614664802, - /* log(34) = */ 3.5263605246161616, - /* log(35) = */ 3.5553480614894135, - /* log(36) = */ 3.5835189384561099, - /* log(37) = */ 3.6109179126442243, - /* log(38) = */ 3.6375861597263857, - /* log(39) = */ 3.6635616461296463, - /* log(40) = */ 3.6888794541139363, - /* log(41) = */ 3.7135720667043080, - /* log(42) = */ 3.7376696182833684, - /* log(43) = */ 3.7612001156935624, - /* log(44) = */ 3.7841896339182610, - /* log(45) = */ 3.8066624897703196, - /* log(46) = */ 3.8286413964890951, - /* log(47) = */ 3.8501476017100584, - /* log(48) = */ 3.8712010109078911, - /* log(49) = */ 3.8918202981106265, - /* log(50) = */ 3.9120230054281460, - /* log(51) = */ 3.9318256327243257, - /* log(52) = */ 3.9512437185814275, - /* log(53) = */ 3.9702919135521220, - /* log(54) = */ 3.9889840465642745, - /* log(55) = */ 4.0073331852324712, - /* log(56) = */ 4.0253516907351496, - /* log(57) = */ 4.0430512678345503, - /* log(58) = */ 4.0604430105464191, - /* log(59) = */ 4.0775374439057197, - /* log(60) = */ 4.0943445622221004, - /* log(61) = */ 4.1108738641733114, - /* log(62) = */ 4.1271343850450917, - /* log(63) = */ 4.1431347263915326, - /* log(64) = */ 4.1588830833596715, - /* log(65) = */ 4.1743872698956368, - /* log(66) = */ 4.1896547420264252, - /* log(67) = */ 4.2046926193909657, - /* log(68) = */ 4.2195077051761070, - /* log(69) = */ 4.2341065045972597, - /* log(70) = */ 4.2484952420493594, - /* log(71) = */ 4.2626798770413155, - /* log(72) = */ 4.2766661190160553, - /* log(73) = */ 4.2904594411483910, - /* log(74) = */ 4.3040650932041702, - /* log(75) = */ 4.3174881135363101, - /* log(76) = */ 4.3307333402863311, - /* log(77) = */ 4.3438054218536841, - /* log(78) = */ 4.3567088266895917, - /* log(79) = */ 4.3694478524670215, - /* log(80) = */ 4.3820266346738812, - /* log(81) = */ 4.3944491546724391, - /* log(82) = */ 4.4067192472642533, - /* log(83) = */ 4.4188406077965983, - /* log(84) = */ 4.4308167988433134, - /* log(85) = */ 4.4426512564903167, - /* log(86) = */ 4.4543472962535073, - /* log(87) = */ 4.4659081186545837, - /* log(88) = */ 4.4773368144782069, - /* log(89) = */ 4.4886363697321396, - /* log(90) = */ 4.4998096703302650, - /* log(91) = */ 4.5108595065168497, - /* log(92) = */ 4.5217885770490405, - /* log(93) = */ 4.5325994931532563, - /* log(94) = */ 4.5432947822700038, - /* log(95) = */ 4.5538768916005408, - /* log(96) = */ 4.5643481914678361, - /* log(97) = */ 4.5747109785033828, - /* log(98) = */ 4.5849674786705723, - /* log(99) = */ 4.5951198501345898, - }; - decimal_fp x = to_decimal(v); - - // dividing the significant by nearest lower value in [1.0, 1.1, 1.2, ..., 9.9] will greatly improve convergence - x.significant *= 10; - const auto isignificant = static_cast(x.significant); - x.significant /= static_cast(isignificant); - const double result = static_cast(x.exponent - 1) * log_table[9] + log_table[isignificant - 1]; - - // 1.0 <= significant < 1.1 converges rapidly - const double y = (x.significant - 1) / (x.significant + 1); - const double y_squared = y * y; - double sum = 0; - // 5 terms are needed for convergence to machine precision in the worst case scenario - for (int k = 4; k > 0; --k) { - sum = y_squared * (1 / (2 * static_cast(k) + 1) + sum); - } - sum = 2 * y * (1 + sum); // k = 0 term - return result + sum; -} - -/* approximate e^x as Taylor series e^x = 1 + x/1! + x^2/2! + x^3/3! +... where N is the order of the Taylor series - use https://math.stackexchange.com/a/1988927 to improve convergence for large values - - larger Factor values improve convergence for all values but reduce the precision -*/ -template - requires gt_zero -[[nodiscard]] constexpr double constexpr_exp(double v) noexcept -{ - if constexpr (N == 0) { - return 1.0; - } else { - constexpr auto coefficients = []() { - std::array coeffs; - std::size_t factorial = 1; - for (std::size_t i = 0; i < N; ++i) { - factorial *= i + 1; - coeffs[i] = 1.0 / static_cast(factorial); - } - return coeffs; - }(); - - const double x = v / static_cast(Factor); - double result = 0; - for (auto i = static_cast(N - 1); i >= 0; --i) { - result = x * (coefficients[static_cast(i)] + result); - } - - // for factors of power of 2 this should be replaced by log2(Factor) multiplications by the compiler - return pow_impl(1 + result); - } -} - -// default template arguments provide reasonable precision even for fairly large exponents -// see constexpr_exp for template arguments -template -[[nodiscard]] constexpr double constexpr_pow(double v, double exponent) noexcept -{ - const double x = exponent * constexpr_log(v); - return constexpr_exp(x); -} - -} // namespace units::detail diff --git a/src/core/include/units/bits/derived_dimension_base.h b/src/core/include/units/bits/derived_dimension_base.h deleted file mode 100644 index 9284eb0e..00000000 --- a/src/core/include/units/bits/derived_dimension_base.h +++ /dev/null @@ -1,60 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::detail { - -/** - * @brief A dimension of a derived quantity - * - * Expression of the dependence of a quantity on the base quantities (and their base dimensions) 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. - * - * A derived dimension can be formed from multiple exponents (i.e. speed is represented as "exponent, exponent"). It is also possible to form a derived dimension with only one exponent (i.e. frequency is represented as just - * "exponent"). - * - * @note This class template is used by the library engine and should not be directly instantiated by the user. - * - * @tparam Es zero or more exponents of a derived dimension - */ -template - requires(BaseDimension && ...) -struct derived_dimension_base : downcast_base> { - using exponents = exponent_list; -}; - -template -struct to_derived_dimension_base; - -template -struct to_derived_dimension_base> { - using type = derived_dimension_base; -}; - -} // namespace units::detail diff --git a/src/core/include/units/bits/derived_symbol_text.h b/src/core/include/units/bits/derived_symbol_text.h deleted file mode 100644 index 2d358725..00000000 --- a/src/core/include/units/bits/derived_symbol_text.h +++ /dev/null @@ -1,89 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -namespace units::detail { - -template -constexpr auto operator_text() -{ - if constexpr (Idx == 0) { - if constexpr (Divide && NegativeExpCount == 1) { - return basic_fixed_string("1/"); - } else { - return basic_fixed_string(""); - } - } else { - if constexpr (Divide && NegativeExpCount == 1) { - return basic_fixed_string("/"); - } else { - return basic_symbol_text("⋅", " "); - } - } -} - -template -constexpr auto exp_text() -{ - // get calculation operator + symbol - const auto txt = operator_text<(E::num < 0), NegativeExpCount, Idx>() + Symbol; - if constexpr (E::den != 1) { - // add root part - return txt + basic_fixed_string("^(") + regular() + basic_fixed_string("/") + regular() + - basic_fixed_string(")"); - } else if constexpr (E::num != 1) { - // add exponent part - if constexpr (NegativeExpCount > 1) { // no '/' sign here (only negative exponents) - return txt + superscript(); - } else if constexpr (E::num != -1) { // -1 is replaced with '/' sign here - return txt + superscript(); - } else { - return txt; - } - } else { - return txt; - } -} - -template -inline constexpr int negative_exp_count = ((Es::num < 0 ? 1 : 0) + ... + 0); - -template -constexpr auto derived_symbol_text(exponent_list, std::index_sequence) -{ - constexpr auto neg_exp = negative_exp_count; - return (exp_text() + ...); -} - -template -constexpr auto derived_symbol_text() -{ - return derived_symbol_text(typename Dim::recipe(), std::index_sequence_for()); -} - -} // namespace units::detail diff --git a/src/core/include/units/bits/dim_consolidate.h b/src/core/include/units/bits/dim_consolidate.h deleted file mode 100644 index 2590b460..00000000 --- a/src/core/include/units/bits/dim_consolidate.h +++ /dev/null @@ -1,67 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::detail { - -/** - * @brief Consolidates contiguous ranges of exponents of the same dimension - * - * If there is more than one exponent with the same dimension they are aggregated into one exponent by adding - * their exponents. If this accumulation will result with 0, such a dimension is removed from the list. - * - * @tparam D derived dimension to consolidate - */ -template -struct dim_consolidate; - -template<> -struct dim_consolidate> { - using type = exponent_list<>; -}; - -template -struct dim_consolidate> { - using type = exponent_list; -}; - -template -struct dim_consolidate> { - using type = type_list_push_front>::type, E1>; -}; - -template -struct dim_consolidate, exponent, ERest...>> { - using r1 = std::ratio; - using r2 = std::ratio; - using r = std::ratio_add; - using type = conditional>::type, - typename dim_consolidate, ERest...>>::type>; -}; - -} // namespace units::detail diff --git a/src/core/include/units/bits/dim_unpack.h b/src/core/include/units/bits/dim_unpack.h deleted file mode 100644 index ae018f2a..00000000 --- a/src/core/include/units/bits/dim_unpack.h +++ /dev/null @@ -1,59 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::detail { - -/** - * @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions - * - * @tparam Es Exponents of potentially derived dimensions - */ -template -struct dim_unpack; - -template<> -struct dim_unpack<> { - using type = exponent_list<>; -}; - -template -struct dim_unpack, ERest...> { - using type = type_list_push_front::type, exponent>; -}; - -template -struct dim_unpack, ERest...> { - using type = TYPENAME dim_unpack, Num, Den>, ERest...>::type; -}; - -template -struct dim_unpack, Num, Den>, ERest...> { - using type = type_list_push_front::type, exponent_multiply...>; -}; - -} // namespace units::detail diff --git a/src/core/include/units/bits/dimension_op.h b/src/core/include/units/bits/dimension_op.h deleted file mode 100644 index 820fbc82..00000000 --- a/src/core/include/units/bits/dimension_op.h +++ /dev/null @@ -1,208 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace units { - -/** - * @brief Unknown dimension - * - * Sometimes a temporary partial result of a complex calculation may not result in a predefined - * dimension. In such a case an `unknown_dimension` is created with a coherent unit of `unknown_coherent_unit` - * with a magnitude being the absolute one of all the exponents of such a dimension. - * - * @tparam Es the list of exponents of ingredient dimensions - */ -template -struct unknown_dimension : derived_dimension, unknown_coherent_unit, Es...> {}; - -namespace detail { - -template -struct check_unknown { - using type = D; -}; - -// downcast did not find a user predefined type -template -struct check_unknown> { - using type = unknown_dimension; -}; - -template -struct downcast_dimension_impl; - -template -struct downcast_dimension_impl { - using type = D; -}; - -template -struct downcast_dimension_impl { - using type = TYPENAME check_unknown>::type; -}; - -} // namespace detail - -template -using downcast_dimension = TYPENAME detail::downcast_dimension_impl::type; - -// dim_invert -namespace detail { - -template -struct dim_invert_impl; - -template -struct dim_invert_impl { - using type = downcast_dimension>>; -}; - -template -struct dim_invert_impl>> { - using type = D; -}; - -template -struct dim_invert_impl> { - using type = downcast_dimension...>>; -}; - -template -struct dim_invert_impl : dim_invert_impl> {}; - -} // namespace detail - -template -using dim_invert = TYPENAME detail::dim_invert_impl::type; - -// dimension_multiply -namespace detail { - -template -struct to_dimension; - -template -struct to_dimension> { - using type = derived_dimension_base; -}; - -template -struct to_dimension>> { - using type = D; -}; - -/** - * @brief Merges 2 sorted derived dimensions into one units::derived_dimension_base - * - * A result of a dimensional calculation may result with many exponents of the same base dimension orginated - * from different parts of the equation. As the exponents lists of both operands it is enough to merge them - * into one list and consolidate duplicates. Also it is possible that final exponents list will contain only - * one element being a base dimension with exponent 1. In such a case the final dimension should be the base - * dimension itself. - */ -template -using merge_dimension = TYPENAME to_dimension>::type>::type; - -template -struct dimension_multiply_impl; - -template -struct dimension_multiply_impl { - using type = downcast_dimension< - merge_dimension>, derived_dimension_base>>>; -}; - -template -struct dimension_multiply_impl { - using type = - downcast_dimension>, typename D2::downcast_base_type>>; -}; - -template -struct dimension_multiply_impl { - using type = TYPENAME dimension_multiply_impl::type; -}; - -template -struct dimension_multiply_impl { - using type = downcast_dimension>; -}; - -} // namespace detail - -template -using dimension_multiply = TYPENAME detail::dimension_multiply_impl::type; - -template -using dimension_divide = TYPENAME detail::dimension_multiply_impl>::type; - -// dimension_pow -namespace detail { - -template -struct dimension_pow_impl; - -template -struct dimension_pow_impl { - using type = downcast_dimension>>; -}; - -template -struct dimension_pow_impl { - using type = D; -}; - -template -struct dimension_pow_impl>, Num, Den> { - using type = D; -}; - -template -struct dimension_pow_impl { - using type = TYPENAME dimension_pow_impl, Num, Den>::type; -}; - -template -struct dimension_pow_impl, Num, Den> { - using type = downcast_dimension...>>; -}; - -} // namespace detail - -template -using dimension_pow = TYPENAME detail::dimension_pow_impl::type; - -template -using dimension_sqrt = TYPENAME detail::dimension_pow_impl::type; - -} // namespace units diff --git a/src/core/include/units/bits/equivalent.h b/src/core/include/units/bits/equivalent.h deleted file mode 100644 index 2fa174ba..00000000 --- a/src/core/include/units/bits/equivalent.h +++ /dev/null @@ -1,133 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units { - -namespace detail { - -template -struct equivalent_impl : std::false_type {}; - -template -struct equivalent_impl : std::true_type {}; - - -// units - -template -struct equivalent_impl : std::disjunction, std::is_base_of> {}; - - -// dimensions - -template -struct equivalent_impl : - std::conjunction, - same_unit_reference> {}; - -template -struct equivalent_exp : std::false_type {}; - -template -struct equivalent_exp, exponent> : equivalent_impl {}; - -template -struct equivalent_derived_dim : std::false_type {}; - -template - requires(sizeof...(Es1) == sizeof...(Es2)) -struct equivalent_derived_dim, derived_dimension_base> : - std::conjunction...> {}; - -template -struct equivalent_impl : - std::disjunction, std::is_base_of, - equivalent_derived_dim, downcast_base_t>> {}; - - -// additionally accounts for unknown dimensions -template -struct equivalent_unit : - std::disjunction, std::bool_constant::mag == reference::mag>> {}; - -// point origins - -template -concept EquivalentPointOrigins = - RebindablePointOriginFor && RebindablePointOriginFor && - std::same_as> && - std::same_as>; - -template -struct equivalent_impl : - std::bool_constant && - equivalent_impl::value> {}; - - -// (point) kinds - -template -struct equivalent_impl : - std::conjunction, - equivalent_impl> {}; - -template -struct equivalent_impl : - std::conjunction, - equivalent_impl> {}; - - -// quantities, quantity points, quantity (point) kinds - -template -struct equivalent_impl : - std::conjunction< - equivalent_impl, - equivalent_unit> {}; - -template -struct equivalent_impl : - std::conjunction, - equivalent_impl> {}; - -template -struct equivalent_impl : - std::conjunction, - equivalent_impl> {}; - -template -struct equivalent_impl : - std::conjunction, - equivalent_impl> {}; - -} // namespace detail - -template -inline constexpr bool equivalent = detail::equivalent_impl::value; - -} // namespace units diff --git a/src/core/include/units/bits/external/downcasting.h b/src/core/include/units/bits/external/downcasting.h deleted file mode 100644 index 96974644..00000000 --- a/src/core/include/units/bits/external/downcasting.h +++ /dev/null @@ -1,106 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -#ifdef UNITS_DOWNCAST_MODE -#if UNITS_DOWNCAST_MODE < 0 || UNITS_DOWNCAST_MODE > 2 -#error "Invalid UNITS_DOWNCAST_MODE value" -#endif -#else -#define UNITS_DOWNCAST_MODE 1 -#endif - -namespace units { - -template -struct downcast_base { - using downcast_base_type = BaseType; - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND - friend auto downcast_guide(downcast_base); - friend auto downcast_poison_pill(downcast_base); - UNITS_DIAGNOSTIC_POP -}; - -template -concept Downcastable = - requires { typename T::downcast_base_type; } && std::derived_from>; - -template -concept has_downcast_guide = requires(T t) { downcast_guide(t); }; - -template -concept has_downcast_poison_pill = requires(T t) { downcast_poison_pill(t); }; - -template -struct downcast_child : T { - friend auto downcast_guide(typename T::downcast_base) { return std::type_identity(); } -}; - -template -struct downcast_poison : T { - friend auto downcast_poison_pill(typename T::downcast_base) { return true; } -}; - -enum class downcast_mode { - off = 0, // no downcasting at all - on = 1, // downcasting always forced -> compile-time errors in case of duplicated definitions - automatic = 2 // downcasting automatically enabled if no collisions are present -}; - - -template(UNITS_DOWNCAST_MODE)> -struct downcast_dispatch : - std::conditional_t> { -}; -#else - std::conditional_t, downcast_poison, - downcast_child>> { -}; -#endif - -namespace detail { - -template -constexpr auto downcast_impl() -{ - if constexpr (has_downcast_guide> && !has_downcast_poison_pill>) - return decltype(downcast_guide(std::declval>()))(); - else - return std::type_identity(); -} - -} // namespace detail - -template -using downcast = TYPENAME decltype(detail::downcast_impl())::type; - -template -using downcast_base_t = TYPENAME T::downcast_base_type; - -} // namespace units diff --git a/src/core/include/units/bits/quantity_of.h b/src/core/include/units/bits/quantity_of.h deleted file mode 100644 index c8e68fb3..00000000 --- a/src/core/include/units/bits/quantity_of.h +++ /dev/null @@ -1,143 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units { - -// DimensionOfT -#if UNITS_DOWNCAST_MODE == 0 - -namespace detail { - -template typename DimTemplate> -inline constexpr bool same_exponents_of = false; - -template typename DimTemplate> -inline constexpr bool same_exponents_of, DimTemplate> = - requires { - typename DimTemplate, unknown_coherent_unit, typename Es::dimension...>; - } && std::same_as, typename DimTemplate, unknown_coherent_unit, - typename Es::dimension...>::recipe>; - -} // namespace detail - -template typename DimTemplate> -concept EquivalentUnknownDimensionOfT = Dimension && is_derived_from_specialization_of && - detail::same_exponents_of; - -#endif - -/** - * @brief A concept matching all dimensions matching provided dimension class template - * - * Satisfied by all dimensions being the instantiations derived from the provided dimension - * class template. - */ -template typename DimTemplate> -concept DimensionOfT = Dimension && (is_derived_from_specialization_of -#if UNITS_DOWNCAST_MODE == 0 - || EquivalentUnknownDimensionOfT -#endif - ); - -/** - * @brief A concept matching all quantities with provided dimension class template - * - * Satisfied by all quantities with a dimension being the instantiation derived from - * the provided dimension class template. - */ -template typename DimTemplate> -concept QuantityOfT = Quantity && DimensionOfT; - -/** - * @brief A concept matching all quantities with provided dimension - * - * Satisfied by all quantities with a dimension being the instantiation derived from - * the provided dimension type. - */ -template -concept QuantityOf = Quantity && Dimension && equivalent; - -/** - * @brief A concept matching two equivalent quantities - * - * Satisfied by quantities having equivalent dimensions. - */ -template -concept QuantityEquivalentTo = Quantity && QuantityOf; - -/** - * @brief A concept matching all quantity points of the provided origin - * - * Satisfied by all quantity points with an origin equivalent to the provided one. - */ -template -concept QuantityPointOf = QuantityPoint && PointOrigin && equivalent; - -/** - * @brief A concept matching two equivalent quantity points - * - * Satisfied by quantity points having equivalent origins. - */ -template -concept QuantityPointEquivalentTo = QuantityPoint && QuantityPointOf; - -/** - * @brief A concept matching only quantity kinds of a specific kind. - * - * @tparam QK Quantity kind to verify. - * @tparam K Kind type to use for verification. - */ -template -concept QuantityKindOf = QuantityKind && Kind && equivalent; - -/** - * @brief A concept matching two equivalent quantity kinds - * - * Satisfied by quantity kinds having equivalent kinds. - */ -template -concept QuantityKindEquivalentTo = QuantityKind && QuantityKindOf; - -/** - * @brief 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. - */ -template -concept QuantityPointKindOf = QuantityPointKind && PointKind && equivalent; - -/** - * @brief A concept matching two equivalent quantity point kinds - * - * Satisfied by quantity point kinds having equivalent kinds. - */ -template -concept QuantityPointKindEquivalentTo = - QuantityPointKind && QuantityPointKindOf; - -} // namespace units diff --git a/src/core/include/units/bits/ratio_maths.h b/src/core/include/units/bits/ratio_maths.h deleted file mode 100644 index a6cbea4c..00000000 --- a/src/core/include/units/bits/ratio_maths.h +++ /dev/null @@ -1,95 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz, Conor Williams, Oliver Schonrock -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace units::detail { - -template -[[nodiscard]] constexpr T abs(T v) noexcept -{ - return v < 0 ? -v : v; -} - -// Computes the rational gcd of n1/d1 and n2/d2 -[[nodiscard]] constexpr auto gcd_frac(std::intmax_t n1, std::intmax_t d1, std::intmax_t n2, std::intmax_t d2) noexcept -{ - // Short cut for equal ratios - if (n1 == n2 && d1 == d2) { - return std::array{n1, d1}; - } - - // gcd(a/b,c/d) = gcd(a⋅d, c⋅b) / b⋅d - - assert(std::numeric_limits::max() / n1 > d2); - assert(std::numeric_limits::max() / n2 > d1); - - std::intmax_t num = std::gcd(n1 * d2, n2 * d1); - - assert(std::numeric_limits::max() / d1 > d2); - - std::intmax_t den = d1 * d2; - - std::intmax_t gcd = std::gcd(num, den); - - return std::array{num / gcd, den / gcd}; -} - -constexpr void normalize(std::intmax_t& num, std::intmax_t& den) -{ - if (num == 0) { - den = 1; - return; - } - - std::intmax_t gcd = std::gcd(num, den); - num = num * (den < 0 ? -1 : 1) / gcd; - den = detail::abs(den) / gcd; -} - -[[nodiscard]] constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs) -{ - constexpr std::intmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4); - - const std::intmax_t a0 = detail::abs(lhs) % c; - const std::intmax_t a1 = detail::abs(lhs) / c; - const std::intmax_t b0 = detail::abs(rhs) % c; - const std::intmax_t b1 = detail::abs(rhs) / c; - - gsl_Expects(a1 == 0 || b1 == 0); // overflow in multiplication - gsl_Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication - gsl_Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication - gsl_Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication - - return lhs * rhs; -} - -} // namespace units::detail diff --git a/src/core/include/units/bits/unit_text.h b/src/core/include/units/bits/unit_text.h deleted file mode 100644 index db0cf31a..00000000 --- a/src/core/include/units/bits/unit_text.h +++ /dev/null @@ -1,166 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include - -namespace units::detail { - -inline constexpr basic_symbol_text base_multiplier("\u00D7 10", "x 10"); - -template -constexpr auto magnitude_text() -{ - constexpr auto exp10 = extract_power_of_10(M); - - constexpr Magnitude auto base = M / pow(mag<10>()); - constexpr Magnitude auto num = numerator(base); - constexpr Magnitude auto den = denominator(base); - static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); - - constexpr auto num_value = get_value(num); - constexpr auto den_value = get_value(den); - - - if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { - return base_multiplier + superscript(); - } else if constexpr (num_value != 1 || den_value != 1 || exp10 != 0) { - auto txt = basic_fixed_string("[") + regular(); - if constexpr (den_value == 1) { - if constexpr (exp10 == 0) { - return txt + basic_fixed_string("]"); - } else { - return txt + " " + base_multiplier + superscript() + basic_fixed_string("]"); - } - } else { - if constexpr (exp10 == 0) { - return txt + basic_fixed_string("/") + regular() + basic_fixed_string("]"); - } else { - return txt + basic_fixed_string("/") + regular() + " " + base_multiplier + superscript() + - basic_fixed_string("]"); - } - } - } else { - return basic_fixed_string(""); - } -} - -template -constexpr auto prefix_or_magnitude_text() -{ - if constexpr (M == mag<1>()) { - // no ratio/prefix - return basic_fixed_string(""); - } else { - // try to form a prefix - using prefix = downcast>; - - if constexpr (can_be_prefixed && !is_same_v>) { - // print as a prefixed unit - return prefix::symbol; - } else { - // print as a ratio of the coherent unit - constexpr auto txt = magnitude_text(); - if constexpr (SymbolLen > 0 && txt.standard().size() > 0) - return txt + basic_fixed_string(" "); - else - return txt; - } - } -} - -template -constexpr auto derived_dimension_unit_text(exponent_list, std::index_sequence) -{ - return (exp_text::symbol, negative_exp_count, Idxs>() + ... + - basic_symbol_text(basic_fixed_string(""))); -} - -template -constexpr auto derived_dimension_unit_text(exponent_list list) -{ - return derived_dimension_unit_text(list, std::index_sequence_for()); -} - -template -constexpr auto exponent_list_with_named_units(exponent_list); - -template -constexpr auto exponent_list_with_named_units(Exp) -{ - using dim = TYPENAME Exp::dimension; - if constexpr (NamedUnit>) { - return exponent_list(); - } else { - using recipe = TYPENAME dim::recipe; - return exponent_list_with_named_units(recipe()); - } -} - -template -constexpr auto exponent_list_with_named_units(exponent_list) -{ - return type_list_join(); -} - -constexpr auto exponent_list_with_named_units(exponent_list<> empty) { return empty; } - -template -constexpr auto derived_dimension_unit_text() -{ - using recipe = TYPENAME Dim::recipe; - return derived_dimension_unit_text(exponent_list_with_named_units(recipe())); -} - -template -// TODO replace with `inline constexpr bool has_symbol` when MSVC cathes up -concept has_symbol = requires { T::symbol; }; - -template -constexpr auto unit_text() -{ - if constexpr (has_symbol) { - // already has a symbol so print it - return U::symbol; - } else { - // print as a prefix or ratio of a coherent unit - using coherent_unit = dimension_unit; - - constexpr auto symbol_text = []() { - if constexpr (has_symbol) - return coherent_unit::symbol; - else - return derived_dimension_unit_text(); - }(); - - constexpr auto prefix_txt = - prefix_or_magnitude_text(); - return prefix_txt + symbol_text; - } -} - -} // namespace units::detail diff --git a/src/core/include/units/chrono.h b/src/core/include/units/chrono.h deleted file mode 100644 index d7b900a1..00000000 --- a/src/core/include/units/chrono.h +++ /dev/null @@ -1,100 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units { - -template -struct quantity_like_traits> { -private: - static constexpr auto mag = ::units::mag(); -public: - 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(); } -}; - -template -struct clock_origin : point_origin {}; - -template -struct quantity_point_like_traits>> { -private: - static constexpr auto mag = ::units::mag(); -public: - using origin = clock_origin; - using unit = downcast_unit; - using rep = Rep; - [[nodiscard]] static constexpr auto relative(const std::chrono::time_point>& qp) - { - return qp.time_since_epoch(); - } -}; - -namespace detail { - -template -inline constexpr bool is_quantity_point_like>> = true; - -constexpr std::intmax_t pow_10(std::intmax_t v) -{ - gsl_Expects(v > 0); - std::intmax_t res = 1; - for (std::intmax_t i = 0; i < v; i++) res *= 10; - return res; -} - -template -constexpr auto to_std_ratio_impl() -{ - return std::ratio{}; -} - -} // namespace detail - -// TODO ICE below on gcc-11 when `ratio` is used instead of `auto` -template -using to_std_ratio = decltype(detail::to_std_ratio_impl()); - -template -[[nodiscard]] constexpr auto to_std_duration(const quantity& q) -{ - return std::chrono::duration>(q.number()); -} - -template -[[nodiscard]] constexpr auto to_std_time_point(const quantity_point, U, Rep>& qp) -{ - using ret_type = std::chrono::time_point>>; - return ret_type(to_std_duration(qp.relative())); -} - -} // namespace units diff --git a/src/core/include/units/derived_dimension.h b/src/core/include/units/derived_dimension.h deleted file mode 100644 index 82f7b560..00000000 --- a/src/core/include/units/derived_dimension.h +++ /dev/null @@ -1,92 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports - -namespace units { - -namespace detail { - -/** - * @brief Converts user provided derived dimension specification into a valid units::derived_dimension_base definition - * - * User provided definition of a derived dimension may contain the same base dimension repeated more than once on the - * list possibly hidden in other derived units provided by the user. The process here should: - * 1. Extract derived dimensions into exponents of base dimensions. - * 2. Sort the exponents so the same dimensions are placed next to each other. - * 3. Consolidate contiguous range of exponents of the same base dimensions to a one (or possibly zero) exponent for - * this base dimension. - */ -template -using make_dimension = TYPENAME to_derived_dimension_base< - typename dim_consolidate::type, exponent_less>>::type>::type; - -} // namespace detail - -/** - * @brief The list of exponents of dimensions (both base and derived) provided by the user - * - * This is the user's interface to create derived dimensions. Exponents list can contain powers of factors of both - * base and derived dimensions. This is called a "recipe" of the dimension and among others is used to print - * unnamed coherent units of this dimension. - * - * Coherent unit is a 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. - * - * The implementation is responsible for unpacking all of the dimensions into a list containing only base dimensions - * and their factors and putting them to derived_dimension_base class template. - * - * Sometimes units of equivalent quantities in different systems of units do not share the same reference so they - * cannot be easily converted to each other. An example can be a pressure for which a coherent unit in SI is pascal - * and in CGS barye. Those two units are not directly related with each other with some ratio. As they both are - * coherent units of their dimensions, the ratio between them is directly determined by the ratios of base units - * defined in base dimensions end their exponents in the derived dimension recipe. To provide interoperability of - * such quantities of different systems mag is being used. The result of the division of two - * mag of two quantities of equivalent dimensions in two different systems gives a ratio between their - * coherent units. Alternatively, the user would always have to directly define a barye in terms of pascal or vice - * versa. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam U a coherent unit of a derived dimension - * @tparam Es the list of exponents of ingredient dimensions - */ -template -struct derived_dimension : downcast_dispatch> { - using recipe = exponent_list; - using coherent_unit = U; - static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = - detail::absolute_magnitude(typename derived_dimension::exponents()) / U::mag; -}; - -} // namespace units diff --git a/src/core/include/units/exponent.h b/src/core/include/units/exponent.h deleted file mode 100644 index 2f713af2..00000000 --- a/src/core/include/units/exponent.h +++ /dev/null @@ -1,85 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units { - -/** - * @brief A power of factor corresponding to the dimension of a quantity - * - * @tparam Dim component dimension of a derived quantity - * @tparam Num numinator of the factor - * @tparam Den denominator of the factor - */ -template -struct exponent { - using dimension = Dim; - static constexpr std::intmax_t num = Num; - static constexpr std::intmax_t den = Den; -}; - -// is_exponent -namespace detail { - -template -inline constexpr bool is_exponent> = true; - -} // namespace detail - -// exponent_less -template - requires BaseDimension && BaseDimension -struct exponent_less : base_dimension_less {}; - -// exponent_invert -namespace detail { - -template -constexpr exponent exponent_invert_impl(exponent); - -} // namespace detail - -template -using exponent_invert = decltype(detail::exponent_invert_impl(E())); - -// exponent_multiply -namespace detail { - -template -struct exponent_multiply_impl { - static constexpr ratio r = ratio(E::num, E::den) * ratio(Num, Den); - using type = exponent; -}; - -} // namespace detail - -template -using exponent_multiply = TYPENAME detail::exponent_multiply_impl::type; - -template -struct exponent_list {}; - -} // namespace units diff --git a/src/core/include/units/generic/angle.h b/src/core/include/units/generic/angle.h deleted file mode 100644 index b806ce4e..00000000 --- a/src/core/include/units/generic/angle.h +++ /dev/null @@ -1,128 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -struct radian : named_unit {}; -struct revolution : named_scaled_unit() * mag_pi, radian> {}; -struct degree : named_scaled_unit(), revolution> {}; -struct gradian : named_scaled_unit(), revolution> {}; - -template -struct dim_angle : base_dimension<"A", U> {}; - -template -concept Angle = QuantityOfT; - -template> U, Representation Rep = double> -using angle = quantity, U, Rep>; - -template -inline constexpr auto cotes_angle = angle(1); - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// rad -constexpr auto operator"" _q_rad(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angle(static_cast(l)); -} -constexpr auto operator"" _q_rad(long double l) { return angle(l); } - -// rot -constexpr auto operator"" _q_rev(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angle(static_cast(l)); -} -constexpr auto operator"" _q_rev(long double l) { return angle(l); } - -// deg -constexpr auto operator"" _q_deg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angle(static_cast(l)); -} -constexpr auto operator"" _q_deg(long double l) { return angle(l); } - -// grad -constexpr auto operator"" _q_grad(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angle(static_cast(l)); -} -constexpr auto operator"" _q_grad(long double l) { return angle(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace angle_references { - -inline constexpr auto rad = reference, radian>{}; -inline constexpr auto rev = reference, revolution>{}; -inline constexpr auto deg = reference, degree>{}; -inline constexpr auto grad = reference, gradian>{}; - -} // namespace angle_references - -namespace references { - -using namespace angle_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::inline angle { - -template -using rad = units::angle; -template -using rev = units::angle; -template -using deg = units::angle; -template -using grad = units::angle; - -} // namespace units::aliases::inline angle - -#endif // UNITS_NO_ALIASES diff --git a/src/core/include/units/generic/dimensionless.h b/src/core/include/units/generic/dimensionless.h deleted file mode 100644 index 576547e6..00000000 --- a/src/core/include/units/generic/dimensionless.h +++ /dev/null @@ -1,50 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -struct one : derived_unit {}; -struct percent : named_scaled_unit(), one> {}; - -/** - * @brief Dimension one - * - * Dimension for which all the exponents of the factors corresponding to the base - * dimensions are zero. Also commonly named as "dimensionless". - */ -struct dim_one : derived_dimension {}; - -template -concept Dimensionless = QuantityOf; - -template U, Representation Rep = double> -using dimensionless = quantity; - -} // namespace units diff --git a/src/core/include/units/generic/solid_angle.h b/src/core/include/units/generic/solid_angle.h deleted file mode 100644 index eff9d388..00000000 --- a/src/core/include/units/generic/solid_angle.h +++ /dev/null @@ -1,104 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -struct steradian : named_unit {}; - -template -struct dim_solid_angle : derived_dimension, U, exponent, 2>> {}; - -struct square_degree : derived_scaled_unit, degree> {}; - -template -concept SolidAngle = QuantityOfT; - -template> U, Representation Rep = double> -using solid_angle = quantity, U, Rep>; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// sr -constexpr auto operator"" _q_sr(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return solid_angle(static_cast(l)); -} -constexpr auto operator"" _q_sr(long double l) { return solid_angle(l); } - -// deg2 -constexpr auto operator"" _q_deg2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return solid_angle(static_cast(l)); -} -constexpr auto operator"" _q_deg2(long double l) { return solid_angle(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace solid_angle_references { - -inline constexpr auto sr = reference, steradian>{}; -inline constexpr auto deg2 = reference, square_degree>{}; - -} // namespace solid_angle_references - -namespace references { - -using namespace solid_angle_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::inline solid_angle { - -template -using sr = units::solid_angle; - -template -using deg2 = units::solid_angle; - -} // namespace units::aliases::inline solid_angle - -#endif // UNITS_NO_ALIASES diff --git a/src/core/include/units/kind.h b/src/core/include/units/kind.h deleted file mode 100644 index 690dcbd5..00000000 --- a/src/core/include/units/kind.h +++ /dev/null @@ -1,68 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units { - -template -struct dynamic_origin; - -namespace detail { - -template -struct _kind_base : downcast_base<_kind_base> { - using base_kind = K; - using dimension = D; -}; - -template -struct _point_kind_base : downcast_base<_point_kind_base> { - using base_kind = K; - using dimension = typename K::dimension; - using origin = O; -}; - -} // namespace detail - -template - requires Kind>> -using downcast_kind = downcast>; - -template> - requires PointKind>> -using downcast_point_kind = downcast>; - -template -struct kind : downcast_dispatch> {}; - -template - requires std::same_as -struct derived_kind : downcast_dispatch> {}; - -template> -struct point_kind : downcast_dispatch> {}; - -} // namespace units diff --git a/src/core/include/units/math.h b/src/core/include/units/math.h deleted file mode 100644 index cdae6963..00000000 --- a/src/core/include/units/math.h +++ /dev/null @@ -1,397 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include -#include - -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -/** - * @brief Computes the value of a quantity raised to the power `N` - * - * Both the quantity value and its dimension are the base of the operation. - * - * @tparam Num Exponent numerator - * @tparam Den Exponent denominator - * @param q Quantity being the base of the operation - * @return Quantity The result of computation - */ -template - requires detail::non_zero -[[nodiscard]] inline auto pow(const Q& q) noexcept - requires requires { pow(q.number(), 1.0); } || requires { std::pow(q.number(), 1.0); } -{ - using rep = TYPENAME Q::rep; - if constexpr (Num == 0) { - return rep(1); - } else { - using dim = dimension_pow; - using unit = downcast_unit(Q::reference.mag) / dim::mag>; - using std::pow; - return quantity( - static_cast(pow(q.number(), static_cast(Num) / static_cast(Den)))); - } -} - -/** - * @brief Computes the square root of a quantity - * - * Both the quantity value and its dimension are the base of the operation. - * - * @param q Quantity being the base of the operation - * @return Quantity The result of computation - */ -template -[[nodiscard]] inline Quantity auto sqrt(const Q& q) noexcept - requires requires { sqrt(q.number()); } || requires { std::sqrt(q.number()); } -{ - using dim = dimension_pow; - using unit = downcast_unit(Q::reference.mag) / dim::mag>; - using rep = TYPENAME Q::rep; - using std::sqrt; - return quantity(static_cast(sqrt(q.number()))); -} - -/** - * @brief Computes the cubic root of a quantity - * - * Both the quantity value and its dimension are the base of the operation. - * - * @param q Quantity being the base of the operation - * @return Quantity The result of computation - */ -template -[[nodiscard]] inline Quantity auto cbrt(const Q& q) noexcept - requires requires { cbrt(q.number()); } || requires { std::cbrt(q.number()); } -{ - using dim = dimension_pow; - using unit = downcast_unit(Q::reference.mag) / dim::mag>; - using rep = TYPENAME Q::rep; - using std::cbrt; - return quantity(static_cast(cbrt(q.number()))); -} - -/** - * @brief Computes Euler's raised to the given power - * - * @note Such an operation has sense only for a dimensionless quantity. - * - * @param q Quantity being the base of the operation - * @return Quantity The value of the same quantity type - */ -template -[[nodiscard]] inline dimensionless exp(const dimensionless& q) - requires requires { exp(q.number()); } || requires { std::exp(q.number()); } -{ - using std::exp; - return quantity_cast(dimensionless(exp(quantity_cast(q).number()))); -} - -/** - * @brief Computes the absolute value of a quantity - * - * @param q Quantity being the base of the operation - * @return Quantity The absolute value of a provided quantity - */ -template -[[nodiscard]] inline quantity abs(const quantity& q) noexcept - requires requires { abs(q.number()); } || requires { std::abs(q.number()); } -{ - using std::abs; - return quantity(abs(q.number())); -} - -/** - * @brief Returns the epsilon of the quantity - * - * The returned value is defined by a std::numeric_limits::epsilon(). - * - * @tparam Q Quantity type being the base of the operation - * @return Quantity The epsilon value for quantity's representation type - */ -template - requires requires { std::numeric_limits::epsilon(); } -[[nodiscard]] constexpr Quantity auto epsilon() noexcept -{ - return Q(std::numeric_limits::epsilon()); -} - -/** - * @brief Computes the largest quantity with integer representation and unit type To with its number not greater than q - * - * @tparam q Quantity being the base of the operation - * @return Quantity The rounded quantity with unit type To - */ -template -[[nodiscard]] constexpr quantity floor(const quantity& q) noexcept - requires((!treat_as_floating_point) || requires { floor(q.number()); } || - requires { std::floor(q.number()); }) && - (std::same_as || requires { - ::units::quantity_cast(q); - quantity::one(); - }) -{ - const auto handle_signed_results = [&](const T& res) { - if (res > q) { - return res - T::one(); - } - return res; - }; - if constexpr (treat_as_floating_point) { - using std::floor; - if constexpr (std::is_same_v) { - return quantity(floor(q.number())); - } else { - return handle_signed_results(quantity(floor(quantity_cast(q).number()))); - } - } else { - if constexpr (std::is_same_v) { - return q; - } else { - return handle_signed_results(quantity_cast(q)); - } - } -} - -/** - * @brief Overload of @c ::units::floor() using the unit type of To - * - * @tparam q Quantity being the base of the operation - * @return Quantity The rounded quantity with unit type of quantity To - */ -template D, typename U, std::same_as Rep> -[[nodiscard]] constexpr quantity floor(const quantity& q) noexcept - requires requires { ::units::floor(q); } -{ - return ::units::floor(q); -} - -/** - * @brief Computes the smallest quantity with integer representation and unit type To with its number not less than q - * - * @tparam q Quantity being the base of the operation - * @return Quantity The rounded quantity with unit type To - */ -template -[[nodiscard]] constexpr quantity ceil(const quantity& q) noexcept - requires((!treat_as_floating_point) || requires { ceil(q.number()); } || requires { std::ceil(q.number()); }) && - (std::same_as || requires { - ::units::quantity_cast(q); - quantity::one(); - }) -{ - const auto handle_signed_results = [&](const T& res) { - if (res < q) { - return res + T::one(); - } - return res; - }; - if constexpr (treat_as_floating_point) { - using std::ceil; - if constexpr (std::is_same_v) { - return quantity(ceil(q.number())); - } else { - return handle_signed_results(quantity(ceil(quantity_cast(q).number()))); - } - } else { - if constexpr (std::is_same_v) { - return q; - } else { - return handle_signed_results(quantity_cast(q)); - } - } -} - -/** - * @brief Overload of @c ::units::ceil() using the unit type of To - * - * @tparam q Quantity being the base of the operation - * @return Quantity The rounded quantity with unit type of quantity To - */ -template D, typename U, std::same_as Rep> -[[nodiscard]] constexpr quantity ceil(const quantity& q) noexcept - requires requires { ::units::ceil(q); } -{ - return ::units::ceil(q); -} - -/** - * @brief Computes the nearest quantity with integer representation and unit type To to q - * - * Rounding halfway cases away from zero, regardless of the current rounding mode. - * - * @tparam q Quantity being the base of the operation - * @return Quantity The rounded quantity with unit type To - */ -template -[[nodiscard]] constexpr quantity round(const quantity& q) noexcept - requires((!treat_as_floating_point) || requires { round(q.number()); } || - requires { std::round(q.number()); }) && - (std::same_as || requires { - ::units::floor(q); - quantity::one(); - }) -{ - if constexpr (std::is_same_v) { - if constexpr (treat_as_floating_point) { - using std::round; - return quantity(round(q.number())); - } else { - return q; - } - } else { - const auto res_low = units::floor(q); - const auto res_high = res_low + decltype(res_low)::one(); - const auto diff0 = q - res_low; - const auto diff1 = res_high - q; - if (diff0 == diff1) { - if (static_cast(res_low.number()) & 1) { - return res_high; - } - return res_low; - } - if (diff0 < diff1) { - return res_low; - } - return res_high; - } -} - -/** - * @brief Overload of @c ::units::round() using the unit type of To - * - * @tparam q Quantity being the base of the operation - * @return Quantity The rounded quantity with unit type of quantity To - */ -template D, typename U, std::same_as Rep> -[[nodiscard]] constexpr quantity round(const quantity& q) noexcept - requires requires { ::units::round(q); } -{ - return ::units::round(q); -} - -/** - * @brief Computes the square root of the sum of the squares of x and y, - * without undue overflow or underflow at intermediate stages of the computation - */ -template -[[nodiscard]] inline std::common_type_t hypot(const Q1& x, const Q2& y) noexcept - requires requires { typename std::common_type_t; } && requires(std::common_type_t q) { - requires requires { hypot(q.number(), q.number()); } || requires { std::hypot(q.number(), q.number()); }; - } -{ - using type = std::common_type_t; - type xx = x; - type yy = y; - using std::hypot; - return type(hypot(xx.number(), yy.number())); -} - -/** - * @brief Computes the square root of the sum of the squares of x, y, and z, - * without undue overflow or underflow at intermediate stages of the computation - */ -template -[[nodiscard]] inline std::common_type_t hypot(const Q1& x, const Q2& y, const Q3& z) noexcept - requires requires { typename std::common_type_t; } && requires(std::common_type_t q) { - requires requires { hypot(q.number(), q.number(), q.number()); } || - requires { std::hypot(q.number(), q.number(), q.number()); }; - } -{ - using type = std::common_type_t; - type xx = x; - type yy = y; - type zz = z; - using std::hypot; - return type(hypot(xx.number(), yy.number(), zz.number())); -} - - -template - requires treat_as_floating_point -[[nodiscard]] inline dimensionless sin(const angle& q) noexcept - requires requires { sin(q.number()); } || requires { std::sin(q.number()); } -{ - using std::sin; - return sin(quantity_cast(q).number()); -} - -template - requires treat_as_floating_point -[[nodiscard]] inline dimensionless cos(const angle& q) noexcept - requires requires { cos(q.number()); } || requires { std::cos(q.number()); } -{ - using std::cos; - return cos(quantity_cast(q).number()); -} - -template - requires treat_as_floating_point -[[nodiscard]] inline dimensionless tan(const angle& q) noexcept - requires requires { tan(q.number()); } || requires { std::tan(q.number()); } -{ - using std::tan; - return tan(quantity_cast(q).number()); -} - - -template - requires treat_as_floating_point -[[nodiscard]] inline angle asin(const dimensionless& q) noexcept - requires requires { asin(q.number()); } || requires { std::asin(q.number()); } -{ - using std::asin; - return angle(asin(quantity_cast(q).number())); -} - -template - requires treat_as_floating_point -[[nodiscard]] inline angle acos(const dimensionless& q) noexcept - requires requires { acos(q.number()); } || requires { std::acos(q.number()); } -{ - using std::acos; - return angle(acos(quantity_cast(q).number())); -} - -template - requires treat_as_floating_point -[[nodiscard]] inline angle atan(const dimensionless& q) noexcept - requires requires { atan(q.number()); } || requires { std::atan(q.number()); } -{ - using std::atan; - return angle(atan(quantity_cast(q).number())); -} - -} // namespace units diff --git a/src/core/include/units/prefix.h b/src/core/include/units/prefix.h deleted file mode 100644 index e3e036c9..00000000 --- a/src/core/include/units/prefix.h +++ /dev/null @@ -1,62 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units { - -namespace detail { - -template -struct prefix_base : downcast_base> { - static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M; -}; - -} // namespace detail - -/** - * @brief A prefix used to scale units - * - * Data from a prefix class is used in two cases: - * - when defining a prefixed_unit its ratio is used to scale the reference unit and its - * symbol is used to prepend to the symbol of referenced unit - * - when printing the symbol of a scaled unit that was not predefined by the user but its - * factor matches ratio of a prefix, its symbol will be prepended to the symbol of the unit - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam Symbol a text representation of the prefix - * @tparam R factor to be used to scale a unit - */ -template -struct prefix : downcast_dispatch, downcast_mode::on> { - static constexpr auto symbol = Symbol; -}; - -} // namespace units diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h deleted file mode 100644 index 306e460b..00000000 --- a/src/core/include/units/quantity.h +++ /dev/null @@ -1,535 +0,0 @@ - -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units { - -namespace detail { - -template // TODO: Replace with `v * R` pending https://github.com/BobSteagall/wg21/issues/58. -inline constexpr auto make_quantity = [](auto&& v) { - using Rep = std::remove_cvref_t; - using ref_type = decltype(R); - using dimension = TYPENAME ref_type::dimension; - using unit = TYPENAME ref_type::unit; - return quantity(std::forward(v)); -}; - -template -concept quantity_one = - Quantity && - (std::same_as || std::same_as>)&&detail:: - equivalent_unit::value; - -} // namespace detail - -template -concept floating_point_ = // exposition only - (Quantity && treat_as_floating_point) || (!Quantity && treat_as_floating_point); - -template -concept safe_convertible_to_ = // exposition only - (!Quantity)&&(!Quantity)&&std::convertible_to && - (floating_point_ || (!floating_point_)); - -// QFrom ratio is an exact multiple of QTo -template -concept harmonic_ = // exposition only - Quantity && Quantity && is_integral(detail::quantity_magnitude / detail::quantity_magnitude); - -template -concept safe_castable_to_ = // exposition only - Quantity && QuantityOf && - scalable_with_ && - (floating_point_ || (!floating_point_ && harmonic_)); - -template -concept quantity_value_for_ = std::regular_invocable && Representation>; - -template -concept invoke_result_convertible_to_ = - Representation && quantity_value_for_ && safe_convertible_to_>; - -template -concept have_quantity_for_ = Quantity && (!Quantity)&&quantity_value_for_; - -template -using quantity_like_type = quantity::dimension, typename quantity_like_traits::unit, - typename quantity_like_traits::rep>; - -/** - * @brief A 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 measurement unit. - * - * @tparam D a dimension of the quantity (can be either a BaseDimension or a DerivedDimension) - * @tparam U a measurement unit of the quantity - * @tparam Rep a type to be used to represent values of a quantity - */ -template U, Representation Rep = double> -class quantity { - Rep number_; -public: - // member types and values - using dimension = D; - using unit = U; - using rep = Rep; - static constexpr units::reference reference{}; - - // static member functions - [[nodiscard]] static constexpr quantity zero() noexcept - requires requires { quantity_values::zero(); } - { - return quantity(quantity_values::zero()); - } - - [[nodiscard]] static constexpr quantity one() noexcept - requires requires { quantity_values::one(); } - { - return quantity(quantity_values::one()); - } - - [[nodiscard]] static constexpr quantity min() noexcept - requires requires { quantity_values::min(); } - { - return quantity(quantity_values::min()); - } - - [[nodiscard]] static constexpr quantity max() noexcept - requires requires { quantity_values::max(); } - { - return quantity(quantity_values::max()); - } - - // construction, assignment, destruction - quantity() = default; - quantity(const quantity&) = default; - quantity(quantity&&) = default; - - template - requires(safe_convertible_to_, rep>) - constexpr explicit(!detail::quantity_one) quantity(Value&& v) : number_(std::forward(v)) - { - } - - template Q> - constexpr explicit(false) quantity(const Q& q) : number_(quantity_cast(q).number()) - { - } - - template - requires(safe_castable_to_, quantity>) - constexpr explicit quantity(const Q& q) : quantity(quantity_like_type(quantity_like_traits::number(q))) - { - } - - quantity& operator=(const quantity&) = default; - quantity& operator=(quantity&&) = default; - - // data access - [[nodiscard]] constexpr rep& number() & noexcept { return number_; } - [[nodiscard]] constexpr const rep& number() const& noexcept { return number_; } - [[nodiscard]] constexpr rep&& number() && noexcept { return std::move(number_); } - [[nodiscard]] constexpr const rep&& number() const&& noexcept { return std::move(number_); } - - // member unary operators - [[nodiscard]] constexpr Quantity auto operator+() const - requires requires(rep v) { - { - +v - } -> std::common_with; - } - { - using ret = quantity; - return ret(+number()); - } - - [[nodiscard]] constexpr Quantity auto operator-() const - requires(std::regular_invocable, rep>) - { - using ret = quantity; - return ret(-number()); - } - - constexpr quantity& operator++() - requires requires(rep v) { - { - ++v - } -> std::same_as; - } - { - ++number_; - return *this; - } - - [[nodiscard]] constexpr quantity operator++(int) - requires requires(rep v) { - { - v++ - } -> std::same_as; - } - { - return quantity(number_++); - } - - constexpr quantity& operator--() - requires requires(rep v) { - { - --v - } -> std::same_as; - } - { - --number_; - return *this; - } - - [[nodiscard]] constexpr quantity operator--(int) - requires requires(rep v) { - { - v-- - } -> std::same_as; - } - { - return quantity(number_--); - } - - constexpr quantity& operator+=(const quantity& q) - requires requires(rep a, rep b) { - { - a += b - } -> std::same_as; - } - { - number_ += q.number(); - return *this; - } - - constexpr quantity& operator-=(const quantity& q) - requires requires(rep a, rep b) { - { - a -= b - } -> std::same_as; - } - { - number_ -= q.number(); - return *this; - } - - template - constexpr quantity& operator*=(const Rep2& rhs) - requires requires(rep a, const Rep2 b) { - { - a *= b - } -> std::same_as; - } - { - number_ *= rhs; - return *this; - } - template - constexpr quantity& operator*=(const Q& rhs) - requires requires(rep a, const typename Q::rep b) { - { - a *= b - } -> std::same_as; - } - { - number_ *= rhs.number(); - return *this; - } - - template - constexpr quantity& operator/=(const Rep2& rhs) - requires requires(rep a, const Rep2 b) { - { - a /= b - } -> std::same_as; - } - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - number_ /= rhs; - return *this; - } - template - constexpr quantity& operator/=(const Q& rhs) - requires requires(rep a, const typename Q::rep b) { - { - a /= b - } -> std::same_as; - } - { - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - number_ /= rhs.number(); - return *this; - } - - template - constexpr quantity& operator%=(const Rep2& rhs) - requires(!floating_point_) && (!floating_point_) && requires(rep a, const Rep2 b) { - { - a %= b - } -> std::same_as; - } - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - number_ %= rhs; - return *this; - } - - template - constexpr quantity& operator%=(const Q& rhs) - requires(!floating_point_) && (!floating_point_) && requires(rep a, const typename Q::rep b) { - { - a %= b - } -> std::same_as; - } - { - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - number_ %= rhs.number(); - return *this; - } - - constexpr quantity& operator%=(const quantity& q) - requires(!floating_point_) && requires(rep a, rep b) { - { - a %= b - } -> std::same_as; - } - { - gsl_ExpectsAudit(q.number() != quantity_values::zero()); - number_ %= q.number(); - return *this; - } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - template - [[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const Value& rhs) - requires requires { // TODO: Simplify when Clang catches up. - requires !Quantity; - requires is_same_v; - requires invoke_result_convertible_to_, rep, Value>; - } - { - return units::quantity(lhs.number() + rhs); - } - template - [[nodiscard]] friend constexpr Quantity auto operator+(const Value& lhs, const quantity& rhs) - requires requires { // TODO: Simplify when Clang catches up. - requires !Quantity; - requires is_same_v; - requires invoke_result_convertible_to_, Value, rep>; - } - { - return units::quantity(lhs + rhs.number()); - } - - template - [[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const Value& rhs) - requires requires { // TODO: Simplify when Clang catches up. - requires !Quantity; - requires is_same_v; - requires invoke_result_convertible_to_, rep, Value>; - } - { - return units::quantity(lhs.number() - rhs); - } - template - [[nodiscard]] friend constexpr Quantity auto operator-(const Value& lhs, const quantity& rhs) - requires requires { // TODO: Simplify when Clang catches up. - requires !Quantity; - requires is_same_v; - requires invoke_result_convertible_to_, Value, rep>; - } - { - return units::quantity(lhs - rhs.number()); - } - - template - requires(invoke_result_convertible_to_, rep, const Value&>) - [[nodiscard]] friend constexpr Quantity auto operator*(const quantity& q, const Value& v) - { - using ret = quantity, rep, Value>>; - return ret(q.number() * v); - } - - template - requires(invoke_result_convertible_to_, const Value&, rep>) - [[nodiscard]] friend constexpr Quantity auto operator*(const Value& v, const quantity& q) - { - using ret = quantity, Value, rep>>; - return ret(v * q.number()); - } - - template - requires(invoke_result_convertible_to_, rep, const Value&>) - [[nodiscard]] friend constexpr Quantity auto operator/(const quantity& q, const Value& v) - { - gsl_ExpectsAudit(v != quantity_values::zero()); - using ret = quantity, rep, Value>>; - return ret(q.number() / v); - } - - template - requires(invoke_result_convertible_to_, const Value&, rep>) - [[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q) - { - return detail::make_quantity<::units::reference{} / reference>(v / q.number()); - } - - template - requires(!Quantity) && (!floating_point_) && (!floating_point_) && - (invoke_result_convertible_to_, rep, const Value&>) - [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& q, const Value& v) - { - gsl_ExpectsAudit(v != quantity_values::zero()); - using ret = quantity, rep, Value>>; - return ret(q.number() % v); - } - - [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) - requires(!floating_point_) && (invoke_result_convertible_to_, rep, rep>) - { - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using ret = quantity, rep, rep>>; - return ret(lhs.number() % rhs.number()); - } - - [[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity& rhs) - requires std::three_way_comparable -#if UNITS_COMP_GCC == 10 && UNITS_COMP_GCC_MINOR >= 2 - = default; -#else - { - return lhs.number() <=> rhs.number(); - } -#endif - - [[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity& rhs) = default; -}; - -// CTAD -#if !UNITS_COMP_CLANG || UNITS_COMP_CLANG > 17 -template -explicit(false) quantity(Rep&&) -> quantity; -#endif - -template -explicit(false) quantity(quantity) -> quantity; - -template -explicit(false) quantity(Rep) -> quantity; - -template -explicit quantity(Q) -> quantity::dimension, typename quantity_like_traits::unit, - typename quantity_like_traits::rep>; - -// non-member binary operators -template Q2> - requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) -[[nodiscard]] constexpr Quantity auto operator+(const Q1& lhs, const Q2& rhs) -{ - using ref = detail::common_quantity_reference; - using ret = quantity; - return ret(ret(lhs).number() + ret(rhs).number()); -} - -template Q2> - requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) -[[nodiscard]] constexpr Quantity auto operator-(const Q1& lhs, const Q2& rhs) -{ - using ref = detail::common_quantity_reference; - using ret = quantity; - return ret(ret(lhs).number() - ret(rhs).number()); -} - -template - requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) -[[nodiscard]] constexpr Quantity auto operator*(const Q1& lhs, const Q2& rhs) -{ - return detail::make_quantity(lhs.number() * rhs.number()); -} - -template - requires(quantity_value_for_, typename Q1::rep, typename Q2::rep>) -[[nodiscard]] constexpr Quantity auto operator/(const Q1& lhs, const Q2& rhs) -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return detail::make_quantity(lhs.number() / rhs.number()); -} - -template - requires(!floating_point_) && (!floating_point_) && - (QuantityEquivalentTo || Dimensionless) && - (quantity_value_for_, typename Q1::rep, typename Q2::rep>) -[[nodiscard]] constexpr Quantity auto operator%(const Q1& lhs, const Q2& rhs) -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using ret = quantity, typename Q1::rep, typename Q2::rep>>; - return ret(lhs.number() % rhs.number()); -} - -template Q2> - requires std::three_way_comparable_with -[[nodiscard]] constexpr auto operator<=>(const Q1& lhs, const Q2& rhs) -{ - using cq = std::common_type_t; - return cq(lhs).number() <=> cq(rhs).number(); -} - -template Q2> - requires std::equality_comparable_with -[[nodiscard]] constexpr bool operator==(const Q1& lhs, const Q2& rhs) -{ - using cq = std::common_type_t; - return cq(lhs).number() == cq(rhs).number(); -} - -// type traits -namespace detail { - -template -inline constexpr bool is_quantity> = true; - -template - requires units::is_derived_from_specialization_of -inline constexpr bool is_quantity = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/quantity_cast.h b/src/core/include/units/quantity_cast.h deleted file mode 100644 index 89c5d059..00000000 --- a/src/core/include/units/quantity_cast.h +++ /dev/null @@ -1,382 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include -#include - -UNITS_DIAGNOSTIC_PUSH -// warning C4244: 'argument': conversion from 'intmax_t' to 'T', possible loss of data with T=int -UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA - -namespace units { - -template U, Representation Rep> -class quantity; - -template U, Representation Rep> -class quantity_point; - -template U, Representation Rep> -class quantity_kind; - -template U, Representation Rep> -class quantity_point_kind; - -namespace detail { - -template -inline constexpr Magnitude auto quantity_magnitude = decltype(Q::reference)::mag; - -template -inline constexpr Magnitude auto cast_magnitude = [] { - using FromU = TYPENAME QFrom::unit; - using ToU = TYPENAME QTo::unit; - if constexpr (same_unit_reference::value) { - return FromU::mag / ToU::mag; - } else { - return quantity_magnitude / quantity_magnitude; - } -}(); - -template -struct cast_traits; - -template - requires common_type_with_, std::intmax_t> -struct cast_traits { - using ratio_type = std::common_type_t, std::intmax_t>; - using rep_type = ratio_type; -}; - -template - requires(!common_type_with_, std::intmax_t> && - scalable_number_, std::intmax_t> && - requires { typename std::common_type_t::value_type; } && - common_type_with_::value_type, std::intmax_t>) -struct cast_traits { - using ratio_type = std::common_type_t::value_type, std::intmax_t>; - using rep_type = std::common_type_t; -}; - -template - requires(!common_type_with_, std::intmax_t> && - scalable_number_, std::intmax_t> && - requires { typename std::common_type_t::element_type; } && - common_type_with_::element_type, std::intmax_t>) -struct cast_traits { - using ratio_type = std::common_type_t::element_type, std::intmax_t>; - using rep_type = std::common_type_t; -}; - -} // namespace detail - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets the target quantity type to cast to. For example: - * - * auto q1 = units::quantity_cast>(1_q_ms); - * - * @tparam To a target quantity type to cast to - */ -template Rep> - requires QuantityOf && (std::constructible_from>) -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - using traits = detail::cast_traits; - using ratio_type = TYPENAME traits::ratio_type; - using rep_type = TYPENAME traits::rep_type; - - constexpr Magnitude auto c_mag = detail::cast_magnitude, To>; - constexpr Magnitude auto num = numerator(c_mag); - constexpr Magnitude auto den = denominator(c_mag); - constexpr Magnitude auto irr = c_mag * (den / num); - - constexpr auto val = [](Magnitude auto m) { return get_value(m); }; - return To(static_cast(static_cast(q.number()) * val(num) / val(den) * val(irr))); -} - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets only the target dimension to cast to. For example: - * - * auto q1 = units::quantity_cast(200_q_Gal); - * - * @tparam ToD a dimension type to use for a target quantity - */ -template - requires equivalent -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - return quantity_cast, Rep>>(q); -} - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets only the target unit to cast to. For example: - * - * auto q1 = units::quantity_cast(1_q_ms); - * - * @tparam ToU a unit type to use for a target quantity - */ -template - requires UnitOf -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - return quantity_cast>(q); -} - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets both the target dimension and unit to cast to. For example: - * - * auto q1 = units::quantity_cast(v1); - * - * @note This cast is especially useful when working with quantities of unknown dimensions - * (@c unknown_dimension). - * - * @tparam ToD a dimension type to use for a target quantity - * @tparam ToU a unit type to use for a target quantity - */ -template - requires equivalent && UnitOf -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - return quantity_cast>(q); -} - -/** - * @brief Explicit cast of a quantity - * - * Implicit conversions between quantities of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In such cases an explicit cast have to be used. - * - * This cast gets only representation to cast to. For example: - * - * auto q1 = units::quantity_cast(1_q_ms); - * - * @tparam ToRep a representation type to use for a target quantity - */ -template Rep> - requires(std::constructible_from>) -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) -{ - return quantity_cast>(q); -} - -/** - * @brief Explicit cast of a quantity point - * - * Implicit conversions between quantity points of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets the target quantity point type to cast to or anything that works for quantity_cast. For example: - * - * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); - * auto q1 = units::quantity_point_cast>(quantity_point{1_q_ms}); - * auto q1 = units::quantity_point_cast(quantity_point{200_q_Gal}); - * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); - * auto q1 = units::quantity_point_cast(quantity_point{1_q_ms}); - * - * @tparam CastSpec a target quantity point type to cast to or anything that works for quantity_cast - */ -template -[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& qp) - requires requires { - requires is_specialization_of; - requires requires { quantity_cast(qp.relative()); }; - requires equivalent; - } || // TODO: Simplify when Clang catches up. - requires { quantity_cast(qp.relative()); } -{ - if constexpr (is_specialization_of) - return quantity_point(quantity_cast(qp.relative())); - else - return quantity_point(quantity_cast(qp.relative())); -} - -/** - * @brief Explicit cast of a quantity point - * - * Implicit conversions between quantity points of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets both the target dimension and unit to cast to. For example: - * - * auto q1 = units::quantity_point_cast(v1); - * - * @note This cast is especially useful when working with quantity points of unknown dimensions - * (@c unknown_dimension). - * - * @tparam ToD a dimension type to use for a target quantity - * @tparam ToU a unit type to use for a target quantity - */ -template - requires equivalent && UnitOf && RebindablePointOriginFor -[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& q) -{ - return quantity_point_cast, ToU, Rep>>(q); -} - -/** - * @brief Explicit cast of a quantity kind - * - * Implicit conversions between quantity kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets the target (quantity) kind type to cast to or anything that works for quantity_cast. For example: - * - * auto q1 = units::quantity_kind_cast(quantity_kind{ns::width{1 * mm}); - * auto q1 = units::quantity_kind_cast(ns::width{1 * m}); - * auto q1 = units::quantity_kind_cast>(ns::width{1 * mm}); - * auto q1 = units::quantity_kind_cast(ns::rate_of_climb{200 * Gal}); - * auto q1 = units::quantity_kind_cast(ns::width{1 * mm}); - * auto q1 = units::quantity_kind_cast(ns::width{1.0 * mm}); - * - * @tparam CastSpec a target (quantity) kind type to cast to or anything that works for quantity_cast - */ -template -[[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind& qk) - requires requires { - requires is_specialization_of; - requires requires { quantity_cast(qk.common()); }; - } || requires { - requires Kind; - requires UnitOf; - } || requires { quantity_cast(qk.common()); } // TODO: Simplify when Clang catches up. -{ - if constexpr (is_specialization_of) - return CastSpec(quantity_cast(qk.common())); - else if constexpr (Kind) - return quantity_kind(qk.common()); - else { - auto q{quantity_cast(qk.common())}; - using Q = decltype(q); - return quantity_kind(static_cast(q)); - } -} - -/** - * @brief Explicit cast of a quantity kind - * - * Implicit conversions between quantity kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets both the target kind and unit to cast to. For example: - * - * auto q1 = units::quantity_kind_cast(w); - * - * @note This cast is especially useful when working with quantity kinds of unknown kind. - * - * @tparam ToK the kind type to use for the target quantity - * @tparam ToU the unit type to use for the target quantity - */ -template - requires equivalent && UnitOf -[[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind& qk) -{ - return quantity_kind_cast>(qk); -} - -/** - * @brief Explicit cast of a quantity point kind - * - * Implicit conversions between quantity point kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets the target (quantity) point kind type to cast to or anything that works for quantity_kind_cast. For - * example: - * - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * m}); - * auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * m}); - * auto q1 = units::quantity_point_kind_cast>(ns::x_coordinate{1 * mm}); - * auto q1 = units::quantity_point_kind_cast(quantity_point_kind(ns::rate_of_climb{200 - * * Gal})); auto q1 = units::quantity_point_kind_cast(ns::x_coordinate{1 * mm}); auto q1 = - * units::quantity_point_kind_cast(ns::x_coordinate{1.0 * mm}); - * - * @tparam CastSpec a target (quantity) point kind type to cast to or anything that works for quantity_kind_cast - */ -template -[[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind& qpk) - requires requires { - requires is_specialization_of; - requires requires { quantity_kind_cast(qpk.relative()); }; - requires equivalent; - } || requires { requires PointKind && UnitOf; } || - requires { quantity_kind_cast(qpk.relative()); } // TODO: Simplify when Clang catches up. -{ - if constexpr (is_specialization_of) - return CastSpec(quantity_kind_cast(qpk.relative())); - else if constexpr (PointKind) - return quantity_point_kind(quantity_kind_cast(qpk.relative())); - else - return quantity_point_kind(quantity_kind_cast(qpk.relative())); -} - -/** - * @brief Explicit cast of a quantity point kind - * - * Implicit conversions between quantity point kinds of different types are allowed only for "safe" - * (i.e. non-truncating) conversion. In other cases an explicit cast has to be used. - * - * This cast gets both the target point kind and unit to cast to. For example: - * - * auto q1 = units::quantity_point_kind_cast(x); - * - * @note This cast is especially useful when working with quantity point kinds of unknown point kind. - * - * @tparam ToPK the point kind type to use for the target quantity - * @tparam ToU the unit type to use for the target quantity - */ -template - requires equivalent && UnitOf -[[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind& qpk) -{ - return quantity_point_kind_cast>(qpk); -} - -} // namespace units - -UNITS_DIAGNOSTIC_POP diff --git a/src/core/include/units/quantity_kind.h b/src/core/include/units/quantity_kind.h deleted file mode 100644 index e806074f..00000000 --- a/src/core/include/units/quantity_kind.h +++ /dev/null @@ -1,409 +0,0 @@ - -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units { - -namespace detail { - -template -inline constexpr auto make_quantity_kind_fn = [](auto&& q) { - using Q = std::remove_reference_t; - return quantity_kind(std::forward(q)); -}; - -template -inline constexpr auto& make_quantity_kind = make_quantity_kind_fn; - -template -inline constexpr auto downcasted_kind_fn = [](auto q) { - using Q = decltype(q); - return make_quantity_kind_fn>(std::move(q)); -}; - -template -inline constexpr auto& downcasted_kind = downcasted_kind_fn; - -template -concept quantity_kind_one = QuantityKind && equivalent> && - detail::quantity_one; - -} // namespace detail - -/** - * @brief A concept matching two related quantity kinds - * - * Satisfied by quantity kinds having equivalent base kinds. - */ -template -concept QuantityKindRelatedTo = QuantityKind && QuantityKind && - equivalent; - -/** - * @brief A quantity kind - * - * A quantity with more specific usage as determined by its kind. - * See https://jcgm.bipm.org/vim/en/1.2.html and NOTE 1 at https://jcgm.bipm.org/vim/en/1.1.html. - * - * @tparam K the kind of quantity - * @tparam U the measurement unit of the quantity kind - * @tparam Rep the type to be used to represent values of the quantity kind - */ -template U, Representation Rep = double> -class quantity_kind { -public: - using kind_type = K; - using quantity_type = quantity; - using dimension = typename quantity_type::dimension; - using unit = typename quantity_type::unit; - using rep = typename quantity_type::rep; - static constexpr units::reference reference{}; - -private: - quantity_type q_; - -public: - quantity_kind() = default; - quantity_kind(const quantity_kind&) = default; - quantity_kind(quantity_kind&&) = default; - - template - requires(Quantity> || QuantityLike> || - (Dimensionless && !Quantity>)) && - std::constructible_from - constexpr explicit quantity_kind(T&& t) : q_(std::forward(t)) - { - } - - template QK2> - requires std::convertible_to - constexpr explicit(false) quantity_kind(const QK2& qk) : q_(qk.common()) - { - } - - quantity_kind& operator=(const quantity_kind&) = default; - quantity_kind& operator=(quantity_kind&&) = default; - - [[nodiscard]] constexpr quantity_type& common() & noexcept { return q_; } - [[nodiscard]] constexpr const quantity_type& common() const& noexcept { return q_; } - [[nodiscard]] constexpr quantity_type&& common() && noexcept { return std::move(q_); } - [[nodiscard]] constexpr const quantity_type&& common() const&& noexcept { return std::move(q_); } - - [[nodiscard]] static constexpr quantity_kind zero() noexcept - requires requires { quantity_type::zero(); } - { - return quantity_kind(quantity_type::zero()); - } - - [[nodiscard]] static constexpr quantity_kind one() noexcept - requires requires { quantity_type::one(); } - { - return quantity_kind(quantity_type::one()); - } - - [[nodiscard]] static constexpr quantity_kind min() noexcept - requires requires { quantity_type::min(); } - { - return quantity_kind(quantity_type::min()); - } - - [[nodiscard]] static constexpr quantity_kind max() noexcept - requires requires { quantity_type::max(); } - { - return quantity_kind(quantity_type::max()); - } - - [[nodiscard]] constexpr quantity_kind operator+() const - requires requires(quantity_type q) { +q; } - { - return *this; - } - - [[nodiscard]] constexpr QuantityKind auto operator-() const - requires requires(quantity_type q) { -q; } - { - return detail::make_quantity_kind(-q_); - } - - constexpr quantity_kind& operator++() - requires requires(quantity_type q) { ++q; } - { - ++q_; - return *this; - } - - [[nodiscard]] constexpr quantity_kind operator++(int) - requires requires(quantity_type q) { q++; } - { - return quantity_kind(q_++); - } - - constexpr quantity_kind& operator--() - requires requires(quantity_type q) { --q; } - { - --q_; - return *this; - } - - [[nodiscard]] constexpr quantity_kind operator--(int) - requires requires(quantity_type q) { q--; } - { - return quantity_kind(q_--); - } - - constexpr quantity_kind& operator+=(const quantity_kind& qk) - requires requires(quantity_type q) { q += qk.common(); } - { - q_ += qk.common(); - return *this; - } - - constexpr quantity_kind& operator-=(const quantity_kind& qk) - requires requires(quantity_type q) { q -= qk.common(); } - { - q_ -= qk.common(); - return *this; - } - - template - constexpr quantity_kind& operator*=(const Rep2& rhs) - requires requires(quantity_type q) { q *= rhs; } - { - q_ *= rhs; - return *this; - } - template QK> - constexpr quantity_kind& operator*=(const QK& rhs) - requires requires(quantity_type q) { q *= rhs.common(); } - { - q_ *= rhs.common(); - return *this; - } - - template - constexpr quantity_kind& operator/=(const Rep2& rhs) - requires requires(quantity_type q) { q /= rhs; } - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - q_ /= rhs; - return *this; - } - template QK> - constexpr quantity_kind& operator/=(const QK& rhs) - requires requires(quantity_type q) { q /= rhs.common(); } - { - q_ /= rhs.common(); - return *this; - } - - template - constexpr quantity_kind& operator%=(const Rep2& rhs) - requires(!Quantity || Dimensionless) && requires(quantity_type q, const Rep2 r) { q %= r; } - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - q_ %= rhs; - return *this; - } - - template - constexpr quantity_kind& operator%=(const QK& rhs) - requires(QuantityKindEquivalentTo || detail::quantity_kind_one) && - requires(quantity_type q) { q %= rhs.common(); } - { - gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); - q_ %= rhs.common(); - return *this; - } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - template - [[nodiscard]] friend constexpr QuantityKind auto operator*(const quantity_kind& qk, const Value& v) - requires requires(quantity_type q) { - { - q* v - } -> Quantity; - } - { - return detail::make_quantity_kind(qk.common() * v); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator*(const Value& v, const quantity_kind& qk) - requires requires(quantity_type q) { - { - v* q - } -> Quantity; - } - { - return detail::make_quantity_kind(v * qk.common()); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator/(const quantity_kind& qk, const Value& v) - requires requires(quantity_type q) { - { - q / v - } -> Quantity; - } - { - gsl_ExpectsAudit(v != quantity_values::zero()); - return detail::make_quantity_kind(qk.common() / v); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator/(const Value& v, const quantity_kind& qk) - requires requires(quantity_type q) { - { - v / q - } -> Quantity; - } - { - gsl_ExpectsAudit(qk.common().number() != quantity_values::zero()); - return detail::downcasted_kind(v / qk.common()); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator%(const quantity_kind& qk, const Value& v) - requires requires(quantity_type q) { q % v; } - { - gsl_ExpectsAudit(v != quantity_values::zero()); - return detail::make_quantity_kind(qk.common() % v); - } - - [[nodiscard]] friend constexpr auto operator<=>(const quantity_kind& lhs, const quantity_kind& rhs) - requires std::three_way_comparable - { - return lhs.common() <=> rhs.common(); - } - - [[nodiscard]] friend constexpr bool operator==(const quantity_kind&, const quantity_kind&) = default; -}; - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator+(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() + rhs.common(); } -{ - return detail::make_quantity_kind(lhs.common() + rhs.common()); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator-(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() - rhs.common(); } -{ - return detail::make_quantity_kind(lhs.common() - rhs.common()); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator*(const QK& lhs, const Q& rhs) - requires requires { lhs.common() * rhs; } -{ - return detail::downcasted_kind(lhs.common() * rhs); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator*(const Q& lhs, const QK& rhs) - requires requires { lhs* rhs.common(); } -{ - return detail::downcasted_kind(lhs * rhs.common()); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator*(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() * rhs.common(); } -{ - return detail::downcasted_kind(lhs.common() * rhs.common()); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator/(const QK& lhs, const Q& rhs) - requires requires { lhs.common() / rhs; } -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return detail::downcasted_kind(lhs.common() / rhs); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator/(const Q& lhs, const QK& rhs) - requires requires { lhs / rhs.common(); } -{ - gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); - return detail::downcasted_kind(lhs / rhs.common()); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator/(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() / rhs.common(); } -{ - return detail::downcasted_kind(lhs.common() / rhs.common()); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator%(const QK& lhs, const D& rhs) - requires requires { lhs.common() % rhs; } -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return detail::make_quantity_kind(lhs.common() % rhs); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator%(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() % rhs.common(); } -{ - gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); - return detail::make_quantity_kind(lhs.common() % rhs.common()); -} - -template QK2> - requires std::three_way_comparable_with -[[nodiscard]] constexpr auto operator<=>(const QK1& lhs, const QK2& rhs) -{ - return lhs.common() <=> rhs.common(); -} - -template QK2> - requires std::equality_comparable_with -[[nodiscard]] constexpr bool operator==(const QK1& lhs, const QK2& rhs) -{ - return lhs.common() == rhs.common(); -} - -// type traits -namespace detail { - -template -inline constexpr bool is_quantity_kind> = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/quantity_point.h b/src/core/include/units/quantity_point.h deleted file mode 100644 index ecb63752..00000000 --- a/src/core/include/units/quantity_point.h +++ /dev/null @@ -1,232 +0,0 @@ - -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units { - -/** - * @brief A statically unspecified quantity point origin - * - * An origin, unspecified in the type system, from which an absolute quantity is measured from. - * - * @tparam D a dimension of the quantity point (can be either a BaseDimension or a DerivedDimension) - */ -template -struct dynamic_origin : point_origin { - template - using rebind = dynamic_origin; -}; - -/** - * @brief A quantity point - * - * An absolute quantity measured from an origin. - * - * @tparam O a type that represents the origin from which the quantity point is measured from - * @tparam U a measurement unit of the quantity point - * @tparam Rep a type to be used to represent values of a quantity point - */ -template U, Representation Rep = double> -class quantity_point { -public: - using origin = O; - using quantity_type = quantity; - using dimension = typename quantity_type::dimension; - using unit = typename quantity_type::unit; - using rep = typename quantity_type::rep; - static constexpr units::reference reference{}; - -private: - quantity_type q_{}; - -public: - quantity_point() = default; - quantity_point(const quantity_point&) = default; - quantity_point(quantity_point&&) = default; - - template - requires std::constructible_from - constexpr explicit quantity_point(T&& t) : q_(std::forward(t)) - { - } - - template QP2> - requires std::convertible_to - constexpr explicit(false) quantity_point(const QP2& qp) : q_(qp.relative()) - { - } - - template - constexpr explicit quantity_point(const QP& qp) - requires std::is_constructible_v::relative(qp))> && - equivalent::origin> - : q_(quantity_point_like_traits::relative(qp)) - { - } - - quantity_point& operator=(const quantity_point&) = default; - quantity_point& operator=(quantity_point&&) = default; - - [[nodiscard]] constexpr quantity_type& relative() & noexcept { return q_; } - [[nodiscard]] constexpr const quantity_type& relative() const& noexcept { return q_; } - [[nodiscard]] constexpr quantity_type&& relative() && noexcept { return std::move(q_); } - [[nodiscard]] constexpr const quantity_type&& relative() const&& noexcept { return std::move(q_); } - - [[nodiscard]] static constexpr quantity_point min() noexcept - requires requires { quantity_type::min(); } - { - return quantity_point(quantity_type::min()); - } - - [[nodiscard]] static constexpr quantity_point max() noexcept - requires requires { quantity_type::max(); } - { - return quantity_point(quantity_type::max()); - } - - constexpr quantity_point& operator++() - requires requires(quantity_type q) { ++q; } - { - ++q_; - return *this; - } - - [[nodiscard]] constexpr quantity_point operator++(int) - requires requires(quantity_type q) { q++; } - { - return quantity_point(q_++); - } - - constexpr quantity_point& operator--() - requires requires(quantity_type q) { --q; } - { - --q_; - return *this; - } - - [[nodiscard]] constexpr quantity_point operator--(int) - requires requires(quantity_type q) { q--; } - { - return quantity_point(q_--); - } - - constexpr quantity_point& operator+=(const quantity_type& q) - requires requires { q_ += q; } - { - q_ += q; - return *this; - } - - constexpr quantity_point& operator-=(const quantity_type& q) - requires requires(quantity_type q1, quantity_type q2) { q1 -= q2; } - { - q_ -= q; - return *this; - } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - - template - [[nodiscard]] friend constexpr QuantityPoint auto operator+(const quantity_point& lhs, const Q& rhs) - requires requires(quantity_type q) { q + rhs; } - { - const auto q = lhs.relative() + rhs; - using q_type = decltype(q); - return quantity_point, typename q_type::unit, - typename q_type::rep>(q); - } - - template - [[nodiscard]] friend constexpr QuantityPoint auto operator+(const Q& lhs, const quantity_point& rhs) - requires requires { rhs + lhs; } - { - return rhs + lhs; - } - - template - [[nodiscard]] friend constexpr QuantityPoint auto operator-(const quantity_point& lhs, const Q& rhs) - requires requires(quantity_type q) { q - rhs; } - { - const auto q = lhs.relative() - rhs; - using q_type = decltype(q); - return quantity_point, typename q_type::unit, - typename q_type::rep>(q); - } - - template QP> - [[nodiscard]] friend constexpr Quantity auto operator-(const quantity_point& lhs, const QP& rhs) - requires requires(quantity_type q) { q - rhs.relative(); } - { - return lhs.relative() - rhs.relative(); - } - - template QP> - requires std::three_way_comparable_with - [[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs) - { - return lhs.relative() <=> rhs.relative(); - } - - template QP> - requires std::equality_comparable_with - [[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs) - { - return lhs.relative() == rhs.relative(); - } -}; - -template -explicit quantity_point(Rep) -> quantity_point, one, Rep>; - -template -explicit quantity_point(Q) -> quantity_point, typename Q::unit, typename Q::rep>; - -template -explicit quantity_point(Q) - -> quantity_point::dimension>, typename quantity_like_traits::unit, - typename quantity_like_traits::rep>; - -template -explicit quantity_point(QP) - -> quantity_point::origin, typename quantity_point_like_traits::unit, - typename quantity_point_like_traits::rep>; - -namespace detail { - -template -inline constexpr bool is_quantity_point> = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/quantity_point_kind.h b/src/core/include/units/quantity_point_kind.h deleted file mode 100644 index 837ab301..00000000 --- a/src/core/include/units/quantity_point_kind.h +++ /dev/null @@ -1,202 +0,0 @@ - -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units { - -/** - * @brief A quantity point kind - * - * An absolute quantity kind measured from an origin. - * - * @tparam PK the point kind of quantity point - * @tparam U the measurement unit of the quantity point kind - * @tparam Rep the type to be used to represent values of the quantity point kind - */ -template U, Representation Rep = double> -class quantity_point_kind { -public: - using point_kind_type = PK; - using kind_type = typename PK::base_kind; - using origin = typename point_kind_type::origin; - using quantity_kind_type = quantity_kind; - using quantity_type = typename quantity_kind_type::quantity_type; - using dimension = typename quantity_type::dimension; - using unit = typename quantity_type::unit; - using rep = typename quantity_type::rep; - static constexpr units::reference reference{}; - -private: - quantity_kind_type qk_; - -public: - quantity_point_kind() = default; - quantity_point_kind(const quantity_point_kind&) = default; - quantity_point_kind(quantity_point_kind&&) = default; - - template - requires std::constructible_from - constexpr explicit quantity_point_kind(T&& t) : qk_(std::forward(t)) - { - } - - constexpr explicit quantity_point_kind(const quantity_point& qp) : qk_(qp.relative()) {} - constexpr explicit quantity_point_kind(quantity_point&& qp) : qk_(std::move(qp).relative()) {} - - template - requires(std::constructible_from, QP>) - constexpr explicit quantity_point_kind(const QP& qp) : qk_(quantity_point_like_traits::relative(qp)) - { - } - - template QPK2> - requires std::convertible_to - constexpr explicit(false) quantity_point_kind(const QPK2& qpk) : qk_(qpk.relative()) - { - } - - quantity_point_kind& operator=(const quantity_point_kind&) = default; - quantity_point_kind& operator=(quantity_point_kind&&) = default; - - [[nodiscard]] constexpr quantity_kind_type& relative() & noexcept { return qk_; } - [[nodiscard]] constexpr const quantity_kind_type& relative() const& noexcept { return qk_; } - [[nodiscard]] constexpr quantity_kind_type&& relative() && noexcept { return std::move(qk_); } - [[nodiscard]] constexpr const quantity_kind_type&& relative() const&& noexcept { return std::move(qk_); } - - [[nodiscard]] static constexpr quantity_point_kind min() noexcept - requires requires { quantity_kind_type::min(); } - { - return quantity_point_kind(quantity_kind_type::min()); - } - - [[nodiscard]] static constexpr quantity_point_kind max() noexcept - requires requires { quantity_kind_type::max(); } - { - return quantity_point_kind(quantity_kind_type::max()); - } - - constexpr quantity_point_kind& operator++() - requires requires(quantity_kind_type qk) { ++qk; } - { - ++qk_; - return *this; - } - - [[nodiscard]] constexpr quantity_point_kind operator++(int) - requires requires(quantity_kind_type qk) { qk++; } - { - return quantity_point_kind(qk_++); - } - - constexpr quantity_point_kind& operator--() - requires requires(quantity_kind_type qk) { --qk; } - { - --qk_; - return *this; - } - - [[nodiscard]] constexpr quantity_point_kind operator--(int) - requires requires(quantity_kind_type qk) { qk--; } - { - return quantity_point_kind(qk_--); - } - - constexpr quantity_point_kind& operator+=(const quantity_kind_type& qk) - requires requires(quantity_kind_type qk1, const quantity_kind_type qk2) { qk1 += qk2; } - { - qk_ += qk; - return *this; - } - - constexpr quantity_point_kind& operator-=(const quantity_kind_type& qk) - requires requires(quantity_kind_type qk1, const quantity_kind_type qk2) { qk1 -= qk2; } - { - qk_ -= qk; - return *this; - } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - - template - [[nodiscard]] friend constexpr QuantityPointKind auto operator+(const quantity_point_kind& lhs, const QK& rhs) - requires requires(quantity_kind_type qk) { qk + rhs; } - { - return units::quantity_point_kind(lhs.relative() + rhs); - } - - template - [[nodiscard]] friend constexpr QuantityPointKind auto operator+(const QK& lhs, const quantity_point_kind& rhs) - requires requires(quantity_kind_type qk) { lhs + qk; } - { - return units::quantity_point_kind(lhs + rhs.relative()); - } - - template - [[nodiscard]] friend constexpr QuantityPointKind auto operator-(const quantity_point_kind& lhs, const QK& rhs) - requires requires(quantity_kind_type qk) { qk - rhs; } - { - return units::quantity_point_kind(lhs.relative() - rhs); - } - - template QPK> - [[nodiscard]] friend constexpr QuantityKind auto operator-(const quantity_point_kind& lhs, const QPK& rhs) - requires requires(quantity_kind_type qk) { qk - qk; } - { - return lhs.relative() - rhs.relative(); - } - - template QPK> - requires std::three_way_comparable_with - [[nodiscard]] friend constexpr auto operator<=>(const quantity_point_kind& lhs, const QPK& rhs) - { - return lhs.relative() <=> rhs.relative(); - } - - template QPK> - requires std::equality_comparable_with - [[nodiscard]] friend constexpr bool operator==(const quantity_point_kind& lhs, const QPK& rhs) - { - return lhs.relative() == rhs.relative(); - } -}; - -template -quantity_point_kind(QK) - -> quantity_point_kind, typename QK::unit, typename QK::rep>; - -namespace detail { - -template -inline constexpr bool is_quantity_point_kind> = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/ratio.h b/src/core/include/units/ratio.h deleted file mode 100644 index 7b045de3..00000000 --- a/src/core/include/units/ratio.h +++ /dev/null @@ -1,92 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units { - -struct ratio; -constexpr ratio inverse(const ratio& r); - -/** - * @brief Provides compile-time rational arithmetic support. - * - * This class is really similar to @c std::ratio. An important difference is the fact that the objects of that class - * are used as class NTTPs rather then a type template parameter kind. - */ -struct ratio { - std::intmax_t num; - std::intmax_t den; - - constexpr explicit(false) ratio(std::intmax_t n, std::intmax_t d = 1) : num(n), den(d) - { - gsl_Expects(den != 0); - detail::normalize(num, den); - } - - [[nodiscard]] friend constexpr bool operator==(const ratio&, const ratio&) = default; - - [[nodiscard]] friend constexpr auto operator<=>(const ratio& lhs, const ratio& rhs) { return (lhs - rhs).num <=> 0; } - - [[nodiscard]] friend constexpr ratio operator-(const ratio& r) { return ratio(-r.num, r.den); } - - [[nodiscard]] friend constexpr ratio operator+(ratio lhs, ratio rhs) - { - return ratio{lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den}; - } - - [[nodiscard]] friend constexpr ratio operator-(const ratio& lhs, const ratio& rhs) { return lhs + (-rhs); } - - [[nodiscard]] friend constexpr ratio operator*(const ratio& lhs, const ratio& rhs) - { - const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den); - const std::intmax_t gcd2 = std::gcd(rhs.num, lhs.den); - return ratio(detail::safe_multiply(lhs.num / gcd1, rhs.num / gcd2), - detail::safe_multiply(lhs.den / gcd2, rhs.den / gcd1)); - } - - [[nodiscard]] friend constexpr ratio operator/(const ratio& lhs, const ratio& rhs) { return lhs * inverse(rhs); } -}; - -[[nodiscard]] constexpr ratio inverse(const ratio& r) { return ratio(r.den, r.num); } - -[[nodiscard]] constexpr bool is_integral(const ratio& r) { return r.num % r.den == 0; } - -// common_ratio -[[nodiscard]] constexpr ratio common_ratio(const ratio& r1, const ratio& r2) -{ - const auto res = detail::gcd_frac(r1.num, r1.den, r2.num, r2.den); - return ratio(res[0], res[1]); -} - -} // namespace units diff --git a/src/core/include/units/reference.h b/src/core/include/units/reference.h deleted file mode 100644 index 2b29e280..00000000 --- a/src/core/include/units/reference.h +++ /dev/null @@ -1,139 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units { - -template U, Representation Rep> -class quantity; - -template U> -struct reference; - -namespace detail { - -template -using reference_multiply_impl = reference>; - -template -using reference_divide_impl = reference>; - -} // namespace detail - -template -using reference_multiply = - detail::reference_multiply_impl, R1, R2>; - -template -using reference_divide = - detail::reference_divide_impl, R1, R2>; - -/** - * @brief The type for quantity references - * - * This type is intended to be used in the quantity references definition: - * - * @code{.cpp} - * namespace length_references { - * - * inline constexpr auto m = reference{}; - * inline constexpr auto km = reference{}; - * - * } - * - * namespace references { - * - * using namespace length_references; - * - * } - * @endcode - * - * Quantity references simplify quantity creation: - * - * @code{.cpp} - * using namespace units::isq::si::references; - * - * auto d = 123 * m; - * auto v = 70 * (km / h); - * @endcode - * - * Also, it is allowed to define custom quantity references from existing ones: - * - * @code{.cpp} - * constexpr auto Nm = N * m; - * constexpr auto mph = mi / h; - * @endcode - * - * The following syntaxes are not allowed: - * `2 / s`, `km * 3`, `s / 4`, `70 * km / h`. - */ -template U> -struct reference { - using dimension = D; - using unit = U; - static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag; - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - - template - [[nodiscard]] friend constexpr reference_multiply operator*(reference, R2) - { - return {}; - } - - template - [[nodiscard]] friend constexpr reference_divide operator/(reference, R2) - { - return {}; - } - - template - [[nodiscard]] friend constexpr Quantity auto operator*(const Rep& lhs, reference) - { - return quantity(lhs); - } - - friend void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, reference) = delete; - - template - [[nodiscard]] friend constexpr bool operator==(reference, R2) - { - return false; - } - - [[nodiscard]] friend constexpr bool operator==(reference, reference) { return true; } -}; - -// type traits -namespace detail { - -template -inline constexpr bool is_reference> = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/symbol_text.h b/src/core/include/units/symbol_text.h deleted file mode 100644 index 5ca2d12d..00000000 --- a/src/core/include/units/symbol_text.h +++ /dev/null @@ -1,183 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units { - -namespace detail { - -constexpr void validate_ascii_char([[maybe_unused]] char c) noexcept { gsl_Expects((c & 0x80) == 0); } - -template -constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[N + 1]) noexcept -{ -#ifndef NDEBUG - if constexpr (N != 0) - for (size_t i = 0; i < N; ++i) validate_ascii_char(s[i]); -#endif -} - -} // namespace detail - - -/** - * @brief A symbol text representation - * - * This class template is responsible for definition and handling of a symbol text - * representation. In the libary it is used to define symbols of units and prefixes. - * Each symbol can have two versions: Unicode and ASCI-only. - * - * @tparam StandardCharT Character type to be used for a Unicode representation - * @tparam N The size of a Unicode symbol - * @tparam M The size of the ASCII-only symbol - */ -template -struct basic_symbol_text { - basic_fixed_string standard_; - basic_fixed_string ascii_; - - constexpr basic_symbol_text(char std) noexcept : standard_(std), ascii_(std) { detail::validate_ascii_char(std); } - constexpr basic_symbol_text(StandardCharT std, char a) noexcept : standard_(std), ascii_(a) - { - detail::validate_ascii_char(a); - } - constexpr basic_symbol_text(const char (&std)[N + 1]) noexcept : standard_(std), ascii_(std) - { - detail::validate_ascii_string(std); - } - constexpr basic_symbol_text(const basic_fixed_string& std) noexcept : standard_(std), ascii_(std) - { - detail::validate_ascii_string(std.data_); - } - constexpr basic_symbol_text(const StandardCharT (&std)[N + 1], const char (&ascii)[M + 1]) noexcept : - standard_(std), ascii_(ascii) - { - detail::validate_ascii_string(ascii); - } - constexpr basic_symbol_text(const basic_fixed_string& std, - const basic_fixed_string& ascii) noexcept : - standard_(std), ascii_(ascii) - { - detail::validate_ascii_string(ascii.data_); - } - - [[nodiscard]] constexpr auto& standard() { return standard_; } - [[nodiscard]] constexpr const auto& standard() const { return standard_; } - [[nodiscard]] constexpr auto& ascii() { return ascii_; } - [[nodiscard]] constexpr const auto& ascii() const { return ascii_; } - - template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_symbol_text& lhs, const basic_symbol_text& rhs) noexcept - { - return basic_symbol_text(lhs.standard() + rhs.standard(), lhs.ascii() + rhs.ascii()); - } - - template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_symbol_text& lhs, const basic_fixed_string& rhs) noexcept - { - return lhs + basic_symbol_text(rhs); - } - - template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_fixed_string& lhs, const basic_symbol_text& rhs) noexcept - { - return basic_symbol_text(lhs) + rhs; - } - - template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const basic_symbol_text& lhs, const StandardCharT (&rhs)[N2]) noexcept - { - return lhs + basic_symbol_text(rhs); - } - - template - [[nodiscard]] constexpr friend basic_symbol_text operator+( - const StandardCharT (&lhs)[N2], const basic_symbol_text& rhs) noexcept - { - return basic_symbol_text(lhs) + rhs; - } - - [[nodiscard]] constexpr friend basic_symbol_text operator+(const basic_symbol_text& lhs, - StandardCharT rhs) noexcept - { - return lhs + basic_symbol_text(rhs); - } - - [[nodiscard]] constexpr friend basic_symbol_text operator+( - StandardCharT lhs, const basic_symbol_text& rhs) noexcept - { - return basic_symbol_text(lhs) + rhs; - } - - template - [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - UNITS_DIAGNOSTIC_PUSH - UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT - if (const auto cmp = lhs.standard() <=> rhs.standard(); cmp != 0) return cmp; - UNITS_DIAGNOSTIC_POP - return lhs.ascii() <=> rhs.ascii(); - } - - template - [[nodiscard]] friend constexpr bool operator==(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return lhs.standard() == rhs.standard() && lhs.ascii() == rhs.ascii(); - } -}; - -basic_symbol_text(char) -> basic_symbol_text; - -template -basic_symbol_text(StandardCharT, char) -> basic_symbol_text; - -template -basic_symbol_text(const char (&)[N]) -> basic_symbol_text; - -template -basic_symbol_text(const basic_fixed_string&) -> basic_symbol_text; - -template -basic_symbol_text(const StandardCharT (&)[N], const char (&)[M]) -> basic_symbol_text; - -template -basic_symbol_text(const basic_fixed_string&, const basic_fixed_string&) - -> basic_symbol_text; - -} // namespace units diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h deleted file mode 100644 index a79dea07..00000000 --- a/src/core/include/units/unit.h +++ /dev/null @@ -1,233 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units { - -namespace detail { - -template -inline constexpr bool can_be_prefixed = false; - -} // namespace detail - -/** - * @brief A common point for a hierarchy of units - * - * A unit is an entity 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. - * - * All units of the same dimension can be convereted between each other. To allow this all of - * them are expressed as different ratios of the same one proprietary chosen reference unit - * (i.e. all length units are expressed in terms of meter, all mass units are expressed in - * terms of gram, ...) - * - * @tparam M a Magnitude representing the (relative) size of this unit - * @tparam U a unit to use as a reference for this dimension - * - * @note U cannot be constrained with Unit as for some specializations (i.e. named_unit) - * it gets the incomplete child's type with the CRTP idiom. - */ -template -struct scaled_unit : downcast_base> { - static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M; - using reference = U; -}; - -template -using downcast_unit = downcast::reference>>; - -template -struct same_unit_reference : is_same {}; - -/** - * @brief A named unit - * - * Defines a named (in most cases coherent) unit that is then passed to a dimension definition. - * A named unit may be composed with a prefix to create a prefixed_unit. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam Symbol a short text representation of the unit - */ -template -struct named_unit : downcast_dispatch(), Child>> { - static constexpr auto symbol = Symbol; -}; - -/** - * @brief A named scaled unit - * - * Defines a new named unit that is a scaled version of another unit. - * A named unit may be composed with a prefix to create a prefixed_unit. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam Symbol a short text representation of the unit - * @tparam M the Magnitude by which to scale U - * @tparam U a reference unit to scale - */ -template -struct named_scaled_unit : downcast_dispatch> { - static constexpr auto symbol = Symbol; -}; - -/** - * @brief A prefixed unit - * - * Defines a new unit that is a scaled version of another unit by the provided prefix. It is - * only possible to create such a unit if the given prefix type matches the one defined in a - * reference unit. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam P prefix to be appied to the reference unit - * @tparam U reference unit - */ -template - requires detail::can_be_prefixed -struct prefixed_unit : downcast_dispatch> { - static constexpr auto symbol = P::symbol + U::symbol; -}; - -/** - * @brief A coherent unit of a derived quantity - * - * Defines a new coherent unit of a derived quantity. It should be passed as a coherent unit - * in the dimension's definition for such a quantity. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - */ -template -struct derived_unit : downcast_dispatch(), Child>> {}; - -/** - * @brief A unit with a deduced ratio and symbol - * - * Defines a new unit with a deduced ratio and symbol based on the recipe from the provided - * derived dimension. The number and order of provided units should match the recipe of the - * derived dimension. All of the units provided should also be a named ones so it is possible - * to create a deduced symbol text. - * - * @tparam Child inherited class type used by the downcasting facility (CRTP Idiom) - * @tparam Dim a derived dimension recipe to use for deduction - * @tparam U the unit of the first composite dimension from provided derived dimension's recipe - * @tparam URest the units for the rest of dimensions from the recipe - */ -template - requires detail::compatible_units -struct derived_scaled_unit : downcast_dispatch> { - static constexpr auto symbol = detail::derived_symbol_text(); -}; - -/** - * @brief An aliased named unit - * - * Defines a named alias for another unit. It is useful to assign alternative names and symbols - * to the already predefined units (i.e. "tonne" for "megagram"). - * A alias unit may be composed with a prefix to create a prefixed_alias_unit. - * - * @tparam U Unit for which an alias is defined - * @tparam Symbol a short text representation of the unit - */ -template -struct alias_unit : U { - static constexpr auto symbol = Symbol; -}; - -/** - * @brief A prefixed alias unit - * - * Defines a new unit that is an alias for a scaled version of another unit by the provided - * prefix. It is only possible to create such a unit if the given prefix type matches the one - * defined in a reference unit. - * - * @tparam U Unit for which an alias is defined - * @tparam P prefix to be appied to the reference unit - * @tparam AU reference alias unit - */ -template - requires(!AliasUnit) -struct prefixed_alias_unit : U { - static constexpr auto symbol = P::symbol + AU::symbol; -}; - -/** - * @brief Unknown coherent unit - * - * Used as a coherent unit of an unknown dimension. - */ -template -struct unknown_coherent_unit : - downcast_dispatch, - scaled_unit()), unknown_coherent_unit>> {}; - -namespace detail { - -template -void is_named_impl(const volatile named_unit*); - -template -void is_named_impl(const volatile named_scaled_unit*); - -template -void is_named_impl(const volatile prefixed_unit*); - -template -void is_named_impl(const volatile alias_unit*); - -template -void is_named_impl(const volatile prefixed_alias_unit*); - -template -inline constexpr bool is_named = requires(U* u) { is_named_impl(u); }; - -template -void can_be_prefixed_impl(const volatile named_unit*); - -template -void can_be_prefixed_impl(const volatile named_scaled_unit*); - -template -void can_be_prefixed_impl(const volatile alias_unit*); - -template -inline constexpr bool can_be_prefixed = requires(U* u) { can_be_prefixed_impl(u); }; - -template -inline constexpr bool can_be_prefixed> = can_be_prefixed; - -} // namespace detail - -} // namespace units diff --git a/src/systems/CMakeLists.txt b/src/systems/CMakeLists.txt index 06a3169d..b21c786b 100644 --- a/src/systems/CMakeLists.txt +++ b/src/systems/CMakeLists.txt @@ -23,36 +23,38 @@ cmake_minimum_required(VERSION 3.19) # systems +add_subdirectory(angular) +add_subdirectory(iec80000) add_subdirectory(isq) -add_subdirectory(isq-iec80000) -add_subdirectory(isq-natural) +add_subdirectory(isq_angle) +add_subdirectory(natural) add_subdirectory(si) -add_subdirectory(si-cgs) -add_subdirectory(si-fps) -add_subdirectory(si-hep) -add_subdirectory(si-iau) -add_subdirectory(si-imperial) -add_subdirectory(si-international) -add_subdirectory(si-typographic) -add_subdirectory(si-uscs) +add_subdirectory(cgs) +add_subdirectory(hep) +add_subdirectory(iau) +add_subdirectory(imperial) +add_subdirectory(international) +add_subdirectory(typographic) +add_subdirectory(usc) # wrapper for all the systems add_library(mp-units-systems INTERFACE) target_link_libraries( mp-units-systems INTERFACE + mp-units::angular + mp-units::iec80000 mp-units::isq - mp-units::isq-iec80000 - mp-units::isq-natural + mp-units::isq_angle + mp-units::natural mp-units::si - mp-units::si-cgs - mp-units::si-fps - mp-units::si-hep - mp-units::si-iau - mp-units::si-imperial - mp-units::si-international - mp-units::si-typographic - mp-units::si-uscs + mp-units::cgs + mp-units::hep + mp-units::iau + mp-units::imperial + mp-units::international + mp-units::typographic + mp-units::usc ) add_library(mp-units::systems ALIAS mp-units-systems) set_target_properties(mp-units-systems PROPERTIES EXPORT_NAME systems) diff --git a/src/systems/si-uscs/CMakeLists.txt b/src/systems/angular/CMakeLists.txt similarity index 84% rename from src/systems/si-uscs/CMakeLists.txt rename to src/systems/angular/CMakeLists.txt index ed94647d..2c7886b2 100644 --- a/src/systems/si-uscs/CMakeLists.txt +++ b/src/systems/angular/CMakeLists.txt @@ -22,7 +22,4 @@ cmake_minimum_required(VERSION 3.19) -add_units_module( - si-uscs DEPENDENCIES mp-units::si HEADERS include/units/isq/si/uscs/length.h include/units/isq/si/uscs/pressure.h - include/units/isq/si/uscs/uscs.h -) +add_units_module(angular DEPENDENCIES mp-units::isq HEADERS include/mp-units/systems/angular/angular.h) diff --git a/src/systems/angular/include/mp-units/systems/angular/angular.h b/src/systems/angular/include/mp-units/systems/angular/angular.h new file mode 100644 index 00000000..cfe1e192 --- /dev/null +++ b/src/systems/angular/include/mp-units/systems/angular/angular.h @@ -0,0 +1,55 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::angular { + +// clang-format off +inline constexpr struct dim_angle : base_dimension<"A"> {} dim_angle; +QUANTITY_SPEC(angle, dim_angle); +QUANTITY_SPEC(solid_angle, pow<2>(angle)); + +inline constexpr struct radian : named_unit<"rad", kind_of> {} radian; +inline constexpr struct revolution : named_unit<"rev", mag<2> * mag_pi * radian> {} revolution; +inline constexpr struct degree : named_unit * revolution> {} degree; +inline constexpr struct gradian : named_unit * revolution> {} gradian; +inline constexpr struct steradian : named_unit<"sr", square(radian)> {} steradian; +// clang-format on + +namespace unit_symbols { + +inline constexpr auto rad = radian; +inline constexpr auto rev = revolution; +inline constexpr auto deg = degree; +inline constexpr auto grad = gradian; +inline constexpr auto sr = steradian; +inline constexpr auto rad2 = square(radian); +inline constexpr auto deg2 = square(degree); + +} // namespace unit_symbols + +} // namespace mp_units::angular diff --git a/src/systems/cgs/CMakeLists.txt b/src/systems/cgs/CMakeLists.txt new file mode 100644 index 00000000..604b5937 --- /dev/null +++ b/src/systems/cgs/CMakeLists.txt @@ -0,0 +1,25 @@ +# 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.19) + +add_units_module(cgs DEPENDENCIES mp-units::si HEADERS include/mp-units/systems/cgs/cgs.h) diff --git a/src/systems/cgs/include/mp-units/systems/cgs/cgs.h b/src/systems/cgs/include/mp-units/systems/cgs/cgs.h new file mode 100644 index 00000000..69f4dcf8 --- /dev/null +++ b/src/systems/cgs/include/mp-units/systems/cgs/cgs.h @@ -0,0 +1,63 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::cgs { + +// clang-format off +inline constexpr struct centimetre : decltype(si::centi) {} centimetre; +inline constexpr struct gram : decltype(si::gram) {} gram; +inline constexpr struct second : decltype(si::second) {} second; +inline constexpr struct gal : named_unit<"Gal", centimetre / square(second)> {} gal; +inline constexpr struct dyne : named_unit<"dyn", gram * centimetre / square(second)> {} dyne; +inline constexpr struct erg : named_unit<"erg", dyne * centimetre> {} erg; +inline constexpr struct barye : named_unit<"Ba", gram / (centimetre * square(second))> {} barye; +inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} poise; +inline constexpr struct stokes : named_unit<"St", square(centimetre) / second> {} stokes; +inline constexpr struct kayser : named_unit<"K", 1 / centimetre> {} kayser; +// clang-format on + +namespace unit_symbols { + +inline constexpr auto cm = centimetre; +inline constexpr auto g = gram; +inline constexpr auto s = second; +inline constexpr auto Gal = gal; +inline constexpr auto dyn = dyne; +inline constexpr auto Ba = barye; +inline constexpr auto P = poise; +inline constexpr auto St = stokes; +inline constexpr auto K = kayser; + +// commonly used squared and cubic units +inline constexpr auto cm2 = square(centimetre); +inline constexpr auto cm3 = cubic(centimetre); +inline constexpr auto s2 = square(second); +inline constexpr auto s3 = cubic(second); + +} // namespace unit_symbols + +} // namespace mp_units::cgs diff --git a/src/systems/si-hep/CMakeLists.txt b/src/systems/hep/CMakeLists.txt similarity index 82% rename from src/systems/si-hep/CMakeLists.txt rename to src/systems/hep/CMakeLists.txt index 635d2981..b09581b4 100644 --- a/src/systems/si-hep/CMakeLists.txt +++ b/src/systems/hep/CMakeLists.txt @@ -22,8 +22,4 @@ cmake_minimum_required(VERSION 3.19) -add_units_module( - si-hep DEPENDENCIES mp-units::si - HEADERS include/units/isq/si/hep/area.h include/units/isq/si/hep/energy.h include/units/isq/si/hep/hep.h - include/units/isq/si/hep/mass.h include/units/isq/si/hep/momentum.h -) +add_units_module(hep DEPENDENCIES mp-units::si HEADERS include/mp-units/systems/hep/hep.h) diff --git a/src/systems/hep/include/mp-units/systems/hep/hep.h b/src/systems/hep/include/mp-units/systems/hep/hep.h new file mode 100644 index 00000000..8e6e2062 --- /dev/null +++ b/src/systems/hep/include/mp-units/systems/hep/hep.h @@ -0,0 +1,100 @@ +// The MIT License (MIT) +// +// Copyright (c) 2021 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::hep { + +// energy +using si::electronvolt; + +// clang-format off + +// area +// effective cross-sectional area according to EU council directive 80/181/EEC +// https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:01980L0181-20090527#page=10 +// https://www.fedlex.admin.ch/eli/cc/1994/3109_3109_3109/de +inline constexpr struct barn : named_unit<"b", mag_power<10, -28> * square(si::metre)> {} barn; + +// mass +inline constexpr struct electron_mass : named_unit<"m_e", mag * mag_power<10, -31> * si::kilogram> {} electron_mass; +inline constexpr struct proton_mass : named_unit<"m_p", mag * mag_power<10, -27> * si::kilogram> {} proton_mass; +inline constexpr struct neutron_mass : named_unit<"m_n", mag * mag_power<10, -27> * si::kilogram> {} neutron_mass; + +// speed +inline constexpr struct speed_of_light : decltype(si::si2019::speed_of_light_in_vacuum) {} speed_of_light; +// clang-format on + +namespace unit_symbols { + +using si::unit_symbols::eV; + +inline constexpr auto qeV = si::quecto; +inline constexpr auto reV = si::ronto; +inline constexpr auto yeV = si::yocto; +inline constexpr auto zeV = si::zepto; +inline constexpr auto aeV = si::atto; +inline constexpr auto feV = si::femto; +inline constexpr auto peV = si::pico; +inline constexpr auto neV = si::nano; +inline constexpr auto ueV = si::micro; +inline constexpr auto meV = si::milli; +inline constexpr auto ceV = si::centi; +inline constexpr auto deV = si::deci; +inline constexpr auto daeV = si::deca; +inline constexpr auto heV = si::hecto; +inline constexpr auto keV = si::kilo; +inline constexpr auto MeV = si::mega; +inline constexpr auto GeV = si::giga; +inline constexpr auto TeV = si::tera; +inline constexpr auto PeV = si::peta; +inline constexpr auto EeV = si::exa; +inline constexpr auto ZeV = si::zetta; +inline constexpr auto YeV = si::yotta; +inline constexpr auto ReV = si::ronna; +inline constexpr auto QeV = si::quetta; + +inline constexpr auto qb = si::quecto; +inline constexpr auto rb = si::ronto; +inline constexpr auto yb = si::yocto; +inline constexpr auto zb = si::zepto; +inline constexpr auto ab = si::atto; +inline constexpr auto fb = si::femto; +inline constexpr auto pb = si::pico; +inline constexpr auto nb = si::nano; +inline constexpr auto ub = si::micro; +inline constexpr auto mb = si::milli; +inline constexpr auto b = barn; + +inline constexpr auto m_e = electron_mass; +inline constexpr auto m_p = proton_mass; +inline constexpr auto m_n = neutron_mass; + +inline constexpr auto c = speed_of_light; +inline constexpr auto c2 = square(speed_of_light); + +} // namespace unit_symbols + +} // namespace mp_units::hep diff --git a/src/systems/iau/CMakeLists.txt b/src/systems/iau/CMakeLists.txt new file mode 100644 index 00000000..6f1cbd6d --- /dev/null +++ b/src/systems/iau/CMakeLists.txt @@ -0,0 +1,25 @@ +# 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.19) + +add_units_module(iau DEPENDENCIES mp-units::si HEADERS include/mp-units/systems/iau/iau.h) diff --git a/src/systems/iau/include/mp-units/systems/iau/iau.h b/src/systems/iau/include/mp-units/systems/iau/iau.h new file mode 100644 index 00000000..cb30008b --- /dev/null +++ b/src/systems/iau/include/mp-units/systems/iau/iau.h @@ -0,0 +1,97 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::iau { + +// https://en.wikipedia.org/wiki/Astronomical_system_of_units + +// clang-format off +// time +inline constexpr struct day : named_unit<"D", si::day> {} day; +inline constexpr struct Julian_year : named_unit<"a", mag * day> {} Julian_year; + +// mass +// https://en.wikipedia.org/wiki/Solar_mass +// TODO What is the official mass of sun (every source in the Internet provides a different value) +inline constexpr struct solar_mass : named_unit * mag_power<10, 30> * si::kilogram> {} solar_mass; +inline constexpr struct Jupiter_mass : named_unit<"M_JUP", mag * mag_power<10, 27> * si::kilogram> {} Jupiter_mass; +inline constexpr struct Earth_mass : named_unit<"M_EARTH", mag * mag_power<10, 24> * si::kilogram> {} Earth_mass; + +// length +inline constexpr struct astronomical_unit : decltype(si::astronomical_unit) {} astronomical_unit; + +// https://en.wikipedia.org/wiki/Lunar_distance_(astronomy) +inline constexpr struct lunar_distance : named_unit<"LD", mag<384'399> * si::kilo> {} lunar_distance; + +// https://en.wikipedia.org/wiki/Light-year +inline constexpr struct light_year : named_unit<"ly", mag<9'460'730'472'580'800> * si::metre> {} light_year; + +// https://en.wikipedia.org/wiki/Parsec +inline constexpr struct parsec : named_unit<"pc", astronomical_unit / (mag * si::degree)> {} parsec; + +// https://en.wikipedia.org/wiki/Angstrom +inline constexpr struct angstrom : named_unit * si::metre> {} angstrom; + +// selected constants +// https://en.wikipedia.org/wiki/Astronomical_constant +inline constexpr struct gaussian_gravitational_constant : + named_unit<"k", mag * pow<3, 2>(astronomical_unit) / pow<1,2>(solar_mass) / day> {} gaussian_gravitational_constant; + +inline constexpr struct speed_of_light : + named_unit {} speed_of_light; + +inline constexpr struct constant_of_gravitation : + named_unit<"G", mag * mag_power<10, -11> * cubic(si::metre) / si::kilogram / square(si::second)> {} constant_of_gravitation; + +inline constexpr struct hubble_constant : + named_unit * si::kilo / si::second / si::mega> {} hubble_constant; +// clang-format on + +namespace unit_symbols { + +inline constexpr auto D = day; +inline constexpr auto a = Julian_year; + +inline constexpr auto M_SUN = solar_mass; +inline constexpr auto M_JUP = Jupiter_mass; +inline constexpr auto M_EARTH = Earth_mass; + +inline constexpr auto au = astronomical_unit; +inline constexpr auto LD = lunar_distance; +inline constexpr auto ly = light_year; +inline constexpr auto pc = parsec; +inline constexpr auto A = angstrom; + +inline constexpr auto k = gaussian_gravitational_constant; +inline constexpr auto c_0 = speed_of_light; +inline constexpr auto G = constant_of_gravitation; +inline constexpr auto H_0 = hubble_constant; + +} // namespace unit_symbols + +} // namespace mp_units::iau diff --git a/src/systems/si-international/CMakeLists.txt b/src/systems/iec80000/CMakeLists.txt similarity index 78% rename from src/systems/si-international/CMakeLists.txt rename to src/systems/iec80000/CMakeLists.txt index 82c940fd..f1bd31ca 100644 --- a/src/systems/si-international/CMakeLists.txt +++ b/src/systems/iec80000/CMakeLists.txt @@ -23,9 +23,9 @@ cmake_minimum_required(VERSION 3.19) add_units_module( - si-international - DEPENDENCIES mp-units::si - HEADERS include/units/isq/si/international/area.h include/units/isq/si/international/international.h - include/units/isq/si/international/length.h include/units/isq/si/international/speed.h - include/units/isq/si/international/volume.h + iec80000 + DEPENDENCIES mp-units::isq mp-units::si + HEADERS include/mp-units/systems/iec80000/binary_prefixes.h include/mp-units/systems/iec80000/quantities.h + include/mp-units/systems/iec80000/iec80000.h include/mp-units/systems/iec80000/unit_symbols.h + include/mp-units/systems/iec80000/units.h ) diff --git a/src/systems/iec80000/include/mp-units/systems/iec80000/binary_prefixes.h b/src/systems/iec80000/include/mp-units/systems/iec80000/binary_prefixes.h new file mode 100644 index 00000000..ca3db21e --- /dev/null +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/binary_prefixes.h @@ -0,0 +1,49 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include + +namespace mp_units::iec80000 { + +// clang-format off +template struct kibi_ : prefixed_unit<"Ki", mag_power<2, 10>, U> {}; +template struct mebi_ : prefixed_unit<"Mi", mag_power<2, 20>, U> {}; +template struct gibi_ : prefixed_unit<"Gi", mag_power<2, 30>, U> {}; +template struct tebi_ : prefixed_unit<"Ti", mag_power<2, 40>, U> {}; +template struct pebi_ : prefixed_unit<"Pi", mag_power<2, 50>, U> {}; +template struct exbi_ : prefixed_unit<"Ei", mag_power<2, 60>, U> {}; +template struct zebi_ : prefixed_unit<"Zi", mag_power<2, 70>, U> {}; +template struct yobi_ : prefixed_unit<"Yi", mag_power<2, 80>, U> {}; + +template inline constexpr kibi_ kibi; +template inline constexpr mebi_ mebi; +template inline constexpr gibi_ gibi; +template inline constexpr tebi_ tebi; +template inline constexpr pebi_ pebi; +template inline constexpr exbi_ exbi; +template inline constexpr zebi_ zebi; +template inline constexpr yobi_ yobi; +// clang-format on + +} // namespace mp_units::iec80000 diff --git a/src/systems/isq-iec80000/include/units/isq/iec80000/iec80000.h b/src/systems/iec80000/include/mp-units/systems/iec80000/iec80000.h similarity index 85% rename from src/systems/isq-iec80000/include/units/isq/iec80000/iec80000.h rename to src/systems/iec80000/include/mp-units/systems/iec80000/iec80000.h index fd518fa4..9fd164b7 100644 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/iec80000.h +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/iec80000.h @@ -23,8 +23,8 @@ #pragma once // IWYU pragma: begin_exports -#include -#include -#include -#include +#include +#include +#include +#include // IWYU pragma: end_exports diff --git a/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h b/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h new file mode 100644 index 00000000..c436943a --- /dev/null +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h @@ -0,0 +1,73 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units::iec80000 { + +// dimensions of base quantities +// clang-format off +inline constexpr struct dim_traffic_intensity : base_dimension<"A"> {} dim_traffic_intensity; +// clang-format on + +// quantities +QUANTITY_SPEC(traffic_intensity, dim_traffic_intensity); +QUANTITY_SPEC(traffic_offered_intensity, traffic_intensity); +QUANTITY_SPEC(traffic_carried_intensity, traffic_intensity); +inline constexpr auto traffic_load = traffic_carried_intensity; +QUANTITY_SPEC(mean_queue_length, dimensionless); +QUANTITY_SPEC(loss_probability, dimensionless); +QUANTITY_SPEC(waiting_probability, dimensionless); +QUANTITY_SPEC(call_intensity, 1 / isq::duration); +inline constexpr auto calling_rate = call_intensity; +QUANTITY_SPEC(completed_call_intensity, call_intensity); +QUANTITY_SPEC(storage_capacity, dimensionless, is_kind); +inline constexpr auto storage_size = storage_capacity; +QUANTITY_SPEC(equivalent_binary_storage_capacity, storage_capacity); +QUANTITY_SPEC(transfer_rate, storage_capacity / isq::duration); +QUANTITY_SPEC(period_of_data_elements, isq::period, 1 / transfer_rate); +QUANTITY_SPEC(binary_digit_rate, transfer_rate); +inline constexpr auto bit_rate = binary_digit_rate; +QUANTITY_SPEC(period_of_binary_digits, isq::period, 1 / binary_digit_rate); +inline constexpr auto bit_period = period_of_binary_digits; +QUANTITY_SPEC(equivalent_binary_digit_rate, binary_digit_rate); +inline constexpr auto equivalent_bit_rate = bit_rate; +QUANTITY_SPEC(modulation_rate, 1 / isq::duration); +inline constexpr auto line_digit_rate = modulation_rate; +QUANTITY_SPEC(quantizing_distortion_power, isq::power); +QUANTITY_SPEC(carrier_power, isq::power); +QUANTITY_SPEC(signal_energy_per_binary_digit, carrier_power* period_of_binary_digits); +QUANTITY_SPEC(error_probability, dimensionless); +QUANTITY_SPEC(Hamming_distance, dimensionless); +QUANTITY_SPEC(clock_frequency, isq::frequency); +inline constexpr auto clock_rate = clock_frequency; +QUANTITY_SPEC(decision_content, dimensionless); + +// TODO how to model information_content and the following quantities??? +// QUANTITY_SPEC(information_content, ...); + +} // namespace mp_units::iec80000 diff --git a/src/systems/iec80000/include/mp-units/systems/iec80000/unit_symbols.h b/src/systems/iec80000/include/mp-units/systems/iec80000/unit_symbols.h new file mode 100644 index 00000000..476544e9 --- /dev/null +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/unit_symbols.h @@ -0,0 +1,109 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::iec80000::unit_symbols { + +// bit +inline constexpr auto kbit = si::kilo; +inline constexpr auto Mbit = si::mega; +inline constexpr auto Gbit = si::giga; +inline constexpr auto Tbit = si::tera; +inline constexpr auto Pbit = si::peta; +inline constexpr auto Ebit = si::exa; +inline constexpr auto Zbit = si::zetta; +inline constexpr auto Ybit = si::yotta; +inline constexpr auto Rbit = si::ronna; +inline constexpr auto Qbit = si::quetta; + +inline constexpr auto Kibit = kibi; +inline constexpr auto Mibit = mebi; +inline constexpr auto Gibit = gibi; +inline constexpr auto Tibit = tebi; +inline constexpr auto Pibit = pebi; +inline constexpr auto Eibit = exbi; + +// octet +inline constexpr auto o = octet; + +inline constexpr auto ko = si::kilo; +inline constexpr auto Mo = si::mega; +inline constexpr auto Go = si::giga; +inline constexpr auto To = si::tera; +inline constexpr auto Po = si::peta; +inline constexpr auto Eo = si::exa; +inline constexpr auto Zo = si::zetta; +inline constexpr auto Yo = si::yotta; +inline constexpr auto Ro = si::ronna; +inline constexpr auto Qo = si::quetta; + +inline constexpr auto Kio = kibi; +inline constexpr auto Mio = mebi; +inline constexpr auto Gio = gibi; +inline constexpr auto Tio = tebi; +inline constexpr auto Pio = pebi; +inline constexpr auto Eio = exbi; + +// byte +inline constexpr auto B = byte; + +inline constexpr auto kB = si::kilo; +inline constexpr auto MB = si::mega; +inline constexpr auto GB = si::giga; +inline constexpr auto TB = si::tera; +inline constexpr auto PB = si::peta; +inline constexpr auto EB = si::exa; +inline constexpr auto ZB = si::zetta; +inline constexpr auto YB = si::yotta; +inline constexpr auto RB = si::ronna; +inline constexpr auto QB = si::quetta; + +inline constexpr auto KiB = kibi; +inline constexpr auto MiB = mebi; +inline constexpr auto GiB = gibi; +inline constexpr auto TiB = tebi; +inline constexpr auto PiB = pebi; +inline constexpr auto EiB = exbi; + +// baud +inline constexpr auto Bd = baud; +inline constexpr auto kBd = si::kilo; +inline constexpr auto MBd = si::mega; +inline constexpr auto GBd = si::giga; +inline constexpr auto TBd = si::tera; +inline constexpr auto PBd = si::peta; +inline constexpr auto EBd = si::exa; +inline constexpr auto ZBd = si::zetta; +inline constexpr auto YBd = si::yotta; +inline constexpr auto RBd = si::ronna; +inline constexpr auto QBd = si::quetta; + +// erlang +// TODO do we need prefixed versions of Erlang? +inline constexpr auto E = erlang; + +} // namespace mp_units::iec80000::unit_symbols diff --git a/src/systems/isq/include/units/isq/dimensions/luminous_intensity.h b/src/systems/iec80000/include/mp-units/systems/iec80000/units.h similarity index 65% rename from src/systems/isq/include/units/isq/dimensions/luminous_intensity.h rename to src/systems/iec80000/include/mp-units/systems/iec80000/units.h index fb04a3fe..2bbe05cf 100644 --- a/src/systems/isq/include/units/isq/dimensions/luminous_intensity.h +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/units.h @@ -22,14 +22,18 @@ #pragma once -#include +#include +#include +#include -namespace units::isq { +namespace mp_units::iec80000 { -template -struct dim_luminous_intensity : base_dimension<"J", U> {}; +// clang-format off +inline constexpr struct erlang : named_unit<"E", kind_of> {} erlang; +inline constexpr struct bit : named_unit<"bit", one, kind_of> {} bit; +inline constexpr struct octet : named_unit<"o", mag<8> * bit> {} octet; +inline constexpr struct byte : named_unit<"B", mag<8> * bit> {} byte; +inline constexpr struct baud : named_unit<"Bd", 1 / si::second, kind_of> {} baud; +// clang-format on -template -concept LuminousIntensity = QuantityOfT; - -} // namespace units::isq +} // namespace mp_units::iec80000 diff --git a/src/systems/si-imperial/CMakeLists.txt b/src/systems/imperial/CMakeLists.txt similarity index 86% rename from src/systems/si-imperial/CMakeLists.txt rename to src/systems/imperial/CMakeLists.txt index 3a441611..cdde9f2f 100644 --- a/src/systems/si-imperial/CMakeLists.txt +++ b/src/systems/imperial/CMakeLists.txt @@ -23,6 +23,5 @@ cmake_minimum_required(VERSION 3.19) add_units_module( - si-imperial DEPENDENCIES mp-units::si HEADERS include/units/isq/si/imperial/imperial.h - include/units/isq/si/imperial/length.h + imperial DEPENDENCIES mp-units::si mp-units::international HEADERS include/mp-units/systems/imperial/imperial.h ) diff --git a/src/systems/imperial/include/mp-units/systems/imperial/imperial.h b/src/systems/imperial/include/mp-units/systems/imperial/imperial.h new file mode 100644 index 00000000..e99ae860 --- /dev/null +++ b/src/systems/imperial/include/mp-units/systems/imperial/imperial.h @@ -0,0 +1,98 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::imperial { + +using namespace international; + +// clang-format off +// https://en.wikipedia.org/wiki/Imperial_units#Length +inline constexpr struct hand : named_unit<"hh", mag * foot> {} hand; +inline constexpr struct barleycorn : named_unit<"Bc", mag * inch> {} barleycorn; +inline constexpr struct thou : named_unit<"th", mag * foot> {} thou; +inline constexpr struct chain : named_unit<"ch", mag<22> * yard> {} chain; +inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; + +// maritime units +inline constexpr struct cable : named_unit<"cb", mag * nautical_mile> {} cable; +inline constexpr struct fathom : named_unit<"ftm", mag * nautical_mile> {} fathom; + +// survey +inline constexpr struct link : named_unit<"li", mag * chain> {} link; +inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod; + +// https://en.wikipedia.org/wiki/Imperial_units#Area +inline constexpr struct perch : decltype(square(rod)) {} perch; +inline constexpr struct rood : decltype(mag<40> * perch) {} rood; +inline constexpr struct acre : decltype(mag<4> * rood) {} acre; + +// https://en.wikipedia.org/wiki/Imperial_units#Volume +inline constexpr struct gallon : named_unit<"gal", mag * si::litre> {} gallon; +inline constexpr struct quart : named_unit<"qt", mag * gallon> {} quart; +inline constexpr struct pint : named_unit<"pt", mag * quart> {} pint; +inline constexpr struct gill : named_unit<"gi", mag * pint> {} gill; +inline constexpr struct fluid_ounce : named_unit<"fl oz", mag * gill> {} fluid_ounce; + +// https://en.wikipedia.org/wiki/Avoirdupois_system#Post-Elizabethan_units +inline constexpr auto drachm = dram; +inline constexpr struct stone : named_unit<"st", mag<14> * pound> {} stone; +inline constexpr struct quarter : named_unit<"qr", mag<2> * stone> {} quarter; +inline constexpr struct long_hundredweight : named_unit<"cwt", mag<8> * stone> {} long_hundredweight; +inline constexpr struct ton : named_unit<"t", mag<2'240> * pound> {} ton; +inline constexpr auto long_ton = ton; +// clang-format on + +namespace unit_symbols { + +using namespace international::unit_symbols; + +inline constexpr auto hh = hand; +inline constexpr auto Bc = barleycorn; +inline constexpr auto th = thou; +inline constexpr auto ch = chain; +inline constexpr auto fur = furlong; + +inline constexpr auto cb = cable; +inline constexpr auto ftm = fathom; + +inline constexpr auto li = link; +inline constexpr auto rd = rod; + +inline constexpr auto gal = gallon; +inline constexpr auto qt = quart; +inline constexpr auto pt = pint; +inline constexpr auto gi = gill; +inline constexpr auto fl_oz = fluid_ounce; + +inline constexpr auto st = stone; +inline constexpr auto qr = quarter; +inline constexpr auto cwt = long_hundredweight; +inline constexpr auto t = ton; + +} // namespace unit_symbols + +} // namespace mp_units::imperial diff --git a/src/systems/international/CMakeLists.txt b/src/systems/international/CMakeLists.txt new file mode 100644 index 00000000..36844f97 --- /dev/null +++ b/src/systems/international/CMakeLists.txt @@ -0,0 +1,25 @@ +# 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.19) + +add_units_module(international DEPENDENCIES mp-units::si HEADERS include/mp-units/systems/international/international.h) diff --git a/src/systems/international/include/mp-units/systems/international/international.h b/src/systems/international/include/mp-units/systems/international/international.h new file mode 100644 index 00000000..dc0731f6 --- /dev/null +++ b/src/systems/international/include/mp-units/systems/international/international.h @@ -0,0 +1,101 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::international { + +// clang-format off +// mass +inline constexpr struct pound : named_unit<"lb", mag * si::kilogram> {} pound; +inline constexpr struct ounce : named_unit<"oz", mag * pound> {} ounce; +inline constexpr struct dram : named_unit<"dr", mag * ounce> {} dram; +inline constexpr struct grain : named_unit<"gr", mag * pound> {} grain; + +// length +// https://en.wikipedia.org/wiki/United_States_customary_units#Length +inline constexpr struct yard : named_unit<"yd", mag * si::metre> {} yard; +inline constexpr struct foot : named_unit<"ft", mag * yard> {} foot; +inline constexpr struct inch : named_unit<"in", mag * foot> {} inch; +inline constexpr struct pica : named_unit<"P", mag * inch> {} pica; +inline constexpr struct point : named_unit<"p", mag * pica> {} point; +inline constexpr struct mil : named_unit<"mil", mag * inch> {} mil; +inline constexpr struct twip : named_unit<"twip", mag * point> {} twip; +inline constexpr struct mile : named_unit<"mi", mag<1760> * yard> {} mile; +inline constexpr struct league : named_unit<"le", mag<3> * mile> {} league; + +inline constexpr struct nautical_mile : named_unit<"nmi", mag<1852> * si::metre> {} nautical_mile; + +// speed +inline constexpr struct knot : named_unit<"kn", nautical_mile / si::hour> {} knot; + +// force +// https://en.wikipedia.org/wiki/Poundal +inline constexpr struct poundal : named_unit<"pdl", pound * foot / square(si::second)> {} poundal; + +// https://en.wikipedia.org/wiki/Pound_(force) +inline constexpr struct pound_force : named_unit<"lbf", pound * si::standard_gravity> {} pound_force; + +// https://en.wikipedia.org/wiki/Kip_(unit), +inline constexpr struct kip : decltype(si::kilo) {} kip; + +// pressure +inline constexpr struct psi : named_unit<"psi", pound_force / square(inch)> {} psi; + +// power +// https://en.wikipedia.org/wiki/Horsepower#Definitions +inline constexpr struct mechanical_horsepower : named_unit<"hp(I)", mag<33'000> * foot * pound_force / si::minute> {} mechanical_horsepower; +// clang-format on + + +namespace unit_symbols { + +inline constexpr auto lb = pound; +inline constexpr auto oz = ounce; +inline constexpr auto dr = dram; +inline constexpr auto gr = grain; + +inline constexpr auto yd = yard; +inline constexpr auto ft = foot; +inline constexpr auto in = inch; +inline constexpr auto P = pica; +inline constexpr auto p = point; +inline constexpr auto mi = mile; +inline constexpr auto le = league; + +inline constexpr auto nmi = nautical_mile; + +inline constexpr auto kn = knot; +inline constexpr auto kt = knot; +inline constexpr auto mph = mile / si::hour; + +inline constexpr auto pdl = poundal; +inline constexpr auto lbf = pound_force; + +inline constexpr auto hp = mechanical_horsepower; + +} // namespace unit_symbols + +} // namespace mp_units::international diff --git a/src/systems/isq-iec80000/CMakeLists.txt b/src/systems/isq-iec80000/CMakeLists.txt deleted file mode 100644 index b2caa696..00000000 --- a/src/systems/isq-iec80000/CMakeLists.txt +++ /dev/null @@ -1,31 +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.19) - -add_units_module( - isq-iec80000 - DEPENDENCIES mp-units::si - HEADERS include/units/isq/iec80000/binary_prefixes.h include/units/isq/iec80000/iec80000.h - include/units/isq/iec80000/modulation_rate.h include/units/isq/iec80000/storage_capacity.h - include/units/isq/iec80000/traffic_intensity.h include/units/isq/iec80000/transfer_rate.h -) diff --git a/src/systems/isq-iec80000/include/units/isq/iec80000/binary_prefixes.h b/src/systems/isq-iec80000/include/units/isq/iec80000/binary_prefixes.h deleted file mode 100644 index 95133401..00000000 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/binary_prefixes.h +++ /dev/null @@ -1,38 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq::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()> {}; - -} // namespace units::isq::iec80000 diff --git a/src/systems/isq-iec80000/include/units/isq/iec80000/modulation_rate.h b/src/systems/isq-iec80000/include/units/isq/iec80000/modulation_rate.h deleted file mode 100644 index 40bf6d24..00000000 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/modulation_rate.h +++ /dev/null @@ -1,158 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::iec80000 { - -struct baud : alias_unit {}; -struct kilobaud : prefixed_alias_unit {}; -struct megabaud : prefixed_alias_unit {}; -struct gigabaud : prefixed_alias_unit {}; -struct terabaud : prefixed_alias_unit {}; -struct petabaud : prefixed_alias_unit {}; -struct exabaud : prefixed_alias_unit {}; -struct zettabaud : prefixed_alias_unit {}; -struct yottabaud : prefixed_alias_unit {}; - -// TODO alias_dimension -using dim_modulation_rate = si::dim_frequency; - -template U, Representation Rep = double> -using modulation_rate = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -constexpr auto operator"" _q_Bd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_kBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_MBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_GBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_TBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_PBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_EBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_ZBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} -constexpr auto operator"" _q_YBd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return modulation_rate(static_cast(l)); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace modulation_rate_references { - -inline constexpr auto Bd = reference{}; -inline constexpr auto kBd = reference{}; -inline constexpr auto MBd = reference{}; -inline constexpr auto GBd = reference{}; -inline constexpr auto TBd = reference{}; -inline constexpr auto PBd = reference{}; -inline constexpr auto EBd = reference{}; -inline constexpr auto ZBd = reference{}; -inline constexpr auto YBd = reference{}; - -} // namespace modulation_rate_references - -namespace references { - -using namespace modulation_rate_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::iec80000 - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::iec80000::inline modulation_rate { - -template -using Bd = units::isq::iec80000::modulation_rate; -template -using kBd = units::isq::iec80000::modulation_rate; -template -using MBd = units::isq::iec80000::modulation_rate; -template -using GBd = units::isq::iec80000::modulation_rate; -template -using TBd = units::isq::iec80000::modulation_rate; -template -using PBd = units::isq::iec80000::modulation_rate; -template -using EBd = units::isq::iec80000::modulation_rate; -template -using ZBd = units::isq::iec80000::modulation_rate; -template -using YBd = units::isq::iec80000::modulation_rate; - -} // namespace units::aliases::isq::iec80000::inline modulation_rate - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-iec80000/include/units/isq/iec80000/storage_capacity.h b/src/systems/isq-iec80000/include/units/isq/iec80000/storage_capacity.h deleted file mode 100644 index 2ca2f0d7..00000000 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/storage_capacity.h +++ /dev/null @@ -1,373 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::iec80000 { - -struct bit : named_unit {}; - -struct kilobit : prefixed_unit {}; -struct megabit : prefixed_unit {}; -struct gigabit : prefixed_unit {}; -struct terabit : prefixed_unit {}; -struct petabit : prefixed_unit {}; -struct exabit : prefixed_unit {}; -struct zettabit : prefixed_unit {}; -struct yottabit : prefixed_unit {}; - -struct kibibit : prefixed_unit {}; -struct mebibit : prefixed_unit {}; -struct gibibit : prefixed_unit {}; -struct tebibit : prefixed_unit {}; -struct pebibit : prefixed_unit {}; -struct exbibit : prefixed_unit {}; - -struct byte : named_scaled_unit(), bit> {}; - -struct kilobyte : prefixed_unit {}; -struct megabyte : prefixed_unit {}; -struct gigabyte : prefixed_unit {}; -struct terabyte : prefixed_unit {}; -struct petabyte : prefixed_unit {}; -struct exabyte : prefixed_unit {}; -struct zettabyte : prefixed_unit {}; -struct yottabyte : prefixed_unit {}; - -struct kibibyte : prefixed_unit {}; -struct mebibyte : prefixed_unit {}; -struct gibibyte : prefixed_unit {}; -struct tebibyte : prefixed_unit {}; -struct pebibyte : prefixed_unit {}; -// struct exbibyte : prefixed_unit {}; - -struct dim_storage_capacity : base_dimension<"M", byte> {}; - -template -concept StorageCapacity = QuantityOf; - -template U, Representation Rep = double> -using storage_capacity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// bits -constexpr auto operator"" _q_bit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} - -constexpr auto operator"" _q_kbit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Mbit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Gbit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Tbit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Pbit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Ebit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Zbit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Ybit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} - -constexpr auto operator"" _q_Kibit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Mibit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Gibit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Tibit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Pibit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_Eibit(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} - -// bytes -constexpr auto operator"" _q_B(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} - -constexpr auto operator"" _q_kB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_MB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_GB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_TB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_PB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_EB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_ZB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_YB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} - -constexpr auto operator"" _q_KiB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_MiB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_GiB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_TiB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -constexpr auto operator"" _q_PiB(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return storage_capacity(static_cast(l)); -} -// constexpr auto operator"" _q_EiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return -// storage_capacity(static_cast(l)); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace storage_capacity_references { - -// bits -inline constexpr auto bit = reference{}; - -inline constexpr auto kbit = reference{}; -inline constexpr auto Mbit = reference{}; -inline constexpr auto Gbit = reference{}; -inline constexpr auto Tbit = reference{}; -inline constexpr auto Pbit = reference{}; -inline constexpr auto Ebit = reference{}; -inline constexpr auto Zbit = reference{}; -inline constexpr auto Ybit = reference{}; - -inline constexpr auto Kibit = reference{}; -inline constexpr auto Mibit = reference{}; -inline constexpr auto Gibit = reference{}; -inline constexpr auto Tibit = reference{}; -inline constexpr auto Pibit = reference{}; -inline constexpr auto Eibit = reference{}; - -// bytes -inline constexpr auto B = reference{}; - -inline constexpr auto kB = reference{}; -inline constexpr auto MB = reference{}; -inline constexpr auto GB = reference{}; -inline constexpr auto TB = reference{}; -inline constexpr auto PB = reference{}; -inline constexpr auto EB = reference{}; -inline constexpr auto ZB = reference{}; -inline constexpr auto YB = reference{}; - -inline constexpr auto KiB = reference{}; -inline constexpr auto MiB = reference{}; -inline constexpr auto GiB = reference{}; -inline constexpr auto TiB = reference{}; -inline constexpr auto PiB = reference{}; -// inline constexpr auto EiB = reference{}; - -} // namespace storage_capacity_references - -namespace references { - -using namespace storage_capacity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::iec80000 - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::iec80000::inline storage_capacity { - -// bits -template -using bit = units::isq::iec80000::storage_capacity; - -template -using kbit = units::isq::iec80000::storage_capacity; -template -using Mbit = units::isq::iec80000::storage_capacity; -template -using Gbit = units::isq::iec80000::storage_capacity; -template -using Tbit = units::isq::iec80000::storage_capacity; -template -using Pbit = units::isq::iec80000::storage_capacity; -template -using Ebit = units::isq::iec80000::storage_capacity; -template -using Zbit = units::isq::iec80000::storage_capacity; -template -using Ybit = units::isq::iec80000::storage_capacity; - -template -using Kibit = units::isq::iec80000::storage_capacity; -template -using Mibit = units::isq::iec80000::storage_capacity; -template -using Gibit = units::isq::iec80000::storage_capacity; -template -using Tibit = units::isq::iec80000::storage_capacity; -template -using Pibit = units::isq::iec80000::storage_capacity; -template -using Eibit = units::isq::iec80000::storage_capacity; - -// bytes -template -using B = units::isq::iec80000::storage_capacity; - -template -using kB = units::isq::iec80000::storage_capacity; -template -using MB = units::isq::iec80000::storage_capacity; -template -using GB = units::isq::iec80000::storage_capacity; -template -using TB = units::isq::iec80000::storage_capacity; -template -using PB = units::isq::iec80000::storage_capacity; -template -using EB = units::isq::iec80000::storage_capacity; -template -using ZB = units::isq::iec80000::storage_capacity; -template -using YB = units::isq::iec80000::storage_capacity; - -template -using KiB = units::isq::iec80000::storage_capacity; -template -using MiB = units::isq::iec80000::storage_capacity; -template -using GiB = units::isq::iec80000::storage_capacity; -template -using TiB = units::isq::iec80000::storage_capacity; -template -using PiB = units::isq::iec80000::storage_capacity; -// template using EiB = -// units::isq::iec80000::storage_capacity; - -} // namespace units::aliases::isq::iec80000::inline storage_capacity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-iec80000/include/units/isq/iec80000/traffic_intensity.h b/src/systems/isq-iec80000/include/units/isq/iec80000/traffic_intensity.h deleted file mode 100644 index 03a31646..00000000 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/traffic_intensity.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::iec80000 { - -struct erlang : named_unit {}; - -struct dim_traffic_intensity : base_dimension<"A", erlang> {}; - -template -concept TrafficIntensity = QuantityOf; - -template U, Representation Rep = double> -using traffic_intensity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -constexpr auto operator"" _q_E(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return traffic_intensity(static_cast(l)); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace traffic_intensity_references { - -inline constexpr auto E = reference{}; - -} // namespace traffic_intensity_references - -namespace references { - -using namespace traffic_intensity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::iec80000 - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::iec80000::inline traffic_intensity { - -template -using E = units::isq::iec80000::traffic_intensity; - -} // namespace units::aliases::isq::iec80000::inline traffic_intensity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-iec80000/include/units/isq/iec80000/transfer_rate.h b/src/systems/isq-iec80000/include/units/isq/iec80000/transfer_rate.h deleted file mode 100644 index 54a02d7e..00000000 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/transfer_rate.h +++ /dev/null @@ -1,138 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::iec80000 { - -struct byte_per_second : derived_unit {}; -struct dim_transfer_rate : - derived_dimension, - exponent> {}; - -struct kilobyte_per_second : derived_scaled_unit {}; -struct megabyte_per_second : derived_scaled_unit {}; -struct gigabyte_per_second : derived_scaled_unit {}; -struct terabyte_per_second : derived_scaled_unit {}; -struct petabyte_per_second : derived_scaled_unit {}; -struct exabyte_per_second : derived_scaled_unit {}; -struct zettabyte_per_second : derived_scaled_unit {}; -struct yottabyte_per_second : derived_scaled_unit {}; - -template -concept TransferRate = QuantityOf; - -template U, Representation Rep = double> -using transfer_rate = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -constexpr auto operator"" _q_B_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_kB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_MB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_GB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_TB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_PB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_EB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_ZB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} -constexpr auto operator"" _q_YB_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return transfer_rate(static_cast(l)); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::iec80000 - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::iec80000::inline transfer_rate { - -template -using B_per_s = units::isq::iec80000::transfer_rate; -template -using kB_per_s = units::isq::iec80000::transfer_rate; -template -using MB_per_s = units::isq::iec80000::transfer_rate; -template -using GB_per_s = units::isq::iec80000::transfer_rate; -template -using TB_per_s = units::isq::iec80000::transfer_rate; -template -using PB_per_s = units::isq::iec80000::transfer_rate; -template -using EB_per_s = units::isq::iec80000::transfer_rate; -template -using ZB_per_s = units::isq::iec80000::transfer_rate; -template -using YB_per_s = units::isq::iec80000::transfer_rate; - -} // namespace units::aliases::isq::iec80000::inline transfer_rate - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/CMakeLists.txt b/src/systems/isq-natural/CMakeLists.txt deleted file mode 100644 index e968bdff..00000000 --- a/src/systems/isq-natural/CMakeLists.txt +++ /dev/null @@ -1,39 +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.19) - -add_units_module( - isq-natural - DEPENDENCIES mp-units::isq - HEADERS include/units/isq/natural/acceleration.h - include/units/isq/natural/constants.h - include/units/isq/natural/energy.h - include/units/isq/natural/force.h - include/units/isq/natural/length.h - include/units/isq/natural/mass.h - include/units/isq/natural/momentum.h - include/units/isq/natural/natural.h - include/units/isq/natural/speed.h - include/units/isq/natural/time.h - include/units/isq/natural/units.h -) diff --git a/src/systems/isq-natural/include/units/isq/natural/acceleration.h b/src/systems/isq-natural/include/units/isq/natural/acceleration.h deleted file mode 100644 index 4b6828e1..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/acceleration.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_acceleration : isq::dim_acceleration {}; - -template U, Representation Rep = double> -using acceleration = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace acceleration_references { - -inline constexpr auto GeV = reference{}; - -} // namespace acceleration_references - -namespace references { - -using namespace acceleration_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline acceleration { - -template -using GeV = units::isq::natural::acceleration; - -} // namespace units::aliases::isq::natural::inline acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/constants.h b/src/systems/isq-natural/include/units/isq/natural/constants.h deleted file mode 100644 index c570a589..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/constants.h +++ /dev/null @@ -1,32 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq::natural { - -template -inline constexpr auto speed_of_light = speed(1); - -} // namespace units::isq::natural diff --git a/src/systems/isq-natural/include/units/isq/natural/energy.h b/src/systems/isq-natural/include/units/isq/natural/energy.h deleted file mode 100644 index 84587a0a..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/energy.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_energy : isq::dim_energy {}; - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace energy_references { - -inline constexpr auto GeV = reference{}; - -} // namespace energy_references - -namespace references { - -using namespace energy_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline energy { - -template -using GeV = units::isq::natural::energy; - -} // namespace units::aliases::isq::natural::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/force.h b/src/systems/isq-natural/include/units/isq/natural/force.h deleted file mode 100644 index 26921dfc..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/force.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_force : isq::dim_force {}; - -template U, Representation Rep = double> -using force = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace force_references { - -inline constexpr auto GeV2 = reference{}; - -} // namespace force_references - -namespace references { - -using namespace force_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline force { - -template -using GeV2 = units::isq::natural::force; - -} // namespace units::aliases::isq::natural::inline force - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/length.h b/src/systems/isq-natural/include/units/isq/natural/length.h deleted file mode 100644 index 7174a525..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/length.h +++ /dev/null @@ -1,67 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_length : isq::dim_length {}; - -template U, Representation Rep = double> -using length = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto inv_GeV = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline length { - -template -using inv_GeV = units::isq::natural::length; - -} // namespace units::aliases::isq::natural::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/mass.h b/src/systems/isq-natural/include/units/isq/natural/mass.h deleted file mode 100644 index d9ff98de..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/mass.h +++ /dev/null @@ -1,67 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto GeV = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline mass { - -template -using GeV = units::isq::natural::mass; - -} // namespace units::aliases::isq::natural::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/momentum.h b/src/systems/isq-natural/include/units/isq/natural/momentum.h deleted file mode 100644 index 32f633d5..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/momentum.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_momentum : isq::dim_momentum {}; - -template U, Representation Rep = double> -using momentum = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace momentum_references { - -inline constexpr auto GeV = reference{}; - -} // namespace momentum_references - -namespace references { - -using namespace momentum_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline momentum { - -template -using GeV = units::isq::natural::momentum; - -} // namespace units::aliases::isq::natural::inline momentum - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/natural.h b/src/systems/isq-natural/include/units/isq/natural/natural.h deleted file mode 100644 index 09dbcfbd..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/natural.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/isq-natural/include/units/isq/natural/time.h b/src/systems/isq-natural/include/units/isq/natural/time.h deleted file mode 100644 index fc82e5ea..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/time.h +++ /dev/null @@ -1,67 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::natural { - -struct dim_time : isq::dim_time {}; - -template U, Representation Rep = double> -using time = quantity; - -#ifndef UNITS_NO_REFERENCES - -namespace time_references { - -inline constexpr auto inv_GeV = reference{}; - -} // namespace time_references - -namespace references { - -using namespace time_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::natural - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::natural::inline time { - -template -using inv_GeV = units::isq::natural::time; - -} // namespace units::aliases::isq::natural::inline time - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/units.h b/src/systems/isq-natural/include/units/isq/natural/units.h deleted file mode 100644 index 82712296..00000000 --- a/src/systems/isq-natural/include/units/isq/natural/units.h +++ /dev/null @@ -1,44 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::natural { - -struct electronvolt : named_unit {}; -struct gigaelectronvolt : prefixed_unit {}; -struct inverted_gigaelectronvolt : named_unit {}; -struct square_gigaelectronvolt : named_unit {}; - -// NOTE: eV as a base unit with no relation to joule prevents us from going back -// from natural units to SI. Do we need such a support or should we treat -// natural units as an isolated island with ev = 1 which simplifies all -// the maths a lot? - -} // namespace units::isq::natural diff --git a/src/systems/isq/CMakeLists.txt b/src/systems/isq/CMakeLists.txt index 029ebfe2..f2633f91 100644 --- a/src/systems/isq/CMakeLists.txt +++ b/src/systems/isq/CMakeLists.txt @@ -25,51 +25,7 @@ cmake_minimum_required(VERSION 3.19) add_units_module( isq DEPENDENCIES mp-units::core - HEADERS include/units/isq/dimensions/absorbed_dose.h - include/units/isq/dimensions/acceleration.h - include/units/isq/dimensions/amount_of_substance.h - include/units/isq/dimensions/angular_acceleration.h - include/units/isq/dimensions/angular_velocity.h - include/units/isq/dimensions/area.h - include/units/isq/dimensions/capacitance.h - include/units/isq/dimensions/catalytic_activity.h - include/units/isq/dimensions/charge_density.h - include/units/isq/dimensions/concentration.h - include/units/isq/dimensions/conductance.h - include/units/isq/dimensions/current_density.h - include/units/isq/dimensions/density.h - include/units/isq/dimensions/dynamic_viscosity.h - include/units/isq/dimensions/electric_charge.h - include/units/isq/dimensions/electric_current.h - include/units/isq/dimensions/electric_field_strength.h - include/units/isq/dimensions/energy.h - include/units/isq/dimensions/energy_density.h - include/units/isq/dimensions/force.h - include/units/isq/dimensions/frequency.h - include/units/isq/dimensions/heat_capacity.h - include/units/isq/dimensions/inductance.h - include/units/isq/dimensions/length.h - include/units/isq/dimensions/luminance.h - include/units/isq/dimensions/luminous_flux.h - include/units/isq/dimensions/luminous_intensity.h - include/units/isq/dimensions/magnetic_flux.h - include/units/isq/dimensions/magnetic_induction.h - include/units/isq/dimensions/mass.h - include/units/isq/dimensions/molar_energy.h - include/units/isq/dimensions/momentum.h - include/units/isq/dimensions/permeability.h - include/units/isq/dimensions/permittivity.h - include/units/isq/dimensions/power.h - include/units/isq/dimensions/pressure.h - include/units/isq/dimensions/radioactivity.h - include/units/isq/dimensions/resistance.h - include/units/isq/dimensions/speed.h - include/units/isq/dimensions/surface_tension.h - include/units/isq/dimensions/thermal_conductivity.h - include/units/isq/dimensions/thermodynamic_temperature.h - include/units/isq/dimensions/time.h - include/units/isq/dimensions/torque.h - include/units/isq/dimensions/voltage.h - include/units/isq/dimensions/volume.h - include/units/isq/dimensions.h + HEADERS include/mp-units/systems/isq/base_quantities.h include/mp-units/systems/isq/electromagnetism.h + include/mp-units/systems/isq/isq.h include/mp-units/systems/isq/mechanics.h + include/mp-units/systems/isq/space_and_time.h include/mp-units/systems/isq/thermodynamics.h ) diff --git a/src/systems/isq/include/mp-units/systems/isq/base_quantities.h b/src/systems/isq/include/mp-units/systems/isq/base_quantities.h new file mode 100644 index 00000000..d7b7c46a --- /dev/null +++ b/src/systems/isq/include/mp-units/systems/isq/base_quantities.h @@ -0,0 +1,51 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::isq { + +// clang-format off +// dimensions of base quantities +inline constexpr struct dim_length : base_dimension<"L"> {} dim_length; +inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass; +inline constexpr struct dim_time : base_dimension<"T"> {} dim_time; +inline constexpr struct dim_electric_current : base_dimension<"I"> {} dim_electric_current; +inline constexpr struct dim_thermodynamic_temperature : base_dimension {} dim_thermodynamic_temperature; +inline constexpr struct dim_amount_of_substance : base_dimension<"N"> {} dim_amount_of_substance; +inline constexpr struct dim_luminous_intensity : base_dimension<"J"> {} dim_luminous_intensity; +// clang-format on + +// base quantities +QUANTITY_SPEC(length, dim_length); +QUANTITY_SPEC(mass, dim_mass); +QUANTITY_SPEC(time, dim_time); +QUANTITY_SPEC(electric_current, dim_electric_current); +QUANTITY_SPEC(thermodynamic_temperature, dim_thermodynamic_temperature); +QUANTITY_SPEC(amount_of_substance, dim_amount_of_substance); +QUANTITY_SPEC(luminous_intensity, dim_luminous_intensity); + +} // namespace mp_units::isq diff --git a/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h b/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h new file mode 100644 index 00000000..981b0b05 --- /dev/null +++ b/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h @@ -0,0 +1,140 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units::isq { + +QUANTITY_SPEC(electric_charge, electric_current* time); +QUANTITY_SPEC(electric_charge_density, electric_charge / volume); +inline constexpr auto volume_electric_charge = electric_charge_density; +QUANTITY_SPEC(surface_density_of_electric_charge, electric_charge / area); +inline constexpr auto areic_electric_charge = surface_density_of_electric_charge; +QUANTITY_SPEC(linear_density_of_electric_charge, electric_charge / length); +inline constexpr auto lineic_electric_charge = linear_density_of_electric_charge; +QUANTITY_SPEC(electric_dipole_moment, electric_charge* position_vector); // vector +QUANTITY_SPEC(electric_polarization, electric_dipole_moment / volume); // vector +QUANTITY_SPEC(electric_current_density, electric_charge_density* velocity); // vector +inline constexpr auto areic_electric_current = electric_current_density; +QUANTITY_SPEC(linear_electric_current_density, surface_density_of_electric_charge* velocity); // vector +inline constexpr auto lineic_electric_current = linear_electric_current_density; +QUANTITY_SPEC(electric_field_strength, force / electric_charge); // vector +QUANTITY_SPEC(electric_potential, electric_field_strength* length, + quantity_character::scalar); // TODO what is a correct equation here? +QUANTITY_SPEC(electric_potential_difference, electric_potential, quantity_character::scalar); +QUANTITY_SPEC(voltage, electric_potential); +inline constexpr auto electric_tension = voltage; +QUANTITY_SPEC(electric_flux_density, electric_polarization); // vector +inline constexpr auto electric_displacement = electric_flux_density; +QUANTITY_SPEC(capacitance, electric_charge / voltage); +// TODO how to calculate an argument of a vector product? +QUANTITY_SPEC(magnetic_flux_density, force / (electric_charge * velocity), quantity_character::vector); +QUANTITY_SPEC(magnetic_vector_potential, + magnetic_flux_density* length); // vector // TODO what is a correct equation here? +QUANTITY_SPEC(linked_flux, magnetic_vector_potential* displacement, quantity_character::scalar); +QUANTITY_SPEC(magnetic_constant, + electric_potential* time / (electric_current * length)); // TODO what is a correct equation here? +inline constexpr auto permeability_of_vacuum = magnetic_constant; +QUANTITY_SPEC(phase_speed_of_electromagnetic_waves, angular_frequency / angular_wavenumber); +QUANTITY_SPEC(speed_of_light, speed); +inline constexpr auto light_speed = speed_of_light; +QUANTITY_SPEC(electric_constant, 1 / (magnetic_constant * pow<2>(speed_of_light))); +inline constexpr auto permittivity_of_vacuum = electric_constant; +QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::scalar); +QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant); +QUANTITY_SPEC(electric_susceptibility, dimensionless, + electric_polarization / electric_constant / electric_field_strength, quantity_character::scalar); +QUANTITY_SPEC(electric_flux, electric_flux_density* area, quantity_character::scalar); +QUANTITY_SPEC(displacement_current_density, electric_flux_density / time); // vector +QUANTITY_SPEC(displacement_current, electric_current, displacement_current_density* area, quantity_character::scalar); +QUANTITY_SPEC(total_current, electric_current); +QUANTITY_SPEC(total_current_density, electric_current_density); // vector +QUANTITY_SPEC(magnetic_flux, magnetic_flux_density* area, quantity_character::scalar); +QUANTITY_SPEC(magnetic_moment, electric_current* area, quantity_character::vector); +inline constexpr auto magnetic_area_moment = magnetic_moment; +QUANTITY_SPEC(magnetization, magnetic_moment / volume); // vector +QUANTITY_SPEC(magnetic_field_strength, magnetization); // vector +inline constexpr auto magnetizing_field = magnetic_field_strength; +QUANTITY_SPEC(permeability, magnetic_flux_density / magnetic_field_strength, quantity_character::scalar); +QUANTITY_SPEC(relative_permeability, dimensionless, permeability / magnetic_constant); +QUANTITY_SPEC(magnetic_susceptibility, dimensionless, magnetization / magnetic_field_strength, + quantity_character::scalar); +QUANTITY_SPEC(magnetic_polarization, magnetic_constant* magnetization); // vector +QUANTITY_SPEC(magnetic_dipole_moment, magnetic_constant* magnetic_moment); // vector +QUANTITY_SPEC(coercivity, magnetic_field_strength, quantity_character::scalar); +QUANTITY_SPEC(electromagnetic_energy_density, electric_field_strength* electric_flux_density, + quantity_character::scalar); +inline constexpr auto volumic_electromagnetic_energy = electromagnetic_energy_density; +QUANTITY_SPEC(Poynting_vector, electric_field_strength* magnetic_field_strength); // vector +QUANTITY_SPEC(source_voltage, voltage); +inline constexpr auto source_tension = source_voltage; +QUANTITY_SPEC(scalar_magnetic_potential, electric_current, magnetic_field_strength* length, + quantity_character::scalar); // TODO what is a correct equation here? +QUANTITY_SPEC(magnetic_tension, electric_current, magnetic_field_strength* position_vector, quantity_character::scalar); +QUANTITY_SPEC(magnetomotive_force, electric_current, magnetic_field_strength* position_vector, + quantity_character::scalar); +QUANTITY_SPEC(current_linkage, electric_current); +QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless); +QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux); +QUANTITY_SPEC(permeance, 1 / reluctance); +QUANTITY_SPEC(inductance, linked_flux / electric_current); +inline constexpr auto self_inductance = inductance; +QUANTITY_SPEC(mutual_inductance, linked_flux / electric_current); +QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance))); +QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor)); +QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::scalar); +QUANTITY_SPEC(resistivity, 1 / conductivity); +// QUANTITY_SPEC(power, voltage* electric_current); // TODO conflicts with mechanical power +// inline constexpr auto instantaneous_power = power; +QUANTITY_SPEC(instantaneous_power, voltage* electric_current); +QUANTITY_SPEC(resistance, voltage / electric_current); +QUANTITY_SPEC(conductance, 1 / resistance); +QUANTITY_SPEC(phase_difference, phase_angle); +QUANTITY_SPEC(electric_current_phasor, electric_current); +QUANTITY_SPEC(voltage_phasor, voltage); +QUANTITY_SPEC(impedance, voltage_phasor / electric_current_phasor); +inline constexpr auto complex_impedance = impedance; +QUANTITY_SPEC(resistance_to_alternating_current, impedance); +QUANTITY_SPEC(reactance, impedance); +QUANTITY_SPEC(modulus_of_impedance, impedance); +QUANTITY_SPEC(admittance, 1 / impedance); +inline constexpr auto complex_admittance = admittance; +QUANTITY_SPEC(conductance_for_alternating_current, admittance); +QUANTITY_SPEC(susceptance, admittance); +QUANTITY_SPEC(modulus_of_admittance, admittance); +QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance); +QUANTITY_SPEC(loss_factor, dimensionless, 1 / quality_factor); +QUANTITY_SPEC(loss_angle, angular_measure); +QUANTITY_SPEC(active_power, 1 / period * (instantaneous_power * time)); +QUANTITY_SPEC(apparent_power, voltage* electric_current); +QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power); +QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); +QUANTITY_SPEC(reactive_power, complex_power); +QUANTITY_SPEC(non_active_power, pow<1, 2>(pow<2>(apparent_power))); +QUANTITY_SPEC(active_energy, instantaneous_power* time); + +} // namespace mp_units::isq diff --git a/src/systems/si-typographic/include/units/isq/si/typographic/typographic.h b/src/systems/isq/include/mp-units/systems/isq/isq.h similarity index 83% rename from src/systems/si-typographic/include/units/isq/si/typographic/typographic.h rename to src/systems/isq/include/mp-units/systems/isq/isq.h index eae31c9f..a73ffadf 100644 --- a/src/systems/si-typographic/include/units/isq/si/typographic/typographic.h +++ b/src/systems/isq/include/mp-units/systems/isq/isq.h @@ -23,5 +23,9 @@ #pragma once // IWYU pragma: begin_exports -#include +#include +#include +#include +#include +#include // IWYU pragma: end_exports diff --git a/src/systems/isq/include/mp-units/systems/isq/mechanics.h b/src/systems/isq/include/mp-units/systems/isq/mechanics.h new file mode 100644 index 00000000..2e9bda62 --- /dev/null +++ b/src/systems/isq/include/mp-units/systems/isq/mechanics.h @@ -0,0 +1,103 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::isq { + +QUANTITY_SPEC(mass_density, mass / volume); +inline constexpr auto density = mass_density; +QUANTITY_SPEC(specific_volume, 1 / mass_density); +QUANTITY_SPEC(relative_mass_density, mass_density / mass_density); +inline constexpr auto relative_density = relative_mass_density; +QUANTITY_SPEC(surface_mass_density, mass / area); +inline constexpr auto surface_density = surface_mass_density; +QUANTITY_SPEC(linear_mass_density, mass / length); +inline constexpr auto linear_density = linear_mass_density; +QUANTITY_SPEC(momentum, mass* velocity); // vector +QUANTITY_SPEC(force, mass* acceleration); // vector // TODO what is a correct equation here? +QUANTITY_SPEC(weight, force, mass* acceleration_of_free_fall); // vector // differs from ISO 80000 +QUANTITY_SPEC(static_friction_force, force); // vector +inline constexpr auto static_friction = static_friction_force; +QUANTITY_SPEC(kinetic_friction_force, force); // vector +inline constexpr auto dynamic_friction_force = kinetic_friction_force; +QUANTITY_SPEC(rolling_resistance, force); // vector +inline constexpr auto rolling_drag = rolling_resistance; +inline constexpr auto rolling_friction_force = rolling_resistance; +QUANTITY_SPEC(drag_force, force); // vector +QUANTITY_SPEC(impulse, force* time); // vector +QUANTITY_SPEC(angular_momentum, position_vector* momentum); // vector +QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor); +QUANTITY_SPEC(moment_of_force, position_vector* force); // vector +QUANTITY_SPEC(torque, moment_of_force, quantity_character::scalar); +QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector +QUANTITY_SPEC(pressure, force / area, quantity_character::scalar); +QUANTITY_SPEC(gauge_pressure, pressure); +QUANTITY_SPEC(stress, pressure, quantity_character::tensor); +QUANTITY_SPEC(normal_stress, pressure, quantity_character::scalar); +QUANTITY_SPEC(shear_stress, pressure, quantity_character::scalar); +QUANTITY_SPEC(strain, dimensionless, quantity_character::tensor); +QUANTITY_SPEC(relative_linear_strain, length / length); +QUANTITY_SPEC(shear_strain, dimensionless, displacement / thickness, quantity_character::scalar); +QUANTITY_SPEC(relative_volume_strain, volume / volume); +QUANTITY_SPEC(Poisson_number, dimensionless, width / length); +QUANTITY_SPEC(modulus_of_elasticity, normal_stress / relative_linear_strain); +inline constexpr auto Young_modulus = modulus_of_elasticity; +QUANTITY_SPEC(modulus_of_rigidity, shear_stress / shear_strain); +inline constexpr auto shear_modulus = modulus_of_rigidity; +QUANTITY_SPEC(modulus_of_compression, pressure / relative_volume_strain); +inline constexpr auto bulk_modulus = modulus_of_compression; +QUANTITY_SPEC(compressibility, 1 / volume * (volume / pressure)); +QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area); +QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area); +QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance); +QUANTITY_SPEC(static_friction_coefficient, dimensionless, static_friction_force / force, quantity_character::scalar); +inline constexpr auto static_friction_factor = static_friction_coefficient; +inline constexpr auto coefficient_of_static_friction = static_friction_coefficient; +QUANTITY_SPEC(kinetic_friction_factor, dimensionless, kinetic_friction_force / force, quantity_character::scalar); +inline constexpr auto dynamic_friction_factor = kinetic_friction_factor; +QUANTITY_SPEC(rolling_resistance_factor, force / force, quantity_character::scalar); +QUANTITY_SPEC(drag_coefficient, dimensionless, drag_force / (mass_density * pow<2>(speed) * area), + quantity_character::scalar); +inline constexpr auto drag_factor = drag_coefficient; +QUANTITY_SPEC(dynamic_viscosity, shear_stress* length / velocity, quantity_character::scalar); +QUANTITY_SPEC(kinematic_viscosity, dynamic_viscosity / mass_density); +QUANTITY_SPEC(surface_tension, force / length, quantity_character::scalar); // TODO what is a correct equation here? +QUANTITY_SPEC(power, force* velocity, quantity_character::scalar); +QUANTITY_SPEC(energy, mass* pow<2>(length) / pow<2>(time)); // ISO 80000 defines this in thermodynamics +QUANTITY_SPEC(mechanical_energy, energy); // differs from ISO 80000 +QUANTITY_SPEC(potential_energy, mechanical_energy); // differs from ISO 80000 +QUANTITY_SPEC(kinetic_energy, mechanical_energy, mass* pow<2>(speed)); // differs from ISO 80000 +QUANTITY_SPEC(mechanical_work, force* displacement, quantity_character::scalar); +inline constexpr auto work = mechanical_work; +QUANTITY_SPEC(efficiency_mechanics, power / power); +QUANTITY_SPEC(mass_flow, mass_density* velocity); // vector +QUANTITY_SPEC(mass_flow_rate, mass_flow* area, quantity_character::scalar); +QUANTITY_SPEC(mass_change_rate, mass / time); +QUANTITY_SPEC(volume_flow_rate, velocity* area, quantity_character::scalar); +QUANTITY_SPEC(action, energy* time); + +} // namespace mp_units::isq diff --git a/src/systems/isq/include/mp-units/systems/isq/space_and_time.h b/src/systems/isq/include/mp-units/systems/isq/space_and_time.h new file mode 100644 index 00000000..0c3ef558 --- /dev/null +++ b/src/systems/isq/include/mp-units/systems/isq/space_and_time.h @@ -0,0 +1,85 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::isq { + +QUANTITY_SPEC(width, length); +inline constexpr auto breadth = width; +QUANTITY_SPEC(height, length); +inline constexpr auto depth = height; +inline constexpr auto altitude = height; +QUANTITY_SPEC(thickness, width); +QUANTITY_SPEC(diameter, width); +QUANTITY_SPEC(radius, width); // differs from ISO 80000 +QUANTITY_SPEC(path_length, length); +inline constexpr auto arc_length = path_length; +QUANTITY_SPEC(distance, path_length); +QUANTITY_SPEC(radial_distance, distance); +QUANTITY_SPEC(position_vector, length, quantity_character::vector); +QUANTITY_SPEC(displacement, length, quantity_character::vector); +QUANTITY_SPEC(radius_of_curvature, radius); +QUANTITY_SPEC(curvature, 1 / radius_of_curvature); +QUANTITY_SPEC(area, pow<2>(length)); +QUANTITY_SPEC(volume, pow<3>(length)); +QUANTITY_SPEC(angular_measure, dimensionless, arc_length / radius, is_kind); +QUANTITY_SPEC(rotational_displacement, angular_measure, path_length / radius); +inline constexpr auto angular_displacement = rotational_displacement; +QUANTITY_SPEC(phase_angle, angular_measure); +QUANTITY_SPEC(solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind); +inline constexpr auto duration = time; +QUANTITY_SPEC(speed, length / time); // differs from ISO 80000 +QUANTITY_SPEC(velocity, speed, position_vector / duration); // vector // differs from ISO 80000 +QUANTITY_SPEC(acceleration, velocity / duration); // vector +QUANTITY_SPEC(acceleration_of_free_fall, acceleration); // not in ISO 80000 +QUANTITY_SPEC(angular_velocity, angular_displacement / duration, quantity_character::vector); +QUANTITY_SPEC(angular_acceleration, angular_velocity / duration); +QUANTITY_SPEC(period_duration, duration); +inline constexpr auto period = period_duration; +QUANTITY_SPEC(time_constant, duration); +QUANTITY_SPEC(rotation, dimensionless); +QUANTITY_SPEC(frequency, 1 / period_duration); +QUANTITY_SPEC(rotational_frequency, rotation / duration); +QUANTITY_SPEC(angular_frequency, phase_angle / duration); +QUANTITY_SPEC(wavelength, length); +QUANTITY_SPEC(repetency, 1 / wavelength); +inline constexpr auto wavenumber = repetency; +QUANTITY_SPEC(wave_vector, repetency, quantity_character::vector); +QUANTITY_SPEC(angular_repetency, 1 / wavelength); +inline constexpr auto angular_wavenumber = angular_repetency; +QUANTITY_SPEC(phase_velocity, angular_frequency / angular_repetency); +inline constexpr auto phase_speed = phase_velocity; +QUANTITY_SPEC(group_velocity, angular_frequency / angular_repetency); +inline constexpr auto group_speed = group_velocity; +QUANTITY_SPEC(damping_coefficient, 1 / time_constant); +QUANTITY_SPEC(logarithmic_decrement, dimensionless, damping_coefficient* period_duration); +QUANTITY_SPEC(attenuation, 1 / distance); +inline constexpr auto extinction = attenuation; +QUANTITY_SPEC(phase_coefficient, phase_angle / path_length); +QUANTITY_SPEC(propagation_coefficient, 1 / length); // γ = α + iβ where α denotes attenuation + // and β the phase coefficient of a plane wave + +} // namespace mp_units::isq diff --git a/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h b/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h new file mode 100644 index 00000000..24e9ce8d --- /dev/null +++ b/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h @@ -0,0 +1,99 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units::isq { + +QUANTITY_SPEC(Celsius_temperature, thermodynamic_temperature); // TODO should we account for T0 here? +QUANTITY_SPEC(linear_expansion_coefficient, 1 / length * (length / thermodynamic_temperature)); +QUANTITY_SPEC(cubic_expansion_coefficient, 1 / volume * (volume / thermodynamic_temperature)); +QUANTITY_SPEC(relative_pressure_coefficient, 1 / pressure * (pressure / thermodynamic_temperature)); +QUANTITY_SPEC(pressure_coefficient, pressure / thermodynamic_temperature); +QUANTITY_SPEC(isothermal_compressibility, 1 / volume * (volume / pressure)); // TODO how to handle "negative" part +QUANTITY_SPEC(isentropic_compressibility, 1 / volume * (volume / pressure)); // TODO how to handle "negative" part +// energy definition moved to mechanics +QUANTITY_SPEC(heat, mass* pow<2>(length) / pow<2>(time)); // TODO what is a correct equation here? +inline constexpr auto amount_of_heat = heat; +QUANTITY_SPEC(latent_heat, heat); // TODO what is a correct equation here? +QUANTITY_SPEC(heat_flow_rate, heat / time); +QUANTITY_SPEC(density_of_heat_flow_rate, heat_flow_rate / area); +QUANTITY_SPEC(thermal_conductivity, density_of_heat_flow_rate*(length / thermodynamic_temperature)); +QUANTITY_SPEC(coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature); +QUANTITY_SPEC(surface_coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature); +QUANTITY_SPEC(thermal_insulance, 1 / coefficient_of_heat_transfer); +inline constexpr auto coefficient_of_thermal_insulance = thermal_insulance; +QUANTITY_SPEC(thermal_resistance, thermodynamic_temperature / heat_flow_rate); +QUANTITY_SPEC(thermal_conductance, 1 / thermal_resistance); +QUANTITY_SPEC(heat_capacity, heat / thermodynamic_temperature); +QUANTITY_SPEC(specific_heat_capacity, heat_capacity / mass); +QUANTITY_SPEC(specific_heat_capacity_at_constant_pressure, specific_heat_capacity); +QUANTITY_SPEC(specific_heat_capacity_at_constant_volume, specific_heat_capacity); +QUANTITY_SPEC(specific_heat_capacity_at_saturated_vapour_pressure, specific_heat_capacity); +QUANTITY_SPEC(thermal_diffusivity, thermal_conductivity / (mass_density * specific_heat_capacity_at_constant_pressure)); +QUANTITY_SPEC(ratio_of_specific_heat_capacities, dimensionless, + specific_heat_capacity_at_constant_pressure / specific_heat_capacity_at_constant_volume); +QUANTITY_SPEC(isentropic_exponent, + volume / pressure * (pressure / volume)); // TODO how to handle "negative" part +inline constexpr auto isentropic_expansion_factor = isentropic_exponent; +QUANTITY_SPEC(entropy, kinetic_energy / thermodynamic_temperature); +QUANTITY_SPEC(specific_entropy, entropy / mass); +QUANTITY_SPEC(enthalpy, energy); // differs from ISO 80000 +QUANTITY_SPEC(internal_energy, enthalpy); // differs from ISO 80000 +inline constexpr auto thermodynamic_energy = internal_energy; +QUANTITY_SPEC(Helmholtz_energy, internal_energy); +inline constexpr auto Helmholtz_function = Helmholtz_energy; +QUANTITY_SPEC(Gibbs_energy, enthalpy); +inline constexpr auto Gibbs_function = Gibbs_energy; +QUANTITY_SPEC(specific_energy, energy / mass); +QUANTITY_SPEC(specific_internal_energy, internal_energy / mass); +inline constexpr auto specific_thermodynamic_energy = specific_internal_energy; +QUANTITY_SPEC(specific_enthalpy, enthalpy / mass); +QUANTITY_SPEC(specific_Helmholtz_energy, Helmholtz_energy / mass); +inline constexpr auto specific_Helmholtz_function = specific_Helmholtz_energy; +QUANTITY_SPEC(specific_Gibbs_energy, Gibbs_energy / mass); +inline constexpr auto specific_Gibbs_function = specific_Gibbs_energy; +QUANTITY_SPEC(Massieu_function, Helmholtz_energy / thermodynamic_temperature); // TODO how to handle "negative" part +QUANTITY_SPEC(Planck_function, Gibbs_energy / thermodynamic_temperature); // TODO how to handle "negative" part +QUANTITY_SPEC(Joule_Thomson_coefficient, thermodynamic_temperature / pressure); +QUANTITY_SPEC(efficiency_thermodynamics, dimensionless, work / heat); +QUANTITY_SPEC(maximum_efficiency, thermodynamic_temperature / thermodynamic_temperature); +QUANTITY_SPEC(specific_gas_constant, entropy / mass); +QUANTITY_SPEC(mass_concentration_of_water, mass / volume); +QUANTITY_SPEC(mass_concentration_of_water_vapour, mass / volume); +QUANTITY_SPEC(mass_ratio_of_water_to_dry_matter, mass / mass); +QUANTITY_SPEC(mass_ratio_of_water_vapour_to_dry_gas, mass / mass); +QUANTITY_SPEC(mass_fraction_of_water, mass_ratio_of_water_to_dry_matter / mass_ratio_of_water_to_dry_matter); +QUANTITY_SPEC(mass_fraction_of_dry_matter, mass_fraction_of_water); +QUANTITY_SPEC(relative_humidity, pressure / pressure); +QUANTITY_SPEC(relative_mass_concentration_of_vapour, + mass_concentration_of_water_vapour / mass_concentration_of_water_vapour); +QUANTITY_SPEC(relative_mass_ratio_of_vapour, + mass_ratio_of_water_vapour_to_dry_gas / mass_ratio_of_water_vapour_to_dry_gas); +QUANTITY_SPEC(dew_point_temperature, thermodynamic_temperature); + +} // namespace mp_units::isq diff --git a/src/systems/isq/include/units/isq/dimensions.h b/src/systems/isq/include/units/isq/dimensions.h deleted file mode 100644 index 5d226fcb..00000000 --- a/src/systems/isq/include/units/isq/dimensions.h +++ /dev/null @@ -1,74 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// TODO Add when downcasting issue is solved (collides with pressure) -// #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// TODO Add when downcasting issue is solved (collides with frequency) -// #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h b/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h deleted file mode 100644 index 633af9a7..00000000 --- a/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_absorbed_dose; - -template E, DimensionOfT M> -struct dim_absorbed_dose : derived_dimension, exponent> {}; - -template -concept AbsorbedDose = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/acceleration.h b/src/systems/isq/include/units/isq/dimensions/acceleration.h deleted file mode 100644 index a122ec6d..00000000 --- a/src/systems/isq/include/units/isq/dimensions/acceleration.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_acceleration; - -template L, DimensionOfT T> -struct dim_acceleration : derived_dimension, exponent> {}; - -template -concept Acceleration = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/angular_acceleration.h b/src/systems/isq/include/units/isq/dimensions/angular_acceleration.h deleted file mode 100644 index a5d38a23..00000000 --- a/src/systems/isq/include/units/isq/dimensions/angular_acceleration.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_angular_acceleration; - -template A, DimensionOfT T> -struct dim_angular_acceleration : derived_dimension, exponent> {}; - -template -concept AngularAcceleration = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/angular_velocity.h b/src/systems/isq/include/units/isq/dimensions/angular_velocity.h deleted file mode 100644 index e2ae4b69..00000000 --- a/src/systems/isq/include/units/isq/dimensions/angular_velocity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_angular_velocity; - -template A, DimensionOfT T> -struct dim_angular_velocity : derived_dimension, exponent> {}; - -template -concept AngularVelocity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/capacitance.h b/src/systems/isq/include/units/isq/dimensions/capacitance.h deleted file mode 100644 index 8f474587..00000000 --- a/src/systems/isq/include/units/isq/dimensions/capacitance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_capacitance; - -template C, DimensionOfT V> -struct dim_capacitance : derived_dimension, exponent> {}; - -template -concept Capacitance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h b/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h deleted file mode 100644 index f0d67250..00000000 --- a/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_catalytic_activity; - -template T, DimensionOfT M> -struct dim_catalytic_activity : derived_dimension, exponent> {}; - -template -concept CatalyticActivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/charge_density.h b/src/systems/isq/include/units/isq/dimensions/charge_density.h deleted file mode 100644 index 8625665a..00000000 --- a/src/systems/isq/include/units/isq/dimensions/charge_density.h +++ /dev/null @@ -1,49 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_charge_density; - -template Q, DimensionOfT L> -struct dim_charge_density : derived_dimension, exponent> {}; - -template -struct dim_surface_charge_density; - -template Q, DimensionOfT L> -struct dim_surface_charge_density : derived_dimension, exponent> {}; - -template -concept ChargeDensity = QuantityOfT; - -template -concept SurfaceChargeDensity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/concentration.h b/src/systems/isq/include/units/isq/dimensions/concentration.h deleted file mode 100644 index c5181d44..00000000 --- a/src/systems/isq/include/units/isq/dimensions/concentration.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_concentration; - -template M, DimensionOfT L> -struct dim_concentration : derived_dimension, exponent> {}; - -template -concept Concentration = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/current_density.h b/src/systems/isq/include/units/isq/dimensions/current_density.h deleted file mode 100644 index f097de77..00000000 --- a/src/systems/isq/include/units/isq/dimensions/current_density.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_current_density; - -template I, DimensionOfT L> -struct dim_current_density : derived_dimension, exponent> {}; - -template -concept CurrentDensity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/density.h b/src/systems/isq/include/units/isq/dimensions/density.h deleted file mode 100644 index cb5196d9..00000000 --- a/src/systems/isq/include/units/isq/dimensions/density.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_density; - -template M, DimensionOfT L> -struct dim_density : derived_dimension, exponent> {}; - -template -concept Density = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h b/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h deleted file mode 100644 index ceac79e5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_dynamic_viscosity; - -template P, DimensionOfT T> -struct dim_dynamic_viscosity : derived_dimension, exponent> {}; - -template -concept DynamicViscosity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/electric_charge.h b/src/systems/isq/include/units/isq/dimensions/electric_charge.h deleted file mode 100644 index 2c7db791..00000000 --- a/src/systems/isq/include/units/isq/dimensions/electric_charge.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_electric_charge; - -template T, DimensionOfT C> -struct dim_electric_charge : derived_dimension, exponent> {}; - -template -concept ElectricCharge = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/electric_current.h b/src/systems/isq/include/units/isq/dimensions/electric_current.h deleted file mode 100644 index 52a3a4a1..00000000 --- a/src/systems/isq/include/units/isq/dimensions/electric_current.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_electric_current : base_dimension<"I", U> {}; - -template -concept ElectricCurrent = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h b/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h deleted file mode 100644 index 4bcd78f6..00000000 --- a/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_electric_field_strength; - -template V, DimensionOfT L> -struct dim_electric_field_strength : derived_dimension, exponent> {}; - -template -concept ElectricFieldStrength = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/energy.h b/src/systems/isq/include/units/isq/dimensions/energy.h deleted file mode 100644 index db090615..00000000 --- a/src/systems/isq/include/units/isq/dimensions/energy.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_energy; - -template F, DimensionOfT L> -struct dim_energy : derived_dimension, exponent> {}; - -template L, DimensionOfT F> -struct dim_energy : derived_dimension, exponent> {}; - -template -concept Energy = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/energy_density.h b/src/systems/isq/include/units/isq/dimensions/energy_density.h deleted file mode 100644 index aa63cbca..00000000 --- a/src/systems/isq/include/units/isq/dimensions/energy_density.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_energy_density; - -template E, DimensionOfT V> -struct dim_energy_density : derived_dimension, exponent> {}; - -template -concept EnergyDensity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/force.h b/src/systems/isq/include/units/isq/dimensions/force.h deleted file mode 100644 index 20dc9540..00000000 --- a/src/systems/isq/include/units/isq/dimensions/force.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_force; - -template M, DimensionOfT A> -struct dim_force : derived_dimension, exponent> {}; - -template -concept Force = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/frequency.h b/src/systems/isq/include/units/isq/dimensions/frequency.h deleted file mode 100644 index 4b3dc285..00000000 --- a/src/systems/isq/include/units/isq/dimensions/frequency.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units::isq { - -template -struct dim_frequency; - -template T> -struct dim_frequency : derived_dimension> {}; - -template -concept Frequency = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/heat_capacity.h b/src/systems/isq/include/units/isq/dimensions/heat_capacity.h deleted file mode 100644 index d4c3e0d4..00000000 --- a/src/systems/isq/include/units/isq/dimensions/heat_capacity.h +++ /dev/null @@ -1,60 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include - -namespace units::isq { - -template -struct dim_heat_capacity; - -template E, DimensionOfT T> -struct dim_heat_capacity : derived_dimension, exponent> {}; - -template -struct dim_specific_heat_capacity; - -template C, DimensionOfT M> -struct dim_specific_heat_capacity : derived_dimension, exponent> {}; - -template -struct dim_molar_heat_capacity; - -template C, DimensionOfT M> -struct dim_molar_heat_capacity : derived_dimension, exponent> {}; - -template -concept HeatCapacity = QuantityOfT; - -template -concept SpecificHeatCapacity = QuantityOfT; - -template -concept MolarHeatCapacity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/inductance.h b/src/systems/isq/include/units/isq/dimensions/inductance.h deleted file mode 100644 index 90ae21cd..00000000 --- a/src/systems/isq/include/units/isq/dimensions/inductance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_inductance; - -template F, DimensionOfT I> -struct dim_inductance : derived_dimension, exponent> {}; - -template -concept Inductance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/length.h b/src/systems/isq/include/units/isq/dimensions/length.h deleted file mode 100644 index 39170399..00000000 --- a/src/systems/isq/include/units/isq/dimensions/length.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_length : base_dimension<"L", U> {}; - -template -concept Length = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/luminance.h b/src/systems/isq/include/units/isq/dimensions/luminance.h deleted file mode 100644 index c5215828..00000000 --- a/src/systems/isq/include/units/isq/dimensions/luminance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_luminance; - -template I, DimensionOfT L> -struct dim_luminance : derived_dimension, exponent> {}; - -template -concept Luminance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/luminous_flux.h b/src/systems/isq/include/units/isq/dimensions/luminous_flux.h deleted file mode 100644 index ffa81053..00000000 --- a/src/systems/isq/include/units/isq/dimensions/luminous_flux.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_luminous_flux; - -template I, DimensionOfT A> -struct dim_luminous_flux : derived_dimension, exponent> {}; - -template -concept LuminousFlux = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h b/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h deleted file mode 100644 index d0f2dab5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_magnetic_flux; - -template B, DimensionOfT A> -struct dim_magnetic_flux : derived_dimension, exponent> {}; - -template -concept MagneticFlux = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h b/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h deleted file mode 100644 index b7b54c0b..00000000 --- a/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h +++ /dev/null @@ -1,42 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -namespace units::isq { - -template -struct dim_magnetic_induction; - -template V, DimensionOfT T, DimensionOfT L> -struct dim_magnetic_induction : - derived_dimension, exponent, exponent> {}; - -template -concept MagneticInduction = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/mass.h b/src/systems/isq/include/units/isq/dimensions/mass.h deleted file mode 100644 index a2706b61..00000000 --- a/src/systems/isq/include/units/isq/dimensions/mass.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_mass : base_dimension<"M", U> {}; - -template -concept Mass = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/molar_energy.h b/src/systems/isq/include/units/isq/dimensions/molar_energy.h deleted file mode 100644 index a8b152b0..00000000 --- a/src/systems/isq/include/units/isq/dimensions/molar_energy.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_molar_energy; - -template E, DimensionOfT M> -struct dim_molar_energy : derived_dimension, exponent> {}; - -template -concept MolarEnergy = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/momentum.h b/src/systems/isq/include/units/isq/dimensions/momentum.h deleted file mode 100644 index 8508fb0a..00000000 --- a/src/systems/isq/include/units/isq/dimensions/momentum.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_momentum; - -template M, DimensionOfT V> -struct dim_momentum : derived_dimension, exponent> {}; - -template -concept Momentum = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/permeability.h b/src/systems/isq/include/units/isq/dimensions/permeability.h deleted file mode 100644 index 01543a57..00000000 --- a/src/systems/isq/include/units/isq/dimensions/permeability.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_permeability; - -template H, DimensionOfT L> -struct dim_permeability : derived_dimension, exponent> {}; - -template -concept Permeability = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/permittivity.h b/src/systems/isq/include/units/isq/dimensions/permittivity.h deleted file mode 100644 index 70601e6d..00000000 --- a/src/systems/isq/include/units/isq/dimensions/permittivity.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_permittivity; - -template C, DimensionOfT L> -struct dim_permittivity : derived_dimension, exponent> {}; - -template -concept Permittivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/power.h b/src/systems/isq/include/units/isq/dimensions/power.h deleted file mode 100644 index 5a0b24ca..00000000 --- a/src/systems/isq/include/units/isq/dimensions/power.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_power; - -template E, DimensionOfT T> -struct dim_power : derived_dimension, exponent> {}; - -template L, DimensionOfT F, DimensionOfT T> -struct dim_power : derived_dimension, exponent, exponent> {}; - -template -concept Power = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/pressure.h b/src/systems/isq/include/units/isq/dimensions/pressure.h deleted file mode 100644 index 47578401..00000000 --- a/src/systems/isq/include/units/isq/dimensions/pressure.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_pressure; - -template F, DimensionOfT A> -struct dim_pressure : derived_dimension, exponent> {}; - -template -concept Pressure = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/radioactivity.h b/src/systems/isq/include/units/isq/dimensions/radioactivity.h deleted file mode 100644 index 591a1da9..00000000 --- a/src/systems/isq/include/units/isq/dimensions/radioactivity.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units::isq { - -template -struct dim_radioactivity; - -template T> -struct dim_radioactivity : derived_dimension> {}; - -template -concept Radioactivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/resistance.h b/src/systems/isq/include/units/isq/dimensions/resistance.h deleted file mode 100644 index e9d8f9b5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/resistance.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_resistance; - -template V, DimensionOfT C> -struct dim_resistance : derived_dimension, exponent> {}; - -template -concept Resistance = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/speed.h b/src/systems/isq/include/units/isq/dimensions/speed.h deleted file mode 100644 index d681420a..00000000 --- a/src/systems/isq/include/units/isq/dimensions/speed.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_speed; - -template L, DimensionOfT T> -struct dim_speed : derived_dimension, exponent> {}; - -template -concept Speed = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/surface_tension.h b/src/systems/isq/include/units/isq/dimensions/surface_tension.h deleted file mode 100644 index 52cdd3f3..00000000 --- a/src/systems/isq/include/units/isq/dimensions/surface_tension.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_surface_tension; - -template F, DimensionOfT L> -struct dim_surface_tension : derived_dimension, exponent> {}; - -template -concept SurfaceTension = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h b/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h deleted file mode 100644 index 1fe804d5..00000000 --- a/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h +++ /dev/null @@ -1,43 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -namespace units::isq { - -template -struct dim_thermal_conductivity; - -template P, DimensionOfT L, - DimensionOfT T> -struct dim_thermal_conductivity : - derived_dimension, exponent, exponent> {}; - -template -concept ThermalConductivity = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h b/src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h deleted file mode 100644 index 8db16a23..00000000 --- a/src/systems/isq/include/units/isq/dimensions/thermodynamic_temperature.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_thermodynamic_temperature : base_dimension<"Θ", U> {}; - -template -concept ThermodynamicTemperature = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/time.h b/src/systems/isq/include/units/isq/dimensions/time.h deleted file mode 100644 index f07b82d9..00000000 --- a/src/systems/isq/include/units/isq/dimensions/time.h +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq { - -template -struct dim_time : base_dimension<"T", U> {}; - -template -concept Time = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/torque.h b/src/systems/isq/include/units/isq/dimensions/torque.h deleted file mode 100644 index e134318e..00000000 --- a/src/systems/isq/include/units/isq/dimensions/torque.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_torque; - -template F, DimensionOfT L, DimensionOfT A> -struct dim_torque : derived_dimension, exponent, exponent> {}; - -template -concept Torque = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/voltage.h b/src/systems/isq/include/units/isq/dimensions/voltage.h deleted file mode 100644 index 187d5808..00000000 --- a/src/systems/isq/include/units/isq/dimensions/voltage.h +++ /dev/null @@ -1,40 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include - -namespace units::isq { - -template -struct dim_voltage; - -template P, DimensionOfT C> -struct dim_voltage : derived_dimension, exponent> {}; - -template -concept Voltage = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/isq/include/units/isq/dimensions/volume.h b/src/systems/isq/include/units/isq/dimensions/volume.h deleted file mode 100644 index e8c3149d..00000000 --- a/src/systems/isq/include/units/isq/dimensions/volume.h +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units::isq { - -template -struct dim_volume; - -template L> -struct dim_volume : derived_dimension> {}; - -template -concept Volume = QuantityOfT; - -} // namespace units::isq diff --git a/src/systems/si-iau/CMakeLists.txt b/src/systems/isq_angle/CMakeLists.txt similarity index 91% rename from src/systems/si-iau/CMakeLists.txt rename to src/systems/isq_angle/CMakeLists.txt index 7e86c0d2..be5b3b9f 100644 --- a/src/systems/si-iau/CMakeLists.txt +++ b/src/systems/isq_angle/CMakeLists.txt @@ -23,5 +23,5 @@ cmake_minimum_required(VERSION 3.19) add_units_module( - si-iau DEPENDENCIES mp-units::si HEADERS include/units/isq/si/iau/iau.h include/units/isq/si/iau/length.h + isq_angle DEPENDENCIES mp-units::angular mp-units::isq HEADERS include/mp-units/systems/isq_angle/isq_angle.h ) diff --git a/src/systems/isq_angle/include/mp-units/systems/isq_angle/isq_angle.h b/src/systems/isq_angle/include/mp-units/systems/isq_angle/isq_angle.h new file mode 100644 index 00000000..2fa547ab --- /dev/null +++ b/src/systems/isq_angle/include/mp-units/systems/isq_angle/isq_angle.h @@ -0,0 +1,59 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include + +namespace mp_units::isq_angle { + +using namespace isq; + +// ISQ angular derived quantities redefinition +QUANTITY_SPEC(cotes_angle_constant, angular::angle); // 1 rad +QUANTITY_SPEC(angular_measure, angular::angle, cotes_angle_constant* arc_length / radius); +QUANTITY_SPEC(rotational_displacement, angular::angle, cotes_angle_constant* path_length / radius); +inline constexpr auto angular_displacement = rotational_displacement; +QUANTITY_SPEC(phase_angle, angular_measure); +QUANTITY_SPEC(solid_angular_measure, pow<2>(cotes_angle_constant) * area / pow<2>(radius)); +QUANTITY_SPEC(angular_velocity, angular_displacement / duration, quantity_character::vector); +QUANTITY_SPEC(angular_acceleration, angular_velocity / duration); +QUANTITY_SPEC(rotation, rotational_displacement); +QUANTITY_SPEC(angular_frequency, phase_angle / duration); +QUANTITY_SPEC(angular_repetency, cotes_angle_constant / wavelength); +inline constexpr auto angular_wavenumber = angular_repetency; +QUANTITY_SPEC(phase_coefficient, phase_angle / path_length); +QUANTITY_SPEC(propagation_coefficient, cotes_angle_constant / length); +QUANTITY_SPEC(angular_momentum, position_vector* momentum / cotes_angle_constant); // vector +QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor); +QUANTITY_SPEC(moment_of_force, position_vector* force / cotes_angle_constant); // vector +QUANTITY_SPEC(torque, moment_of_force, quantity_character::scalar); +QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector +QUANTITY_SPEC(loss_angle, angular_measure); + +// constants +inline constexpr auto cotes_angle = cotes_angle_constant[angular::radian]; + +} // namespace mp_units::isq_angle diff --git a/src/systems/natural/CMakeLists.txt b/src/systems/natural/CMakeLists.txt new file mode 100644 index 00000000..1489b2e8 --- /dev/null +++ b/src/systems/natural/CMakeLists.txt @@ -0,0 +1,25 @@ +# 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.19) + +add_units_module(natural DEPENDENCIES mp-units::isq HEADERS include/mp-units/systems/natural/natural.h) diff --git a/src/systems/natural/include/mp-units/systems/natural/natural.h b/src/systems/natural/include/mp-units/systems/natural/natural.h new file mode 100644 index 00000000..3d614336 --- /dev/null +++ b/src/systems/natural/include/mp-units/systems/natural/natural.h @@ -0,0 +1,60 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include + +namespace mp_units::natural { + +// clang-format off +// units +inline constexpr struct electronvolt : named_unit<"eV"> {} electronvolt; +inline constexpr struct gigaelectronvolt : decltype(si::giga) {} gigaelectronvolt; + +// system references +inline constexpr struct time : system_reference {} time; +inline constexpr struct length : system_reference {} length; +inline constexpr struct mass : system_reference {} mass; +inline constexpr struct velocity : system_reference {} velocity; +inline constexpr struct speed : system_reference {} speed; +inline constexpr struct acceleration : system_reference {} acceleration; +inline constexpr struct momentum : system_reference {} momentum; +inline constexpr struct force : system_reference {} force; +inline constexpr struct energy : system_reference {} energy; +// clang-format on + +// constants +inline constexpr auto speed_of_light = speed[one]; + +namespace unit_symbols { + +inline constexpr auto GeV = gigaelectronvolt; +inline constexpr auto GeV2 = square(gigaelectronvolt); + +} // namespace unit_symbols + +} // namespace mp_units::natural diff --git a/src/systems/si-cgs/CMakeLists.txt b/src/systems/si-cgs/CMakeLists.txt deleted file mode 100644 index 08316c20..00000000 --- a/src/systems/si-cgs/CMakeLists.txt +++ /dev/null @@ -1,39 +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.19) - -add_units_module( - si-cgs - DEPENDENCIES mp-units::si - HEADERS include/units/isq/si/cgs/acceleration.h - include/units/isq/si/cgs/area.h - include/units/isq/si/cgs/cgs.h - include/units/isq/si/cgs/energy.h - include/units/isq/si/cgs/force.h - include/units/isq/si/cgs/length.h - include/units/isq/si/cgs/mass.h - include/units/isq/si/cgs/power.h - include/units/isq/si/cgs/pressure.h - include/units/isq/si/cgs/speed.h - include/units/isq/si/cgs/time.h -) diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h b/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h deleted file mode 100644 index fc983980..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h +++ /dev/null @@ -1,86 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::cgs { - -struct gal : named_unit {}; -struct dim_acceleration : isq::dim_acceleration {}; - -template U, Representation Rep = double> -using acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Gal -constexpr auto operator"" _q_Gal(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return acceleration(static_cast(l)); -} -constexpr auto operator"" _q_Gal(long double l) { return acceleration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace acceleration_references { - -inline constexpr auto Gal = reference{}; - -} // namespace acceleration_references - -namespace references { - -using namespace acceleration_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline acceleration { - -template -using Gal = units::isq::si::cgs::acceleration; - -} // namespace units::aliases::isq::si::cgs::inline acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/area.h b/src/systems/si-cgs/include/units/isq/si/cgs/area.h deleted file mode 100644 index ca3e14da..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/area.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::cgs { - -using si::square_centimetre; - -struct dim_area : isq::dim_area {}; - -template U, Representation Rep = double> -using area = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cm2 -constexpr auto operator"" _q_cm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_cm2(long double l) { return area(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto cm2 = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline area { - -template -using cm2 = units::isq::si::cgs::area; - -} // namespace units::aliases::isq::si::cgs::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/cgs.h b/src/systems/si-cgs/include/units/isq/si/cgs/cgs.h deleted file mode 100644 index 26453d23..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/cgs.h +++ /dev/null @@ -1,36 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/energy.h b/src/systems/si-cgs/include/units/isq/si/cgs/energy.h deleted file mode 100644 index 7ca8af7f..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/energy.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::cgs { - -struct erg : named_unit {}; - -struct dim_energy : isq::dim_energy {}; - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// erg -constexpr auto operator"" _q_erg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_erg(long double l) { return energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace energy_references { - -inline constexpr auto erg = reference{}; - -} // namespace energy_references - -namespace references { - -using namespace energy_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline energy { - -template -using erg = units::isq::si::cgs::energy; - -} // namespace units::aliases::isq::si::cgs::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/force.h b/src/systems/si-cgs/include/units/isq/si/cgs/force.h deleted file mode 100644 index f6f7bca3..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/force.h +++ /dev/null @@ -1,89 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si::cgs { - -struct dyne : named_unit {}; - -struct dim_force : isq::dim_force {}; - -template U, Representation Rep = double> -using force = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// dyn -constexpr auto operator"" _q_dyn(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_dyn(long double l) { return force(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace force_references { - -inline constexpr auto dyn = reference{}; - -} // namespace force_references - -namespace references { - -using namespace force_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline force { - -template -using dyn = units::isq::si::cgs::force; - -} // namespace units::aliases::isq::si::cgs::inline force - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/length.h b/src/systems/si-cgs/include/units/isq/si/cgs/length.h deleted file mode 100644 index 52e8dc96..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/length.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units::isq::si::cgs { - -using si::centimetre; - -struct dim_length : isq::dim_length {}; - -template U, Representation Rep = double> -using length = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cm -constexpr auto operator"" _q_cm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_cm(long double l) { return length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto cm = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline length { - -template -using cm = units::isq::si::cgs::length; - -} // namespace units::aliases::isq::si::cgs::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/mass.h b/src/systems/si-cgs/include/units/isq/si/cgs/mass.h deleted file mode 100644 index 725447a0..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/mass.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::cgs { - -using si::gram; - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// g -constexpr auto operator"" _q_g(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_g(long double l) { return mass(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto g = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline mass { - -template -using g = units::isq::si::cgs::mass; - -} // namespace units::aliases::isq::si::cgs::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/power.h b/src/systems/si-cgs/include/units/isq/si/cgs/power.h deleted file mode 100644 index 5d2b0483..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/power.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::cgs { - -struct erg_per_second : derived_unit {}; - -struct dim_power : isq::dim_power {}; - -template U, Representation Rep = double> -using power = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// erg/s -constexpr auto operator"" _q_erg_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_erg_per_s(long double l) { return power(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline power { - -template -using erg_per_s = units::isq::si::cgs::power; - -} // namespace units::aliases::isq::si::cgs::inline power - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h b/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h deleted file mode 100644 index e3b1a36a..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h +++ /dev/null @@ -1,89 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si::cgs { - -struct barye : named_unit {}; - -struct dim_pressure : isq::dim_pressure {}; - -template U, Representation Rep = double> -using pressure = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Ba -constexpr auto operator"" _q_Ba(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_Ba(long double l) { return pressure(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace pressure_references { - -inline constexpr auto Ba = reference{}; - -} // namespace pressure_references - -namespace references { - -using namespace pressure_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline pressure { - -template -using Ba = units::isq::si::cgs::pressure; - -} // namespace units::aliases::isq::si::cgs::inline pressure - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/speed.h b/src/systems/si-cgs/include/units/isq/si/cgs/speed.h deleted file mode 100644 index c70ee197..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/speed.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::cgs { - -struct centimetre_per_second : derived_unit {}; -struct dim_speed : isq::dim_speed {}; - -template U, Representation Rep = double> -using speed = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cm/s -constexpr auto operator"" _q_cm_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_cm_per_s(long double l) { return speed(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline speed { - -template -using cm_per_s = units::isq::si::cgs::speed; - -} // namespace units::aliases::isq::si::cgs::inline speed - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-cgs/include/units/isq/si/cgs/time.h b/src/systems/si-cgs/include/units/isq/si/cgs/time.h deleted file mode 100644 index e84ae05c..00000000 --- a/src/systems/si-cgs/include/units/isq/si/cgs/time.h +++ /dev/null @@ -1,76 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -namespace units::isq::si::cgs { - -using si::second; - -using si::dim_time; -using si::time; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -using si::literals::operator"" _q_s; - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace time_references { - -using si::references::s; - -} // namespace time_references - -namespace references { - -using namespace time_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::cgs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::cgs::inline time { - -using namespace units::aliases::isq::si::time; - -} // namespace units::aliases::isq::si::cgs::inline time - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/CMakeLists.txt b/src/systems/si-fps/CMakeLists.txt deleted file mode 100644 index ffd302de..00000000 --- a/src/systems/si-fps/CMakeLists.txt +++ /dev/null @@ -1,41 +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.19) - -add_units_module( - si-fps - DEPENDENCIES mp-units::si-international - HEADERS include/units/isq/si/fps/acceleration.h - include/units/isq/si/fps/area.h - include/units/isq/si/fps/density.h - include/units/isq/si/fps/energy.h - include/units/isq/si/fps/force.h - include/units/isq/si/fps/fps.h - include/units/isq/si/fps/length.h - include/units/isq/si/fps/mass.h - include/units/isq/si/fps/power.h - include/units/isq/si/fps/pressure.h - include/units/isq/si/fps/speed.h - include/units/isq/si/fps/time.h - include/units/isq/si/fps/volume.h -) diff --git a/src/systems/si-fps/include/units/isq/si/fps/acceleration.h b/src/systems/si-fps/include/units/isq/si/fps/acceleration.h deleted file mode 100644 index da1c9593..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/acceleration.h +++ /dev/null @@ -1,69 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::fps { - -struct foot_per_second_sq : derived_unit {}; -struct dim_acceleration : isq::dim_acceleration {}; - -template U, Representation Rep = double> -using acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft/s2 -constexpr auto operator"" _q_ft_per_s2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return acceleration(static_cast(l)); -} -constexpr auto operator"" _q_ft_per_s2(long double l) { return acceleration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline acceleration { - -template -using ft_per_s2 = units::isq::si::fps::acceleration; - -} // namespace units::aliases::isq::si::fps::inline acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/area.h b/src/systems/si-fps/include/units/isq/si/fps/area.h deleted file mode 100644 index 076dab96..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/area.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::fps { - -struct square_foot : derived_unit {}; -struct dim_area : isq::dim_area {}; - - -template U, Representation Rep = double> -using area = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft2 -constexpr auto operator"" _q_ft2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ft2(long double l) { return area(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto ft2 = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline area { - -template -using ft2 = units::isq::si::fps::area; - -} // namespace units::aliases::isq::si::fps::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/density.h b/src/systems/si-fps/include/units/isq/si/fps/density.h deleted file mode 100644 index 41ee340e..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/density.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::fps { - -struct pound_per_foot_cub : derived_unit {}; - -struct dim_density : isq::dim_density {}; - -template U, Representation Rep = double> -using density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// lb/ft³ -constexpr auto operator"" _q_lb_per_ft3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return density(static_cast(l)); -} -constexpr auto operator"" _q_lb_per_ft3(long double l) { return density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline density { - -template -using lb_per_ft3 = units::isq::si::fps::density; - -} // namespace units::aliases::isq::si::fps::inline density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/energy.h b/src/systems/si-fps/include/units/isq/si/fps/energy.h deleted file mode 100644 index 593319a0..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/energy.h +++ /dev/null @@ -1,85 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::fps { - -// https://en.wikipedia.org/wiki/Foot-poundal -struct foot_poundal : derived_unit {}; - -struct dim_energy : isq::dim_energy {}; - -// https://en.wikipedia.org/wiki/Foot-pound_(energy) -struct foot_pound_force : derived_scaled_unit {}; - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// foot poundal -constexpr auto operator"" _q_ft_pdl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_ft_pdl(long double l) { return energy(l); } - -// foot_pound force -constexpr auto operator"" _q_ft_lbf(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_ft_lbf(long double l) { return energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline energy { - -template -using ft_pdl = units::isq::si::fps::energy; -template -using ft_lbf = units::isq::si::fps::energy; - -} // namespace units::aliases::isq::si::fps::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/force.h b/src/systems/si-fps/include/units/isq/si/fps/force.h deleted file mode 100644 index f8569719..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/force.h +++ /dev/null @@ -1,120 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si::fps { - -// https://en.wikipedia.org/wiki/Poundal -struct poundal : named_unit {}; - -// https://en.wikipedia.org/wiki/Pound_(force) -struct pound_force : named_scaled_unit(), poundal> {}; - -struct kilopound_force : prefixed_unit {}; - -// https://en.wikipedia.org/wiki/Kip_(unit), -struct kip : alias_unit {}; - -struct dim_force : isq::dim_force {}; - -template U, Representation Rep = double> -using force = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// poundal -constexpr auto operator"" _q_pdl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_pdl(long double l) { return force(l); } - -// pound force -constexpr auto operator"" _q_lbf(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_lbf(long double l) { return force(l); } - -// kilopound force -constexpr auto operator"" _q_klbf(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_klbf(long double l) { return force(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace force_references { - -inline constexpr auto pdl = reference{}; -inline constexpr auto lbf = reference{}; -inline constexpr auto klbf = reference{}; - -} // namespace force_references - -namespace references { - -using namespace force_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline force { - -template -using pdl = units::isq::si::fps::force; -template -using lbf = units::isq::si::fps::force; -template -using klbf = units::isq::si::fps::force; - -} // namespace units::aliases::isq::si::fps::inline force - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/fps.h b/src/systems/si-fps/include/units/isq/si/fps/fps.h deleted file mode 100644 index 6bd88132..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/fps.h +++ /dev/null @@ -1,38 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/si-fps/include/units/isq/si/fps/length.h b/src/systems/si-fps/include/units/isq/si/fps/length.h deleted file mode 100644 index adc29a8d..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/length.h +++ /dev/null @@ -1,190 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::fps { - -// https://en.wikipedia.org/wiki/Foot_(unit) -using si::international::fathom; -using si::international::foot; -using si::international::inch; -using si::international::mil; -using si::international::mile; -using si::international::thou; -using si::international::yard; - -// thousandth of an inch -struct thousandth : alias_unit {}; - -struct kiloyard : prefixed_unit {}; - -struct nautical_mile : named_scaled_unit(), yard> {}; - -struct dim_length : isq::dim_length {}; - -template U, Representation Rep = double> -using length = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Thousandth -constexpr auto operator"" _q_thou(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_thou(long double l) { return length(l); } -constexpr auto operator"" _q_mil(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_mil(long double l) { return length(l); } - - -// Inch -constexpr auto operator"" _q_in(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_in(long double l) { return length(l); } - -// Foot -constexpr auto operator"" _q_ft(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_ft(long double l) { return length(l); } - -// Yard -constexpr auto operator"" _q_yd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_yd(long double l) { return length(l); } - -// Fathom -constexpr auto operator"" _q_ftm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_ftm(long double l) { return length(l); } - -// Kiloyard -constexpr auto operator"" _q_kyd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_kyd(long double l) { return length(l); } - -// Mile -constexpr auto operator"" _q_mile(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_mile(long double l) { return length(l); } - -// Nautical mile -constexpr auto operator"" _q_naut_mi(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_naut_mi(long double l) { return length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto thou = reference{}; -inline constexpr auto mil = thou; - -inline constexpr auto in = reference{}; -inline constexpr auto ft = reference{}; -inline constexpr auto yd = reference{}; -inline constexpr auto ftm = reference{}; -inline constexpr auto kyd = reference{}; -inline constexpr auto mile = reference{}; -inline constexpr auto naut_mi = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline length { - -template -using thou = units::isq::si::fps::length; -template -using mil = thou; - -template -using in = units::isq::si::fps::length; -template -using ft = units::isq::si::fps::length; -template -using yd = units::isq::si::fps::length; -template -using ftm = units::isq::si::fps::length; -template -using kyd = units::isq::si::fps::length; -template -using mile = units::isq::si::fps::length; -template -using naut_mi = units::isq::si::fps::length; - -} // namespace units::aliases::isq::si::fps::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/mass.h b/src/systems/si-fps/include/units/isq/si/fps/mass.h deleted file mode 100644 index 246aba06..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/mass.h +++ /dev/null @@ -1,192 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::fps { - -// https://en.wikipedia.org/wiki/Pound_(mass) -struct pound : named_scaled_unit(), si::kilogram> {}; - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -struct grain : named_scaled_unit(), pound> {}; - -struct dram : named_scaled_unit(), pound> {}; - -struct ounce : named_scaled_unit(), pound> {}; - -struct stone : named_scaled_unit(), pound> {}; - -struct quarter : named_scaled_unit(), pound> {}; - -struct hundredweight : named_scaled_unit(), pound> {}; - -struct short_ton : named_scaled_unit(), pound> {}; - -struct long_ton : named_scaled_unit(), pound> {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Grain -constexpr auto operator"" _q_gr(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_gr(long double l) { return mass(l); } - -// Dram -constexpr auto operator"" _q_dr(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dr(long double l) { return mass(l); } - -// Ounce -constexpr auto operator"" _q_oz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_oz(long double l) { return mass(l); } - -// Pound -constexpr auto operator"" _q_lb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_lb(long double l) { return mass(l); } - -// Stone -constexpr auto operator"" _q_st(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_st(long double l) { return mass(l); } - -// Quarter -constexpr auto operator"" _q_qr(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_qr(long double l) { return mass(l); } - -// Hundredweight -constexpr auto operator"" _q_cwt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_cwt(long double l) { return mass(l); } - -// Short ton -constexpr auto operator"" _q_ston(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ston(long double l) { return mass(l); } - -// Long Ton -constexpr auto operator"" _q_lton(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_lton(long double l) { return mass(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto gr = reference{}; -inline constexpr auto dr = reference{}; -inline constexpr auto oz = reference{}; -inline constexpr auto lb = reference{}; -inline constexpr auto st = reference{}; -inline constexpr auto qr = reference{}; -inline constexpr auto cwt = reference{}; -inline constexpr auto ston = reference{}; -inline constexpr auto lton = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline mass { - -template -using gr = units::isq::si::fps::mass; -template -using dr = units::isq::si::fps::mass; -template -using oz = units::isq::si::fps::mass; -template -using lb = units::isq::si::fps::mass; -template -using st = units::isq::si::fps::mass; -template -using qr = units::isq::si::fps::mass; -template -using cwt = units::isq::si::fps::mass; -template -using ston = units::isq::si::fps::mass; -template -using lton = units::isq::si::fps::mass; - -} // namespace units::aliases::isq::si::fps::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/power.h b/src/systems/si-fps/include/units/isq/si/fps/power.h deleted file mode 100644 index 85930563..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/power.h +++ /dev/null @@ -1,113 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::fps { - -struct foot_poundal_per_second : derived_unit {}; - -struct dim_power : isq::dim_power {}; - -struct foot_pound_force_per_second : - derived_scaled_unit {}; - -struct horse_power : named_scaled_unit(), foot_pound_force_per_second> {}; - -template U, Representation Rep = double> -using power = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// foot pound force per second -constexpr auto operator"" _q_ft_pdl_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_ft_pdl_per_s(long double l) { return power(l); } - -// foot pound force per second -constexpr auto operator"" _q_ft_lbf_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_ft_lbf_per_s(long double l) { return power(l); } - -// horse power -constexpr auto operator"" _q_hp(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_hp(long double l) { return power(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace power_references { - -inline constexpr auto hp = reference{}; - -} // namespace power_references - -namespace references { - -using namespace power_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline power { - -template -using ft_pdl_per_s = units::isq::si::fps::power; -template -using ft_lbf_per_s = units::isq::si::fps::power; -template -using hp = units::isq::si::fps::power; - -} // namespace units::aliases::isq::si::fps::inline power - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/pressure.h b/src/systems/si-fps/include/units/isq/si/fps/pressure.h deleted file mode 100644 index e155d961..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/pressure.h +++ /dev/null @@ -1,118 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si::fps { - -struct poundal_per_foot_sq : derived_unit {}; - -struct dim_pressure : isq::dim_pressure {}; - -template U, Representation Rep = double> -using pressure = quantity; - -struct pound_force_per_foot_sq : - named_scaled_unit(), poundal_per_foot_sq> {}; - -struct pound_force_per_inch_sq : - named_scaled_unit(), pound_force_per_foot_sq> {}; - -struct kilopound_force_per_inch_sq : prefixed_unit {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Poundal per square foot -constexpr auto operator"" _q_pdl_per_ft2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_pdl_per_ft2(long double l) { return pressure(l); } - -// Pounds per square inch -constexpr auto operator"" _q_psi(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_psi(long double l) { return pressure(l); } - -// kilopounds per square inch -constexpr auto operator"" _q_kpsi(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_kpsi(long double l) { return pressure(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace pressure_references { - -inline constexpr auto psi = reference{}; -inline constexpr auto kpsi = reference{}; - -} // namespace pressure_references - -namespace references { - -using namespace pressure_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline pressure { - -template -using pdl_per_ft2 = units::isq::si::fps::pressure; -template -using psi = units::isq::si::fps::pressure; -template -using kpsi = units::isq::si::fps::pressure; - -} // namespace units::aliases::isq::si::fps::inline pressure - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/speed.h b/src/systems/si-fps/include/units/isq/si/fps/speed.h deleted file mode 100644 index 6ec5944d..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/speed.h +++ /dev/null @@ -1,112 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::fps { - -struct foot_per_second : derived_unit {}; -struct dim_speed : isq::dim_speed {}; - -template U, Representation Rep = double> -using speed = quantity; - -struct mile_per_hour : derived_scaled_unit {}; -struct nautical_mile_per_hour : derived_scaled_unit {}; -struct knot : alias_unit {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft/s -constexpr auto operator"" _q_ft_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_ft_per_s(long double l) { return speed(l); } - -// mph -constexpr auto operator"" _q_mph(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_mph(long double l) { return speed(l); } - -// kn -constexpr auto operator"" _q_kn(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_kn(long double l) { return speed(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace speed_references { - -inline constexpr auto mph = reference{}; -inline constexpr auto kn = reference{}; - -} // namespace speed_references - -namespace references { - -using namespace speed_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline speed { - -template -using ft_per_s = units::isq::si::fps::speed; -template -using mph = units::isq::si::fps::speed; -template -using kn = units::isq::si::fps::speed; - -} // namespace units::aliases::isq::si::fps::inline speed - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/time.h b/src/systems/si-fps/include/units/isq/si/fps/time.h deleted file mode 100644 index 6bf892b8..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/time.h +++ /dev/null @@ -1,80 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::fps { - -using si::hour; -using si::minute; -using si::second; - -using si::dim_time; -using si::time; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -using si::literals::operator"" _q_s; - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace time_references { - -using si::references::s; - -} // namespace time_references - -namespace references { - -using namespace time_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline time { - -using namespace units::aliases::isq::si::time; - -} // namespace units::aliases::isq::si::fps::inline time - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-fps/include/units/isq/si/fps/volume.h b/src/systems/si-fps/include/units/isq/si/fps/volume.h deleted file mode 100644 index 7df571e2..00000000 --- a/src/systems/si-fps/include/units/isq/si/fps/volume.h +++ /dev/null @@ -1,99 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::fps { - -struct cubic_foot : derived_unit {}; -struct dim_volume : isq::dim_volume {}; - -struct cubic_yard : derived_scaled_unit {}; - -template U, Representation Rep = double> -using volume = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft3 -constexpr auto operator"" _q_ft3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ft3(long double l) { return volume(l); } - -// yd3 -constexpr auto operator"" _q_yd3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_yd3(long double l) { return volume(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace volume_references { - -inline constexpr auto ft3 = reference{}; -inline constexpr auto yd3 = reference{}; - -} // namespace volume_references - -namespace references { - -using namespace volume_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::fps - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::fps::inline volume { - -template -using ft3 = units::isq::si::fps::volume; -template -using yd3 = units::isq::si::fps::volume; - -} // namespace units::aliases::isq::si::fps::inline volume - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-hep/include/units/isq/si/hep/area.h b/src/systems/si-hep/include/units/isq/si/hep/area.h deleted file mode 100644 index 65130f8a..00000000 --- a/src/systems/si-hep/include/units/isq/si/hep/area.h +++ /dev/null @@ -1,138 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2021 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::hep { - -// effective cross-sectional area according to EU council directive 80/181/EEC -// https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:01980L0181-20090527#page=10 -// https://www.fedlex.admin.ch/eli/cc/1994/3109_3109_3109/de -struct barn : named_scaled_unit(), square_metre> {}; -struct yocto_barn : prefixed_unit {}; -struct zepto_barn : prefixed_unit {}; -struct atto_barn : prefixed_unit {}; -struct femto_barn : prefixed_unit {}; -struct pico_barn : prefixed_unit {}; -struct nano_barn : prefixed_unit {}; -struct micro_barn : prefixed_unit {}; -struct milli_barn : prefixed_unit {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { -constexpr auto operator"" _q_yb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_yb(long double l) { return area(l); } -constexpr auto operator"" _q_zb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_zb(long double l) { return area(l); } -constexpr auto operator"" _q_ab(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ab(long double l) { return area(l); } -constexpr auto operator"" _q_fb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_fb(long double l) { return area(l); } -constexpr auto operator"" _q_pb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_pb(long double l) { return area(l); } -constexpr auto operator"" _q_nb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_nb(long double l) { return area(l); } -constexpr auto operator"" _q_ub(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ub(long double l) { return area(l); } -constexpr auto operator"" _q_mb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_mb(long double l) { return area(l); } -constexpr auto operator"" _q_b(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_b(long double l) { return area(l); } -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto barn = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::hep - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::hep::inline area { - -template -using barn = units::isq::si::area; - -} // namespace units::aliases::isq::si::hep::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-hep/include/units/isq/si/hep/energy.h b/src/systems/si-hep/include/units/isq/si/hep/energy.h deleted file mode 100644 index dd76f8fe..00000000 --- a/src/systems/si-hep/include/units/isq/si/hep/energy.h +++ /dev/null @@ -1,213 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2021 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports -#include - -namespace units::isq::si::hep { -using units::isq::si::electronvolt; - -struct yeV : prefixed_unit {}; // N.B. very rarely used -struct zeV : prefixed_unit {}; // N.B. very rarely used -struct aeV : prefixed_unit {}; // N.B. very rarely used -struct feV : prefixed_unit {}; -struct peV : prefixed_unit {}; -struct neV : prefixed_unit {}; -struct ueV : prefixed_unit {}; -struct meV : prefixed_unit {}; -using eV = electronvolt; -struct keV : prefixed_unit {}; -struct MeV : prefixed_unit {}; -using GeV = gigaelectronvolt; -struct TeV : prefixed_unit {}; -struct PeV : prefixed_unit {}; -struct EeV : prefixed_unit {}; // N.B. very rarely used -struct ZeV : prefixed_unit {}; // N.B. very rarely used -struct YeV : prefixed_unit {}; // N.B. very rarely used - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -constexpr auto operator"" _q_feV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_feV(long double l) { return energy(l); } -constexpr auto operator"" _q_peV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_peV(long double l) { return energy(l); } -constexpr auto operator"" _q_neV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_neV(long double l) { return energy(l); } -constexpr auto operator"" _q_ueV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_ueV(long double l) { return energy(l); } -constexpr auto operator"" _q_meV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_meV(long double l) { return energy(l); } - -constexpr auto operator"" _q_eV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_eV(long double l) { return energy(l); } - -constexpr auto operator"" _q_keV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_keV(long double l) { return energy(l); } -constexpr auto operator"" _q_MeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_MeV(long double l) { return energy(l); } -constexpr auto operator"" _q_GeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_GeV(long double l) { return energy(l); } -constexpr auto operator"" _q_TeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_TeV(long double l) { return energy(l); } -constexpr auto operator"" _q_PeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_PeV(long double l) { return energy(l); } -constexpr auto operator"" _q_EeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_EeV(long double l) { return energy(l); } -constexpr auto operator"" _q_ZeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_ZeV(long double l) { return energy(l); } -constexpr auto operator"" _q_YeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_YeV(long double l) { return energy(l); } -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace energy_references { - -inline constexpr auto eV = reference{}; - -} // namespace energy_references - -namespace references { - -using namespace energy_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::hep - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::hep::inline energy { - -template -using yeV = units::isq::si::hep::energy; -template -using zeV = units::isq::si::hep::energy; -template -using aeV = units::isq::si::hep::energy; -template -using feV = units::isq::si::hep::energy; -template -using peV = units::isq::si::hep::energy; -template -using neV = units::isq::si::hep::energy; -template -using ueV = units::isq::si::hep::energy; -template -using meV = units::isq::si::hep::energy; - -template -using eV = units::isq::si::hep::energy; - -template -using keV = units::isq::si::hep::energy; -template -using MeV = units::isq::si::hep::energy; -template -using GeV = units::isq::si::hep::energy; -template -using TeV = units::isq::si::hep::energy; -template -using PeV = units::isq::si::hep::energy; -template -using EeV = units::isq::si::hep::energy; -template -using ZeV = units::isq::si::hep::energy; -template -using YeV = units::isq::si::hep::energy; - -} // namespace units::aliases::isq::si::hep::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-hep/include/units/isq/si/hep/mass.h b/src/systems/si-hep/include/units/isq/si/hep/mass.h deleted file mode 100644 index cf97b869..00000000 --- a/src/systems/si-hep/include/units/isq/si/hep/mass.h +++ /dev/null @@ -1,212 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2021 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -// Necessary to factor `1'672'621'923'695`, which appears in the proton mass. -template<> -inline constexpr std::optional units::known_first_factor<334'524'384'739> = 334'524'384'739; - -// Necessary to factor `17'826'619'216'279`, which appears in the value for eV/c^2. -template<> -inline constexpr std::optional units::known_first_factor<225'653'407'801> = 225'653'407'801; - -namespace units::isq::si::hep { - -struct eV_per_c2 : - named_scaled_unit() * mag_power<10, -35>(), kilogram> {}; -struct feV_per_c2 : prefixed_unit {}; -struct peV_per_c2 : prefixed_unit {}; -struct neV_per_c2 : prefixed_unit {}; -struct ueV_per_c2 : prefixed_unit {}; -struct meV_per_c2 : - prefixed_unit {}; // approximate mass of an electron/positron (0.511 MeV/c2) -struct keV_per_c2 : prefixed_unit {}; -struct MeV_per_c2 : prefixed_unit {}; -struct GeV_per_c2 : - prefixed_unit {}; // approximate mass of a proton (0.938 GeV/c2) or neutron -struct TeV_per_c2 : prefixed_unit {}; -struct PeV_per_c2 : prefixed_unit {}; -struct EeV_per_c2 : prefixed_unit {}; -struct YeV_per_c2 : prefixed_unit {}; -struct electron_mass : - named_scaled_unit() * mag_power<10, -31>(), - kilogram> {}; -struct proton_mass : - named_scaled_unit() * mag_power<10, -27>(), - kilogram> {}; -struct neutron_mass : - named_scaled_unit() * mag_power<10, -27>(), - kilogram> {}; - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { -constexpr auto operator"" _q_feV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_feV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_peV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_peV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_neV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_neV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_ueV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ueV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_meV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_meV_per_c2(long double l) { return mass(l); } - -// eV_per_c2 -constexpr auto operator"" _q_eV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_eV_per_c2(long double l) { return mass(l); } - -constexpr auto operator"" _q_keV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_keV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_MeV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_MeV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_GeV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_GeV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_TeV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_TeV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_PeV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_PeV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_EeV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_EeV_per_c2(long double l) { return mass(l); } -constexpr auto operator"" _q_YeV_per_c2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_YeV_per_c2(long double l) { return mass(l); } - -// special HEP masses -constexpr auto operator"" _q_electron_mass(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_electron_mass(long double l) { return mass(l); } -constexpr auto operator"" _q_proton_mass(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_proton_mass(long double l) { return mass(l); } -constexpr auto operator"" _q_neutron_mass(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_neutron_mass(long double l) { return mass(l); } -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto eV_per_c2 = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::hep - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::hep::inline mass { - -template -using eV_per_c2g = units::isq::si::hep::mass; - -} // namespace units::aliases::isq::si::hep::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-hep/include/units/isq/si/hep/momentum.h b/src/systems/si-hep/include/units/isq/si/hep/momentum.h deleted file mode 100644 index a03ae821..00000000 --- a/src/systems/si-hep/include/units/isq/si/hep/momentum.h +++ /dev/null @@ -1,165 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2021 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -// Necessary to factor `5'344'285'992'678`, which appears in the value for eV/c. -template<> -inline constexpr std::optional units::known_first_factor<296'904'777'371> = 157'667; - -namespace units::isq::si::hep { - -struct kilogram_metre_per_second : derived_unit {}; - -struct eV_per_c : - named_scaled_unit() * mag_power<10, -35>(), - kilogram_metre_per_second> {}; -struct feV_per_c : prefixed_unit {}; -struct peV_per_c : prefixed_unit {}; -struct neV_per_c : prefixed_unit {}; -struct ueV_per_c : prefixed_unit {}; -struct meV_per_c : prefixed_unit {}; -struct keV_per_c : prefixed_unit {}; -struct MeV_per_c : prefixed_unit {}; -struct GeV_per_c : prefixed_unit {}; -struct TeV_per_c : prefixed_unit {}; -struct PeV_per_c : prefixed_unit {}; -struct EeV_per_c : prefixed_unit {}; -struct YeV_per_c : prefixed_unit {}; - -struct dim_momentum : isq::dim_momentum {}; - -template U, Representation Rep = double> -using momentum = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -constexpr auto operator"" _q_feV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_feV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_peV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_peV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_neV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_neV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_ueV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_ueV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_meV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_meV_per_c(long double l) { return momentum(l); } - -// eV_per_c -constexpr auto operator"" _q_eV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_eV_per_c(long double l) { return momentum(l); } - -constexpr auto operator"" _q_keV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_keV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_MeV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_MeV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_GeV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_GeV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_TeV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_TeV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_PeV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_PeV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_EeV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_EeV_per_c(long double l) { return momentum(l); } -constexpr auto operator"" _q_YeV_per_c(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_YeV_per_c(long double l) { return momentum(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si::hep - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline momentum { - -template -using eV_per_c = units::isq::si::hep::momentum; - -} // namespace units::aliases::isq::si::inline momentum - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-iau/include/units/isq/si/iau/iau.h b/src/systems/si-iau/include/units/isq/si/iau/iau.h deleted file mode 100644 index cf34a093..00000000 --- a/src/systems/si-iau/include/units/isq/si/iau/iau.h +++ /dev/null @@ -1,27 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports diff --git a/src/systems/si-iau/include/units/isq/si/iau/length.h b/src/systems/si-iau/include/units/isq/si/iau/length.h deleted file mode 100644 index 974dd8fc..00000000 --- a/src/systems/si-iau/include/units/isq/si/iau/length.h +++ /dev/null @@ -1,112 +0,0 @@ - -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::iau { - -// https://en.wikipedia.org/wiki/Light-year -struct light_year : named_scaled_unit(), si::metre> {}; - -// https://en.wikipedia.org/wiki/Parsec -struct parsec : named_scaled_unit(), si::metre> {}; - -// https://en.wikipedia.org/wiki/Angstrom -struct angstrom : named_scaled_unit(), si::metre> {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ly -constexpr auto operator"" _q_ly(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_ly(long double l) { return si::length(l); } - -// pc -constexpr auto operator"" _q_pc(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_pc(long double l) { return si::length(l); } - -// angstrom -constexpr auto operator"" _q_angstrom(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_angstrom(long double l) { return si::length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto ly = reference{}; -inline constexpr auto pc = reference{}; -inline constexpr auto angstrom = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::iau - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::iau::inline length { - -template -using ly = units::isq::si::length; -template -using pc = units::isq::si::length; -template -using angstrom = units::isq::si::length; - -} // namespace units::aliases::isq::si::iau::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-imperial/include/units/isq/si/imperial/imperial.h b/src/systems/si-imperial/include/units/isq/si/imperial/imperial.h deleted file mode 100644 index 09d40ffe..00000000 --- a/src/systems/si-imperial/include/units/isq/si/imperial/imperial.h +++ /dev/null @@ -1,27 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -// IWYU pragma: end_exports diff --git a/src/systems/si-imperial/include/units/isq/si/imperial/length.h b/src/systems/si-imperial/include/units/isq/si/imperial/length.h deleted file mode 100644 index f6c278f4..00000000 --- a/src/systems/si-imperial/include/units/isq/si/imperial/length.h +++ /dev/null @@ -1,97 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::imperial { - -// https://en.wikipedia.org/wiki/Chain_(unit) -struct chain : named_scaled_unit(), si::international::yard> {}; - -// https://en.wikipedia.org/wiki/Rod_(unit) -struct rod : named_scaled_unit(), chain> {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ch -constexpr auto operator"" _q_ch(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_ch(long double l) { return si::length(l); } - -// rd -constexpr auto operator"" _q_rd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_rd(long double l) { return si::length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto ch = reference{}; -inline constexpr auto rd = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::imperial - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::imperial::inline length { - -template -using ch = units::isq::si::length; -template -using rd = units::isq::si::length; - -} // namespace units::aliases::isq::si::imperial::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-international/include/units/isq/si/international/area.h b/src/systems/si-international/include/units/isq/si/international/area.h deleted file mode 100644 index 40fdc533..00000000 --- a/src/systems/si-international/include/units/isq/si/international/area.h +++ /dev/null @@ -1,83 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::international { - -struct square_foot : derived_scaled_unit {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft2 -constexpr auto operator"" _q_ft2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::area(static_cast(l)); -} -constexpr auto operator"" _q_ft2(long double l) { return si::area(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto ft2 = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::international - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::international::inline area { - -template -using ft2 = units::isq::si::area; - -} // namespace units::aliases::isq::si::international::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-international/include/units/isq/si/international/international.h b/src/systems/si-international/include/units/isq/si/international/international.h deleted file mode 100644 index f3a8f2ab..00000000 --- a/src/systems/si-international/include/units/isq/si/international/international.h +++ /dev/null @@ -1,30 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/si-international/include/units/isq/si/international/length.h b/src/systems/si-international/include/units/isq/si/international/length.h deleted file mode 100644 index ef9378ad..00000000 --- a/src/systems/si-international/include/units/isq/si/international/length.h +++ /dev/null @@ -1,188 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::international { - -// si::international yard -// https://en.wikipedia.org/wiki/International_yard_and_pound -struct yard : named_scaled_unit(), si::metre> {}; - -// si::international foot -// https://en.wikipedia.org/wiki/Foot_(unit)#International_foot -struct foot : named_scaled_unit(), yard> {}; - -// https://en.wikipedia.org/wiki/Fathom#International_fathom -struct fathom : named_scaled_unit(), yard> {}; - -// si::international inch -// https://en.wikipedia.org/wiki/Inch#Equivalences -struct inch : named_scaled_unit(), yard> {}; - -// intrnational mile -// https://en.wikipedia.org/wiki/Mile#International_mile -struct mile : named_scaled_unit(), si::kilometre> {}; - -// si::international nautical mile -// https://en.wikipedia.org/wiki/Nautical_mile -struct nautical_mile : named_scaled_unit(), si::metre> {}; - -// thou -// https://en.wikipedia.org/wiki/Thousandth_of_an_inch -struct thou : named_scaled_unit(), inch> {}; - -// mil - different name for thou -// https://en.wikipedia.org/wiki/Thousandth_of_an_inch -using mil = thou; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// yd -constexpr auto operator"" _q_yd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_yd(long double l) { return si::length(l); } - -// ft -constexpr auto operator"" _q_ft(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_ft(long double l) { return si::length(l); } - -// fathom -constexpr auto operator"" _q_fathom(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_fathom(long double l) { return si::length(l); } - -// in -constexpr auto operator"" _q_in(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_in(long double l) { return si::length(l); } - -// mi -constexpr auto operator"" _q_mi(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_mi(long double l) { return si::length(l); } - -// mi_naut -constexpr auto operator"" _q_naut_mi(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_naut_mi(long double l) { return si::length(l); } - -// thou -constexpr auto operator"" _q_thou(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_thou(long double l) { return si::length(l); } - -// mil -constexpr auto operator"" _q_mil(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_mil(long double l) { return si::length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto yd = reference{}; -inline constexpr auto ft = reference{}; -inline constexpr auto fathom = reference{}; -inline constexpr auto in = reference{}; -inline constexpr auto mi = reference{}; -inline constexpr auto mi_naut = reference{}; -inline constexpr auto thou = reference{}; -inline constexpr auto mil = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::international - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::international::inline length { - -template -using yd = units::isq::si::length; -template -using ft = units::isq::si::length; -template -using fathom = units::isq::si::length; -template -using in = units::isq::si::length; -template -using mi = units::isq::si::length; -template -using mi_naut = units::isq::si::length; -template -using thou = units::isq::si::length; -template -using mil = units::isq::si::length; - -} // namespace units::aliases::isq::si::international::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-international/include/units/isq/si/international/speed.h b/src/systems/si-international/include/units/isq/si/international/speed.h deleted file mode 100644 index 84f2dbf1..00000000 --- a/src/systems/si-international/include/units/isq/si/international/speed.h +++ /dev/null @@ -1,107 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::international { - -struct mile_per_hour : derived_scaled_unit {}; -struct nautical_mile_per_hour : - derived_scaled_unit {}; -struct knot : alias_unit {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// mi/h -constexpr auto operator"" _q_mi_per_h(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::speed(static_cast(l)); -} -constexpr auto operator"" _q_mi_per_h(long double l) { return si::speed(l); } - -// nmi/h -constexpr auto operator"" _q_nmi_per_h(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::speed(static_cast(l)); -} -constexpr auto operator"" _q_nmi_per_h(long double l) { return si::speed(l); } - -// kn -constexpr auto operator"" _q_kn(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::speed(static_cast(l)); -} -constexpr auto operator"" _q_kn(long double l) { return si::speed(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace speed_references { - -inline constexpr auto kn = reference{}; - -} // namespace speed_references - -namespace references { - -using namespace speed_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::international - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::international::inline speed { - -template -using mi_per_h = units::isq::si::speed; - -template -using nmi_per_h = units::isq::si::speed; - -template -using kn = units::isq::si::speed; - -} // namespace units::aliases::isq::si::international::inline speed - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-international/include/units/isq/si/international/volume.h b/src/systems/si-international/include/units/isq/si/international/volume.h deleted file mode 100644 index 4a5fcbcd..00000000 --- a/src/systems/si-international/include/units/isq/si/international/volume.h +++ /dev/null @@ -1,83 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si::international { - -struct cubic_foot : derived_scaled_unit {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft3 -constexpr auto operator"" _q_ft3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::volume(static_cast(l)); -} -constexpr auto operator"" _q_ft3(long double l) { return si::volume(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace volume_references { - -inline constexpr auto ft3 = reference{}; - -} // namespace volume_references - -namespace references { - -using namespace volume_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::international - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::international::inline volume { - -template -using ft3 = units::isq::si::volume; - -} // namespace units::aliases::isq::si::international::inline volume - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-typographic/include/units/isq/si/typographic/length.h b/src/systems/si-typographic/include/units/isq/si/typographic/length.h deleted file mode 100644 index e5b409c6..00000000 --- a/src/systems/si-typographic/include/units/isq/si/typographic/length.h +++ /dev/null @@ -1,124 +0,0 @@ - -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::typographic { - -// TODO Conflicts with (https://en.wikipedia.org/wiki/Pica_(typography)), verify correctness of below conversion factors -// and provide hyperlinks to definitions -struct pica_comp : named_scaled_unit() * mag_power<10, -9>(), si::metre> {}; -struct pica_prn : - named_scaled_unit() * mag_power<10, -3>(), si::metre> {}; -struct point_comp : - named_scaled_unit() * mag_power<10, -4>(), si::metre> {}; -struct point_prn : - named_scaled_unit() * mag_power<10, -4>(), si::metre> {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// pica comp -constexpr auto operator"" _q_pica_comp(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_pica_comp(long double l) { return si::length(l); } - -// pica prn -constexpr auto operator"" _q_pica_prn(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_pica_prn(long double l) { return si::length(l); } - -// point comp -constexpr auto operator"" _q_point_comp(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_point_comp(long double l) { return si::length(l); } - -// point prn -constexpr auto operator"" _q_point_prn(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_point_prn(long double l) { return si::length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto pica_comp = reference{}; -inline constexpr auto pica_prn = reference{}; -inline constexpr auto point_comp = reference{}; -inline constexpr auto point_prn = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::typographic - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::typographic::inline length { - -template -using pica_comp = units::isq::si::length; -template -using pica_prn = units::isq::si::length; -template -using point_comp = units::isq::si::length; -template -using point_prn = units::isq::si::length; - -} // namespace units::aliases::isq::si::typographic::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-uscs/include/units/isq/si/uscs/length.h b/src/systems/si-uscs/include/units/isq/si/uscs/length.h deleted file mode 100644 index e2dafbb5..00000000 --- a/src/systems/si-uscs/include/units/isq/si/uscs/length.h +++ /dev/null @@ -1,116 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::uscs { - -// https://en.wikipedia.org/wiki/Foot_(unit)#US_survey_foot -// https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors#B6 -struct foot : named_scaled_unit(), si::metre> {}; - -// https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors#B6 -struct fathom : named_scaled_unit(), foot> {}; - -// https://en.wikipedia.org/wiki/Mile#U.S._survey_mile -// https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors#B6 -struct mile : named_scaled_unit(), foot> {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ft -constexpr auto operator"" _q_ft_us(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_ft_us(long double l) { return si::length(l); } - -// fathom -constexpr auto operator"" _q_fathom_us(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_fathom_us(long double l) -{ - return si::length(l); -} - -// mi -constexpr auto operator"" _q_mi_us(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::length(static_cast(l)); -} -constexpr auto operator"" _q_mi_us(long double l) { return si::length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto ft = reference{}; -inline constexpr auto fathom = reference{}; -inline constexpr auto mi = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::uscs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::uscs::inline length { - -template -using ft = units::isq::si::length; -template -using fathom = units::isq::si::length; -template -using mi = units::isq::si::length; - -} // namespace units::aliases::isq::si::uscs::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-uscs/include/units/isq/si/uscs/pressure.h b/src/systems/si-uscs/include/units/isq/si/uscs/pressure.h deleted file mode 100644 index a02b4aba..00000000 --- a/src/systems/si-uscs/include/units/isq/si/uscs/pressure.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// Copyright (c) 2023 Tobias Lorenz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si::uscs { - -// https://en.wikipedia.org/wiki/Inch_of_mercury -// https://www.nist.gov/pml/special-publication-811/nist-guide-si-appendix-b-conversion-factors/nist-guide-si-appendix-b8 -struct inch_of_mercury : named_scaled_unit(), si::pascal> {}; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// inHg -constexpr auto operator"" _q_inHg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return si::pressure(static_cast(l)); -} -constexpr auto operator"" _q_inHg(long double l) -{ - return si::pressure(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace pressure_references { - -inline constexpr auto inHg = reference{}; - -} // namespace pressure_references - -namespace references { - -using namespace pressure_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si::uscs - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::uscs::inline pressure { - -template -using inHg = units::isq::si::pressure; - -} // namespace units::aliases::isq::si::uscs::inline pressure - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si-uscs/include/units/isq/si/uscs/uscs.h b/src/systems/si-uscs/include/units/isq/si/uscs/uscs.h deleted file mode 100644 index 84b0df2e..00000000 --- a/src/systems/si-uscs/include/units/isq/si/uscs/uscs.h +++ /dev/null @@ -1,28 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -// IWYU pragma: end_exports diff --git a/src/systems/si/CMakeLists.txt b/src/systems/si/CMakeLists.txt index f4a59f96..7f9de7a8 100644 --- a/src/systems/si/CMakeLists.txt +++ b/src/systems/si/CMakeLists.txt @@ -25,53 +25,7 @@ cmake_minimum_required(VERSION 3.19) add_units_module( si DEPENDENCIES mp-units::isq - HEADERS include/units/isq/si/absorbed_dose.h - include/units/isq/si/acceleration.h - include/units/isq/si/amount_of_substance.h - include/units/isq/si/angular_acceleration.h - include/units/isq/si/angular_velocity.h - include/units/isq/si/area.h - include/units/isq/si/capacitance.h - include/units/isq/si/catalytic_activity.h - include/units/isq/si/charge_density.h - include/units/isq/si/concentration.h - include/units/isq/si/conductance.h - include/units/isq/si/constants.h - include/units/isq/si/current_density.h - include/units/isq/si/density.h - include/units/isq/si/dynamic_viscosity.h - include/units/isq/si/electric_charge.h - include/units/isq/si/electric_current.h - include/units/isq/si/electric_field_strength.h - include/units/isq/si/energy.h - include/units/isq/si/energy_density.h - include/units/isq/si/force.h - include/units/isq/si/frequency.h - include/units/isq/si/heat_capacity.h - include/units/isq/si/inductance.h - include/units/isq/si/length.h - include/units/isq/si/luminance.h - include/units/isq/si/luminous_flux.h - include/units/isq/si/luminous_intensity.h - include/units/isq/si/magnetic_flux.h - include/units/isq/si/magnetic_induction.h - include/units/isq/si/mass.h - include/units/isq/si/molar_energy.h - include/units/isq/si/momentum.h - include/units/isq/si/permeability.h - include/units/isq/si/permittivity.h - include/units/isq/si/power.h - include/units/isq/si/prefixes.h - include/units/isq/si/pressure.h - include/units/isq/si/radioactivity.h - include/units/isq/si/resistance.h - include/units/isq/si/si.h - include/units/isq/si/speed.h - include/units/isq/si/surface_tension.h - include/units/isq/si/thermal_conductivity.h - include/units/isq/si/thermodynamic_temperature.h - include/units/isq/si/time.h - include/units/isq/si/torque.h - include/units/isq/si/voltage.h - include/units/isq/si/volume.h + HEADERS include/mp-units/systems/si/constants.h include/mp-units/systems/si/prefixes.h + include/mp-units/systems/si/si.h include/mp-units/systems/si/unit_symbols.h + include/mp-units/systems/si/units.h ) diff --git a/src/systems/si/include/mp-units/systems/si/constants.h b/src/systems/si/include/mp-units/systems/si/constants.h new file mode 100644 index 00000000..a0ad268d --- /dev/null +++ b/src/systems/si/include/mp-units/systems/si/constants.h @@ -0,0 +1,58 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::si { + +namespace si2019 { + +// clang-format off +inline constexpr struct hyperfine_structure_transition_frequency_of_cs : + named_unit * hertz> {} hyperfine_structure_transition_frequency_of_cs; +inline constexpr struct speed_of_light_in_vacuum : + named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; +inline constexpr struct planck_constant : + named_unit<"h", mag * mag_power<10, -34> * joule * second> {} planck_constant; +inline constexpr struct elementary_charge : + named_unit<"e", mag * mag_power<10, -19> * coulomb> {} elementary_charge; +inline constexpr struct boltzmann_constant : + named_unit<"k", mag * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; +inline constexpr struct avogadro_constant : + named_unit<"N_A", mag * mag_power<10, 23> * (1 / mole)> {} avogadro_constant; +inline constexpr struct luminous_efficacy : + named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy; +// clang-format on + +} // namespace si2019 + +// clang-format off +inline constexpr struct standard_gravity : + named_unit * metre / square(second)> {} standard_gravity; +inline constexpr struct magnetic_constant : + named_unit * mag_pi * mag_power<10, -7> * henry / metre> {} magnetic_constant; +// clang-format on + +} // namespace mp_units::si diff --git a/src/systems/si/include/mp-units/systems/si/prefixes.h b/src/systems/si/include/mp-units/systems/si/prefixes.h new file mode 100644 index 00000000..f8c9431c --- /dev/null +++ b/src/systems/si/include/mp-units/systems/si/prefixes.h @@ -0,0 +1,81 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include + +namespace mp_units::si { + +// clang-format off +template struct quecto_ : prefixed_unit<"q", mag_power<10, -30>, U> {}; +template struct ronto_ : prefixed_unit<"r", mag_power<10, -27>, U> {}; +template struct yocto_ : prefixed_unit<"y", mag_power<10, -24>, U> {}; +template struct zepto_ : prefixed_unit<"z", mag_power<10, -21>, U> {}; +template struct atto_ : prefixed_unit<"a", mag_power<10, -18>, U> {}; +template struct femto_ : prefixed_unit<"f", mag_power<10, -15>, U> {}; +template struct pico_ : prefixed_unit<"p", mag_power<10, -12>, U> {}; +template struct nano_ : prefixed_unit<"n", mag_power<10, -9>, U> {}; +template struct micro_ : prefixed_unit, U> {}; +template struct milli_ : prefixed_unit<"m", mag_power<10, -3>, U> {}; +template struct centi_ : prefixed_unit<"c", mag_power<10, -2>, U> {}; +template struct deci_ : prefixed_unit<"d", mag_power<10, -1>, U> {}; +template struct deca_ : prefixed_unit<"da", mag_power<10, 1>, U> {}; +template struct hecto_ : prefixed_unit<"h", mag_power<10, 2>, U> {}; +template struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; +template struct mega_ : prefixed_unit<"M", mag_power<10, 6>, U> {}; +template struct giga_ : prefixed_unit<"G", mag_power<10, 9>, U> {}; +template struct tera_ : prefixed_unit<"T", mag_power<10, 12>, U> {}; +template struct peta_ : prefixed_unit<"P", mag_power<10, 15>, U> {}; +template struct exa_ : prefixed_unit<"E", mag_power<10, 18>, U> {}; +template struct zetta_ : prefixed_unit<"Z", mag_power<10, 21>, U> {}; +template struct yotta_ : prefixed_unit<"Y", mag_power<10, 24>, U> {}; +template struct ronna_ : prefixed_unit<"R", mag_power<10, 27>, U> {}; +template struct quetta_ : prefixed_unit<"Q", mag_power<10, 30>, U> {}; + +template inline constexpr quecto_ quecto; +template inline constexpr ronto_ ronto; +template inline constexpr yocto_ yocto; +template inline constexpr zepto_ zepto; +template inline constexpr atto_ atto; +template inline constexpr femto_ femto; +template inline constexpr pico_ pico; +template inline constexpr nano_ nano; +template inline constexpr micro_ micro; +template inline constexpr milli_ milli; +template inline constexpr centi_ centi; +template inline constexpr deci_ deci; +template inline constexpr deca_ deca; +template inline constexpr hecto_ hecto; +template inline constexpr kilo_ kilo; +template inline constexpr mega_ mega; +template inline constexpr giga_ giga; +template inline constexpr tera_ tera; +template inline constexpr peta_ peta; +template inline constexpr exa_ exa; +template inline constexpr zetta_ zetta; +template inline constexpr yotta_ yotta; +template inline constexpr ronna_ ronna; +template inline constexpr quetta_ quetta; +// clang-format on + +} // namespace mp_units::si diff --git a/src/core/include/units/point_origin.h b/src/systems/si/include/mp-units/systems/si/si.h similarity index 87% rename from src/core/include/units/point_origin.h rename to src/systems/si/include/mp-units/systems/si/si.h index 581ccbfc..9efad6f3 100644 --- a/src/core/include/units/point_origin.h +++ b/src/systems/si/include/mp-units/systems/si/si.h @@ -22,13 +22,7 @@ #pragma once -#include - -namespace units { - -template -struct point_origin { - using dimension = D; -}; - -} // namespace units +#include +#include +#include +#include diff --git a/src/systems/si/include/mp-units/systems/si/unit_symbols.h b/src/systems/si/include/mp-units/systems/si/unit_symbols.h new file mode 100644 index 00000000..8e37c53f --- /dev/null +++ b/src/systems/si/include/mp-units/systems/si/unit_symbols.h @@ -0,0 +1,756 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::si::unit_symbols { + +inline constexpr auto qm = quecto; +inline constexpr auto rm = ronto; +inline constexpr auto ym = yocto; +inline constexpr auto zm = zepto; +inline constexpr auto am = atto; +inline constexpr auto fm = femto; +inline constexpr auto pm = pico; +inline constexpr auto nm = nano; +inline constexpr auto um = micro; +inline constexpr auto mm = milli; +inline constexpr auto cm = centi; +inline constexpr auto dm = deci; +inline constexpr auto m = metre; +inline constexpr auto dam = deca; +inline constexpr auto hm = hecto; +inline constexpr auto km = kilo; +inline constexpr auto Mm = mega; +inline constexpr auto Gm = giga; +inline constexpr auto Tm = tera; +inline constexpr auto Pm = peta; +inline constexpr auto Em = exa; +inline constexpr auto Zm = zetta; +inline constexpr auto Ym = yotta; +inline constexpr auto Rm = ronna; +inline constexpr auto Qm = quetta; + +inline constexpr auto qs = quecto; +inline constexpr auto rs = ronto; +inline constexpr auto ys = yocto; +inline constexpr auto zs = zepto; +inline constexpr auto as = atto; +inline constexpr auto fs = femto; +inline constexpr auto ps = pico; +inline constexpr auto ns = nano; +inline constexpr auto us = micro; +inline constexpr auto ms = milli; +inline constexpr auto cs = centi; +inline constexpr auto ds = deci; +inline constexpr auto s = second; +// TODO Should the below multiples of second be provided? +inline constexpr auto das = deca; +inline constexpr auto hs = hecto; +inline constexpr auto ks = kilo; +inline constexpr auto Ms = mega; +inline constexpr auto Gs = giga; +inline constexpr auto Ts = tera; +inline constexpr auto Ps = peta; +inline constexpr auto Es = exa; +inline constexpr auto Zs = zetta; +inline constexpr auto Ys = yotta; +inline constexpr auto Rs = ronna; +inline constexpr auto Qs = quetta; + +inline constexpr auto qg = quecto; +inline constexpr auto rg = ronto; +inline constexpr auto yg = yocto; +inline constexpr auto zg = zepto; +inline constexpr auto ag = atto; +inline constexpr auto fg = femto; +inline constexpr auto pg = pico; +inline constexpr auto ng = nano; +inline constexpr auto ug = micro; +inline constexpr auto mg = milli; +inline constexpr auto cg = centi; +inline constexpr auto dg = deci; +inline constexpr auto g = gram; +inline constexpr auto dag = deca; +inline constexpr auto hg = hecto; +inline constexpr auto kg = kilogram; +inline constexpr auto Mg = mega; +inline constexpr auto Gg = giga; +inline constexpr auto Tg = tera; +inline constexpr auto Pg = peta; +inline constexpr auto Eg = exa; +inline constexpr auto Zg = zetta; +inline constexpr auto Yg = yotta; +inline constexpr auto Rg = ronna; +inline constexpr auto Qg = quetta; + +inline constexpr auto qA = quecto; +inline constexpr auto rA = ronto; +inline constexpr auto yA = yocto; +inline constexpr auto zA = zepto; +inline constexpr auto aA = atto; +inline constexpr auto fA = femto; +inline constexpr auto pA = pico; +inline constexpr auto nA = nano; +inline constexpr auto uA = micro; +inline constexpr auto mA = milli; +inline constexpr auto cA = centi; +inline constexpr auto dA = deci; +inline constexpr auto A = ampere; +inline constexpr auto daA = deca; +inline constexpr auto hA = hecto; +inline constexpr auto kA = kilo; +inline constexpr auto MA = mega; +inline constexpr auto GA = giga; +inline constexpr auto TA = tera; +inline constexpr auto PA = peta; +inline constexpr auto EA = exa; +inline constexpr auto ZA = zetta; +inline constexpr auto YA = yotta; +inline constexpr auto RA = ronna; +inline constexpr auto QA = quetta; + +inline constexpr auto qK = quecto; +inline constexpr auto rK = ronto; +inline constexpr auto yK = yocto; +inline constexpr auto zK = zepto; +inline constexpr auto aK = atto; +inline constexpr auto fK = femto; +inline constexpr auto pK = pico; +inline constexpr auto nK = nano; +inline constexpr auto uK = micro; +inline constexpr auto mK = milli; +inline constexpr auto cK = centi; +inline constexpr auto dK = deci; +inline constexpr auto K = kelvin; +inline constexpr auto daK = deca; +inline constexpr auto hK = hecto; +inline constexpr auto kK = kilo; +inline constexpr auto MK = mega; +inline constexpr auto GK = giga; +inline constexpr auto TK = tera; +inline constexpr auto PK = peta; +inline constexpr auto EK = exa; +inline constexpr auto ZK = zetta; +inline constexpr auto YK = yotta; +inline constexpr auto RK = ronna; +inline constexpr auto QK = quetta; + +inline constexpr auto qmol = quecto; +inline constexpr auto rmol = ronto; +inline constexpr auto ymol = yocto; +inline constexpr auto zmol = zepto; +inline constexpr auto amol = atto; +inline constexpr auto fmol = femto; +inline constexpr auto pmol = pico; +inline constexpr auto nmol = nano; +inline constexpr auto umol = micro; +inline constexpr auto mmol = milli; +inline constexpr auto cmol = centi; +inline constexpr auto dmol = deci; +inline constexpr auto mol = mole; +inline constexpr auto damol = deca; +inline constexpr auto hmol = hecto; +inline constexpr auto kmol = kilo; +inline constexpr auto Mmol = mega; +inline constexpr auto Gmol = giga; +inline constexpr auto Tmol = tera; +inline constexpr auto Pmol = peta; +inline constexpr auto Emol = exa; +inline constexpr auto Zmol = zetta; +inline constexpr auto Ymol = yotta; +inline constexpr auto Rmol = ronna; +inline constexpr auto Qmol = quetta; + +inline constexpr auto qcd = quecto; +inline constexpr auto rcd = ronto; +inline constexpr auto ycd = yocto; +inline constexpr auto zcd = zepto; +inline constexpr auto acd = atto; +inline constexpr auto fcd = femto; +inline constexpr auto pcd = pico; +inline constexpr auto ncd = nano; +inline constexpr auto ucd = micro; +inline constexpr auto mcd = milli; +inline constexpr auto ccd = centi; +inline constexpr auto dcd = deci; +inline constexpr auto cd = candela; +inline constexpr auto dacd = deca; +inline constexpr auto hcd = hecto; +inline constexpr auto kcd = kilo; +inline constexpr auto Mcd = mega; +inline constexpr auto Gcd = giga; +inline constexpr auto Tcd = tera; +inline constexpr auto Pcd = peta; +inline constexpr auto Ecd = exa; +inline constexpr auto Zcd = zetta; +inline constexpr auto Ycd = yotta; +inline constexpr auto Rcd = ronna; +inline constexpr auto Qcd = quetta; + +inline constexpr auto qrad = quecto; +inline constexpr auto rrad = ronto; +inline constexpr auto yrad = yocto; +inline constexpr auto zrad = zepto; +inline constexpr auto arad = atto; +inline constexpr auto frad = femto; +inline constexpr auto prad = pico; +inline constexpr auto nrad = nano; +inline constexpr auto urad = micro; +inline constexpr auto mrad = milli; +inline constexpr auto crad = centi; +inline constexpr auto drad = deci; +inline constexpr auto rad = radian; +inline constexpr auto darad = deca; +inline constexpr auto hrad = hecto; +inline constexpr auto krad = kilo; +inline constexpr auto Mrad = mega; +inline constexpr auto Grad = giga; +inline constexpr auto Trad = tera; +inline constexpr auto Prad = peta; +inline constexpr auto Erad = exa; +inline constexpr auto Zrad = zetta; +inline constexpr auto Yrad = yotta; +inline constexpr auto Rrad = ronna; +inline constexpr auto Qrad = quetta; + +inline constexpr auto qsr = quecto; +inline constexpr auto rsr = ronto; +inline constexpr auto ysr = yocto; +inline constexpr auto zsr = zepto; +inline constexpr auto asr = atto; +inline constexpr auto fsr = femto; +inline constexpr auto psr = pico; +inline constexpr auto nsr = nano; +inline constexpr auto usr = micro; +inline constexpr auto msr = milli; +inline constexpr auto csr = centi; +inline constexpr auto dsr = deci; +inline constexpr auto sr = steradian; +inline constexpr auto dasr = deca; +inline constexpr auto hsr = hecto; +inline constexpr auto ksr = kilo; +inline constexpr auto Msr = mega; +inline constexpr auto Gsr = giga; +inline constexpr auto Tsr = tera; +inline constexpr auto Psr = peta; +inline constexpr auto Esr = exa; +inline constexpr auto Zsr = zetta; +inline constexpr auto Ysr = yotta; +inline constexpr auto Rsr = ronna; +inline constexpr auto Qsr = quetta; + +inline constexpr auto qHz = quecto; +inline constexpr auto rHz = ronto; +inline constexpr auto yHz = yocto; +inline constexpr auto zHz = zepto; +inline constexpr auto aHz = atto; +inline constexpr auto fHz = femto; +inline constexpr auto pHz = pico; +inline constexpr auto nHz = nano; +inline constexpr auto uHz = micro; +inline constexpr auto mHz = milli; +inline constexpr auto cHz = centi; +inline constexpr auto dHz = deci; +inline constexpr auto Hz = hertz; +inline constexpr auto daHz = deca; +inline constexpr auto hHz = hecto; +inline constexpr auto kHz = kilo; +inline constexpr auto MHz = mega; +inline constexpr auto GHz = giga; +inline constexpr auto THz = tera; +inline constexpr auto PHz = peta; +inline constexpr auto EHz = exa; +inline constexpr auto ZHz = zetta; +inline constexpr auto YHz = yotta; +inline constexpr auto RHz = ronna; +inline constexpr auto QHz = quetta; + +inline constexpr auto qN = quecto; +inline constexpr auto rN = ronto; +inline constexpr auto yN = yocto; +inline constexpr auto zN = zepto; +inline constexpr auto aN = atto; +inline constexpr auto fN = femto; +inline constexpr auto pN = pico; +inline constexpr auto nN = nano; +inline constexpr auto uN = micro; +inline constexpr auto mN = milli; +inline constexpr auto cN = centi; +inline constexpr auto dN = deci; +inline constexpr auto N = newton; +inline constexpr auto daN = deca; +inline constexpr auto hN = hecto; +inline constexpr auto kN = kilo; +inline constexpr auto MN = mega; +inline constexpr auto GN = giga; +inline constexpr auto TN = tera; +inline constexpr auto PN = peta; +inline constexpr auto EN = exa; +inline constexpr auto ZN = zetta; +inline constexpr auto YN = yotta; +inline constexpr auto RN = ronna; +inline constexpr auto QN = quetta; + +inline constexpr auto qPa = quecto; +inline constexpr auto rPa = ronto; +inline constexpr auto yPa = yocto; +inline constexpr auto zPa = zepto; +inline constexpr auto aPa = atto; +inline constexpr auto fPa = femto; +inline constexpr auto pPa = pico; +inline constexpr auto nPa = nano; +inline constexpr auto uPa = micro; +inline constexpr auto mPa = milli; +inline constexpr auto cPa = centi; +inline constexpr auto dPa = deci; +inline constexpr auto Pa = pascal; +inline constexpr auto daPa = deca; +inline constexpr auto hPa = hecto; +inline constexpr auto kPa = kilo; +inline constexpr auto MPa = mega; +inline constexpr auto GPa = giga; +inline constexpr auto TPa = tera; +inline constexpr auto PPa = peta; +inline constexpr auto EPa = exa; +inline constexpr auto ZPa = zetta; +inline constexpr auto YPa = yotta; +inline constexpr auto RPa = ronna; +inline constexpr auto QPa = quetta; + +inline constexpr auto qJ = quecto; +inline constexpr auto rJ = ronto; +inline constexpr auto yJ = yocto; +inline constexpr auto zJ = zepto; +inline constexpr auto aJ = atto; +inline constexpr auto fJ = femto; +inline constexpr auto pJ = pico; +inline constexpr auto nJ = nano; +inline constexpr auto uJ = micro; +inline constexpr auto mJ = milli; +inline constexpr auto cJ = centi; +inline constexpr auto dJ = deci; +inline constexpr auto J = joule; +inline constexpr auto daJ = deca; +inline constexpr auto hJ = hecto; +inline constexpr auto kJ = kilo; +inline constexpr auto MJ = mega; +inline constexpr auto GJ = giga; +inline constexpr auto TJ = tera; +inline constexpr auto PJ = peta; +inline constexpr auto EJ = exa; +inline constexpr auto ZJ = zetta; +inline constexpr auto YJ = yotta; +inline constexpr auto RJ = ronna; +inline constexpr auto QJ = quetta; + +inline constexpr auto qW = quecto; +inline constexpr auto rW = ronto; +inline constexpr auto yW = yocto; +inline constexpr auto zW = zepto; +inline constexpr auto aW = atto; +inline constexpr auto fW = femto; +inline constexpr auto pW = pico; +inline constexpr auto nW = nano; +inline constexpr auto uW = micro; +inline constexpr auto mW = milli; +inline constexpr auto cW = centi; +inline constexpr auto dW = deci; +inline constexpr auto W = watt; +inline constexpr auto daW = deca; +inline constexpr auto hW = hecto; +inline constexpr auto kW = kilo; +inline constexpr auto MW = mega; +inline constexpr auto GW = giga; +inline constexpr auto TW = tera; +inline constexpr auto PW = peta; +inline constexpr auto EW = exa; +inline constexpr auto ZW = zetta; +inline constexpr auto YW = yotta; +inline constexpr auto RW = ronna; +inline constexpr auto QW = quetta; + +inline constexpr auto qC = quecto; +inline constexpr auto rC = ronto; +inline constexpr auto yC = yocto; +inline constexpr auto zC = zepto; +inline constexpr auto aC = atto; +inline constexpr auto fC = femto; +inline constexpr auto pC = pico; +inline constexpr auto nC = nano; +inline constexpr auto uC = micro; +inline constexpr auto mC = milli; +inline constexpr auto cC = centi; +inline constexpr auto dC = deci; +inline constexpr auto C = coulomb; +inline constexpr auto daC = deca; +inline constexpr auto hC = hecto; +inline constexpr auto kC = kilo; +inline constexpr auto MC = mega; +inline constexpr auto GC = giga; +inline constexpr auto TC = tera; +inline constexpr auto PC = peta; +inline constexpr auto EC = exa; +inline constexpr auto ZC = zetta; +inline constexpr auto YC = yotta; +inline constexpr auto RC = ronna; +inline constexpr auto QC = quetta; + +inline constexpr auto qV = quecto; +inline constexpr auto rV = ronto; +inline constexpr auto yV = yocto; +inline constexpr auto zV = zepto; +inline constexpr auto aV = atto; +inline constexpr auto fV = femto; +inline constexpr auto pV = pico; +inline constexpr auto nV = nano; +inline constexpr auto uV = micro; +inline constexpr auto mV = milli; +inline constexpr auto cV = centi; +inline constexpr auto dV = deci; +inline constexpr auto V = volt; +inline constexpr auto daV = deca; +inline constexpr auto hV = hecto; +inline constexpr auto kV = kilo; +inline constexpr auto MV = mega; +inline constexpr auto GV = giga; +inline constexpr auto TV = tera; +inline constexpr auto PV = peta; +inline constexpr auto EV = exa; +inline constexpr auto ZV = zetta; +inline constexpr auto YV = yotta; +inline constexpr auto RV = ronna; +inline constexpr auto QV = quetta; + +inline constexpr auto qF = quecto; +inline constexpr auto rF = ronto; +inline constexpr auto yF = yocto; +inline constexpr auto zF = zepto; +inline constexpr auto aF = atto; +inline constexpr auto fF = femto; +inline constexpr auto pF = pico; +inline constexpr auto nF = nano; +inline constexpr auto uF = micro; +inline constexpr auto mF = milli; +inline constexpr auto cF = centi; +inline constexpr auto dF = deci; +inline constexpr auto F = farad; +inline constexpr auto daF = deca; +inline constexpr auto hF = hecto; +inline constexpr auto kF = kilo; +inline constexpr auto MF = mega; +inline constexpr auto GF = giga; +inline constexpr auto TF = tera; +inline constexpr auto PF = peta; +inline constexpr auto EF = exa; +inline constexpr auto ZF = zetta; +inline constexpr auto YF = yotta; +inline constexpr auto RF = ronna; +inline constexpr auto QF = quetta; + +inline constexpr auto qS = quecto; +inline constexpr auto rS = ronto; +inline constexpr auto yS = yocto; +inline constexpr auto zS = zepto; +inline constexpr auto aS = atto; +inline constexpr auto fS = femto; +inline constexpr auto pS = pico; +inline constexpr auto nS = nano; +inline constexpr auto uS = micro; +inline constexpr auto mS = milli; +inline constexpr auto cS = centi; +inline constexpr auto dS = deci; +inline constexpr auto S = siemens; +inline constexpr auto daS = deca; +inline constexpr auto hS = hecto; +inline constexpr auto kS = kilo; +inline constexpr auto MS = mega; +inline constexpr auto GS = giga; +inline constexpr auto TS = tera; +inline constexpr auto PS = peta; +inline constexpr auto ES = exa; +inline constexpr auto ZS = zetta; +inline constexpr auto YS = yotta; +inline constexpr auto RS = ronna; +inline constexpr auto QS = quetta; + +inline constexpr auto qWb = quecto; +inline constexpr auto rWb = ronto; +inline constexpr auto yWb = yocto; +inline constexpr auto zWb = zepto; +inline constexpr auto aWb = atto; +inline constexpr auto fWb = femto; +inline constexpr auto pWb = pico; +inline constexpr auto nWb = nano; +inline constexpr auto uWb = micro; +inline constexpr auto mWb = milli; +inline constexpr auto cWb = centi; +inline constexpr auto dWb = deci; +inline constexpr auto Wb = weber; +inline constexpr auto daWb = deca; +inline constexpr auto hWb = hecto; +inline constexpr auto kWb = kilo; +inline constexpr auto MWb = mega; +inline constexpr auto GWb = giga; +inline constexpr auto TWb = tera; +inline constexpr auto PWb = peta; +inline constexpr auto EWb = exa; +inline constexpr auto ZWb = zetta; +inline constexpr auto YWb = yotta; +inline constexpr auto RWb = ronna; +inline constexpr auto QWb = quetta; + +inline constexpr auto qT = quecto; +inline constexpr auto rT = ronto; +inline constexpr auto yT = yocto; +inline constexpr auto zT = zepto; +inline constexpr auto aT = atto; +inline constexpr auto fT = femto; +inline constexpr auto pT = pico; +inline constexpr auto nT = nano; +inline constexpr auto uT = micro; +inline constexpr auto mT = milli; +inline constexpr auto cT = centi; +inline constexpr auto dT = deci; +inline constexpr auto T = tesla; +inline constexpr auto daT = deca; +inline constexpr auto hT = hecto; +inline constexpr auto kT = kilo; +inline constexpr auto MT = mega; +inline constexpr auto GT = giga; +inline constexpr auto TT = tera; +inline constexpr auto PT = peta; +inline constexpr auto ET = exa; +inline constexpr auto ZT = zetta; +inline constexpr auto YT = yotta; +inline constexpr auto RT = ronna; +inline constexpr auto QT = quetta; + +inline constexpr auto qH = quecto; +inline constexpr auto rH = ronto; +inline constexpr auto yH = yocto; +inline constexpr auto zH = zepto; +inline constexpr auto aH = atto; +inline constexpr auto fH = femto; +inline constexpr auto pH = pico; +inline constexpr auto nH = nano; +inline constexpr auto uH = micro; +inline constexpr auto mH = milli; +inline constexpr auto cH = centi; +inline constexpr auto dH = deci; +inline constexpr auto H = henry; +inline constexpr auto daH = deca; +inline constexpr auto hH = hecto; +inline constexpr auto kH = kilo; +inline constexpr auto MH = mega; +inline constexpr auto GH = giga; +inline constexpr auto TH = tera; +inline constexpr auto PH = peta; +inline constexpr auto EH = exa; +inline constexpr auto ZH = zetta; +inline constexpr auto YH = yotta; +inline constexpr auto RH = ronna; +inline constexpr auto QH = quetta; + +inline constexpr auto qlm = quecto; +inline constexpr auto rlm = ronto; +inline constexpr auto ylm = yocto; +inline constexpr auto zlm = zepto; +inline constexpr auto alm = atto; +inline constexpr auto flm = femto; +inline constexpr auto plm = pico; +inline constexpr auto nlm = nano; +inline constexpr auto ulm = micro; +inline constexpr auto mlm = milli; +inline constexpr auto clm = centi; +inline constexpr auto dlm = deci; +inline constexpr auto lm = lumen; +inline constexpr auto dalm = deca; +inline constexpr auto hlm = hecto; +inline constexpr auto klm = kilo; +inline constexpr auto Mlm = mega; +inline constexpr auto Glm = giga; +inline constexpr auto Tlm = tera; +inline constexpr auto Plm = peta; +inline constexpr auto Elm = exa; +inline constexpr auto Zlm = zetta; +inline constexpr auto Ylm = yotta; +inline constexpr auto Rlm = ronna; +inline constexpr auto Qlm = quetta; + +inline constexpr auto qlx = quecto; +inline constexpr auto rlx = ronto; +inline constexpr auto ylx = yocto; +inline constexpr auto zlx = zepto; +inline constexpr auto alx = atto; +inline constexpr auto flx = femto; +inline constexpr auto plx = pico; +inline constexpr auto nlx = nano; +inline constexpr auto ulx = micro; +inline constexpr auto mlx = milli; +inline constexpr auto clx = centi; +inline constexpr auto dlx = deci; +inline constexpr auto lx = lux; +inline constexpr auto dalx = deca; +inline constexpr auto hlx = hecto; +inline constexpr auto klx = kilo; +inline constexpr auto Mlx = mega; +inline constexpr auto Glx = giga; +inline constexpr auto Tlx = tera; +inline constexpr auto Plx = peta; +inline constexpr auto Elx = exa; +inline constexpr auto Zlx = zetta; +inline constexpr auto Ylx = yotta; +inline constexpr auto Rlx = ronna; +inline constexpr auto Qlx = quetta; + +inline constexpr auto qBq = quecto; +inline constexpr auto rBq = ronto; +inline constexpr auto yBq = yocto; +inline constexpr auto zBq = zepto; +inline constexpr auto aBq = atto; +inline constexpr auto fBq = femto; +inline constexpr auto pBq = pico; +inline constexpr auto nBq = nano; +inline constexpr auto uBq = micro; +inline constexpr auto mBq = milli; +inline constexpr auto cBq = centi; +inline constexpr auto dBq = deci; +inline constexpr auto Bq = becquerel; +inline constexpr auto daBq = deca; +inline constexpr auto hBq = hecto; +inline constexpr auto kBq = kilo; +inline constexpr auto MBq = mega; +inline constexpr auto GBq = giga; +inline constexpr auto TBq = tera; +inline constexpr auto PBq = peta; +inline constexpr auto EBq = exa; +inline constexpr auto ZBq = zetta; +inline constexpr auto YBq = yotta; +inline constexpr auto RBq = ronna; +inline constexpr auto QBq = quetta; + +inline constexpr auto qGy = quecto; +inline constexpr auto rGy = ronto; +inline constexpr auto yGy = yocto; +inline constexpr auto zGy = zepto; +inline constexpr auto aGy = atto; +inline constexpr auto fGy = femto; +inline constexpr auto pGy = pico; +inline constexpr auto nGy = nano; +inline constexpr auto uGy = micro; +inline constexpr auto mGy = milli; +inline constexpr auto cGy = centi; +inline constexpr auto dGy = deci; +inline constexpr auto Gy = gray; +inline constexpr auto daGy = deca; +inline constexpr auto hGy = hecto; +inline constexpr auto kGy = kilo; +inline constexpr auto MGy = mega; +inline constexpr auto GGy = giga; +inline constexpr auto TGy = tera; +inline constexpr auto PGy = peta; +inline constexpr auto EGy = exa; +inline constexpr auto ZGy = zetta; +inline constexpr auto YGy = yotta; +inline constexpr auto RGy = ronna; +inline constexpr auto QGy = quetta; + +inline constexpr auto qSv = quecto; +inline constexpr auto rSv = ronto; +inline constexpr auto ySv = yocto; +inline constexpr auto zSv = zepto; +inline constexpr auto aSv = atto; +inline constexpr auto fSv = femto; +inline constexpr auto pSv = pico; +inline constexpr auto nSv = nano; +inline constexpr auto uSv = micro; +inline constexpr auto mSv = milli; +inline constexpr auto cSv = centi; +inline constexpr auto dSv = deci; +inline constexpr auto Sv = sievert; +inline constexpr auto daSv = deca; +inline constexpr auto hSv = hecto; +inline constexpr auto kSv = kilo; +inline constexpr auto MSv = mega; +inline constexpr auto GSv = giga; +inline constexpr auto TSv = tera; +inline constexpr auto PSv = peta; +inline constexpr auto ESv = exa; +inline constexpr auto ZSv = zetta; +inline constexpr auto YSv = yotta; +inline constexpr auto RSv = ronna; +inline constexpr auto QSv = quetta; + +inline constexpr auto qkat = quecto; +inline constexpr auto rkat = ronto; +inline constexpr auto ykat = yocto; +inline constexpr auto zkat = zepto; +inline constexpr auto akat = atto; +inline constexpr auto fkat = femto; +inline constexpr auto pkat = pico; +inline constexpr auto nkat = nano; +inline constexpr auto ukat = micro; +inline constexpr auto mkat = milli; +inline constexpr auto ckat = centi; +inline constexpr auto dkat = deci; +inline constexpr auto kat = katal; +inline constexpr auto dakat = deca; +inline constexpr auto hkat = hecto; +inline constexpr auto kkat = kilo; +inline constexpr auto Mkat = mega; +inline constexpr auto Gkat = giga; +inline constexpr auto Tkat = tera; +inline constexpr auto Pkat = peta; +inline constexpr auto Ekat = exa; +inline constexpr auto Zkat = zetta; +inline constexpr auto Ykat = yotta; +inline constexpr auto Rkat = ronna; +inline constexpr auto Qkat = quetta; + +// TODO Should the following non-SI units have prefixes symbols predefiend as well? +inline constexpr auto au = astronomical_unit; +inline constexpr auto deg = degree; +inline constexpr auto a = are; +inline constexpr auto ha = hectare; +inline constexpr auto l = litre; +inline constexpr auto t = tonne; +inline constexpr auto Da = dalton; +inline constexpr auto eV = electronvolt; + +// No prefixes should be provided for the below units +inline constexpr auto deg_C = degree_Celsius; +inline constexpr auto min = minute; +inline constexpr auto h = hour; +inline constexpr auto d = day; + +// commonly used squared and cubic units +inline constexpr auto m2 = square(metre); +inline constexpr auto m3 = cubic(metre); +inline constexpr auto m4 = pow<4>(metre); +inline constexpr auto s2 = square(second); +inline constexpr auto s3 = cubic(second); + +} // namespace mp_units::si::unit_symbols diff --git a/src/systems/si/include/mp-units/systems/si/units.h b/src/systems/si/include/mp-units/systems/si/units.h new file mode 100644 index 00000000..bbb830d4 --- /dev/null +++ b/src/systems/si/include/mp-units/systems/si/units.h @@ -0,0 +1,114 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include + +namespace mp_units::si { + +// clang-format off +// base units +inline constexpr struct second : named_unit<"s", kind_of> {} second; +inline constexpr struct metre : named_unit<"m", kind_of> {} metre; +inline constexpr struct gram : named_unit<"g", kind_of> {} gram; +inline constexpr struct kilogram : decltype(kilo) {} kilogram; +inline constexpr struct ampere : named_unit<"A", kind_of> {} ampere; +inline constexpr struct kelvin : named_unit<"K", kind_of> {} kelvin; +// inline constexpr struct kelvin : named_unit<"K", isq::thermodynamic_temperature, not_for {} kelvin; +inline constexpr struct mole : named_unit<"mol", kind_of> {} mole; +inline constexpr struct candela : named_unit<"cd", kind_of> {} candela; + +// derived named units +inline constexpr struct radian : named_unit<"rad", metre / metre, kind_of> {} radian; +inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of> {} steradian; +inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of> {} hertz; +inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; +#ifdef pascal +#pragma push_macro("pascal") +#undef pascal +#define UNITS_REDEFINE_PASCAL +#endif +inline constexpr struct pascal : named_unit<"Pa", newton / square(metre)> {} pascal; +#ifdef UNITS_REDEFINE_PASCAL +#pragma pop_macro("pascal") +#undef UNITS_REDEFINE_PASCAL +#endif +inline constexpr struct joule : named_unit<"J", newton * metre> {} joule; +inline constexpr struct watt : named_unit<"W", joule / second> {} watt; +inline constexpr struct coulomb : named_unit<"C", ampere * second> {} coulomb; +inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt; +inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad; +inline constexpr struct ohm : named_unit {} ohm; +inline constexpr struct siemens : named_unit<"S", 1 / ohm> {} siemens; +inline constexpr struct weber : named_unit<"Wb", volt * second> {} weber; +inline constexpr struct tesla : named_unit<"T", weber / square(metre)> {} tesla; +inline constexpr struct henry : named_unit<"H", weber / ampere> {} henry; +// inline constexpr struct degree_Celsius : named_unit * milli, only_for {} degree_Celsius; +inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; +inline constexpr struct lumen : named_unit<"lm", candela * steradian> {} lumen; +inline constexpr struct lux : named_unit<"lx", lumen / square(metre)> {} lux; +// inline constexpr struct becquerel : named_unit<"Bq", 1 / second, kind_of> {} becquerel; +inline constexpr struct becquerel : named_unit<"Bq", 1 / second> {} becquerel; +inline constexpr struct gray : named_unit<"Gy", joule / kilogram> {} gray; +inline constexpr struct sievert : named_unit<"Sv", joule / kilogram> {} sievert; +inline constexpr struct katal : named_unit<"kat", mole / second> {} katal; + +// non-SI units accepted for use with the SI +inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; +inline constexpr struct hour : named_unit<"h", mag<60> * minute> {} hour; +inline constexpr struct day : named_unit<"d", mag<24> * hour> {} day; +inline constexpr struct astronomical_unit : named_unit<"au", mag<149'597'870'700> * metre> {} astronomical_unit; +inline constexpr struct degree : named_unit * radian> {} degree; +// TODO how to disambiguate below angular units from time units (inline namespace `plane_angle`?) +// inline constexpr struct minute : named_unit * degree> {} minute; +// inline constexpr struct second : named_unit * minute> {} second; +inline constexpr struct are : named_unit<"a", square(deca)> {} are; +inline constexpr struct hectare : decltype(hecto) {} hectare; +inline constexpr struct litre : named_unit<"l", cubic(deci)> {} litre; +inline constexpr struct tonne : named_unit<"t", mag<1000> * kilogram> {} tonne; +inline constexpr struct dalton : named_unit<"Da", mag * mag_power<10, -27> * kilogram> {} dalton; +// TODO A different value is provided in the SI Brochure and different in the ISO 80000 +inline constexpr struct electronvolt : named_unit<"eV", mag * mag_power<10, -19> * joule> {} electronvolt; +// TODO the below are logarithmic units - how to support those? +// neper +// bel +// decibel + +// clang-format on + +} // namespace mp_units::si + +namespace mp_units { + +template<> +inline constexpr bool unit_can_be_prefixed = false; +template<> +inline constexpr bool unit_can_be_prefixed = false; +template<> +inline constexpr bool unit_can_be_prefixed = false; +template<> +inline constexpr bool unit_can_be_prefixed = false; + +} // namespace mp_units diff --git a/src/systems/si/include/units/isq/si/absorbed_dose.h b/src/systems/si/include/units/isq/si/absorbed_dose.h deleted file mode 100644 index 40159573..00000000 --- a/src/systems/si/include/units/isq/si/absorbed_dose.h +++ /dev/null @@ -1,328 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct gray : named_unit {}; -struct yoctogray : prefixed_unit {}; -struct zeptogray : prefixed_unit {}; -struct attogray : prefixed_unit {}; -struct femtogray : prefixed_unit {}; -struct picogray : prefixed_unit {}; -struct nanogray : prefixed_unit {}; -struct microgray : prefixed_unit {}; -struct milligray : prefixed_unit {}; -struct centigray : prefixed_unit {}; -struct decigray : prefixed_unit {}; -struct decagray : prefixed_unit {}; -struct hectogray : prefixed_unit {}; -struct kilogray : prefixed_unit {}; -struct megagray : prefixed_unit {}; -struct gigagray : prefixed_unit {}; -struct teragray : prefixed_unit {}; -struct petagray : prefixed_unit {}; -struct exagray : prefixed_unit {}; -struct zettagray : prefixed_unit {}; -struct yottagray : prefixed_unit {}; - -struct dim_absorbed_dose : isq::dim_absorbed_dose {}; - -template U, Representation Rep = double> -using absorbed_dose = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Gy -constexpr auto operator"" _q_Gy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_Gy(long double l) { return absorbed_dose(l); } - -// yGy -constexpr auto operator"" _q_yGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_yGy(long double l) { return absorbed_dose(l); } - -// zGy -constexpr auto operator"" _q_zGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_zGy(long double l) { return absorbed_dose(l); } - -// aGy -constexpr auto operator"" _q_aGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_aGy(long double l) { return absorbed_dose(l); } - -// fGy -constexpr auto operator"" _q_fGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_fGy(long double l) { return absorbed_dose(l); } - -// pGy -constexpr auto operator"" _q_pGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_pGy(long double l) { return absorbed_dose(l); } - -// nGy -constexpr auto operator"" _q_nGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_nGy(long double l) { return absorbed_dose(l); } - -// uGy -constexpr auto operator"" _q_uGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_uGy(long double l) { return absorbed_dose(l); } - -// mGy -constexpr auto operator"" _q_mGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_mGy(long double l) { return absorbed_dose(l); } - -// cGy -constexpr auto operator"" _q_cGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_cGy(long double l) { return absorbed_dose(l); } - -// dGy -constexpr auto operator"" _q_dGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_dGy(long double l) { return absorbed_dose(l); } - -// daGy -constexpr auto operator"" _q_daGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_daGy(long double l) { return absorbed_dose(l); } - -// hGy -constexpr auto operator"" _q_hGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_hGy(long double l) { return absorbed_dose(l); } - -// kGy -constexpr auto operator"" _q_kGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_kGy(long double l) { return absorbed_dose(l); } - -// MGy -constexpr auto operator"" _q_MGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_MGy(long double l) { return absorbed_dose(l); } - -// GGy -constexpr auto operator"" _q_GGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_GGy(long double l) { return absorbed_dose(l); } - -// TGy -constexpr auto operator"" _q_TGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_TGy(long double l) { return absorbed_dose(l); } - -// PGy -constexpr auto operator"" _q_PGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_PGy(long double l) { return absorbed_dose(l); } - -// EGy -constexpr auto operator"" _q_EGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_EGy(long double l) { return absorbed_dose(l); } - -// ZGy -constexpr auto operator"" _q_ZGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_ZGy(long double l) { return absorbed_dose(l); } - -// YGy -constexpr auto operator"" _q_YGy(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return absorbed_dose(static_cast(l)); -} -constexpr auto operator"" _q_YGy(long double l) { return absorbed_dose(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace absorbed_dose_references { - -inline constexpr auto Gy = reference{}; -inline constexpr auto yGy = reference{}; -inline constexpr auto zGy = reference{}; -inline constexpr auto aGy = reference{}; -inline constexpr auto fGy = reference{}; -inline constexpr auto pGy = reference{}; -inline constexpr auto nGy = reference{}; -inline constexpr auto uGy = reference{}; -inline constexpr auto mGy = reference{}; -inline constexpr auto cGy = reference{}; -inline constexpr auto dGy = reference{}; -inline constexpr auto daGy = reference{}; -inline constexpr auto hGy = reference{}; -inline constexpr auto kGy = reference{}; -inline constexpr auto MGy = reference{}; -inline constexpr auto GGy = reference{}; -inline constexpr auto TGy = reference{}; -inline constexpr auto PGy = reference{}; -inline constexpr auto EGy = reference{}; -inline constexpr auto ZGy = reference{}; -inline constexpr auto YGy = reference{}; - -} // namespace absorbed_dose_references - -namespace references { - -using namespace absorbed_dose_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline absorbed_dose { - -template -using Gy = units::isq::si::absorbed_dose; -template -using yGy = units::isq::si::absorbed_dose; -template -using zGy = units::isq::si::absorbed_dose; -template -using aGy = units::isq::si::absorbed_dose; -template -using fGy = units::isq::si::absorbed_dose; -template -using pGy = units::isq::si::absorbed_dose; -template -using nGy = units::isq::si::absorbed_dose; -template -using uGy = units::isq::si::absorbed_dose; -template -using mGy = units::isq::si::absorbed_dose; -template -using cGy = units::isq::si::absorbed_dose; -template -using dGy = units::isq::si::absorbed_dose; -template -using daGy = units::isq::si::absorbed_dose; -template -using hGy = units::isq::si::absorbed_dose; -template -using kGy = units::isq::si::absorbed_dose; -template -using MGy = units::isq::si::absorbed_dose; -template -using GGy = units::isq::si::absorbed_dose; -template -using TGy = units::isq::si::absorbed_dose; -template -using PGy = units::isq::si::absorbed_dose; -template -using EGy = units::isq::si::absorbed_dose; -template -using ZGy = units::isq::si::absorbed_dose; -template -using YGy = units::isq::si::absorbed_dose; - -} // namespace units::aliases::isq::si::inline absorbed_dose - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/acceleration.h b/src/systems/si/include/units/isq/si/acceleration.h deleted file mode 100644 index 90f0168a..00000000 --- a/src/systems/si/include/units/isq/si/acceleration.h +++ /dev/null @@ -1,69 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include - -namespace units::isq::si { - -struct metre_per_second_sq : derived_unit {}; -struct dim_acceleration : isq::dim_acceleration {}; - -template U, Representation Rep = double> -using acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m/s2 -constexpr auto operator"" _q_m_per_s2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return acceleration(static_cast(l)); -} -constexpr auto operator"" _q_m_per_s2(long double l) { return acceleration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline acceleration { - -template -using m_per_s2 = units::isq::si::acceleration; - -} // namespace units::aliases::isq::si::inline acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/amount_of_substance.h b/src/systems/si/include/units/isq/si/amount_of_substance.h deleted file mode 100644 index ba7578d8..00000000 --- a/src/systems/si/include/units/isq/si/amount_of_substance.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct mole : named_unit {}; - -struct dim_amount_of_substance : isq::dim_amount_of_substance {}; - -template U, Representation Rep = double> -using amount_of_substance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// mol -constexpr auto operator"" _q_mol(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return amount_of_substance(static_cast(l)); -} -constexpr auto operator"" _q_mol(long double l) { return amount_of_substance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace amount_of_substance_references { - -inline constexpr auto mol = reference{}; - -} // namespace amount_of_substance_references - -namespace references { - -using namespace amount_of_substance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline amount_of_substance { - -template -using mol = units::isq::si::amount_of_substance; - -} // namespace units::aliases::isq::si::inline amount_of_substance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/angular_acceleration.h b/src/systems/si/include/units/isq/si/angular_acceleration.h deleted file mode 100644 index 4899448b..00000000 --- a/src/systems/si/include/units/isq/si/angular_acceleration.h +++ /dev/null @@ -1,76 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct radian_per_second_sq : derived_unit {}; - -struct dim_angular_acceleration : - isq::dim_angular_acceleration, dim_time> {}; - -template U, Representation Rep = double> -using angular_acceleration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// rad/s2 -constexpr auto operator"" _q_rad_per_s2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angular_acceleration(static_cast(l)); -} -constexpr auto operator"" _q_rad_per_s2(long double l) -{ - return angular_acceleration(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline angular_acceleration { - -template -using rad_per_s2 = units::isq::si::angular_acceleration; - -} // namespace units::aliases::isq::si::inline angular_acceleration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/angular_velocity.h b/src/systems/si/include/units/isq/si/angular_velocity.h deleted file mode 100644 index 81bdc296..00000000 --- a/src/systems/si/include/units/isq/si/angular_velocity.h +++ /dev/null @@ -1,73 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct radian_per_second : derived_unit {}; - -struct dim_angular_velocity : - isq::dim_angular_velocity, dim_time> {}; - -template U, Representation Rep = double> -using angular_velocity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// rad/s -constexpr auto operator"" _q_rad_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return angular_velocity(static_cast(l)); -} -constexpr auto operator"" _q_rad_per_s(long double l) { return angular_velocity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline angular_velocity { - -template -using rad_per_s = units::isq::si::angular_velocity; - -} // namespace units::aliases::isq::si::inline angular_velocity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/area.h b/src/systems/si/include/units/isq/si/area.h deleted file mode 100644 index d430a38c..00000000 --- a/src/systems/si/include/units/isq/si/area.h +++ /dev/null @@ -1,382 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct square_metre : derived_unit {}; -struct dim_area : isq::dim_area {}; - -struct square_yoctometre : derived_scaled_unit {}; -struct square_zeptometre : derived_scaled_unit {}; -struct square_attometre : derived_scaled_unit {}; -struct square_femtometre : derived_scaled_unit {}; -struct square_picometre : derived_scaled_unit {}; -struct square_nanometre : derived_scaled_unit {}; -struct square_micrometre : derived_scaled_unit {}; -struct square_millimetre : derived_scaled_unit {}; -struct square_centimetre : derived_scaled_unit {}; -struct square_decimetre : derived_scaled_unit {}; -struct square_decametre : derived_scaled_unit {}; -struct square_hectometre : derived_scaled_unit {}; -struct square_kilometre : derived_scaled_unit {}; -struct square_megametre : derived_scaled_unit {}; -struct square_gigametre : derived_scaled_unit {}; -struct square_terametre : derived_scaled_unit {}; -struct square_petametre : derived_scaled_unit {}; -struct square_exametre : derived_scaled_unit {}; -struct square_zettametre : derived_scaled_unit {}; -struct square_yottametre : derived_scaled_unit {}; - -struct are : alias_unit {}; -struct centiare : prefixed_alias_unit {}; -struct deciare : prefixed_unit {}; -struct decare : prefixed_unit {}; -struct hectare : prefixed_alias_unit {}; - -template U, Representation Rep = double> -using area = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m2 -constexpr auto operator"" _q_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_m2(long double l) { return area(l); } - -// ym2 -constexpr auto operator"" _q_ym2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ym2(long double l) { return area(l); } - -// zm2 -constexpr auto operator"" _q_zm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_zm2(long double l) { return area(l); } - -// am2 -constexpr auto operator"" _q_am2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_am2(long double l) { return area(l); } - -// fm2 -constexpr auto operator"" _q_fm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_fm2(long double l) { return area(l); } - -// pm2 -constexpr auto operator"" _q_pm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_pm2(long double l) { return area(l); } - -// nm2 -constexpr auto operator"" _q_nm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_nm2(long double l) { return area(l); } - -// um2 -constexpr auto operator"" _q_um2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_um2(long double l) { return area(l); } - -// mm2 -constexpr auto operator"" _q_mm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_mm2(long double l) { return area(l); } - -// cm2 -constexpr auto operator"" _q_cm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_cm2(long double l) { return area(l); } - -// dm2 -constexpr auto operator"" _q_dm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_dm2(long double l) { return area(l); } - -// dam2 -constexpr auto operator"" _q_dam2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_dam2(long double l) { return area(l); } - -// hm2 -constexpr auto operator"" _q_hm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_hm2(long double l) { return area(l); } - -// km2 -constexpr auto operator"" _q_km2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_km2(long double l) { return area(l); } - -// Mm2 -constexpr auto operator"" _q_Mm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Mm2(long double l) { return area(l); } - -// Gm2 -constexpr auto operator"" _q_Gm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Gm2(long double l) { return area(l); } - -// Tm2 -constexpr auto operator"" _q_Tm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Tm2(long double l) { return area(l); } - -// Pm2 -constexpr auto operator"" _q_Pm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Pm2(long double l) { return area(l); } - -// Em2 -constexpr auto operator"" _q_Em2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Em2(long double l) { return area(l); } - -// Zm2 -constexpr auto operator"" _q_Zm2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Zm2(long double l) { return area(l); } - -// Ym2 -constexpr auto operator"" _q_Ym2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_Ym2(long double l) { return area(l); } - -// a -constexpr auto operator"" _q_a(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_a(long double l) { return area(l); } - -// ca -constexpr auto operator"" _q_ca(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ca(long double l) { return area(l); } - -// da -constexpr auto operator"" _q_da(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_da(long double l) { return area(l); } - -// daa -constexpr auto operator"" _q_daa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_daa(long double l) { return area(l); } - -// ha -constexpr auto operator"" _q_ha(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return area(static_cast(l)); -} -constexpr auto operator"" _q_ha(long double l) { return area(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace area_references { - -inline constexpr auto m2 = reference{}; -inline constexpr auto ym2 = reference{}; -inline constexpr auto zm2 = reference{}; -inline constexpr auto am2 = reference{}; -inline constexpr auto fm2 = reference{}; -inline constexpr auto pm2 = reference{}; -inline constexpr auto nm2 = reference{}; -inline constexpr auto um2 = reference{}; -inline constexpr auto mm2 = reference{}; -inline constexpr auto cm2 = reference{}; -inline constexpr auto dm2 = reference{}; -inline constexpr auto dam2 = reference{}; -inline constexpr auto hm2 = reference{}; -inline constexpr auto km2 = reference{}; -inline constexpr auto Mm2 = reference{}; -inline constexpr auto Gm2 = reference{}; -inline constexpr auto Tm2 = reference{}; -inline constexpr auto Pm2 = reference{}; -inline constexpr auto Em2 = reference{}; -inline constexpr auto Zm2 = reference{}; -inline constexpr auto Ym2 = reference{}; - -inline constexpr auto a = reference{}; -inline constexpr auto ca = reference{}; -inline constexpr auto da = reference{}; -inline constexpr auto daa = reference{}; -inline constexpr auto ha = reference{}; - -} // namespace area_references - -namespace references { - -using namespace area_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline area { - -template -using m2 = units::isq::si::area; -template -using ym2 = units::isq::si::area; -template -using zm2 = units::isq::si::area; -template -using am2 = units::isq::si::area; -template -using fm2 = units::isq::si::area; -template -using pm2 = units::isq::si::area; -template -using nm2 = units::isq::si::area; -template -using um2 = units::isq::si::area; -template -using mm2 = units::isq::si::area; -template -using cm2 = units::isq::si::area; -template -using dm2 = units::isq::si::area; -template -using dam2 = units::isq::si::area; -template -using hm2 = units::isq::si::area; -template -using km2 = units::isq::si::area; -template -using Mm2 = units::isq::si::area; -template -using Gm2 = units::isq::si::area; -template -using Tm2 = units::isq::si::area; -template -using Pm2 = units::isq::si::area; -template -using Em2 = units::isq::si::area; -template -using Zm2 = units::isq::si::area; -template -using Ym2 = units::isq::si::area; - -template -using ha = units::isq::si::area; - -} // namespace units::aliases::isq::si::inline area - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/capacitance.h b/src/systems/si/include/units/isq/si/capacitance.h deleted file mode 100644 index 31a477f9..00000000 --- a/src/systems/si/include/units/isq/si/capacitance.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct farad : named_unit {}; -struct yoctofarad : prefixed_unit {}; -struct zeptofarad : prefixed_unit {}; -struct attofarad : prefixed_unit {}; -struct femtofarad : prefixed_unit {}; -struct picofarad : prefixed_unit {}; -struct nanofarad : prefixed_unit {}; -struct microfarad : prefixed_unit {}; -struct millifarad : prefixed_unit {}; -struct centifarad : prefixed_unit {}; -struct decifarad : prefixed_unit {}; -struct decafarad : prefixed_unit {}; -struct hectofarad : prefixed_unit {}; -struct kilofarad : prefixed_unit {}; -struct megafarad : prefixed_unit {}; -struct gigafarad : prefixed_unit {}; -struct terafarad : prefixed_unit {}; -struct petafarad : prefixed_unit {}; -struct exafarad : prefixed_unit {}; -struct zettafarad : prefixed_unit {}; -struct yottafarad : prefixed_unit {}; - -struct dim_capacitance : isq::dim_capacitance {}; - -template U, Representation Rep = double> -using capacitance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// F -constexpr auto operator"" _q_F(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_F(long double l) { return capacitance(l); } - -// yF -constexpr auto operator"" _q_yF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_yF(long double l) { return capacitance(l); } - -// zF -constexpr auto operator"" _q_zF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_zF(long double l) { return capacitance(l); } - -// aF -constexpr auto operator"" _q_aF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_aF(long double l) { return capacitance(l); } - -// fF -constexpr auto operator"" _q_fF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_fF(long double l) { return capacitance(l); } - -// pF -constexpr auto operator"" _q_pF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_pF(long double l) { return capacitance(l); } - -// nF -constexpr auto operator"" _q_nF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_nF(long double l) { return capacitance(l); } - -// uF -constexpr auto operator"" _q_uF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_uF(long double l) { return capacitance(l); } - -// mF -constexpr auto operator"" _q_mF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_mF(long double l) { return capacitance(l); } - -// cF -constexpr auto operator"" _q_cF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_cF(long double l) { return capacitance(l); } - -// dF -constexpr auto operator"" _q_dF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_dF(long double l) { return capacitance(l); } - -// daF -constexpr auto operator"" _q_daF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_daF(long double l) { return capacitance(l); } - -// hF -constexpr auto operator"" _q_hF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_hF(long double l) { return capacitance(l); } - -// kF -constexpr auto operator"" _q_kF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_kF(long double l) { return capacitance(l); } - -// MF -constexpr auto operator"" _q_MF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_MF(long double l) { return capacitance(l); } - -// GF -constexpr auto operator"" _q_GF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_GF(long double l) { return capacitance(l); } - -// TF -constexpr auto operator"" _q_TF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_TF(long double l) { return capacitance(l); } - -// PF -constexpr auto operator"" _q_PF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_PF(long double l) { return capacitance(l); } - -// EF -constexpr auto operator"" _q_EF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_EF(long double l) { return capacitance(l); } - -// ZF -constexpr auto operator"" _q_ZF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_ZF(long double l) { return capacitance(l); } - -// YF -constexpr auto operator"" _q_YF(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return capacitance(static_cast(l)); -} -constexpr auto operator"" _q_YF(long double l) { return capacitance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace capacitance_references { - -inline constexpr auto F = reference{}; -inline constexpr auto yF = reference{}; -inline constexpr auto zF = reference{}; -inline constexpr auto aF = reference{}; -inline constexpr auto fF = reference{}; -inline constexpr auto pF = reference{}; -inline constexpr auto nF = reference{}; -inline constexpr auto uF = reference{}; -inline constexpr auto mF = reference{}; -inline constexpr auto cF = reference{}; -inline constexpr auto dF = reference{}; -inline constexpr auto daF = reference{}; -inline constexpr auto hF = reference{}; -inline constexpr auto kF = reference{}; -inline constexpr auto MF = reference{}; -inline constexpr auto GF = reference{}; -inline constexpr auto TF = reference{}; -inline constexpr auto PF = reference{}; -inline constexpr auto EF = reference{}; -inline constexpr auto ZF = reference{}; -inline constexpr auto YF = reference{}; - -} // namespace capacitance_references - -namespace references { - -using namespace capacitance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline capacitance { - -template -using F = units::isq::si::capacitance; -template -using yF = units::isq::si::capacitance; -template -using zF = units::isq::si::capacitance; -template -using aF = units::isq::si::capacitance; -template -using fF = units::isq::si::capacitance; -template -using pF = units::isq::si::capacitance; -template -using nF = units::isq::si::capacitance; -template -using uF = units::isq::si::capacitance; -template -using mF = units::isq::si::capacitance; -template -using cF = units::isq::si::capacitance; -template -using dF = units::isq::si::capacitance; -template -using daF = units::isq::si::capacitance; -template -using hF = units::isq::si::capacitance; -template -using kF = units::isq::si::capacitance; -template -using MF = units::isq::si::capacitance; -template -using GF = units::isq::si::capacitance; -template -using TF = units::isq::si::capacitance; -template -using PF = units::isq::si::capacitance; -template -using EF = units::isq::si::capacitance; -template -using ZF = units::isq::si::capacitance; -template -using YF = units::isq::si::capacitance; - -} // namespace units::aliases::isq::si::inline capacitance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/catalytic_activity.h b/src/systems/si/include/units/isq/si/catalytic_activity.h deleted file mode 100644 index 926705d6..00000000 --- a/src/systems/si/include/units/isq/si/catalytic_activity.h +++ /dev/null @@ -1,343 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct katal : named_unit {}; -struct yoctokatal : prefixed_unit {}; -struct zeptokatal : prefixed_unit {}; -struct attokatal : prefixed_unit {}; -struct femtokatal : prefixed_unit {}; -struct picokatal : prefixed_unit {}; -struct nanokatal : prefixed_unit {}; -struct microkatal : prefixed_unit {}; -struct millikatal : prefixed_unit {}; -struct centikatal : prefixed_unit {}; -struct decikatal : prefixed_unit {}; -struct decakatal : prefixed_unit {}; -struct hectokatal : prefixed_unit {}; -struct kilokatal : prefixed_unit {}; -struct megakatal : prefixed_unit {}; -struct gigakatal : prefixed_unit {}; -struct terakatal : prefixed_unit {}; -struct petakatal : prefixed_unit {}; -struct exakatal : prefixed_unit {}; -struct zettakatal : prefixed_unit {}; -struct yottakatal : prefixed_unit {}; - -struct enzyme_unit : named_scaled_unit() * mag_power<10, -6>(), katal> {}; - -struct dim_catalytic_activity : - isq::dim_catalytic_activity {}; - -template U, Representation Rep = double> -using catalytic_activity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// kat -constexpr auto operator"" _q_kat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_kat(long double l) { return catalytic_activity(l); } - -// ykat -constexpr auto operator"" _q_ykat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_ykat(long double l) { return catalytic_activity(l); } - -// zkat -constexpr auto operator"" _q_zkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_zkat(long double l) { return catalytic_activity(l); } - -// akat -constexpr auto operator"" _q_akat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_akat(long double l) { return catalytic_activity(l); } - -// fkat -constexpr auto operator"" _q_fkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_fkat(long double l) { return catalytic_activity(l); } - -// pkat -constexpr auto operator"" _q_pkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_pkat(long double l) { return catalytic_activity(l); } - -// nkat -constexpr auto operator"" _q_nkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_nkat(long double l) { return catalytic_activity(l); } - -// ukat -constexpr auto operator"" _q_ukat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_ukat(long double l) { return catalytic_activity(l); } - -// mkat -constexpr auto operator"" _q_mkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_mkat(long double l) { return catalytic_activity(l); } - -// ckat -constexpr auto operator"" _q_ckat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_ckat(long double l) { return catalytic_activity(l); } - -// dkat -constexpr auto operator"" _q_dkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_dkat(long double l) { return catalytic_activity(l); } - -// dakat -constexpr auto operator"" _q_dakat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_dakat(long double l) { return catalytic_activity(l); } - -// hkat -constexpr auto operator"" _q_hkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_hkat(long double l) { return catalytic_activity(l); } - -// kkat -constexpr auto operator"" _q_kkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_kkat(long double l) { return catalytic_activity(l); } - -// Mkat -constexpr auto operator"" _q_Mkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Mkat(long double l) { return catalytic_activity(l); } - -// Gkat -constexpr auto operator"" _q_Gkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Gkat(long double l) { return catalytic_activity(l); } - -// Tkat -constexpr auto operator"" _q_Tkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Tkat(long double l) { return catalytic_activity(l); } - -// Pkat -constexpr auto operator"" _q_Pkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Pkat(long double l) { return catalytic_activity(l); } - -// Ekat -constexpr auto operator"" _q_Ekat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Ekat(long double l) { return catalytic_activity(l); } - -// Zkat -constexpr auto operator"" _q_Zkat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Zkat(long double l) { return catalytic_activity(l); } - -// Ykat -constexpr auto operator"" _q_Ykat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_Ykat(long double l) { return catalytic_activity(l); } - -// U -constexpr auto operator"" _q_U(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return catalytic_activity(static_cast(l)); -} -constexpr auto operator"" _q_U(long double l) { return catalytic_activity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace catalytic_activity_references { - -inline constexpr auto kat = reference{}; -inline constexpr auto ykat = reference{}; -inline constexpr auto zkat = reference{}; -inline constexpr auto akat = reference{}; -inline constexpr auto fkat = reference{}; -inline constexpr auto pkat = reference{}; -inline constexpr auto nkat = reference{}; -inline constexpr auto ukat = reference{}; -inline constexpr auto mkat = reference{}; -inline constexpr auto ckat = reference{}; -inline constexpr auto dkat = reference{}; -inline constexpr auto dakat = reference{}; -inline constexpr auto hkat = reference{}; -inline constexpr auto kkat = reference{}; -inline constexpr auto Mkat = reference{}; -inline constexpr auto Gkat = reference{}; -inline constexpr auto Tkat = reference{}; -inline constexpr auto Pkat = reference{}; -inline constexpr auto Ekat = reference{}; -inline constexpr auto Zkat = reference{}; -inline constexpr auto Ykat = reference{}; -inline constexpr auto U = reference{}; - -} // namespace catalytic_activity_references - -namespace references { - -using namespace catalytic_activity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline catalytic_activity { - -template -using kat = units::isq::si::catalytic_activity; -template -using ykat = units::isq::si::catalytic_activity; -template -using zkat = units::isq::si::catalytic_activity; -template -using akat = units::isq::si::catalytic_activity; -template -using fkat = units::isq::si::catalytic_activity; -template -using pkat = units::isq::si::catalytic_activity; -template -using nkat = units::isq::si::catalytic_activity; -template -using ukat = units::isq::si::catalytic_activity; -template -using mkat = units::isq::si::catalytic_activity; -template -using ckat = units::isq::si::catalytic_activity; -template -using dkat = units::isq::si::catalytic_activity; -template -using dakat = units::isq::si::catalytic_activity; -template -using hkat = units::isq::si::catalytic_activity; -template -using kkat = units::isq::si::catalytic_activity; -template -using Mkat = units::isq::si::catalytic_activity; -template -using Gkat = units::isq::si::catalytic_activity; -template -using Tkat = units::isq::si::catalytic_activity; -template -using Pkat = units::isq::si::catalytic_activity; -template -using Ekat = units::isq::si::catalytic_activity; -template -using Zkat = units::isq::si::catalytic_activity; -template -using Ykat = units::isq::si::catalytic_activity; -template -using U = units::isq::si::catalytic_activity; - -} // namespace units::aliases::isq::si::inline catalytic_activity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/charge_density.h b/src/systems/si/include/units/isq/si/charge_density.h deleted file mode 100644 index 52fba248..00000000 --- a/src/systems/si/include/units/isq/si/charge_density.h +++ /dev/null @@ -1,93 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct coulomb_per_metre_cub : derived_unit {}; -struct coulomb_per_metre_sq : derived_unit {}; - -struct dim_charge_density : - isq::dim_charge_density {}; -struct dim_surface_charge_density : - isq::dim_surface_charge_density { -}; - -template U, Representation Rep = double> -using charge_density = quantity; - -template U, Representation Rep = double> -using surface_charge_density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// C/m³ -constexpr auto operator"" _q_C_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return charge_density(static_cast(l)); -} -constexpr auto operator"" _q_C_per_m3(long double l) { return charge_density(l); } - -// C/m² -constexpr auto operator"" _q_C_per_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return surface_charge_density(static_cast(l)); -} -constexpr auto operator"" _q_C_per_m2(long double l) -{ - return surface_charge_density(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline charge_density { - -template -using C_per_m3 = units::isq::si::charge_density; -template -using C_per_m2 = units::isq::si::surface_charge_density; - -} // namespace units::aliases::isq::si::inline charge_density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/concentration.h b/src/systems/si/include/units/isq/si/concentration.h deleted file mode 100644 index 732583a5..00000000 --- a/src/systems/si/include/units/isq/si/concentration.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct mol_per_metre_cub : derived_unit {}; -struct dim_concentration : - isq::dim_concentration {}; - -template U, Representation Rep = double> -using concentration = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// mol/m³ -constexpr auto operator"" _q_mol_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return concentration(static_cast(l)); -} -constexpr auto operator"" _q_mol_per_m3(long double l) { return concentration(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline concentration { - -template -using mol_per_m3 = units::isq::si::concentration; - -} // namespace units::aliases::isq::si::inline concentration - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/conductance.h b/src/systems/si/include/units/isq/si/conductance.h deleted file mode 100644 index 5442201f..00000000 --- a/src/systems/si/include/units/isq/si/conductance.h +++ /dev/null @@ -1,280 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct siemens : named_unit {}; -struct yoctosiemens : prefixed_unit {}; -struct zeptosiemens : prefixed_unit {}; -struct attosiemens : prefixed_unit {}; -struct femtosiemens : prefixed_unit {}; -struct picosiemens : prefixed_unit {}; -struct nanosiemens : prefixed_unit {}; -struct microsiemens : prefixed_unit {}; -struct millisiemens : prefixed_unit {}; -struct kilosiemens : prefixed_unit {}; -struct megasiemens : prefixed_unit {}; -struct gigasiemens : prefixed_unit {}; -struct terasiemens : prefixed_unit {}; -struct petasiemens : prefixed_unit {}; -struct exasiemens : prefixed_unit {}; -struct zettasiemens : prefixed_unit {}; -struct yottasiemens : prefixed_unit {}; - -struct dim_conductance : isq::dim_conductance {}; - -template U, Representation Rep = double> -using conductance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// R -constexpr auto operator"" _q_S(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_S(long double l) { return conductance(l); } - -// yS -constexpr auto operator"" _q_yS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_yS(long double l) { return conductance(l); } - -// zS -constexpr auto operator"" _q_zS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_zS(long double l) { return conductance(l); } - -// aS -constexpr auto operator"" _q_aS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_aS(long double l) { return conductance(l); } - -// fS -constexpr auto operator"" _q_fS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_fS(long double l) { return conductance(l); } - -// pS -constexpr auto operator"" _q_pS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_pS(long double l) { return conductance(l); } - -// nS -constexpr auto operator"" _q_nS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_nS(long double l) { return conductance(l); } - -// µS -constexpr auto operator"" _q_uS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_uS(long double l) { return conductance(l); } - -// mS -constexpr auto operator"" _q_mS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_mS(long double l) { return conductance(l); } - -// kS -constexpr auto operator"" _q_kS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_kS(long double l) { return conductance(l); } - -// MS -constexpr auto operator"" _q_MS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_MS(long double l) { return conductance(l); } - -// GS -constexpr auto operator"" _q_GS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_GS(long double l) { return conductance(l); } - -// TS -constexpr auto operator"" _q_TS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_TS(long double l) { return conductance(l); } - -// PS -constexpr auto operator"" _q_PS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_PS(long double l) { return conductance(l); } - -// ES -constexpr auto operator"" _q_ES(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_ES(long double l) { return conductance(l); } - -// ZS -constexpr auto operator"" _q_ZS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_ZS(long double l) { return conductance(l); } - -// YS -constexpr auto operator"" _q_YS(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return conductance(static_cast(l)); -} -constexpr auto operator"" _q_YS(long double l) { return conductance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace conductance_references { - -inline constexpr auto S = reference{}; -inline constexpr auto yS = reference{}; -inline constexpr auto zS = reference{}; -inline constexpr auto aS = reference{}; -inline constexpr auto fS = reference{}; -inline constexpr auto pS = reference{}; -inline constexpr auto nS = reference{}; -inline constexpr auto uS = reference{}; -inline constexpr auto mS = reference{}; -inline constexpr auto kS = reference{}; -inline constexpr auto MS = reference{}; -inline constexpr auto GS = reference{}; -inline constexpr auto TS = reference{}; -inline constexpr auto PS = reference{}; -inline constexpr auto ES = reference{}; -inline constexpr auto ZS = reference{}; -inline constexpr auto YS = reference{}; - -} // namespace conductance_references - -namespace references { - -using namespace conductance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline conductance { - -template -using S = units::isq::si::conductance; -template -using yS = units::isq::si::conductance; -template -using zS = units::isq::si::conductance; -template -using aS = units::isq::si::conductance; -template -using fS = units::isq::si::conductance; -template -using pS = units::isq::si::conductance; -template -using nS = units::isq::si::conductance; -template -using uS = units::isq::si::conductance; -template -using mS = units::isq::si::conductance; -template -using kS = units::isq::si::conductance; -template -using MS = units::isq::si::conductance; -template -using GS = units::isq::si::conductance; -template -using TS = units::isq::si::conductance; -template -using PS = units::isq::si::conductance; -template -using ES = units::isq::si::conductance; -template -using ZS = units::isq::si::conductance; -template -using YS = units::isq::si::conductance; - -} // namespace units::aliases::isq::si::inline conductance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/constants.h b/src/systems/si/include/units/isq/si/constants.h deleted file mode 100644 index 217f0416..00000000 --- a/src/systems/si/include/units/isq/si/constants.h +++ /dev/null @@ -1,66 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace units::isq::si { - -namespace si2019 { - -// defining constants -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); - -} // namespace si2019 - -template -inline constexpr auto standard_gravity = acceleration(9.80665); - -} // namespace units::isq::si diff --git a/src/systems/si/include/units/isq/si/current_density.h b/src/systems/si/include/units/isq/si/current_density.h deleted file mode 100644 index 94234b5b..00000000 --- a/src/systems/si/include/units/isq/si/current_density.h +++ /dev/null @@ -1,73 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct ampere_per_metre_sq : derived_unit {}; - -struct dim_current_density : - isq::dim_current_density {}; - -template U, Representation Rep = double> -using current_density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// A / m² -constexpr auto operator"" _q_A_per_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return current_density(static_cast(l)); -} -constexpr auto operator"" _q_A_per_m2(long double l) { return current_density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline current_density { - -template -using A_per_m2 = units::isq::si::current_density; - -} // namespace units::aliases::isq::si::inline current_density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/density.h b/src/systems/si/include/units/isq/si/density.h deleted file mode 100644 index d890e225..00000000 --- a/src/systems/si/include/units/isq/si/density.h +++ /dev/null @@ -1,72 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct kilogram_per_metre_cub : derived_unit {}; - -struct dim_density : isq::dim_density {}; - -template U, Representation Rep = double> -using density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// kg / m³ -constexpr auto operator"" _q_kg_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return density(static_cast(l)); -} -constexpr auto operator"" _q_kg_per_m3(long double l) { return density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline density { - -template -using kg_per_m3 = units::isq::si::density; - -} // namespace units::aliases::isq::si::inline density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/dynamic_viscosity.h b/src/systems/si/include/units/isq/si/dynamic_viscosity.h deleted file mode 100644 index 81f0d2bb..00000000 --- a/src/systems/si/include/units/isq/si/dynamic_viscosity.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct pascal_second : derived_unit {}; -struct dim_dynamic_viscosity : - isq::dim_dynamic_viscosity {}; - -template U, Representation Rep = double> -using dynamic_viscosity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Pa·s -constexpr auto operator"" _q_Pa_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return dynamic_viscosity(static_cast(l)); -} -constexpr auto operator"" _q_Pa_s(long double l) { return dynamic_viscosity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline dynamic_viscosity { - -template -using Pa_s = units::isq::si::dynamic_viscosity; - -} // namespace units::aliases::isq::si::inline dynamic_viscosity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/electric_charge.h b/src/systems/si/include/units/isq/si/electric_charge.h deleted file mode 100644 index ca431827..00000000 --- a/src/systems/si/include/units/isq/si/electric_charge.h +++ /dev/null @@ -1,88 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct coulomb : named_unit {}; - -struct dim_electric_charge : isq::dim_electric_charge {}; - -template U, Representation Rep = double> -using electric_charge = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// C -constexpr auto operator"" _q_C(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_charge(static_cast(l)); -} -constexpr auto operator"" _q_C(long double l) { return electric_charge(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace electric_charge_references { - -inline constexpr auto C = reference{}; - -} // namespace electric_charge_references - -namespace references { - -using namespace electric_charge_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline electric_charge { - -template -using C = units::isq::si::electric_charge; - -} // namespace units::aliases::isq::si::inline electric_charge - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/electric_current.h b/src/systems/si/include/units/isq/si/electric_current.h deleted file mode 100644 index 740eb113..00000000 --- a/src/systems/si/include/units/isq/si/electric_current.h +++ /dev/null @@ -1,327 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct ampere : named_unit {}; -struct yoctoampere : prefixed_unit {}; -struct zeptoampere : prefixed_unit {}; -struct attoampere : prefixed_unit {}; -struct femtoampere : prefixed_unit {}; -struct picoampere : prefixed_unit {}; -struct nanoampere : prefixed_unit {}; -struct microampere : prefixed_unit {}; -struct milliampere : prefixed_unit {}; -struct centiampere : prefixed_unit {}; -struct deciampere : prefixed_unit {}; -struct decaampere : prefixed_unit {}; -struct hectoampere : prefixed_unit {}; -struct kiloampere : prefixed_unit {}; -struct megaampere : prefixed_unit {}; -struct gigaampere : prefixed_unit {}; -struct teraampere : prefixed_unit {}; -struct petaampere : prefixed_unit {}; -struct exaampere : prefixed_unit {}; -struct zettaampere : prefixed_unit {}; -struct yottaampere : prefixed_unit {}; - -struct dim_electric_current : isq::dim_electric_current {}; - -template U, Representation Rep = double> -using electric_current = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// A -constexpr auto operator"" _q_A(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_A(long double l) { return electric_current(l); } - -// yA -constexpr auto operator"" _q_yA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_yA(long double l) { return electric_current(l); } - -// zA -constexpr auto operator"" _q_zA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_zA(long double l) { return electric_current(l); } - -// aA -constexpr auto operator"" _q_aA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_aA(long double l) { return electric_current(l); } - -// fA -constexpr auto operator"" _q_fA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_fA(long double l) { return electric_current(l); } - -// pA -constexpr auto operator"" _q_pA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_pA(long double l) { return electric_current(l); } - -// nA -constexpr auto operator"" _q_nA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_nA(long double l) { return electric_current(l); } - -// uA -constexpr auto operator"" _q_uA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_uA(long double l) { return electric_current(l); } - -// mA -constexpr auto operator"" _q_mA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_mA(long double l) { return electric_current(l); } - -// cA -constexpr auto operator"" _q_cA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_cA(long double l) { return electric_current(l); } - -// dA -constexpr auto operator"" _q_dA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_dA(long double l) { return electric_current(l); } - -// daA -constexpr auto operator"" _q_daA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_daA(long double l) { return electric_current(l); } - -// hA -constexpr auto operator"" _q_hA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_hA(long double l) { return electric_current(l); } - -// kA -constexpr auto operator"" _q_kA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_kA(long double l) { return electric_current(l); } - -// MA -constexpr auto operator"" _q_MA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_MA(long double l) { return electric_current(l); } - -// GA -constexpr auto operator"" _q_GA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_GA(long double l) { return electric_current(l); } - -// TA -constexpr auto operator"" _q_TA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_TA(long double l) { return electric_current(l); } - -// PA -constexpr auto operator"" _q_PA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_PA(long double l) { return electric_current(l); } - -// EA -constexpr auto operator"" _q_EA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_EA(long double l) { return electric_current(l); } - -// ZA -constexpr auto operator"" _q_ZA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_ZA(long double l) { return electric_current(l); } - -// YA -constexpr auto operator"" _q_YA(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_current(static_cast(l)); -} -constexpr auto operator"" _q_YA(long double l) { return electric_current(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace electric_current_references { - -inline constexpr auto A = reference{}; -inline constexpr auto yA = reference{}; -inline constexpr auto zA = reference{}; -inline constexpr auto aA = reference{}; -inline constexpr auto fA = reference{}; -inline constexpr auto pA = reference{}; -inline constexpr auto nA = reference{}; -inline constexpr auto uA = reference{}; -inline constexpr auto mA = reference{}; -inline constexpr auto cA = reference{}; -inline constexpr auto dA = reference{}; -inline constexpr auto daA = reference{}; -inline constexpr auto hA = reference{}; -inline constexpr auto kA = reference{}; -inline constexpr auto MA = reference{}; -inline constexpr auto GA = reference{}; -inline constexpr auto TA = reference{}; -inline constexpr auto PA = reference{}; -inline constexpr auto EA = reference{}; -inline constexpr auto ZA = reference{}; -inline constexpr auto YA = reference{}; - -} // namespace electric_current_references - -namespace references { - -using namespace electric_current_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline electric_current { - -template -using A = units::isq::si::electric_current; -template -using yA = units::isq::si::electric_current; -template -using zA = units::isq::si::electric_current; -template -using aA = units::isq::si::electric_current; -template -using fA = units::isq::si::electric_current; -template -using pA = units::isq::si::electric_current; -template -using nA = units::isq::si::electric_current; -template -using uA = units::isq::si::electric_current; -template -using mA = units::isq::si::electric_current; -template -using cA = units::isq::si::electric_current; -template -using dA = units::isq::si::electric_current; -template -using daA = units::isq::si::electric_current; -template -using hA = units::isq::si::electric_current; -template -using kA = units::isq::si::electric_current; -template -using MA = units::isq::si::electric_current; -template -using GA = units::isq::si::electric_current; -template -using TA = units::isq::si::electric_current; -template -using PA = units::isq::si::electric_current; -template -using EA = units::isq::si::electric_current; -template -using ZA = units::isq::si::electric_current; -template -using YA = units::isq::si::electric_current; - -} // namespace units::aliases::isq::si::inline electric_current - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/electric_field_strength.h b/src/systems/si/include/units/isq/si/electric_field_strength.h deleted file mode 100644 index 773640d5..00000000 --- a/src/systems/si/include/units/isq/si/electric_field_strength.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct volt_per_metre : derived_unit {}; -struct dim_electric_field_strength : - isq::dim_electric_field_strength {}; - -template U, Representation Rep = double> -using electric_field_strength = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// V/m -constexpr auto operator"" _q_V_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return electric_field_strength(static_cast(l)); -} -constexpr auto operator"" _q_V_per_m(long double l) { return electric_field_strength(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline electric_field_strength { - -template -using V_per_m = units::isq::si::electric_field_strength; - -} // namespace units::aliases::isq::si::inline electric_field_strength - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/energy.h b/src/systems/si/include/units/isq/si/energy.h deleted file mode 100644 index 7511c4d0..00000000 --- a/src/systems/si/include/units/isq/si/energy.h +++ /dev/null @@ -1,310 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct joule : named_unit {}; -struct yoctojoule : prefixed_unit {}; -struct zeptojoule : prefixed_unit {}; -struct attojoule : prefixed_unit {}; -struct femtojoule : prefixed_unit {}; -struct picojoule : prefixed_unit {}; -struct nanojoule : prefixed_unit {}; -struct microjoule : prefixed_unit {}; -struct millijoule : prefixed_unit {}; -struct kilojoule : prefixed_unit {}; -struct megajoule : prefixed_unit {}; -struct gigajoule : prefixed_unit {}; -struct terajoule : prefixed_unit {}; -struct petajoule : prefixed_unit {}; -struct exajoule : prefixed_unit {}; -struct zettajoule : prefixed_unit {}; -struct yottajoule : prefixed_unit {}; - -// N.B. electron charge (and eV) is an exact constant: -// https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf#page=147 -struct electronvolt : - named_scaled_unit() * mag_power<10, -19>(), joule> {}; -struct gigaelectronvolt : prefixed_unit {}; - -struct dim_energy : isq::dim_energy {}; - -template U, Representation Rep = double> -using energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// J -constexpr auto operator"" _q_J(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_J(long double l) { return energy(l); } - -// yJ -constexpr auto operator"" _q_yJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_yJ(long double l) { return energy(l); } - -// zJ -constexpr auto operator"" _q_zJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_zJ(long double l) { return energy(l); } - -// aJ -constexpr auto operator"" _q_aJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_aJ(long double l) { return energy(l); } - -// fJ -constexpr auto operator"" _q_fJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_fJ(long double l) { return energy(l); } - -// pJ -constexpr auto operator"" _q_pJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_pJ(long double l) { return energy(l); } - -// nJ -constexpr auto operator"" _q_nJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_nJ(long double l) { return energy(l); } - -// uJ -constexpr auto operator"" _q_uJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_uJ(long double l) { return energy(l); } - -// mJ -constexpr auto operator"" _q_mJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_mJ(long double l) { return energy(l); } - -// kJ -constexpr auto operator"" _q_kJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_kJ(long double l) { return energy(l); } - -// MJ -constexpr auto operator"" _q_MJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_MJ(long double l) { return energy(l); } - -// GJ -constexpr auto operator"" _q_GJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_GJ(long double l) { return energy(l); } - -// TJ -constexpr auto operator"" _q_TJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_TJ(long double l) { return energy(l); } - -// PJ -constexpr auto operator"" _q_PJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_PJ(long double l) { return energy(l); } - -// EJ -constexpr auto operator"" _q_EJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_EJ(long double l) { return energy(l); } - -// ZJ -constexpr auto operator"" _q_ZJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_ZJ(long double l) { return energy(l); } - -// YJ -constexpr auto operator"" _q_YJ(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_YJ(long double l) { return energy(l); } - -// eV -constexpr auto operator"" _q_eV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_eV(long double l) { return energy(l); } - -// GeV -constexpr auto operator"" _q_GeV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy(static_cast(l)); -} -constexpr auto operator"" _q_GeV(long double l) { return energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace energy_references { - -inline constexpr auto J = reference{}; -inline constexpr auto yJ = reference{}; -inline constexpr auto zJ = reference{}; -inline constexpr auto aJ = reference{}; -inline constexpr auto fJ = reference{}; -inline constexpr auto pJ = reference{}; -inline constexpr auto nJ = reference{}; -inline constexpr auto uJ = reference{}; -inline constexpr auto mJ = reference{}; -inline constexpr auto kJ = reference{}; -inline constexpr auto MJ = reference{}; -inline constexpr auto GJ = reference{}; -inline constexpr auto TJ = reference{}; -inline constexpr auto PJ = reference{}; -inline constexpr auto EJ = reference{}; -inline constexpr auto ZJ = reference{}; -inline constexpr auto YJ = reference{}; - -inline constexpr auto eV = reference{}; -inline constexpr auto GeV = reference{}; - -} // namespace energy_references - -namespace references { - -using namespace energy_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline energy { - -template -using J = units::isq::si::energy; -template -using yJ = units::isq::si::energy; -template -using zJ = units::isq::si::energy; -template -using aJ = units::isq::si::energy; -template -using fJ = units::isq::si::energy; -template -using pJ = units::isq::si::energy; -template -using nJ = units::isq::si::energy; -template -using uJ = units::isq::si::energy; -template -using mJ = units::isq::si::energy; -template -using kJ = units::isq::si::energy; -template -using MJ = units::isq::si::energy; -template -using GJ = units::isq::si::energy; -template -using TJ = units::isq::si::energy; -template -using PJ = units::isq::si::energy; -template -using EJ = units::isq::si::energy; -template -using ZJ = units::isq::si::energy; -template -using YJ = units::isq::si::energy; - -template -using eV = units::isq::si::energy; -template -using GeV = units::isq::si::energy; - -} // namespace units::aliases::isq::si::inline energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/energy_density.h b/src/systems/si/include/units/isq/si/energy_density.h deleted file mode 100644 index e9e156d7..00000000 --- a/src/systems/si/include/units/isq/si/energy_density.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct joule_per_metre_cub : derived_unit {}; -struct dim_energy_density : isq::dim_energy_density {}; - -template U, Representation Rep = double> -using energy_density = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// N/m -constexpr auto operator"" _q_J_per_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return energy_density(static_cast(l)); -} -constexpr auto operator"" _q_J_per_m3(long double l) { return energy_density(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline energy_density { - -template -using J_per_m3 = units::isq::si::energy_density; - -} // namespace units::aliases::isq::si::inline energy_density - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/force.h b/src/systems/si/include/units/isq/si/force.h deleted file mode 100644 index fa2c1880..00000000 --- a/src/systems/si/include/units/isq/si/force.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct newton : named_unit {}; -struct yoctonewton : prefixed_unit {}; -struct zeptonewton : prefixed_unit {}; -struct attonewton : prefixed_unit {}; -struct femtonewton : prefixed_unit {}; -struct piconewton : prefixed_unit {}; -struct nanonewton : prefixed_unit {}; -struct micronewton : prefixed_unit {}; -struct millinewton : prefixed_unit {}; -struct centinewton : prefixed_unit {}; -struct decinewton : prefixed_unit {}; -struct decanewton : prefixed_unit {}; -struct hectonewton : prefixed_unit {}; -struct kilonewton : prefixed_unit {}; -struct meganewton : prefixed_unit {}; -struct giganewton : prefixed_unit {}; -struct teranewton : prefixed_unit {}; -struct petanewton : prefixed_unit {}; -struct exanewton : prefixed_unit {}; -struct zettanewton : prefixed_unit {}; -struct yottanewton : prefixed_unit {}; - -struct dim_force : isq::dim_force {}; - -template U, Representation Rep = double> -using force = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// N -constexpr auto operator"" _q_N(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_N(long double l) { return force(l); } - -// yN -constexpr auto operator"" _q_yN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_yN(long double l) { return force(l); } - -// zN -constexpr auto operator"" _q_zN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_zN(long double l) { return force(l); } - -// aN -constexpr auto operator"" _q_aN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_aN(long double l) { return force(l); } - -// fN -constexpr auto operator"" _q_fN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_fN(long double l) { return force(l); } - -// pN -constexpr auto operator"" _q_pN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_pN(long double l) { return force(l); } - -// nN -constexpr auto operator"" _q_nN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_nN(long double l) { return force(l); } - -// uN -constexpr auto operator"" _q_uN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_uN(long double l) { return force(l); } - -// mN -constexpr auto operator"" _q_mN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_mN(long double l) { return force(l); } - -// cN -constexpr auto operator"" _q_cN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_cN(long double l) { return force(l); } - -// dN -constexpr auto operator"" _q_dN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_dN(long double l) { return force(l); } - -// daN -constexpr auto operator"" _q_daN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_daN(long double l) { return force(l); } - -// hN -constexpr auto operator"" _q_hN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_hN(long double l) { return force(l); } - -// kN -constexpr auto operator"" _q_kN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_kN(long double l) { return force(l); } - -// MN -constexpr auto operator"" _q_MN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_MN(long double l) { return force(l); } - -// GN -constexpr auto operator"" _q_GN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_GN(long double l) { return force(l); } - -// TN -constexpr auto operator"" _q_TN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_TN(long double l) { return force(l); } - -// PN -constexpr auto operator"" _q_PN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_PN(long double l) { return force(l); } - -// EN -constexpr auto operator"" _q_EN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_EN(long double l) { return force(l); } - -// ZN -constexpr auto operator"" _q_ZN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_ZN(long double l) { return force(l); } - -// YN -constexpr auto operator"" _q_YN(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return force(static_cast(l)); -} -constexpr auto operator"" _q_YN(long double l) { return force(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace force_references { - -inline constexpr auto N = reference{}; -inline constexpr auto yN = reference{}; -inline constexpr auto zN = reference{}; -inline constexpr auto aN = reference{}; -inline constexpr auto fN = reference{}; -inline constexpr auto pN = reference{}; -inline constexpr auto nN = reference{}; -inline constexpr auto uN = reference{}; -inline constexpr auto mN = reference{}; -inline constexpr auto cN = reference{}; -inline constexpr auto dN = reference{}; -inline constexpr auto daN = reference{}; -inline constexpr auto hN = reference{}; -inline constexpr auto kN = reference{}; -inline constexpr auto MN = reference{}; -inline constexpr auto GN = reference{}; -inline constexpr auto TN = reference{}; -inline constexpr auto PN = reference{}; -inline constexpr auto EN = reference{}; -inline constexpr auto ZN = reference{}; -inline constexpr auto YN = reference{}; - -} // namespace force_references - -namespace references { - -using namespace force_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline force { - -template -using N = units::isq::si::force; -template -using yN = units::isq::si::force; -template -using zN = units::isq::si::force; -template -using aN = units::isq::si::force; -template -using fN = units::isq::si::force; -template -using pN = units::isq::si::force; -template -using nN = units::isq::si::force; -template -using uN = units::isq::si::force; -template -using mN = units::isq::si::force; -template -using cN = units::isq::si::force; -template -using dN = units::isq::si::force; -template -using daN = units::isq::si::force; -template -using hN = units::isq::si::force; -template -using kN = units::isq::si::force; -template -using MN = units::isq::si::force; -template -using GN = units::isq::si::force; -template -using TN = units::isq::si::force; -template -using PN = units::isq::si::force; -template -using EN = units::isq::si::force; -template -using ZN = units::isq::si::force; -template -using YN = units::isq::si::force; - -} // namespace units::aliases::isq::si::inline force - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/frequency.h b/src/systems/si/include/units/isq/si/frequency.h deleted file mode 100644 index 39fa13ee..00000000 --- a/src/systems/si/include/units/isq/si/frequency.h +++ /dev/null @@ -1,279 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct hertz : named_unit {}; -struct yoctohertz : prefixed_unit {}; -struct zeptohertz : prefixed_unit {}; -struct attohertz : prefixed_unit {}; -struct femtohertz : prefixed_unit {}; -struct picohertz : prefixed_unit {}; -struct nanohertz : prefixed_unit {}; -struct microhertz : prefixed_unit {}; -struct millihertz : prefixed_unit {}; -struct kilohertz : prefixed_unit {}; -struct megahertz : prefixed_unit {}; -struct gigahertz : prefixed_unit {}; -struct terahertz : prefixed_unit {}; -struct petahertz : prefixed_unit {}; -struct exahertz : prefixed_unit {}; -struct zettahertz : prefixed_unit {}; -struct yottahertz : prefixed_unit {}; - -struct dim_frequency : isq::dim_frequency {}; - -template U, Representation Rep = double> -using frequency = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Hz -constexpr auto operator"" _q_Hz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_Hz(long double l) { return frequency(l); } - -// yHz -constexpr auto operator"" _q_yHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_yHz(long double l) { return frequency(l); } - -// zHz -constexpr auto operator"" _q_zHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_zHz(long double l) { return frequency(l); } - -// aHz -constexpr auto operator"" _q_aHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_aHz(long double l) { return frequency(l); } - -// fHz -constexpr auto operator"" _q_fHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_fHz(long double l) { return frequency(l); } - -// pHz -constexpr auto operator"" _q_pHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_pHz(long double l) { return frequency(l); } - -// nHz -constexpr auto operator"" _q_nHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_nHz(long double l) { return frequency(l); } - -// uHz -constexpr auto operator"" _q_uHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_uHz(long double l) { return frequency(l); } - -// mHz -constexpr auto operator"" _q_mHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_mHz(long double l) { return frequency(l); } - -// kHz -constexpr auto operator"" _q_kHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_kHz(long double l) { return frequency(l); } - -// MHz -constexpr auto operator"" _q_MHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_MHz(long double l) { return frequency(l); } - -// GHz -constexpr auto operator"" _q_GHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_GHz(long double l) { return frequency(l); } - -// THz -constexpr auto operator"" _q_THz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_THz(long double l) { return frequency(l); } - -// PHz -constexpr auto operator"" _q_PHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_PHz(long double l) { return frequency(l); } - -// EHz -constexpr auto operator"" _q_EHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_EHz(long double l) { return frequency(l); } - -// ZHz -constexpr auto operator"" _q_ZHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_ZHz(long double l) { return frequency(l); } - -// YHz -constexpr auto operator"" _q_YHz(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return frequency(static_cast(l)); -} -constexpr auto operator"" _q_YHz(long double l) { return frequency(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace frequency_references { - -inline constexpr auto Hz = reference{}; -inline constexpr auto yHz = reference{}; -inline constexpr auto zHz = reference{}; -inline constexpr auto aHz = reference{}; -inline constexpr auto fHz = reference{}; -inline constexpr auto pHz = reference{}; -inline constexpr auto nHz = reference{}; -inline constexpr auto uHz = reference{}; -inline constexpr auto mHz = reference{}; -inline constexpr auto kHz = reference{}; -inline constexpr auto MHz = reference{}; -inline constexpr auto GHz = reference{}; -inline constexpr auto THz = reference{}; -inline constexpr auto PHz = reference{}; -inline constexpr auto EHz = reference{}; -inline constexpr auto ZHz = reference{}; -inline constexpr auto YHz = reference{}; - -} // namespace frequency_references - -namespace references { - -using namespace frequency_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline frequency { - -template -using Hz = units::isq::si::frequency; -template -using yHz = units::isq::si::frequency; -template -using zHz = units::isq::si::frequency; -template -using aHz = units::isq::si::frequency; -template -using fHz = units::isq::si::frequency; -template -using pHz = units::isq::si::frequency; -template -using nHz = units::isq::si::frequency; -template -using uHz = units::isq::si::frequency; -template -using mHz = units::isq::si::frequency; -template -using kHz = units::isq::si::frequency; -template -using MHz = units::isq::si::frequency; -template -using GHz = units::isq::si::frequency; -template -using THz = units::isq::si::frequency; -template -using PHz = units::isq::si::frequency; -template -using EHz = units::isq::si::frequency; -template -using ZHz = units::isq::si::frequency; -template -using YHz = units::isq::si::frequency; - -} // namespace units::aliases::isq::si::inline frequency - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/heat_capacity.h b/src/systems/si/include/units/isq/si/heat_capacity.h deleted file mode 100644 index 5ae30cfa..00000000 --- a/src/systems/si/include/units/isq/si/heat_capacity.h +++ /dev/null @@ -1,114 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include -#include - -namespace units::isq::si { - -struct joule_per_kelvin : derived_unit {}; -struct joule_per_kilogram_kelvin : derived_unit {}; -struct joule_per_mole_kelvin : derived_unit {}; - -struct dim_heat_capacity : - isq::dim_heat_capacity {}; -struct dim_specific_heat_capacity : - isq::dim_specific_heat_capacity {}; -struct dim_molar_heat_capacity : - isq::dim_molar_heat_capacity {}; - -template U, Representation Rep = double> -using heat_capacity = quantity; - -template U, Representation Rep = double> -using specific_heat_capacity = quantity; - -template U, Representation Rep = double> -using molar_heat_capacity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// J/K -constexpr auto operator"" _q_J_per_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return heat_capacity(static_cast(l)); -} -constexpr auto operator"" _q_J_per_K(long double l) { return heat_capacity(l); } - -// J/(kg·K) -constexpr auto operator"" _q_J_per_kg_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return specific_heat_capacity(static_cast(l)); -} -constexpr auto operator"" _q_J_per_kg_K(long double l) -{ - return specific_heat_capacity(l); -} - -// J/(mol·K) -constexpr auto operator"" _q_J_per_mol_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return molar_heat_capacity(static_cast(l)); -} -constexpr auto operator"" _q_J_per_mol_K(long double l) -{ - return molar_heat_capacity(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::heat_capacity { - -template -using J_per_K = units::isq::si::heat_capacity; -template -using J_per_kg_K = units::isq::si::specific_heat_capacity; -template -using J_per_mol_K = units::isq::si::molar_heat_capacity; - -} // namespace units::aliases::isq::si::heat_capacity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/inductance.h b/src/systems/si/include/units/isq/si/inductance.h deleted file mode 100644 index c6a14a98..00000000 --- a/src/systems/si/include/units/isq/si/inductance.h +++ /dev/null @@ -1,281 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct henry : named_unit {}; - -struct yoctohenry : prefixed_unit {}; -struct zeptohenry : prefixed_unit {}; -struct attohenry : prefixed_unit {}; -struct femtohenry : prefixed_unit {}; -struct picohenry : prefixed_unit {}; -struct nanohenry : prefixed_unit {}; -struct microhenry : prefixed_unit {}; -struct millihenry : prefixed_unit {}; -struct kilohenry : prefixed_unit {}; -struct megahenry : prefixed_unit {}; -struct gigahenry : prefixed_unit {}; -struct terahenry : prefixed_unit {}; -struct petahenry : prefixed_unit {}; -struct exahenry : prefixed_unit {}; -struct zettahenry : prefixed_unit {}; -struct yottahenry : prefixed_unit {}; - -struct dim_inductance : isq::dim_inductance {}; - -template U, Representation Rep = double> -using inductance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// H -constexpr auto operator"" _q_H(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_H(long double l) { return inductance(l); } - -// yH -constexpr auto operator"" _q_yH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_yH(long double l) { return inductance(l); } - -// zH -constexpr auto operator"" _q_zH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_zH(long double l) { return inductance(l); } - -// aH -constexpr auto operator"" _q_aH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_aH(long double l) { return inductance(l); } - -// fH -constexpr auto operator"" _q_fH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_fH(long double l) { return inductance(l); } - -// pH -constexpr auto operator"" _q_pH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_pH(long double l) { return inductance(l); } - -// nH -constexpr auto operator"" _q_nH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_nH(long double l) { return inductance(l); } - -// µH -constexpr auto operator"" _q_uH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_uH(long double l) { return inductance(l); } - -// mH -constexpr auto operator"" _q_mH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_mH(long double l) { return inductance(l); } - -// kH -constexpr auto operator"" _q_kH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_kH(long double l) { return inductance(l); } - -// MH -constexpr auto operator"" _q_MH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_MH(long double l) { return inductance(l); } - -// GH -constexpr auto operator"" _q_GH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_GH(long double l) { return inductance(l); } - -// TH -constexpr auto operator"" _q_TH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_TH(long double l) { return inductance(l); } - -// PH -constexpr auto operator"" _q_PH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_PH(long double l) { return inductance(l); } - -// EH -constexpr auto operator"" _q_EH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_EH(long double l) { return inductance(l); } - -// ZH -constexpr auto operator"" _q_ZH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_ZH(long double l) { return inductance(l); } - -// YH -constexpr auto operator"" _q_YH(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return inductance(static_cast(l)); -} -constexpr auto operator"" _q_YH(long double l) { return inductance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace inductance_references { - -inline constexpr auto H = reference{}; -inline constexpr auto yH = reference{}; -inline constexpr auto zH = reference{}; -inline constexpr auto aH = reference{}; -inline constexpr auto fH = reference{}; -inline constexpr auto pH = reference{}; -inline constexpr auto nH = reference{}; -inline constexpr auto uH = reference{}; -inline constexpr auto mH = reference{}; -inline constexpr auto kH = reference{}; -inline constexpr auto MH = reference{}; -inline constexpr auto GH = reference{}; -inline constexpr auto TH = reference{}; -inline constexpr auto PH = reference{}; -inline constexpr auto EH = reference{}; -inline constexpr auto ZH = reference{}; -inline constexpr auto YH = reference{}; - -} // namespace inductance_references - -namespace references { - -using namespace inductance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline inductance { - -template -using H = units::isq::si::inductance; -template -using yH = units::isq::si::inductance; -template -using zH = units::isq::si::inductance; -template -using aH = units::isq::si::inductance; -template -using fH = units::isq::si::inductance; -template -using pH = units::isq::si::inductance; -template -using nH = units::isq::si::inductance; -template -using uH = units::isq::si::inductance; -template -using mH = units::isq::si::inductance; -template -using kH = units::isq::si::inductance; -template -using MH = units::isq::si::inductance; -template -using GH = units::isq::si::inductance; -template -using TH = units::isq::si::inductance; -template -using PH = units::isq::si::inductance; -template -using EH = units::isq::si::inductance; -template -using ZH = units::isq::si::inductance; -template -using YH = units::isq::si::inductance; - -} // namespace units::aliases::isq::si::inline inductance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/length.h b/src/systems/si/include/units/isq/si/length.h deleted file mode 100644 index 6585ed92..00000000 --- a/src/systems/si/include/units/isq/si/length.h +++ /dev/null @@ -1,340 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct metre : named_unit {}; -struct yoctometre : prefixed_unit {}; -struct zeptometre : prefixed_unit {}; -struct attometre : prefixed_unit {}; -struct femtometre : prefixed_unit {}; -struct picometre : prefixed_unit {}; -struct nanometre : prefixed_unit {}; -struct micrometre : prefixed_unit {}; -struct millimetre : prefixed_unit {}; -struct centimetre : prefixed_unit {}; -struct decimetre : prefixed_unit {}; -struct decametre : prefixed_unit {}; -struct hectometre : prefixed_unit {}; -struct kilometre : prefixed_unit {}; -struct megametre : prefixed_unit {}; -struct gigametre : prefixed_unit {}; -struct terametre : prefixed_unit {}; -struct petametre : prefixed_unit {}; -struct exametre : prefixed_unit {}; -struct zettametre : prefixed_unit {}; -struct yottametre : prefixed_unit {}; - -struct astronomical_unit : named_scaled_unit(), metre> {}; - -struct dim_length : isq::dim_length {}; - -template U, Representation Rep = double> -using length = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m -constexpr auto operator"" _q_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_m(long double l) { return length(l); } - -// ym -constexpr auto operator"" _q_ym(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_ym(long double l) { return length(l); } - -// zm -constexpr auto operator"" _q_zm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_zm(long double l) { return length(l); } - -// am -constexpr auto operator"" _q_am(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_am(long double l) { return length(l); } - -// fm -constexpr auto operator"" _q_fm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_fm(long double l) { return length(l); } - -// pm -constexpr auto operator"" _q_pm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_pm(long double l) { return length(l); } - -// nm -constexpr auto operator"" _q_nm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_nm(long double l) { return length(l); } - -// um -constexpr auto operator"" _q_um(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_um(long double l) { return length(l); } - -// mm -constexpr auto operator"" _q_mm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_mm(long double l) { return length(l); } - -// cm -constexpr auto operator"" _q_cm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_cm(long double l) { return length(l); } - -// dm -constexpr auto operator"" _q_dm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_dm(long double l) { return length(l); } - -// dam -constexpr auto operator"" _q_dam(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_dam(long double l) { return length(l); } - -// hm -constexpr auto operator"" _q_hm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_hm(long double l) { return length(l); } - -// km -constexpr auto operator"" _q_km(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_km(long double l) { return length(l); } - -// Mm -constexpr auto operator"" _q_Mm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Mm(long double l) { return length(l); } - -// Gm -constexpr auto operator"" _q_Gm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Gm(long double l) { return length(l); } - -// Tm -constexpr auto operator"" _q_Tm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Tm(long double l) { return length(l); } - -// Pm -constexpr auto operator"" _q_Pm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Pm(long double l) { return length(l); } - -// Em -constexpr auto operator"" _q_Em(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Em(long double l) { return length(l); } - -// Zm -constexpr auto operator"" _q_Zm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Zm(long double l) { return length(l); } - -// Ym -constexpr auto operator"" _q_Ym(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_Ym(long double l) { return length(l); } - -// au -constexpr auto operator"" _q_au(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return length(static_cast(l)); -} -constexpr auto operator"" _q_au(long double l) { return length(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace length_references { - -inline constexpr auto m = reference{}; -inline constexpr auto ym = reference{}; -inline constexpr auto zm = reference{}; -inline constexpr auto am = reference{}; -inline constexpr auto fm = reference{}; -inline constexpr auto pm = reference{}; -inline constexpr auto nm = reference{}; -inline constexpr auto um = reference{}; -inline constexpr auto mm = reference{}; -inline constexpr auto cm = reference{}; -inline constexpr auto dm = reference{}; -inline constexpr auto dam = reference{}; -inline constexpr auto hm = reference{}; -inline constexpr auto km = reference{}; -inline constexpr auto Mm = reference{}; -inline constexpr auto Gm = reference{}; -inline constexpr auto Tm = reference{}; -inline constexpr auto Pm = reference{}; -inline constexpr auto Em = reference{}; -inline constexpr auto Zm = reference{}; -inline constexpr auto Ym = reference{}; -inline constexpr auto au = reference{}; - -} // namespace length_references - -namespace references { - -using namespace length_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline length { - -template -using m = units::isq::si::length; -template -using ym = units::isq::si::length; -template -using zm = units::isq::si::length; -template -using am = units::isq::si::length; -template -using fm = units::isq::si::length; -template -using pm = units::isq::si::length; -template -using nm = units::isq::si::length; -template -using um = units::isq::si::length; -template -using mm = units::isq::si::length; -template -using cm = units::isq::si::length; -template -using dm = units::isq::si::length; -template -using dam = units::isq::si::length; -template -using hm = units::isq::si::length; -template -using km = units::isq::si::length; -template -using Mm = units::isq::si::length; -template -using Gm = units::isq::si::length; -template -using Tm = units::isq::si::length; -template -using Pm = units::isq::si::length; -template -using Em = units::isq::si::length; -template -using Zm = units::isq::si::length; -template -using Ym = units::isq::si::length; -template -using au = units::isq::si::length; - -} // namespace units::aliases::isq::si::inline length - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/luminance.h b/src/systems/si/include/units/isq/si/luminance.h deleted file mode 100644 index 48f01073..00000000 --- a/src/systems/si/include/units/isq/si/luminance.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct candela_per_metre_sq : derived_unit {}; -struct dim_luminance : isq::dim_luminance {}; - -template U, Representation Rep = double> -using luminance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cd/m² -constexpr auto operator"" _q_cd_per_m2(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminance(static_cast(l)); -} -constexpr auto operator"" _q_cd_per_m2(long double l) { return luminance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline luminance { - -template -using cd_per_m2 = units::isq::si::luminance; - -} // namespace units::aliases::isq::si::inline luminance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/luminous_flux.h b/src/systems/si/include/units/isq/si/luminous_flux.h deleted file mode 100644 index c35f5e8c..00000000 --- a/src/systems/si/include/units/isq/si/luminous_flux.h +++ /dev/null @@ -1,90 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct lumen : named_unit {}; - -struct dim_luminous_flux : - isq::dim_luminous_flux> {}; - -template U, Representation Rep = double> -using luminous_flux = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// lm -constexpr auto operator"" _q_lm(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_flux(static_cast(l)); -} -constexpr auto operator"" _q_lm(long double l) { return luminous_flux(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace luminous_flux_references { - -inline constexpr auto lm = reference{}; - -} // namespace luminous_flux_references - -namespace references { - -using namespace luminous_flux_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline luminous_flux { - -template -using lm = units::isq::si::luminous_flux; - -} // namespace units::aliases::isq::si::inline luminous_flux - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/luminous_intensity.h b/src/systems/si/include/units/isq/si/luminous_intensity.h deleted file mode 100644 index 38e658f0..00000000 --- a/src/systems/si/include/units/isq/si/luminous_intensity.h +++ /dev/null @@ -1,327 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct candela : named_unit {}; -struct yoctocandela : prefixed_unit {}; -struct zeptocandela : prefixed_unit {}; -struct attocandela : prefixed_unit {}; -struct femtocandela : prefixed_unit {}; -struct picocandela : prefixed_unit {}; -struct nanocandela : prefixed_unit {}; -struct microcandela : prefixed_unit {}; -struct millicandela : prefixed_unit {}; -struct centicandela : prefixed_unit {}; -struct decicandela : prefixed_unit {}; -struct decacandela : prefixed_unit {}; -struct hectocandela : prefixed_unit {}; -struct kilocandela : prefixed_unit {}; -struct megacandela : prefixed_unit {}; -struct gigacandela : prefixed_unit {}; -struct teracandela : prefixed_unit {}; -struct petacandela : prefixed_unit {}; -struct exacandela : prefixed_unit {}; -struct zettacandela : prefixed_unit {}; -struct yottacandela : prefixed_unit {}; - -struct dim_luminous_intensity : isq::dim_luminous_intensity {}; - -template U, Representation Rep = double> -using luminous_intensity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// cd -constexpr auto operator"" _q_cd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_cd(long double l) { return luminous_intensity(l); } - -// ycd -constexpr auto operator"" _q_ycd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ycd(long double l) { return luminous_intensity(l); } - -// zcd -constexpr auto operator"" _q_zcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_zcd(long double l) { return luminous_intensity(l); } - -// acd -constexpr auto operator"" _q_acd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_acd(long double l) { return luminous_intensity(l); } - -// fcd -constexpr auto operator"" _q_fcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_fcd(long double l) { return luminous_intensity(l); } - -// pcd -constexpr auto operator"" _q_pcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_pcd(long double l) { return luminous_intensity(l); } - -// ncd -constexpr auto operator"" _q_ncd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ncd(long double l) { return luminous_intensity(l); } - -// ucd -constexpr auto operator"" _q_ucd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ucd(long double l) { return luminous_intensity(l); } - -// mcd -constexpr auto operator"" _q_mcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_mcd(long double l) { return luminous_intensity(l); } - -// ccd -constexpr auto operator"" _q_ccd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_ccd(long double l) { return luminous_intensity(l); } - -// dcd -constexpr auto operator"" _q_dcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_dcd(long double l) { return luminous_intensity(l); } - -// dacd -constexpr auto operator"" _q_dacd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_dacd(long double l) { return luminous_intensity(l); } - -// hcd -constexpr auto operator"" _q_hcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_hcd(long double l) { return luminous_intensity(l); } - -// kcd -constexpr auto operator"" _q_kcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_kcd(long double l) { return luminous_intensity(l); } - -// Mcd -constexpr auto operator"" _q_Mcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Mcd(long double l) { return luminous_intensity(l); } - -// Gcd -constexpr auto operator"" _q_Gcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Gcd(long double l) { return luminous_intensity(l); } - -// Tcd -constexpr auto operator"" _q_Tcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Tcd(long double l) { return luminous_intensity(l); } - -// Pcd -constexpr auto operator"" _q_Pcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Pcd(long double l) { return luminous_intensity(l); } - -// Ecd -constexpr auto operator"" _q_Ecd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Ecd(long double l) { return luminous_intensity(l); } - -// Zcd -constexpr auto operator"" _q_Zcd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Zcd(long double l) { return luminous_intensity(l); } - -// Ycd -constexpr auto operator"" _q_Ycd(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return luminous_intensity(static_cast(l)); -} -constexpr auto operator"" _q_Ycd(long double l) { return luminous_intensity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace luminous_intensity_references { - -inline constexpr auto cd = reference{}; -inline constexpr auto ycd = reference{}; -inline constexpr auto zcd = reference{}; -inline constexpr auto acd = reference{}; -inline constexpr auto fcd = reference{}; -inline constexpr auto pcd = reference{}; -inline constexpr auto ncd = reference{}; -inline constexpr auto ucd = reference{}; -inline constexpr auto mcd = reference{}; -inline constexpr auto ccd = reference{}; -inline constexpr auto dcd = reference{}; -inline constexpr auto dacd = reference{}; -inline constexpr auto hcd = reference{}; -inline constexpr auto kcd = reference{}; -inline constexpr auto Mcd = reference{}; -inline constexpr auto Gcd = reference{}; -inline constexpr auto Tcd = reference{}; -inline constexpr auto Pcd = reference{}; -inline constexpr auto Ecd = reference{}; -inline constexpr auto Zcd = reference{}; -inline constexpr auto Ycd = reference{}; - -} // namespace luminous_intensity_references - -namespace references { - -using namespace luminous_intensity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::luminous_intensity { - -template -using cd = units::isq::si::luminous_intensity; -template -using ycd = units::isq::si::luminous_intensity; -template -using zcd = units::isq::si::luminous_intensity; -template -using acd = units::isq::si::luminous_intensity; -template -using fcd = units::isq::si::luminous_intensity; -template -using pcd = units::isq::si::luminous_intensity; -template -using ncd = units::isq::si::luminous_intensity; -template -using ucd = units::isq::si::luminous_intensity; -template -using mcd = units::isq::si::luminous_intensity; -template -using ccd = units::isq::si::luminous_intensity; -template -using dcd = units::isq::si::luminous_intensity; -template -using dacd = units::isq::si::luminous_intensity; -template -using hcd = units::isq::si::luminous_intensity; -template -using kcd = units::isq::si::luminous_intensity; -template -using Mcd = units::isq::si::luminous_intensity; -template -using Gcd = units::isq::si::luminous_intensity; -template -using Tcd = units::isq::si::luminous_intensity; -template -using Pcd = units::isq::si::luminous_intensity; -template -using Ecd = units::isq::si::luminous_intensity; -template -using Zcd = units::isq::si::luminous_intensity; -template -using Ycd = units::isq::si::luminous_intensity; - -} // namespace units::aliases::isq::si::luminous_intensity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/magnetic_flux.h b/src/systems/si/include/units/isq/si/magnetic_flux.h deleted file mode 100644 index 77b1410c..00000000 --- a/src/systems/si/include/units/isq/si/magnetic_flux.h +++ /dev/null @@ -1,281 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct weber : named_unit {}; - -struct yoctoweber : prefixed_unit {}; -struct zeptoweber : prefixed_unit {}; -struct attoweber : prefixed_unit {}; -struct femtoweber : prefixed_unit {}; -struct picoweber : prefixed_unit {}; -struct nanoweber : prefixed_unit {}; -struct microweber : prefixed_unit {}; -struct milliweber : prefixed_unit {}; -struct kiloweber : prefixed_unit {}; -struct megaweber : prefixed_unit {}; -struct gigaweber : prefixed_unit {}; -struct teraweber : prefixed_unit {}; -struct petaweber : prefixed_unit {}; -struct exaweber : prefixed_unit {}; -struct zettaweber : prefixed_unit {}; -struct yottaweber : prefixed_unit {}; - -struct dim_magnetic_flux : isq::dim_magnetic_flux {}; - -template U, Representation Rep = double> -using magnetic_flux = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Wb -constexpr auto operator"" _q_Wb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_Wb(long double l) { return magnetic_flux(l); } - -// yWb -constexpr auto operator"" _q_yWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_yWb(long double l) { return magnetic_flux(l); } - -// zWb -constexpr auto operator"" _q_zWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_zWb(long double l) { return magnetic_flux(l); } - -// aWb -constexpr auto operator"" _q_aWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_aWb(long double l) { return magnetic_flux(l); } - -// fWb -constexpr auto operator"" _q_fWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_fWb(long double l) { return magnetic_flux(l); } - -// pWb -constexpr auto operator"" _q_pWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_pWb(long double l) { return magnetic_flux(l); } - -// nWb -constexpr auto operator"" _q_nWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_nWb(long double l) { return magnetic_flux(l); } - -// µWb -constexpr auto operator"" _q_uWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_uWb(long double l) { return magnetic_flux(l); } - -// mWb -constexpr auto operator"" _q_mWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_mWb(long double l) { return magnetic_flux(l); } - -// kWb -constexpr auto operator"" _q_kWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_kWb(long double l) { return magnetic_flux(l); } - -// MWb -constexpr auto operator"" _q_MWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_MWb(long double l) { return magnetic_flux(l); } - -// GWb -constexpr auto operator"" _q_GWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_GWb(long double l) { return magnetic_flux(l); } - -// TWb -constexpr auto operator"" _q_TWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_TWb(long double l) { return magnetic_flux(l); } - -// PWb -constexpr auto operator"" _q_PWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_PWb(long double l) { return magnetic_flux(l); } - -// EWb -constexpr auto operator"" _q_EWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_EWb(long double l) { return magnetic_flux(l); } - -// ZWb -constexpr auto operator"" _q_ZWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_ZWb(long double l) { return magnetic_flux(l); } - -// YWb -constexpr auto operator"" _q_YWb(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_flux(static_cast(l)); -} -constexpr auto operator"" _q_YWb(long double l) { return magnetic_flux(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace magnetic_flux_references { - -inline constexpr auto Wb = reference{}; -inline constexpr auto yWb = reference{}; -inline constexpr auto zWb = reference{}; -inline constexpr auto aWb = reference{}; -inline constexpr auto fWb = reference{}; -inline constexpr auto pWb = reference{}; -inline constexpr auto nWb = reference{}; -inline constexpr auto uWb = reference{}; -inline constexpr auto mWb = reference{}; -inline constexpr auto kWb = reference{}; -inline constexpr auto MWb = reference{}; -inline constexpr auto GWb = reference{}; -inline constexpr auto TWb = reference{}; -inline constexpr auto PWb = reference{}; -inline constexpr auto EWb = reference{}; -inline constexpr auto ZWb = reference{}; -inline constexpr auto YWb = reference{}; - -} // namespace magnetic_flux_references - -namespace references { - -using namespace magnetic_flux_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline magnetic_flux { - -template -using Wb = units::isq::si::magnetic_flux; -template -using yWb = units::isq::si::magnetic_flux; -template -using zWb = units::isq::si::magnetic_flux; -template -using aWb = units::isq::si::magnetic_flux; -template -using fWb = units::isq::si::magnetic_flux; -template -using pWb = units::isq::si::magnetic_flux; -template -using nWb = units::isq::si::magnetic_flux; -template -using uWb = units::isq::si::magnetic_flux; -template -using mWb = units::isq::si::magnetic_flux; -template -using kWb = units::isq::si::magnetic_flux; -template -using MWb = units::isq::si::magnetic_flux; -template -using GWb = units::isq::si::magnetic_flux; -template -using TWb = units::isq::si::magnetic_flux; -template -using PWb = units::isq::si::magnetic_flux; -template -using EWb = units::isq::si::magnetic_flux; -template -using ZWb = units::isq::si::magnetic_flux; -template -using YWb = units::isq::si::magnetic_flux; - -} // namespace units::aliases::isq::si::inline magnetic_flux - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/magnetic_induction.h b/src/systems/si/include/units/isq/si/magnetic_induction.h deleted file mode 100644 index 529a7f9a..00000000 --- a/src/systems/si/include/units/isq/si/magnetic_induction.h +++ /dev/null @@ -1,297 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include -#include - -namespace units::isq::si { - -struct tesla : named_unit {}; - -struct yoctotesla : prefixed_unit {}; -struct zeptotesla : prefixed_unit {}; -struct attotesla : prefixed_unit {}; -struct femtotesla : prefixed_unit {}; -struct picotesla : prefixed_unit {}; -struct nanotesla : prefixed_unit {}; -struct microtesla : prefixed_unit {}; -struct millitesla : prefixed_unit {}; -struct kilotesla : prefixed_unit {}; -struct megatesla : prefixed_unit {}; -struct gigatesla : prefixed_unit {}; -struct teratesla : prefixed_unit {}; -struct petatesla : prefixed_unit {}; -struct exatesla : prefixed_unit {}; -struct zettatesla : prefixed_unit {}; -struct yottatesla : prefixed_unit {}; - -struct gauss : named_scaled_unit(), tesla> {}; - -struct dim_magnetic_induction : - isq::dim_magnetic_induction {}; - -template U, Representation Rep = double> -using magnetic_induction = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// T -constexpr auto operator"" _q_T(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_T(long double l) { return magnetic_induction(l); } - -// yT -constexpr auto operator"" _q_yT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_yT(long double l) { return magnetic_induction(l); } - -// zT -constexpr auto operator"" _q_zT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_zT(long double l) { return magnetic_induction(l); } - -// aT -constexpr auto operator"" _q_aT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_aT(long double l) { return magnetic_induction(l); } - -// fT -constexpr auto operator"" _q_fT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_fT(long double l) { return magnetic_induction(l); } - -// pT -constexpr auto operator"" _q_pT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_pT(long double l) { return magnetic_induction(l); } - -// nT -constexpr auto operator"" _q_nT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_nT(long double l) { return magnetic_induction(l); } - -// µT -constexpr auto operator"" _q_uT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_uT(long double l) { return magnetic_induction(l); } - -// mT -constexpr auto operator"" _q_mT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_mT(long double l) { return magnetic_induction(l); } - -// kT -constexpr auto operator"" _q_kT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_kT(long double l) { return magnetic_induction(l); } - -// MT -constexpr auto operator"" _q_MT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_MT(long double l) { return magnetic_induction(l); } - -// GT -constexpr auto operator"" _q_GT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_GT(long double l) { return magnetic_induction(l); } - -// TT -constexpr auto operator"" _q_TT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_TT(long double l) { return magnetic_induction(l); } - -// PT -constexpr auto operator"" _q_PT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_PT(long double l) { return magnetic_induction(l); } - -// ET -constexpr auto operator"" _q_ET(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_ET(long double l) { return magnetic_induction(l); } - -// ZT -constexpr auto operator"" _q_ZT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_ZT(long double l) { return magnetic_induction(l); } - -// YT -constexpr auto operator"" _q_YT(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_YT(long double l) { return magnetic_induction(l); } - -// G -constexpr auto operator"" _q_G(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return magnetic_induction(static_cast(l)); -} -constexpr auto operator"" _q_G(long double l) { return magnetic_induction(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace magnetic_induction_references { - -inline constexpr auto T = reference{}; -inline constexpr auto yT = reference{}; -inline constexpr auto zT = reference{}; -inline constexpr auto aT = reference{}; -inline constexpr auto fT = reference{}; -inline constexpr auto pT = reference{}; -inline constexpr auto nT = reference{}; -inline constexpr auto uT = reference{}; -inline constexpr auto mT = reference{}; -inline constexpr auto kT = reference{}; -inline constexpr auto MT = reference{}; -inline constexpr auto GT = reference{}; -inline constexpr auto TT = reference{}; -inline constexpr auto PT = reference{}; -inline constexpr auto ET = reference{}; -inline constexpr auto ZT = reference{}; -inline constexpr auto YT = reference{}; -inline constexpr auto G = reference{}; - -} // namespace magnetic_induction_references - -namespace references { - -using namespace magnetic_induction_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline magnetic_induction { - -template -using T = units::isq::si::magnetic_induction; -template -using yT = units::isq::si::magnetic_induction; -template -using zT = units::isq::si::magnetic_induction; -template -using aT = units::isq::si::magnetic_induction; -template -using fT = units::isq::si::magnetic_induction; -template -using pT = units::isq::si::magnetic_induction; -template -using nT = units::isq::si::magnetic_induction; -template -using uT = units::isq::si::magnetic_induction; -template -using mT = units::isq::si::magnetic_induction; -template -using kT = units::isq::si::magnetic_induction; -template -using MT = units::isq::si::magnetic_induction; -template -using GT = units::isq::si::magnetic_induction; -template -using TT = units::isq::si::magnetic_induction; -template -using PT = units::isq::si::magnetic_induction; -template -using ET = units::isq::si::magnetic_induction; -template -using ZT = units::isq::si::magnetic_induction; -template -using YT = units::isq::si::magnetic_induction; -template -using G = units::isq::si::magnetic_induction; - -} // namespace units::aliases::isq::si::inline magnetic_induction - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/mass.h b/src/systems/si/include/units/isq/si/mass.h deleted file mode 100644 index d57069d8..00000000 --- a/src/systems/si/include/units/isq/si/mass.h +++ /dev/null @@ -1,595 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct gram : named_unit {}; -struct yoctogram : prefixed_unit {}; -struct zeptogram : prefixed_unit {}; -struct attogram : prefixed_unit {}; -struct femtogram : prefixed_unit {}; -struct picogram : prefixed_unit {}; -struct nanogram : prefixed_unit {}; -struct microgram : prefixed_unit {}; -struct milligram : prefixed_unit {}; -struct centigram : prefixed_unit {}; -struct decigram : prefixed_unit {}; -struct decagram : prefixed_unit {}; -struct hectogram : prefixed_unit {}; -struct kilogram : prefixed_unit {}; -struct megagram : prefixed_unit {}; -struct gigagram : prefixed_unit {}; -struct teragram : prefixed_unit {}; -struct petagram : prefixed_unit {}; -struct exagram : prefixed_unit {}; -struct zettagram : prefixed_unit {}; -struct yottagram : prefixed_unit {}; - -struct tonne : alias_unit {}; -struct yoctotonne : prefixed_alias_unit {}; -struct zeptotonne : prefixed_alias_unit {}; -struct attotonne : prefixed_alias_unit {}; -struct femtotonne : prefixed_alias_unit {}; -struct picotonne : prefixed_alias_unit {}; -struct nanotonne : prefixed_alias_unit {}; -struct microtonne : prefixed_alias_unit {}; -struct millitonne : prefixed_alias_unit {}; -struct centitonne : prefixed_unit {}; -struct decitonne : prefixed_unit {}; -struct decatonne : prefixed_unit {}; -struct hectotonne : prefixed_unit {}; -struct kilotonne : prefixed_alias_unit {}; -struct megatonne : prefixed_alias_unit {}; -struct gigatonne : prefixed_alias_unit {}; -struct teratonne : prefixed_alias_unit {}; -struct petatonne : prefixed_alias_unit {}; -struct exatonne : prefixed_alias_unit {}; -struct zettatonne : prefixed_unit {}; -struct yottatonne : prefixed_unit {}; - -struct dalton : - named_scaled_unit() * mag_power<10, -27>(), - kilogram> {}; - -struct dim_mass : isq::dim_mass {}; - -template U, Representation Rep = double> -using mass = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// g -constexpr auto operator"" _q_g(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_g(long double l) { return mass(l); } - -// yg -constexpr auto operator"" _q_yg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_yg(long double l) { return mass(l); } - -// zg -constexpr auto operator"" _q_zg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_zg(long double l) { return mass(l); } - -// ag -constexpr auto operator"" _q_ag(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ag(long double l) { return mass(l); } - -// fg -constexpr auto operator"" _q_fg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_fg(long double l) { return mass(l); } - -// pg -constexpr auto operator"" _q_pg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_pg(long double l) { return mass(l); } - -// ng -constexpr auto operator"" _q_ng(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ng(long double l) { return mass(l); } - -// ug -constexpr auto operator"" _q_ug(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ug(long double l) { return mass(l); } - -// mg -constexpr auto operator"" _q_mg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_mg(long double l) { return mass(l); } - -// cg -constexpr auto operator"" _q_cg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_cg(long double l) { return mass(l); } - -// dg -constexpr auto operator"" _q_dg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dg(long double l) { return mass(l); } - -// dag -constexpr auto operator"" _q_dag(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dag(long double l) { return mass(l); } - -// hg -constexpr auto operator"" _q_hg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_hg(long double l) { return mass(l); } - -// kg -constexpr auto operator"" _q_kg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_kg(long double l) { return mass(l); } - -// Mg -constexpr auto operator"" _q_Mg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Mg(long double l) { return mass(l); } - -// Gg -constexpr auto operator"" _q_Gg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Gg(long double l) { return mass(l); } - -// Tg -constexpr auto operator"" _q_Tg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Tg(long double l) { return mass(l); } - -// Pg -constexpr auto operator"" _q_Pg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Pg(long double l) { return mass(l); } - -// Eg -constexpr auto operator"" _q_Eg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Eg(long double l) { return mass(l); } - -// Zg -constexpr auto operator"" _q_Zg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Zg(long double l) { return mass(l); } - -// Yg -constexpr auto operator"" _q_Yg(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Yg(long double l) { return mass(l); } - -// t -constexpr auto operator"" _q_t(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_t(long double l) { return mass(l); } - -// yt -constexpr auto operator"" _q_yt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_yt(long double l) { return mass(l); } - -// zt -constexpr auto operator"" _q_zt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_zt(long double l) { return mass(l); } - -// at -constexpr auto operator"" _q_at(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_at(long double l) { return mass(l); } - -// TODO Collides with foot -// ft -// constexpr auto operator"" _q_ft(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return -// mass(static_cast(l)); } constexpr auto operator"" _q_ft(long double l) { -// return mass(l); } - -// pt -constexpr auto operator"" _q_pt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_pt(long double l) { return mass(l); } - -// nt -constexpr auto operator"" _q_nt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_nt(long double l) { return mass(l); } - -// ut -constexpr auto operator"" _q_ut(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ut(long double l) { return mass(l); } - -// mt -constexpr auto operator"" _q_mt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_mt(long double l) { return mass(l); } - -// ct -constexpr auto operator"" _q_ct(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ct(long double l) { return mass(l); } - -// dt -constexpr auto operator"" _q_dt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dt(long double l) { return mass(l); } - -// dat -constexpr auto operator"" _q_dat(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_dat(long double l) { return mass(l); } - -// ht -constexpr auto operator"" _q_ht(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_ht(long double l) { return mass(l); } - -// kt -constexpr auto operator"" _q_kt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_kt(long double l) { return mass(l); } - -// Mt -constexpr auto operator"" _q_Mt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Mt(long double l) { return mass(l); } - -// Gt -constexpr auto operator"" _q_Gt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Gt(long double l) { return mass(l); } - -// Tt -constexpr auto operator"" _q_Tt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Tt(long double l) { return mass(l); } - -// Pt -constexpr auto operator"" _q_Pt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Pt(long double l) { return mass(l); } - -// Et -constexpr auto operator"" _q_Et(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Et(long double l) { return mass(l); } - -// Zt -constexpr auto operator"" _q_Zt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Zt(long double l) { return mass(l); } - -// Yt -constexpr auto operator"" _q_Yt(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Yt(long double l) { return mass(l); } - -// Da -constexpr auto operator"" _q_Da(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return mass(static_cast(l)); -} -constexpr auto operator"" _q_Da(long double l) { return mass(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace mass_references { - -inline constexpr auto g = reference{}; -inline constexpr auto yg = reference{}; -inline constexpr auto zg = reference{}; -inline constexpr auto ag = reference{}; -inline constexpr auto fg = reference{}; -inline constexpr auto pg = reference{}; -inline constexpr auto ng = reference{}; -inline constexpr auto ug = reference{}; -inline constexpr auto mg = reference{}; -inline constexpr auto cg = reference{}; -inline constexpr auto dg = reference{}; -inline constexpr auto dag = reference{}; -inline constexpr auto hg = reference{}; -inline constexpr auto kg = reference{}; -inline constexpr auto Mg = reference{}; -inline constexpr auto Gg = reference{}; -inline constexpr auto Tg = reference{}; -inline constexpr auto Pg = reference{}; -inline constexpr auto Eg = reference{}; -inline constexpr auto Zg = reference{}; -inline constexpr auto Yg = reference{}; - -inline constexpr auto t = reference{}; -inline constexpr auto yt = reference{}; -inline constexpr auto zt = reference{}; -inline constexpr auto at = reference{}; -inline constexpr auto ft = reference{}; -inline constexpr auto pt = reference{}; -inline constexpr auto nt = reference{}; -inline constexpr auto ut = reference{}; -inline constexpr auto mt = reference{}; -inline constexpr auto ct = reference{}; -inline constexpr auto dt = reference{}; -inline constexpr auto dat = reference{}; -inline constexpr auto ht = reference{}; -inline constexpr auto kt = reference{}; -inline constexpr auto Mt = reference{}; -inline constexpr auto Gt = reference{}; -inline constexpr auto Tt = reference{}; -inline constexpr auto Pt = reference{}; -inline constexpr auto Et = reference{}; -inline constexpr auto Zt = reference{}; -inline constexpr auto Yt = reference{}; -inline constexpr auto Da = reference{}; - -} // namespace mass_references - -namespace references { - -using namespace mass_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline mass { - -template -using g = units::isq::si::mass; -template -using yg = units::isq::si::mass; -template -using zg = units::isq::si::mass; -template -using ag = units::isq::si::mass; -template -using fg = units::isq::si::mass; -template -using pg = units::isq::si::mass; -template -using ng = units::isq::si::mass; -template -using ug = units::isq::si::mass; -template -using mg = units::isq::si::mass; -template -using cg = units::isq::si::mass; -template -using dg = units::isq::si::mass; -template -using dag = units::isq::si::mass; -template -using hg = units::isq::si::mass; -template -using kg = units::isq::si::mass; -template -using Mg = units::isq::si::mass; -template -using Gg = units::isq::si::mass; -template -using Tg = units::isq::si::mass; -template -using Pg = units::isq::si::mass; -template -using Eg = units::isq::si::mass; -template -using Zg = units::isq::si::mass; -template -using Yg = units::isq::si::mass; - -template -using t = units::isq::si::mass; -template -using yt = units::isq::si::mass; -template -using zt = units::isq::si::mass; -template -using at = units::isq::si::mass; -template -using ft = units::isq::si::mass; -template -using pt = units::isq::si::mass; -template -using nt = units::isq::si::mass; -template -using ut = units::isq::si::mass; -template -using mt = units::isq::si::mass; -template -using ct = units::isq::si::mass; -template -using dt = units::isq::si::mass; -template -using dat = units::isq::si::mass; -template -using ht = units::isq::si::mass; -template -using kt = units::isq::si::mass; -template -using Mt = units::isq::si::mass; -template -using Gt = units::isq::si::mass; -template -using Tt = units::isq::si::mass; -template -using Pt = units::isq::si::mass; -template -using Et = units::isq::si::mass; -template -using Zt = units::isq::si::mass; -template -using Yt = units::isq::si::mass; -template -using Da = units::isq::si::mass; - -} // namespace units::aliases::isq::si::inline mass - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/molar_energy.h b/src/systems/si/include/units/isq/si/molar_energy.h deleted file mode 100644 index 02cb9072..00000000 --- a/src/systems/si/include/units/isq/si/molar_energy.h +++ /dev/null @@ -1,73 +0,0 @@ -// The MIT License (MIT) -// -// Hopyright (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 SOHTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OH ANY KIND, EXPRESS OR -// IMPLIED, INHLUDING BUT NOT LIMITED TO THE WARRANTIES OH MERHHANTABILITY, -// HITNESS HOR A PARTIHULAR PURPOSE AND NONINHRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR HOPYRIGHT HOLDERS BE LIABLE HOR ANY HLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN AHTION OH HONTRAHT, TORT OR OTHERWISE, ARISING HROM, -// OUT OH OR IN HONNEHTION WITH THE SOHTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOHTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct joule_per_mole : derived_unit {}; - -struct dim_molar_energy : - isq::dim_molar_energy {}; - -template U, Representation Rep = double> -using molar_energy = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// J/mol -constexpr auto operator"" _q_J_per_mol(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return molar_energy(static_cast(l)); -} -constexpr auto operator"" _q_J_per_mol(long double l) { return molar_energy(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline molar_energy { - -template -using J_per_mol = units::isq::si::molar_energy; - -} // namespace units::aliases::isq::si::inline molar_energy - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/momentum.h b/src/systems/si/include/units/isq/si/momentum.h deleted file mode 100644 index 46446c92..00000000 --- a/src/systems/si/include/units/isq/si/momentum.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct kilogram_metre_per_second : derived_unit {}; -struct dim_momentum : isq::dim_momentum {}; - -template U, Representation Rep = double> -using momentum = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// kg*m/s -constexpr auto operator"" _q_kg_m_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return momentum(static_cast(l)); -} -constexpr auto operator"" _q_kg_m_per_s(long double l) { return momentum(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline momentum { - -template -using kg_m_per_s = units::isq::si::momentum; - -} // namespace units::aliases::isq::si::inline momentum - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/permeability.h b/src/systems/si/include/units/isq/si/permeability.h deleted file mode 100644 index 5b961b21..00000000 --- a/src/systems/si/include/units/isq/si/permeability.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Hopyright (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 SOHTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OH ANY KIND, EXPRESS OR -// IMPLIED, INHLUDING BUT NOT LIMITED TO THE WARRANTIES OH MERHHANTABILITY, -// HITNESS HOR A PARTIHULAR PURPOSE AND NONINHRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR HOPYRIGHT HOLDERS BE LIABLE HOR ANY HLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN AHTION OH HONTRAHT, TORT OR OTHERWISE, ARISING HROM, -// OUT OH OR IN HONNEHTION WITH THE SOHTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOHTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct henry_per_metre : derived_unit {}; - -struct dim_permeability : isq::dim_permeability {}; - -template U, Representation Rep = double> -using permeability = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// H/m -constexpr auto operator"" _q_H_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return permeability(static_cast(l)); -} -constexpr auto operator"" _q_H_per_m(long double l) { return permeability(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline permeability { - -template -using H_per_m = units::isq::si::permeability; - -} // namespace units::aliases::isq::si::inline permeability - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/permittivity.h b/src/systems/si/include/units/isq/si/permittivity.h deleted file mode 100644 index cd99be6c..00000000 --- a/src/systems/si/include/units/isq/si/permittivity.h +++ /dev/null @@ -1,71 +0,0 @@ -// The MIT License (MIT) -// -// Fopyright (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, INFLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERFHANTABILITY, -// FITNESS FOR A PARTIFULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR FOPYRIGHT HOLDERS BE LIABLE FOR ANY FLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN AFTION OF FONTRAFT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN FONNEFTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct farad_per_metre : derived_unit {}; - -struct dim_permittivity : isq::dim_permittivity {}; - -template U, Representation Rep = double> -using permittivity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// F/m -constexpr auto operator"" _q_F_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return permittivity(static_cast(l)); -} -constexpr auto operator"" _q_F_per_m(long double l) { return permittivity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline permittivity { - -template -using F_per_m = units::isq::si::permittivity; - -} // namespace units::aliases::isq::si::inline permittivity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/power.h b/src/systems/si/include/units/isq/si/power.h deleted file mode 100644 index d95d5c30..00000000 --- a/src/systems/si/include/units/isq/si/power.h +++ /dev/null @@ -1,280 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct watt : named_unit {}; -struct yoctowatt : prefixed_unit {}; -struct zeptowatt : prefixed_unit {}; -struct attowatt : prefixed_unit {}; -struct femtowatt : prefixed_unit {}; -struct picowatt : prefixed_unit {}; -struct nanowatt : prefixed_unit {}; -struct microwatt : prefixed_unit {}; -struct milliwatt : prefixed_unit {}; -struct kilowatt : prefixed_unit {}; -struct megawatt : prefixed_unit {}; -struct gigawatt : prefixed_unit {}; -struct terawatt : prefixed_unit {}; -struct petawatt : prefixed_unit {}; -struct exawatt : prefixed_unit {}; -struct zettawatt : prefixed_unit {}; -struct yottawatt : prefixed_unit {}; - -struct dim_power : isq::dim_power {}; - -template U, Representation Rep = double> -using power = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// W -constexpr auto operator"" _q_W(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_W(long double l) { return power(l); } - -// yW -constexpr auto operator"" _q_yW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_yW(long double l) { return power(l); } - -// zW -constexpr auto operator"" _q_zW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_zW(long double l) { return power(l); } - -// aW -constexpr auto operator"" _q_aW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_aW(long double l) { return power(l); } - -// fW -constexpr auto operator"" _q_fW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_fW(long double l) { return power(l); } - -// pW -constexpr auto operator"" _q_pW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_pW(long double l) { return power(l); } - -// nW -constexpr auto operator"" _q_nW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_nW(long double l) { return power(l); } - -// uW -constexpr auto operator"" _q_uW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_uW(long double l) { return power(l); } - -// mW -constexpr auto operator"" _q_mW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_mW(long double l) { return power(l); } - -// kW -constexpr auto operator"" _q_kW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_kW(long double l) { return power(l); } - -// MW -constexpr auto operator"" _q_MW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_MW(long double l) { return power(l); } - -// GW -constexpr auto operator"" _q_GW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_GW(long double l) { return power(l); } - -// TW -constexpr auto operator"" _q_TW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_TW(long double l) { return power(l); } - -// PW -constexpr auto operator"" _q_PW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_PW(long double l) { return power(l); } - -// EW -constexpr auto operator"" _q_EW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_EW(long double l) { return power(l); } - -// ZW -constexpr auto operator"" _q_ZW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_ZW(long double l) { return power(l); } - -// YW -constexpr auto operator"" _q_YW(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return power(static_cast(l)); -} -constexpr auto operator"" _q_YW(long double l) { return power(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace power_references { - -inline constexpr auto W = reference{}; -inline constexpr auto yW = reference{}; -inline constexpr auto zW = reference{}; -inline constexpr auto aW = reference{}; -inline constexpr auto fW = reference{}; -inline constexpr auto pW = reference{}; -inline constexpr auto nW = reference{}; -inline constexpr auto uW = reference{}; -inline constexpr auto mW = reference{}; -inline constexpr auto kW = reference{}; -inline constexpr auto MW = reference{}; -inline constexpr auto GW = reference{}; -inline constexpr auto TW = reference{}; -inline constexpr auto PW = reference{}; -inline constexpr auto EW = reference{}; -inline constexpr auto ZW = reference{}; -inline constexpr auto YW = reference{}; - -} // namespace power_references - -namespace references { - -using namespace power_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline power { - -template -using W = units::isq::si::power; -template -using yW = units::isq::si::power; -template -using zW = units::isq::si::power; -template -using aW = units::isq::si::power; -template -using fW = units::isq::si::power; -template -using pW = units::isq::si::power; -template -using nW = units::isq::si::power; -template -using uW = units::isq::si::power; -template -using mW = units::isq::si::power; -template -using kW = units::isq::si::power; -template -using MW = units::isq::si::power; -template -using GW = units::isq::si::power; -template -using TW = units::isq::si::power; -template -using PW = units::isq::si::power; -template -using EW = units::isq::si::power; -template -using ZW = units::isq::si::power; -template -using YW = units::isq::si::power; - -} // namespace units::aliases::isq::si::inline power - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/prefixes.h b/src/systems/si/include/units/isq/si/prefixes.h deleted file mode 100644 index 66142605..00000000 --- a/src/systems/si/include/units/isq/si/prefixes.h +++ /dev/null @@ -1,52 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units::isq::si { - -// clang-format off -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()> {}; -// clang-format on - -} // namespace units::isq::si diff --git a/src/systems/si/include/units/isq/si/pressure.h b/src/systems/si/include/units/isq/si/pressure.h deleted file mode 100644 index 86bed5d2..00000000 --- a/src/systems/si/include/units/isq/si/pressure.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct pascal : named_unit {}; -struct yoctopascal : prefixed_unit {}; -struct zeptopascal : prefixed_unit {}; -struct attopascal : prefixed_unit {}; -struct femtopascal : prefixed_unit {}; -struct picopascal : prefixed_unit {}; -struct nanopascal : prefixed_unit {}; -struct micropascal : prefixed_unit {}; -struct millipascal : prefixed_unit {}; -struct centipascal : prefixed_unit {}; -struct decipascal : prefixed_unit {}; -struct decapascal : prefixed_unit {}; -struct hectopascal : prefixed_unit {}; -struct kilopascal : prefixed_unit {}; -struct megapascal : prefixed_unit {}; -struct gigapascal : prefixed_unit {}; -struct terapascal : prefixed_unit {}; -struct petapascal : prefixed_unit {}; -struct exapascal : prefixed_unit {}; -struct zettapascal : prefixed_unit {}; -struct yottapascal : prefixed_unit {}; - -struct dim_pressure : isq::dim_pressure {}; - -template U, Representation Rep = double> -using pressure = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Pa -constexpr auto operator"" _q_Pa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_Pa(long double l) { return pressure(l); } - -// yPa -constexpr auto operator"" _q_yPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_yPa(long double l) { return pressure(l); } - -// zPa -constexpr auto operator"" _q_zPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_zPa(long double l) { return pressure(l); } - -// aPa -constexpr auto operator"" _q_aPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_aPa(long double l) { return pressure(l); } - -// fPa -constexpr auto operator"" _q_fPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_fPa(long double l) { return pressure(l); } - -// pPa -constexpr auto operator"" _q_pPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_pPa(long double l) { return pressure(l); } - -// nPa -constexpr auto operator"" _q_nPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_nPa(long double l) { return pressure(l); } - -// uPa -constexpr auto operator"" _q_uPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_uPa(long double l) { return pressure(l); } - -// mPa -constexpr auto operator"" _q_mPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_mPa(long double l) { return pressure(l); } - -// cPa -constexpr auto operator"" _q_cPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_cPa(long double l) { return pressure(l); } - -// dPa -constexpr auto operator"" _q_dPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_dPa(long double l) { return pressure(l); } - -// daPa -constexpr auto operator"" _q_daPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_daPa(long double l) { return pressure(l); } - -// hPa -constexpr auto operator"" _q_hPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_hPa(long double l) { return pressure(l); } - -// kPa -constexpr auto operator"" _q_kPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_kPa(long double l) { return pressure(l); } - -// MPa -constexpr auto operator"" _q_MPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_MPa(long double l) { return pressure(l); } - -// GPa -constexpr auto operator"" _q_GPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_GPa(long double l) { return pressure(l); } - -// TPa -constexpr auto operator"" _q_TPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_TPa(long double l) { return pressure(l); } - -// PPa -constexpr auto operator"" _q_PPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_PPa(long double l) { return pressure(l); } - -// EPa -constexpr auto operator"" _q_EPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_EPa(long double l) { return pressure(l); } - -// ZPa -constexpr auto operator"" _q_ZPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_ZPa(long double l) { return pressure(l); } - -// YPa -constexpr auto operator"" _q_YPa(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return pressure(static_cast(l)); -} -constexpr auto operator"" _q_YPa(long double l) { return pressure(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace pressure_references { - -inline constexpr auto Pa = reference{}; -inline constexpr auto yPa = reference{}; -inline constexpr auto zPa = reference{}; -inline constexpr auto aPa = reference{}; -inline constexpr auto fPa = reference{}; -inline constexpr auto pPa = reference{}; -inline constexpr auto nPa = reference{}; -inline constexpr auto uPa = reference{}; -inline constexpr auto mPa = reference{}; -inline constexpr auto cPa = reference{}; -inline constexpr auto dPa = reference{}; -inline constexpr auto daPa = reference{}; -inline constexpr auto hPa = reference{}; -inline constexpr auto kPa = reference{}; -inline constexpr auto MPa = reference{}; -inline constexpr auto GPa = reference{}; -inline constexpr auto TPa = reference{}; -inline constexpr auto PPa = reference{}; -inline constexpr auto EPa = reference{}; -inline constexpr auto ZPa = reference{}; -inline constexpr auto YPa = reference{}; - -} // namespace pressure_references - -namespace references { - -using namespace pressure_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline pressure { - -template -using Pa = units::isq::si::pressure; -template -using yPa = units::isq::si::pressure; -template -using zPa = units::isq::si::pressure; -template -using aPa = units::isq::si::pressure; -template -using fPa = units::isq::si::pressure; -template -using pPa = units::isq::si::pressure; -template -using nPa = units::isq::si::pressure; -template -using uPa = units::isq::si::pressure; -template -using mPa = units::isq::si::pressure; -template -using cPa = units::isq::si::pressure; -template -using dPa = units::isq::si::pressure; -template -using daPa = units::isq::si::pressure; -template -using hPa = units::isq::si::pressure; -template -using kPa = units::isq::si::pressure; -template -using MPa = units::isq::si::pressure; -template -using GPa = units::isq::si::pressure; -template -using TPa = units::isq::si::pressure; -template -using PPa = units::isq::si::pressure; -template -using EPa = units::isq::si::pressure; -template -using ZPa = units::isq::si::pressure; -template -using YPa = units::isq::si::pressure; - -} // namespace units::aliases::isq::si::inline pressure - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/radioactivity.h b/src/systems/si/include/units/isq/si/radioactivity.h deleted file mode 100644 index d46c81e4..00000000 --- a/src/systems/si/include/units/isq/si/radioactivity.h +++ /dev/null @@ -1,327 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct becquerel : named_unit {}; -struct yoctobecquerel : prefixed_unit {}; -struct zeptobecquerel : prefixed_unit {}; -struct attobecquerel : prefixed_unit {}; -struct femtobecquerel : prefixed_unit {}; -struct picobecquerel : prefixed_unit {}; -struct nanobecquerel : prefixed_unit {}; -struct microbecquerel : prefixed_unit {}; -struct millibecquerel : prefixed_unit {}; -struct centibecquerel : prefixed_unit {}; -struct decibecquerel : prefixed_unit {}; -struct decabecquerel : prefixed_unit {}; -struct hectobecquerel : prefixed_unit {}; -struct kilobecquerel : prefixed_unit {}; -struct megabecquerel : prefixed_unit {}; -struct gigabecquerel : prefixed_unit {}; -struct terabecquerel : prefixed_unit {}; -struct petabecquerel : prefixed_unit {}; -struct exabecquerel : prefixed_unit {}; -struct zettabecquerel : prefixed_unit {}; -struct yottabecquerel : prefixed_unit {}; - -struct dim_radioactivity : isq::dim_radioactivity {}; - -template U, Representation Rep = double> -using radioactivity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Bq -constexpr auto operator"" _q_Bq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_Bq(long double l) { return radioactivity(l); } - -// yBq -constexpr auto operator"" _q_yBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_yBq(long double l) { return radioactivity(l); } - -// zBq -constexpr auto operator"" _q_zBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_zBq(long double l) { return radioactivity(l); } - -// aBq -constexpr auto operator"" _q_aBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_aBq(long double l) { return radioactivity(l); } - -// fBq -constexpr auto operator"" _q_fBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_fBq(long double l) { return radioactivity(l); } - -// pBq -constexpr auto operator"" _q_pBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_pBq(long double l) { return radioactivity(l); } - -// nBq -constexpr auto operator"" _q_nBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_nBq(long double l) { return radioactivity(l); } - -// uBq -constexpr auto operator"" _q_uBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_uBq(long double l) { return radioactivity(l); } - -// mBq -constexpr auto operator"" _q_mBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_mBq(long double l) { return radioactivity(l); } - -// cBq -constexpr auto operator"" _q_cBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_cBq(long double l) { return radioactivity(l); } - -// dBq -constexpr auto operator"" _q_dBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_dBq(long double l) { return radioactivity(l); } - -// daBq -constexpr auto operator"" _q_daBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_daBq(long double l) { return radioactivity(l); } - -// hBq -constexpr auto operator"" _q_hBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_hBq(long double l) { return radioactivity(l); } - -// kBq -constexpr auto operator"" _q_kBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_kBq(long double l) { return radioactivity(l); } - -// MBq -constexpr auto operator"" _q_MBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_MBq(long double l) { return radioactivity(l); } - -// GBq -constexpr auto operator"" _q_GBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_GBq(long double l) { return radioactivity(l); } - -// TBq -constexpr auto operator"" _q_TBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_TBq(long double l) { return radioactivity(l); } - -// PBq -constexpr auto operator"" _q_PBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_PBq(long double l) { return radioactivity(l); } - -// EBq -constexpr auto operator"" _q_EBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_EBq(long double l) { return radioactivity(l); } - -// ZBq -constexpr auto operator"" _q_ZBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_ZBq(long double l) { return radioactivity(l); } - -// YBq -constexpr auto operator"" _q_YBq(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return radioactivity(static_cast(l)); -} -constexpr auto operator"" _q_YBq(long double l) { return radioactivity(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace radioactivity_references { - -inline constexpr auto Bq = reference{}; -inline constexpr auto yBq = reference{}; -inline constexpr auto zBq = reference{}; -inline constexpr auto aBq = reference{}; -inline constexpr auto fBq = reference{}; -inline constexpr auto pBq = reference{}; -inline constexpr auto nBq = reference{}; -inline constexpr auto uBq = reference{}; -inline constexpr auto mBq = reference{}; -inline constexpr auto cBq = reference{}; -inline constexpr auto dBq = reference{}; -inline constexpr auto daBq = reference{}; -inline constexpr auto hBq = reference{}; -inline constexpr auto kBq = reference{}; -inline constexpr auto MBq = reference{}; -inline constexpr auto GBq = reference{}; -inline constexpr auto TBq = reference{}; -inline constexpr auto PBq = reference{}; -inline constexpr auto EBq = reference{}; -inline constexpr auto ZBq = reference{}; -inline constexpr auto YBq = reference{}; - -} // namespace radioactivity_references - -namespace references { - -using namespace radioactivity_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline radioactivity { - -template -using Bq = units::isq::si::radioactivity; -template -using yBq = units::isq::si::radioactivity; -template -using zBq = units::isq::si::radioactivity; -template -using aBq = units::isq::si::radioactivity; -template -using fBq = units::isq::si::radioactivity; -template -using pBq = units::isq::si::radioactivity; -template -using nBq = units::isq::si::radioactivity; -template -using uBq = units::isq::si::radioactivity; -template -using mBq = units::isq::si::radioactivity; -template -using cBq = units::isq::si::radioactivity; -template -using dBq = units::isq::si::radioactivity; -template -using daBq = units::isq::si::radioactivity; -template -using hBq = units::isq::si::radioactivity; -template -using kBq = units::isq::si::radioactivity; -template -using MBq = units::isq::si::radioactivity; -template -using GBq = units::isq::si::radioactivity; -template -using TBq = units::isq::si::radioactivity; -template -using PBq = units::isq::si::radioactivity; -template -using EBq = units::isq::si::radioactivity; -template -using ZBq = units::isq::si::radioactivity; -template -using YBq = units::isq::si::radioactivity; - -} // namespace units::aliases::isq::si::inline radioactivity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/resistance.h b/src/systems/si/include/units/isq/si/resistance.h deleted file mode 100644 index ea57ed61..00000000 --- a/src/systems/si/include/units/isq/si/resistance.h +++ /dev/null @@ -1,281 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct ohm : named_unit {}; -struct yoctoohm : prefixed_unit {}; -struct zeptoohm : prefixed_unit {}; -struct attoohm : prefixed_unit {}; -struct femtoohm : prefixed_unit {}; -struct picoohm : prefixed_unit {}; -struct nanoohm : prefixed_unit {}; -struct microohm : prefixed_unit {}; -struct milliohm : prefixed_unit {}; -struct kiloohm : prefixed_unit {}; -struct megaohm : prefixed_unit {}; -struct gigaohm : prefixed_unit {}; -struct teraohm : prefixed_unit {}; -struct petaohm : prefixed_unit {}; -struct exaohm : prefixed_unit {}; -struct zettaohm : prefixed_unit {}; -struct yottaohm : prefixed_unit {}; - -struct dim_resistance : isq::dim_resistance {}; - -template U, Representation Rep = double> -using resistance = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// R -constexpr auto operator"" _q_R(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_R(long double l) { return resistance(l); } - -// yR -constexpr auto operator"" _q_yR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_yR(long double l) { return resistance(l); } - -// zR -constexpr auto operator"" _q_zR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_zR(long double l) { return resistance(l); } - -// aR -constexpr auto operator"" _q_aR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_aR(long double l) { return resistance(l); } - -// fR -constexpr auto operator"" _q_fR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_fR(long double l) { return resistance(l); } - -// pR -constexpr auto operator"" _q_pR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_pR(long double l) { return resistance(l); } - -// nR -constexpr auto operator"" _q_nR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_nR(long double l) { return resistance(l); } - -// uR -constexpr auto operator"" _q_uR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_uR(long double l) { return resistance(l); } - -// mR -constexpr auto operator"" _q_mR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_mR(long double l) { return resistance(l); } - -// kR -constexpr auto operator"" _q_kR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_kR(long double l) { return resistance(l); } - -// MR -constexpr auto operator"" _q_MR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_MR(long double l) { return resistance(l); } - -// GR -constexpr auto operator"" _q_GR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_GR(long double l) { return resistance(l); } - -// TR -constexpr auto operator"" _q_TR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_TR(long double l) { return resistance(l); } - -// PR -constexpr auto operator"" _q_PR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_PR(long double l) { return resistance(l); } - -// ER -constexpr auto operator"" _q_ER(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_ER(long double l) { return resistance(l); } - -// ZR -constexpr auto operator"" _q_ZR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_ZR(long double l) { return resistance(l); } - -// YR -constexpr auto operator"" _q_YR(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return resistance(static_cast(l)); -} -constexpr auto operator"" _q_YR(long double l) { return resistance(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace resistance_references { - -inline constexpr auto R = reference{}; -inline constexpr auto yR = reference{}; -inline constexpr auto zR = reference{}; -inline constexpr auto aR = reference{}; -inline constexpr auto fR = reference{}; -inline constexpr auto pR = reference{}; -inline constexpr auto nR = reference{}; -inline constexpr auto uR = reference{}; -inline constexpr auto mR = reference{}; -inline constexpr auto kR = reference{}; -inline constexpr auto MR = reference{}; -inline constexpr auto GR = reference{}; -inline constexpr auto TR = reference{}; -inline constexpr auto PR = reference{}; -inline constexpr auto ER = reference{}; -inline constexpr auto ZR = reference{}; -inline constexpr auto YR = reference{}; - -} // namespace resistance_references - -namespace references { - -using namespace resistance_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline resistance { - -template -using R = units::isq::si::resistance; -template -using yR = units::isq::si::resistance; -template -using zR = units::isq::si::resistance; -template -using aR = units::isq::si::resistance; -template -using fR = units::isq::si::resistance; -template -using pR = units::isq::si::resistance; -template -using nR = units::isq::si::resistance; -template -using uR = units::isq::si::resistance; -template -using mR = units::isq::si::resistance; -template -using kR = units::isq::si::resistance; -template -using MR = units::isq::si::resistance; -template -using GR = units::isq::si::resistance; -template -using TR = units::isq::si::resistance; -template -using PR = units::isq::si::resistance; -template -using ER = units::isq::si::resistance; -template -using ZR = units::isq::si::resistance; -template -using YR = units::isq::si::resistance; - -} // namespace units::aliases::isq::si::inline resistance - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/si.h b/src/systems/si/include/units/isq/si/si.h deleted file mode 100644 index 683047fb..00000000 --- a/src/systems/si/include/units/isq/si/si.h +++ /dev/null @@ -1,78 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -// TODO Add when downcasting issue is solved (collides with pressure) -// #include - -// TODO Add when downcasting issue is solved (collides with frequency) -// #include diff --git a/src/systems/si/include/units/isq/si/speed.h b/src/systems/si/include/units/isq/si/speed.h deleted file mode 100644 index 8bcc17b7..00000000 --- a/src/systems/si/include/units/isq/si/speed.h +++ /dev/null @@ -1,82 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct metre_per_second : derived_unit {}; -struct dim_speed : isq::dim_speed {}; - -struct kilometre_per_hour : derived_scaled_unit {}; - -template U, Representation Rep = double> -using speed = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m/s -constexpr auto operator"" _q_m_per_s(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_m_per_s(long double l) { return speed(l); } - -// km/h -constexpr auto operator"" _q_km_per_h(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return speed(static_cast(l)); -} -constexpr auto operator"" _q_km_per_h(long double l) { return speed(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -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; - -} // namespace units::aliases::isq::si::inline speed - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/surface_tension.h b/src/systems/si/include/units/isq/si/surface_tension.h deleted file mode 100644 index 382b133f..00000000 --- a/src/systems/si/include/units/isq/si/surface_tension.h +++ /dev/null @@ -1,70 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct newton_per_metre : derived_unit {}; - -struct dim_surface_tension : isq::dim_surface_tension {}; - -template U, Representation Rep = double> -using surface_tension = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// N/m -constexpr auto operator"" _q_N_per_m(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return surface_tension(static_cast(l)); -} -constexpr auto operator"" _q_N_per_m(long double l) { return surface_tension(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline surface_tension { - -template -using N_per_m = units::isq::si::surface_tension; - -} // namespace units::aliases::isq::si::inline surface_tension - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/thermal_conductivity.h b/src/systems/si/include/units/isq/si/thermal_conductivity.h deleted file mode 100644 index 64177b52..00000000 --- a/src/systems/si/include/units/isq/si/thermal_conductivity.h +++ /dev/null @@ -1,76 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct watt_per_metre_kelvin : derived_unit {}; - -struct dim_thermal_conductivity : - isq::dim_thermal_conductivity {}; - -template U, Representation Rep = double> -using thermal_conductivity = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// W/(m K) -constexpr auto operator"" _q_W_per_m_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return thermal_conductivity(static_cast(l)); -} -constexpr auto operator"" _q_W_per_m_K(long double l) -{ - return thermal_conductivity(l); -} - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline thermal_conductivity { - -template -using W_per_m_K = units::isq::si::thermal_conductivity; - -} // namespace units::aliases::isq::si::inline thermal_conductivity - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/thermodynamic_temperature.h b/src/systems/si/include/units/isq/si/thermodynamic_temperature.h deleted file mode 100644 index cc0e3206..00000000 --- a/src/systems/si/include/units/isq/si/thermodynamic_temperature.h +++ /dev/null @@ -1,87 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct kelvin : named_unit {}; - -struct dim_thermodynamic_temperature : isq::dim_thermodynamic_temperature {}; - -template U, Representation Rep = double> -using thermodynamic_temperature = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// K -constexpr auto operator"" _q_K(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return thermodynamic_temperature(static_cast(l)); -} -constexpr auto operator"" _q_K(long double l) { return thermodynamic_temperature(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace thermodynamic_temperature_references { - -inline constexpr auto K = reference{}; - -} // namespace thermodynamic_temperature_references - -namespace references { - -using namespace thermodynamic_temperature_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline thermodynamic_temperature { - -template -using K = units::isq::si::thermodynamic_temperature; - -} // namespace units::aliases::isq::si::inline thermodynamic_temperature - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/time.h b/src/systems/si/include/units/isq/si/time.h deleted file mode 100644 index f023377a..00000000 --- a/src/systems/si/include/units/isq/si/time.h +++ /dev/null @@ -1,219 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units::isq::si { - -struct second : named_unit {}; -struct yoctosecond : prefixed_unit {}; -struct zeptosecond : prefixed_unit {}; -struct attosecond : prefixed_unit {}; -struct femtosecond : prefixed_unit {}; -struct picosecond : prefixed_unit {}; -struct nanosecond : prefixed_unit {}; -struct microsecond : prefixed_unit {}; -struct millisecond : prefixed_unit {}; -struct minute : named_scaled_unit(), second> {}; -struct hour : named_scaled_unit(), minute> {}; -struct day : named_scaled_unit(), hour> {}; - -struct dim_time : isq::dim_time {}; - -template U, Representation Rep = double> -using time = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// ys -constexpr auto operator"" _q_ys(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ys(long double l) { return time(l); } - -// zs -constexpr auto operator"" _q_zs(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_zs(long double l) { return time(l); } - -// as -constexpr auto operator"" _q_as(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_as(long double l) { return time(l); } - -// fs -constexpr auto operator"" _q_fs(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_fs(long double l) { return time(l); } - -// ps -constexpr auto operator"" _q_ps(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ps(long double l) { return time(l); } - -// ns -constexpr auto operator"" _q_ns(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ns(long double l) { return time(l); } - -// us -constexpr auto operator"" _q_us(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_us(long double l) { return time(l); } - -// ms -constexpr auto operator"" _q_ms(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_ms(long double l) { return time(l); } - -// s -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); } - -// min -constexpr auto operator"" _q_min(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_min(long double l) { return time(l); } - -// h -constexpr auto operator"" _q_h(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_h(long double l) { return time(l); } - -// d -constexpr auto operator"" _q_d(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return time(static_cast(l)); -} -constexpr auto operator"" _q_d(long double l) { return time(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace time_references { - -inline constexpr auto ys = reference{}; -inline constexpr auto zs = reference{}; -inline constexpr auto as = reference{}; -inline constexpr auto fs = reference{}; -inline constexpr auto ps = reference{}; -inline constexpr auto ns = reference{}; -inline constexpr auto us = reference{}; -inline constexpr auto ms = reference{}; -inline constexpr auto s = reference{}; -inline constexpr auto min = reference{}; -inline constexpr auto h = reference{}; -inline constexpr auto d = reference{}; - -} // namespace time_references - -namespace references { - -using namespace time_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline time { - -template -using ys = units::isq::si::time; -template -using zs = units::isq::si::time; -template -using as = units::isq::si::time; -template -using fs = units::isq::si::time; -template -using ps = units::isq::si::time; -template -using ns = units::isq::si::time; -template -using us = units::isq::si::time; -template -using ms = units::isq::si::time; -template -using s = units::isq::si::time; -template -using min = units::isq::si::time; -template -using h = units::isq::si::time; -template -using d = units::isq::si::time; - -} // namespace units::aliases::isq::si::inline time - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/torque.h b/src/systems/si/include/units/isq/si/torque.h deleted file mode 100644 index 14e5aec2..00000000 --- a/src/systems/si/include/units/isq/si/torque.h +++ /dev/null @@ -1,72 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct newton_metre_per_radian : derived_unit {}; - -struct dim_torque : isq::dim_torque> {}; - -template U, Representation Rep = double> -using torque = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// Nm -constexpr auto operator"" _q_N_m_per_rad(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return torque(static_cast(l)); -} -constexpr auto operator"" _q_N_m_per_rad(long double l) { return torque(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline torque { - -template -using N_m_per_rad = units::isq::si::torque; - -} // namespace units::aliases::isq::si::inline torque - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/voltage.h b/src/systems/si/include/units/isq/si/voltage.h deleted file mode 100644 index e06cc1be..00000000 --- a/src/systems/si/include/units/isq/si/voltage.h +++ /dev/null @@ -1,329 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include -#include -#include - -namespace units::isq::si { - -struct volt : named_unit {}; -struct yoctovolt : prefixed_unit {}; -struct zeptovolt : prefixed_unit {}; -struct attovolt : prefixed_unit {}; -struct femtovolt : prefixed_unit {}; -struct picovolt : prefixed_unit {}; -struct nanovolt : prefixed_unit {}; -struct microvolt : prefixed_unit {}; -struct millivolt : prefixed_unit {}; -struct centivolt : prefixed_unit {}; -struct decivolt : prefixed_unit {}; -struct decavolt : prefixed_unit {}; -struct hectovolt : prefixed_unit {}; -struct kilovolt : prefixed_unit {}; -struct megavolt : prefixed_unit {}; -struct gigavolt : prefixed_unit {}; -struct teravolt : prefixed_unit {}; -struct petavolt : prefixed_unit {}; -struct exavolt : prefixed_unit {}; -struct zettavolt : prefixed_unit {}; -struct yottavolt : prefixed_unit {}; - -struct dim_voltage : isq::dim_voltage {}; - -template U, Representation Rep = double> -using voltage = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// V -constexpr auto operator"" _q_V(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_V(long double l) { return voltage(l); } - -// yV -constexpr auto operator"" _q_yV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_yV(long double l) { return voltage(l); } - -// zV -constexpr auto operator"" _q_zV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_zV(long double l) { return voltage(l); } - -// aV -constexpr auto operator"" _q_aV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_aV(long double l) { return voltage(l); } - -// fV -constexpr auto operator"" _q_fV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_fV(long double l) { return voltage(l); } - -// pV -constexpr auto operator"" _q_pV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_pV(long double l) { return voltage(l); } - -// nV -constexpr auto operator"" _q_nV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_nV(long double l) { return voltage(l); } - -// uV -constexpr auto operator"" _q_uV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_uV(long double l) { return voltage(l); } - -// mV -constexpr auto operator"" _q_mV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_mV(long double l) { return voltage(l); } - -// cV -constexpr auto operator"" _q_cV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_cV(long double l) { return voltage(l); } - -// dV -constexpr auto operator"" _q_dV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_dV(long double l) { return voltage(l); } - -// daV -constexpr auto operator"" _q_daV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_daV(long double l) { return voltage(l); } - -// hV -constexpr auto operator"" _q_hV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_hV(long double l) { return voltage(l); } - -// kV -constexpr auto operator"" _q_kV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_kV(long double l) { return voltage(l); } - -// MV -constexpr auto operator"" _q_MV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_MV(long double l) { return voltage(l); } - -// GV -constexpr auto operator"" _q_GV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_GV(long double l) { return voltage(l); } - -// TV -constexpr auto operator"" _q_TV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_TV(long double l) { return voltage(l); } - -// PV -constexpr auto operator"" _q_PV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_PV(long double l) { return voltage(l); } - -// EV -constexpr auto operator"" _q_EV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_EV(long double l) { return voltage(l); } - -// ZV -constexpr auto operator"" _q_ZV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_ZV(long double l) { return voltage(l); } - -// YV -constexpr auto operator"" _q_YV(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return voltage(static_cast(l)); -} -constexpr auto operator"" _q_YV(long double l) { return voltage(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace voltage_references { - -inline constexpr auto V = reference{}; -inline constexpr auto yV = reference{}; -inline constexpr auto zV = reference{}; -inline constexpr auto aV = reference{}; -inline constexpr auto fV = reference{}; -inline constexpr auto pV = reference{}; -inline constexpr auto nV = reference{}; -inline constexpr auto uV = reference{}; -inline constexpr auto mV = reference{}; -inline constexpr auto cV = reference{}; -inline constexpr auto dV = reference{}; -inline constexpr auto daV = reference{}; -inline constexpr auto hV = reference{}; -inline constexpr auto kV = reference{}; -inline constexpr auto MV = reference{}; -inline constexpr auto GV = reference{}; -inline constexpr auto TV = reference{}; -inline constexpr auto PV = reference{}; -inline constexpr auto EV = reference{}; -inline constexpr auto ZV = reference{}; -inline constexpr auto YV = reference{}; - -} // namespace voltage_references - -namespace references { - -using namespace voltage_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline voltage { - -template -using V = units::isq::si::voltage; -template -using yV = units::isq::si::voltage; -template -using zV = units::isq::si::voltage; -template -using aV = units::isq::si::voltage; -template -using fV = units::isq::si::voltage; -template -using pV = units::isq::si::voltage; -template -using nV = units::isq::si::voltage; -template -using uV = units::isq::si::voltage; -template -using mV = units::isq::si::voltage; -template -using cV = units::isq::si::voltage; -template -using dV = units::isq::si::voltage; -template -using daV = units::isq::si::voltage; -template -using hV = units::isq::si::voltage; -template -using kV = units::isq::si::voltage; -template -using MV = units::isq::si::voltage; -template -using GV = units::isq::si::voltage; -template -using TV = units::isq::si::voltage; -template -using PV = units::isq::si::voltage; -template -using EV = units::isq::si::voltage; -template -using ZV = units::isq::si::voltage; -template -using YV = units::isq::si::voltage; - -} // namespace units::aliases::isq::si::inline voltage - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/si/include/units/isq/si/volume.h b/src/systems/si/include/units/isq/si/volume.h deleted file mode 100644 index 1f61d874..00000000 --- a/src/systems/si/include/units/isq/si/volume.h +++ /dev/null @@ -1,582 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -// IWYU pragma: begin_exports -#include -#include -#include -#include -// IWYU pragma: end_exports - -#include -#include - -namespace units::isq::si { - -struct cubic_metre : derived_unit {}; -struct dim_volume : isq::dim_volume {}; - -struct cubic_yoctometre : derived_scaled_unit {}; -struct cubic_zeptometre : derived_scaled_unit {}; -struct cubic_attometre : derived_scaled_unit {}; -struct cubic_femtometre : derived_scaled_unit {}; -struct cubic_picometre : derived_scaled_unit {}; -struct cubic_nanometre : derived_scaled_unit {}; -struct cubic_micrometre : derived_scaled_unit {}; -struct cubic_millimetre : derived_scaled_unit {}; -struct cubic_centimetre : derived_scaled_unit {}; -struct cubic_decimetre : derived_scaled_unit {}; -struct cubic_decametre : derived_scaled_unit {}; -struct cubic_hectometre : derived_scaled_unit {}; -struct cubic_kilometre : derived_scaled_unit {}; -struct cubic_megametre : derived_scaled_unit {}; -struct cubic_gigametre : derived_scaled_unit {}; -struct cubic_terametre : derived_scaled_unit {}; -struct cubic_petametre : derived_scaled_unit {}; -struct cubic_exametre : derived_scaled_unit {}; -struct cubic_zettametre : derived_scaled_unit {}; -struct cubic_yottametre : derived_scaled_unit {}; - -struct litre : alias_unit {}; -struct yoctolitre : prefixed_alias_unit {}; -struct zeptolitre : prefixed_unit {}; -struct attolitre : prefixed_unit {}; -struct femtolitre : prefixed_alias_unit {}; -struct picolitre : prefixed_unit {}; -struct nanolitre : prefixed_unit {}; -struct microlitre : prefixed_alias_unit {}; -struct millilitre : prefixed_alias_unit {}; -struct centilitre : prefixed_unit {}; -struct decilitre : prefixed_unit {}; -struct decalitre : prefixed_unit {}; -struct hectolitre : prefixed_alias_unit {}; -struct kilolitre : prefixed_alias_unit {}; -struct megalitre : prefixed_alias_unit {}; -struct gigalitre : prefixed_alias_unit {}; -struct teralitre : prefixed_alias_unit {}; -struct petalitre : prefixed_unit {}; -struct exalitre : prefixed_unit {}; -struct zettalitre : prefixed_alias_unit {}; -struct yottalitre : prefixed_unit {}; - -template U, Representation Rep = double> -using volume = quantity; - -#ifndef UNITS_NO_LITERALS - -inline namespace literals { - -// m3 -constexpr auto operator"" _q_m3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_m3(long double l) { return volume(l); } - -// ym3 -constexpr auto operator"" _q_ym3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ym3(long double l) { return volume(l); } - -// zm3 -constexpr auto operator"" _q_zm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_zm3(long double l) { return volume(l); } - -// am3 -constexpr auto operator"" _q_am3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_am3(long double l) { return volume(l); } - -// fm3 -constexpr auto operator"" _q_fm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_fm3(long double l) { return volume(l); } - -// pm3 -constexpr auto operator"" _q_pm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_pm3(long double l) { return volume(l); } - -// nm3 -constexpr auto operator"" _q_nm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_nm3(long double l) { return volume(l); } - -// um3 -constexpr auto operator"" _q_um3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_um3(long double l) { return volume(l); } - -// mm3 -constexpr auto operator"" _q_mm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_mm3(long double l) { return volume(l); } - -// cm3 -constexpr auto operator"" _q_cm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_cm3(long double l) { return volume(l); } - -// dm3 -constexpr auto operator"" _q_dm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dm3(long double l) { return volume(l); } - -// dam3 -constexpr auto operator"" _q_dam3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dam3(long double l) { return volume(l); } - -// hm3 -constexpr auto operator"" _q_hm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_hm3(long double l) { return volume(l); } - -// km3 -constexpr auto operator"" _q_km3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_km3(long double l) { return volume(l); } - -// Mm3 -constexpr auto operator"" _q_Mm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Mm3(long double l) { return volume(l); } - -// Gm3 -constexpr auto operator"" _q_Gm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Gm3(long double l) { return volume(l); } - -// Tm3 -constexpr auto operator"" _q_Tm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Tm3(long double l) { return volume(l); } - -// Pm3 -constexpr auto operator"" _q_Pm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Pm3(long double l) { return volume(l); } - -// Em3 -constexpr auto operator"" _q_Em3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Em3(long double l) { return volume(l); } - -// Zm3 -constexpr auto operator"" _q_Zm3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Zm3(long double l) { return volume(l); } - -// Ym3 -constexpr auto operator"" _q_Ym3(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Ym3(long double l) { return volume(l); } - -// l -constexpr auto operator"" _q_l(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_l(long double l) { return volume(l); } - -// yl -constexpr auto operator"" _q_yl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_yl(long double l) { return volume(l); } - -// zl -constexpr auto operator"" _q_zl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_zl(long double l) { return volume(l); } - -// al -constexpr auto operator"" _q_al(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_al(long double l) { return volume(l); } - -// fl -constexpr auto operator"" _q_fl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_fl(long double l) { return volume(l); } - -// pl -constexpr auto operator"" _q_pl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_pl(long double l) { return volume(l); } - -// nl -constexpr auto operator"" _q_nl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_nl(long double l) { return volume(l); } - -// ul -constexpr auto operator"" _q_ul(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ul(long double l) { return volume(l); } - -// ml -constexpr auto operator"" _q_ml(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_ml(long double l) { return volume(l); } - -// cl -constexpr auto operator"" _q_cl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_cl(long double l) { return volume(l); } - -// dl -constexpr auto operator"" _q_dl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dl(long double l) { return volume(l); } - -// dal -constexpr auto operator"" _q_dal(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_dal(long double l) { return volume(l); } - -// hl -constexpr auto operator"" _q_hl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_hl(long double l) { return volume(l); } - -// kl -constexpr auto operator"" _q_kl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_kl(long double l) { return volume(l); } - -// Ml -constexpr auto operator"" _q_Ml(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Ml(long double l) { return volume(l); } - -// Gl -constexpr auto operator"" _q_Gl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Gl(long double l) { return volume(l); } - -// Tl -constexpr auto operator"" _q_Tl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Tl(long double l) { return volume(l); } - -// Pl -constexpr auto operator"" _q_Pl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Pl(long double l) { return volume(l); } - -// El -constexpr auto operator"" _q_El(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_El(long double l) { return volume(l); } - -// Zl -constexpr auto operator"" _q_Zl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Zl(long double l) { return volume(l); } - -// Yl -constexpr auto operator"" _q_Yl(unsigned long long l) -{ - gsl_ExpectsAudit(std::in_range(l)); - return volume(static_cast(l)); -} -constexpr auto operator"" _q_Yl(long double l) { return volume(l); } - -} // namespace literals - -#endif // UNITS_NO_LITERALS - -#ifndef UNITS_NO_REFERENCES - -namespace volume_references { - -inline constexpr auto m3 = reference{}; -inline constexpr auto ym3 = reference{}; -inline constexpr auto zm3 = reference{}; -inline constexpr auto am3 = reference{}; -inline constexpr auto fm3 = reference{}; -inline constexpr auto pm3 = reference{}; -inline constexpr auto nm3 = reference{}; -inline constexpr auto um3 = reference{}; -inline constexpr auto mm3 = reference{}; -inline constexpr auto cm3 = reference{}; -inline constexpr auto dm3 = reference{}; -inline constexpr auto dam3 = reference{}; -inline constexpr auto hm3 = reference{}; -inline constexpr auto km3 = reference{}; -inline constexpr auto Mm3 = reference{}; -inline constexpr auto Gm3 = reference{}; -inline constexpr auto Tm3 = reference{}; -inline constexpr auto Pm3 = reference{}; -inline constexpr auto Em3 = reference{}; -inline constexpr auto Zm3 = reference{}; -inline constexpr auto Ym3 = reference{}; - -inline constexpr auto l = reference{}; -inline constexpr auto yl = reference{}; -inline constexpr auto zl = reference{}; -inline constexpr auto al = reference{}; -inline constexpr auto fl = reference{}; -inline constexpr auto pl = reference{}; -inline constexpr auto nl = reference{}; -inline constexpr auto ul = reference{}; -inline constexpr auto ml = reference{}; -inline constexpr auto cl = reference{}; -inline constexpr auto dl = reference{}; -inline constexpr auto dal = reference{}; -inline constexpr auto hl = reference{}; -inline constexpr auto kl = reference{}; -inline constexpr auto Ml = reference{}; -inline constexpr auto Gl = reference{}; -inline constexpr auto Tl = reference{}; -inline constexpr auto Pl = reference{}; -inline constexpr auto El = reference{}; -inline constexpr auto Zl = reference{}; -inline constexpr auto Yl = reference{}; - -} // namespace volume_references - -namespace references { - -using namespace volume_references; - -} // namespace references - -#endif // UNITS_NO_REFERENCES - -} // namespace units::isq::si - -#ifndef UNITS_NO_ALIASES - -namespace units::aliases::isq::si::inline volume { - -template -using m3 = units::isq::si::volume; -template -using ym3 = units::isq::si::volume; -template -using zm3 = units::isq::si::volume; -template -using am3 = units::isq::si::volume; -template -using fm3 = units::isq::si::volume; -template -using pm3 = units::isq::si::volume; -template -using nm3 = units::isq::si::volume; -template -using um3 = units::isq::si::volume; -template -using mm3 = units::isq::si::volume; -template -using cm3 = units::isq::si::volume; -template -using dm3 = units::isq::si::volume; -template -using dam3 = units::isq::si::volume; -template -using hm3 = units::isq::si::volume; -template -using km3 = units::isq::si::volume; -template -using Mm3 = units::isq::si::volume; -template -using Gm3 = units::isq::si::volume; -template -using Tm3 = units::isq::si::volume; -template -using Pm3 = units::isq::si::volume; -template -using Em3 = units::isq::si::volume; -template -using Zm3 = units::isq::si::volume; -template -using Ym3 = units::isq::si::volume; - -template -using l = units::isq::si::volume; -template -using yl = units::isq::si::volume; -template -using zl = units::isq::si::volume; -template -using al = units::isq::si::volume; -template -using fl = units::isq::si::volume; -template -using pl = units::isq::si::volume; -template -using nl = units::isq::si::volume; -template -using ul = units::isq::si::volume; -template -using ml = units::isq::si::volume; -template -using cl = units::isq::si::volume; -template -using dl = units::isq::si::volume; -template -using dal = units::isq::si::volume; -template -using hl = units::isq::si::volume; -template -using kl = units::isq::si::volume; -template -using Ml = units::isq::si::volume; -template -using Gl = units::isq::si::volume; -template -using Tl = units::isq::si::volume; -template -using Pl = units::isq::si::volume; -template -using El = units::isq::si::volume; -template -using Zl = units::isq::si::volume; -template -using Yl = units::isq::si::volume; - -} // namespace units::aliases::isq::si::inline volume - -#endif // UNITS_NO_ALIASES diff --git a/src/systems/typographic/CMakeLists.txt b/src/systems/typographic/CMakeLists.txt new file mode 100644 index 00000000..f9bd1a7c --- /dev/null +++ b/src/systems/typographic/CMakeLists.txt @@ -0,0 +1,25 @@ +# 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.19) + +add_units_module(typographic DEPENDENCIES mp-units::usc HEADERS include/mp-units/systems/typographic/typographic.h) diff --git a/src/systems/isq-natural/include/units/isq/natural/speed.h b/src/systems/typographic/include/mp-units/systems/typographic/typographic.h similarity index 62% rename from src/systems/isq-natural/include/units/isq/natural/speed.h rename to src/systems/typographic/include/mp-units/systems/typographic/typographic.h index 29f388cc..6f1fcfaa 100644 --- a/src/systems/isq-natural/include/units/isq/natural/speed.h +++ b/src/systems/typographic/include/mp-units/systems/typographic/typographic.h @@ -22,23 +22,18 @@ #pragma once -#include -#include +#include +#include -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -#include -// IWYU pragma: end_exports +namespace mp_units::typographic { -namespace units::isq::natural { +// clang-format off +// https://en.wikipedia.org/wiki/Point_(typography) +inline constexpr struct pica_us : named_unit<"pica(us)", mag * international::inch> {} pica_us; +inline constexpr struct point_us : named_unit<"point(us)", mag * pica_us> {} point_us; -struct dim_speed : isq::dim_speed {}; +inline constexpr struct point_dtp : named_unit<"point(dtp)", mag * international::inch> {} point_dtp; +inline constexpr struct pica_dtp : named_unit<"pica(dtp)", mag<12> * point_dtp> {} pica_dtp; +// clang-format on -template U, Representation Rep = double> -using speed = quantity; - -} // namespace units::isq::natural +} // namespace mp_units::typographic diff --git a/src/systems/usc/CMakeLists.txt b/src/systems/usc/CMakeLists.txt new file mode 100644 index 00000000..d5041e29 --- /dev/null +++ b/src/systems/usc/CMakeLists.txt @@ -0,0 +1,25 @@ +# 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.19) + +add_units_module(usc DEPENDENCIES mp-units::si mp-units::international HEADERS include/mp-units/systems/usc/usc.h) diff --git a/src/systems/usc/include/mp-units/systems/usc/usc.h b/src/systems/usc/include/mp-units/systems/usc/usc.h new file mode 100644 index 00000000..98c1ea41 --- /dev/null +++ b/src/systems/usc/include/mp-units/systems/usc/usc.h @@ -0,0 +1,168 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include + +namespace mp_units::usc { + +using namespace international; + +// clang-format off + +// https://en.wikipedia.org/wiki/United_States_customary_units#Length +// nautical +inline constexpr struct fathom : named_unit<"ftm(us)", mag<2> * yard> {} fathom; +inline constexpr struct cable : named_unit<"cb(us)", mag<120> * fathom> {} cable; + +// survey +struct us_survey_foot : named_unit<"ft(us)", mag * si::metre> {}; +struct us_survey_mile : named_unit<"mi(us)", mag<5280> * us_survey_foot{}> {}; + +[[deprecated("In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is deprecated.")]] +inline constexpr us_survey_foot us_survey_foot; + +[[deprecated("In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is deprecated.")]] +inline constexpr us_survey_mile us_survey_mile; + +inline constexpr struct link : named_unit<"li", mag * foot> {} link; +inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod; +inline constexpr struct chain : named_unit<"ch", mag<4> * rod> {} chain; +inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; +// clang-format on + +namespace survey1893 { + +// clang-format off +inline constexpr struct us_survey_foot : named_unit<"ft(us)", mag * si::metre> {} us_survey_foot; +inline constexpr struct link : named_unit<"li", mag * us_survey_foot> {} link; +inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod; +inline constexpr struct chain : named_unit<"ch", mag<4> * rod> {} chain; +inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; +inline constexpr struct us_survey_mile : named_unit<"mi(us)", mag<8> * furlong> {} us_survey_mile; +inline constexpr struct league : named_unit<"lea", mag<3> * us_survey_mile> {} league; +// clang-format on + +} // namespace survey1893 + +// clang-format off +// https://en.wikipedia.org/wiki/United_States_customary_units#Area +inline constexpr struct acre : named_unit<"acre", mag<10> * square(survey1893::chain)> {} acre; +inline constexpr struct section : named_unit<"section", mag<640> * acre> {} section; + +// https://en.wikipedia.org/wiki/United_States_customary_units#Fluid_volume +inline constexpr struct gallon : named_unit<"gal", mag<231> * cubic(inch)> {} gallon; +inline constexpr struct pottle : named_unit<"pot", mag * gallon> {} pottle; +inline constexpr struct quart : named_unit<"qt", mag * pottle> {} quart; +inline constexpr struct pint : named_unit<"pt", mag * quart> {} pint; +inline constexpr struct cup : named_unit<"c", mag * pint> {} cup; +inline constexpr struct gill : named_unit<"gi", mag * cup> {} gill; +inline constexpr struct fluid_ounce : named_unit<"fl oz", mag * gill> {} fluid_ounce; +inline constexpr struct tablespoon : named_unit<"tbsp", mag * fluid_ounce> {} tablespoon; +inline constexpr struct shot : named_unit<"jig", mag<3> * tablespoon> {} shot; +inline constexpr struct teaspoon : named_unit<"tsp", mag * tablespoon> {} teaspoon; +inline constexpr struct minim : named_unit<"min", mag * teaspoon> {} minim; +inline constexpr struct fluid_dram : named_unit<"fl dr", mag<60> * minim> {} fluid_dram; +inline constexpr struct barrel : named_unit<"bbl", mag * gallon> {} barrel; +inline constexpr struct oil_barrel : named_unit<"bbl", mag * barrel> {} oil_barrel; +inline constexpr struct hogshead : decltype(mag<63> * gallon) {} hogshead; + +// https://en.wikipedia.org/wiki/United_States_customary_units#Dry_volume +inline constexpr struct dry_barrel : named_unit<"bbl", mag<7056> * cubic(inch)> {} dry_barrel; +inline constexpr struct bushel : named_unit<"bu", mag * si::litre> {} bushel; +inline constexpr struct peck : named_unit<"pk", mag * bushel> {} peck; +inline constexpr struct dry_gallon : named_unit<"gal", mag * peck> {} dry_gallon; +inline constexpr struct dry_quart : named_unit<"qt", mag * dry_gallon> {} dry_quart; +inline constexpr struct dry_pint : named_unit<"pt", mag * dry_quart> {} dry_pint; + +// https://en.wikipedia.org/wiki/United_States_customary_units#Mass_and_Weight +// https://en.wikipedia.org/wiki/Avoirdupois_system#American_customary_system +inline constexpr struct quarter : named_unit<"qr", mag<25> * pound> {} quarter; +inline constexpr struct short_hundredweight : named_unit<"cwt", mag<100> * pound> {} short_hundredweight; +inline constexpr struct ton : named_unit<"t", mag<2'000> * pound> {} ton; +inline constexpr auto short_ton = ton; +inline constexpr struct pennyweight : named_unit<"dwt", mag<24> * grain> {} pennyweight; +inline constexpr struct troy_once : named_unit<"oz t", mag<20> * pennyweight> {} troy_once; +inline constexpr struct troy_pound : named_unit<"lb t", mag<12> * troy_once> {} troy_pound; + +// https://en.wikipedia.org/wiki/Inch_of_mercury +inline constexpr struct inch_of_mercury : named_unit<"inHg", mag * si::pascal> {} inch_of_mercury; + +// https://en.wikipedia.org/wiki/United_States_customary_units#Temperature +inline constexpr struct degree_Fahrenheit : named_unit * si::degree_Celsius> {} degree_Fahrenheit; +// clang-format on + +namespace unit_symbols { + +using namespace international::unit_symbols; + +inline constexpr auto ftm = fathom; +inline constexpr auto cb = cable; +[[deprecated( + "In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is " + "deprecated.")]] inline constexpr struct us_survey_foot us_ft; +[[deprecated( + "In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is " + "deprecated.")]] inline constexpr struct us_survey_mile us_mi; +inline constexpr auto li = link; +inline constexpr auto rd = rod; +inline constexpr auto ch = chain; +inline constexpr auto fur = furlong; +inline constexpr auto lea = league; + +inline constexpr auto gal = gallon; +inline constexpr auto pot = pottle; +inline constexpr auto qt = quart; +inline constexpr auto pt = pint; +inline constexpr auto c = cup; +inline constexpr auto gi = gill; +inline constexpr auto fl_oz = fluid_ounce; +inline constexpr auto tbsp = tablespoon; +inline constexpr auto jig = shot; +inline constexpr auto tsp = teaspoon; +inline constexpr auto min = minim; +inline constexpr auto fl_dr = fluid_dram; +inline constexpr auto bbl = barrel; + +inline constexpr auto dry_bbl = dry_barrel; +inline constexpr auto bu = bushel; +inline constexpr auto pk = peck; +inline constexpr auto dry_gal = dry_gallon; +inline constexpr auto dry_qt = dry_quart; +inline constexpr auto dry_pt = dry_pint; + +inline constexpr auto qr = quarter; +inline constexpr auto cwt = short_hundredweight; +inline constexpr auto t = ton; +inline constexpr auto dwt = pennyweight; +inline constexpr auto oz_t = troy_once; +inline constexpr auto lb_t = troy_pound; + +inline constexpr auto inHg = inch_of_mercury; + +inline constexpr auto deg_F = degree_Fahrenheit; + +} // namespace unit_symbols + +} // namespace mp_units::usc diff --git a/src/systems/si-typographic/CMakeLists.txt b/src/utility/CMakeLists.txt similarity index 85% rename from src/systems/si-typographic/CMakeLists.txt rename to src/utility/CMakeLists.txt index 7e359ea2..7b51d34c 100644 --- a/src/systems/si-typographic/CMakeLists.txt +++ b/src/utility/CMakeLists.txt @@ -23,6 +23,6 @@ cmake_minimum_required(VERSION 3.19) add_units_module( - si-typographic DEPENDENCIES mp-units::si HEADERS include/units/isq/si/typographic/length.h - include/units/isq/si/typographic/typographic.h + utility DEPENDENCIES mp-units::core mp-units::isq mp-units::si mp-units::angular + HEADERS include/mp-units/chrono.h include/mp-units/math.h include/mp-units/random.h ) diff --git a/src/utility/include/mp-units/chrono.h b/src/utility/include/mp-units/chrono.h new file mode 100644 index 00000000..62918fae --- /dev/null +++ b/src/utility/include/mp-units/chrono.h @@ -0,0 +1,107 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace mp_units { + +namespace detail { + +template +[[nodiscard]] inline consteval auto time_unit_from_chrono_period() +{ + using namespace si; + + if constexpr (is_same_v) + return nano; + else if constexpr (is_same_v) + return micro; + else if constexpr (is_same_v) + return milli; + else if constexpr (is_same_v) + return second; + else if constexpr (is_same_v) + return minute; + else if constexpr (is_same_v) + return hour; + else if constexpr (is_same_v) + return day; + else + return mag * second; +} + +} // namespace detail + +template +struct quantity_like_traits> { + static constexpr auto reference = detail::time_unit_from_chrono_period(); + using rep = Rep; + [[nodiscard]] static constexpr rep number(const std::chrono::duration& q) { return q.count(); } +}; + +template +struct chrono_point_origin_ : absolute_point_origin { + using clock = C; +}; +template +inline constexpr chrono_point_origin_ chrono_point_origin; + + +template +struct quantity_point_like_traits>> { + static constexpr auto reference = detail::time_unit_from_chrono_period(); + static constexpr auto point_origin = chrono_point_origin; + using rep = Rep; + [[nodiscard]] static constexpr auto relative(const std::chrono::time_point>& qp) + { + return qp.time_since_epoch(); + } +}; + +template Q> +[[nodiscard]] constexpr auto to_chrono_duration(const Q& q) +{ + constexpr auto canonical = detail::get_canonical_unit(Q::unit); + constexpr ratio r = as_ratio(canonical.mag); + return std::chrono::duration>{q.number()}; +} + +template QP> + requires is_specialization_of, chrono_point_origin_> +[[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp) +{ + using clock = TYPENAME decltype(QP::absolute_point_origin)::clock; + using rep = TYPENAME QP::rep; + constexpr auto canonical = detail::get_canonical_unit(QP::unit); + constexpr ratio r = as_ratio(canonical.mag); + using ret_type = std::chrono::time_point>>; + return ret_type(to_chrono_duration(qp.absolute())); +} + +} // namespace mp_units diff --git a/src/utility/include/mp-units/math.h b/src/utility/include/mp-units/math.h new file mode 100644 index 00000000..094f4b6e --- /dev/null +++ b/src/utility/include/mp-units/math.h @@ -0,0 +1,415 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +// IWYU pragma: begin_exports +#include +#include +// IWYU pragma: end_exports + +#include + +namespace mp_units { + +/** + * @brief Computes the value of a quantity raised to the `Num/Den` power + * + * Both the quantity value and its quantity specification are the base of the operation. + * + * @tparam Num Exponent numerator + * @tparam Den Exponent denominator + * @param q Quantity being the base of the operation + * @return Quantity The result of computation + */ +template + requires detail::non_zero && + requires { quantity_values::one(); } + [[nodiscard]] constexpr quantity(R), Rep> pow(const quantity& q) noexcept + requires requires { pow(q.number(), 1.0); } || requires { std::pow(q.number(), 1.0); } +{ + if constexpr (Num == 0) { + return quantity(R), Rep>::one(); + } else if constexpr (ratio{Num, Den} == 1) { + return q; + } else { + using std::pow; + return make_quantity(R)>( + static_cast(pow(q.number(), static_cast(Num) / static_cast(Den)))); + } +} + +/** + * @brief Computes the square root of a quantity + * + * Both the quantity value and its quantity specification are the base of the operation. + * + * @param q Quantity being the base of the operation + * @return Quantity The result of computation + */ +template +[[nodiscard]] constexpr quantity sqrt(const quantity& q) noexcept + requires requires { sqrt(q.number()); } || requires { std::sqrt(q.number()); } +{ + using std::sqrt; + return make_quantity(static_cast(sqrt(q.number()))); +} + +/** + * @brief Computes the cubic root of a quantity + * + * Both the quantity value and its quantity specification are the base of the operation. + * + * @param q Quantity being the base of the operation + * @return Quantity The result of computation + */ +template +[[nodiscard]] constexpr quantity cbrt(const quantity& q) noexcept + requires requires { cbrt(q.number()); } || requires { std::cbrt(q.number()); } +{ + using std::cbrt; + return make_quantity(static_cast(cbrt(q.number()))); +} + +/** + * @brief Computes Euler's raised to the given power + * + * @note Such an operation has sense only for a dimensionless quantity. + * + * @param q Quantity being the base of the operation + * @return Quantity The value of the same quantity type + */ +template auto R, typename Rep> +[[nodiscard]] constexpr quantity exp(const quantity& q) + requires requires { exp(q.number()); } || requires { std::exp(q.number()); } +{ + using std::exp; + return value_cast( + make_quantity(R)>(static_cast(exp(value_cast(q).number())))); +} + +/** + * @brief Computes the absolute value of a quantity + * + * @param q Quantity being the base of the operation + * @return Quantity The absolute value of a provided quantity + */ +template +[[nodiscard]] constexpr quantity abs(const quantity& q) noexcept + requires requires { abs(q.number()); } || requires { std::abs(q.number()); } +{ + using std::abs; + return make_quantity(static_cast(abs(q.number()))); +} + +/** + * @brief Returns the epsilon of the quantity + * + * The returned value is defined by a std::numeric_limits::epsilon(). + * + * @tparam Q Quantity type being the base of the operation + * @return Quantity The epsilon value for quantity's representation type + */ +template + requires requires { std::numeric_limits::epsilon(); } +[[nodiscard]] constexpr quantity epsilon(R r) noexcept +{ + return make_quantity(static_cast(std::numeric_limits::epsilon())); +} + +/** + * @brief Computes the largest quantity with integer representation and unit type To with its number not greater than q + * + * @tparam q Quantity being the base of the operation + * @return Quantity The rounded quantity with unit type To + */ +template +[[nodiscard]] constexpr quantity(R), Rep> floor(const quantity& q) noexcept + requires((!treat_as_floating_point) || requires { floor(q.number()); } || + requires { std::floor(q.number()); }) && + (To == get_unit(R) || requires { + ::mp_units::value_cast(q); + quantity_values::one(); + }) +{ + const auto handle_signed_results = [&](const T& res) { + if (res > q) { + return res - T::one(); + } + return res; + }; + if constexpr (treat_as_floating_point) { + using std::floor; + if constexpr (To == get_unit(R)) { + return make_quantity(R)>(static_cast(floor(q.number()))); + } else { + return handle_signed_results(make_quantity(q.reference)>( + static_cast(floor(value_cast(q).number())))); + } + } else { + if constexpr (To == get_unit(R)) { + return value_cast(q); + } else { + return handle_signed_results(value_cast(q)); + } + } +} + +/** + * @brief Computes the smallest quantity with integer representation and unit type To with its number not less than q + * + * @tparam q Quantity being the base of the operation + * @return Quantity The rounded quantity with unit type To + */ +template +[[nodiscard]] constexpr quantity(R), Rep> ceil(const quantity& q) noexcept + requires((!treat_as_floating_point) || requires { ceil(q.number()); } || requires { std::ceil(q.number()); }) && + (To == get_unit(R) || requires { + ::mp_units::value_cast(q); + quantity_values::one(); + }) +{ + const auto handle_signed_results = [&](const T& res) { + if (res < q) { + return res + T::one(); + } + return res; + }; + if constexpr (treat_as_floating_point) { + using std::ceil; + if constexpr (To == get_unit(R)) { + return make_quantity(q.reference)>(static_cast(ceil(q.number()))); + } else { + return handle_signed_results(make_quantity(q.reference)>( + static_cast(ceil(value_cast(q).number())))); + } + } else { + if constexpr (To == get_unit(R)) { + return value_cast(q); + } else { + return handle_signed_results(value_cast(q)); + } + } +} + +/** + * @brief Computes the nearest quantity with integer representation and unit type To to q + * + * Rounding halfway cases away from zero, regardless of the current rounding mode. + * + * @tparam q Quantity being the base of the operation + * @return Quantity The rounded quantity with unit type To + */ +template +[[nodiscard]] constexpr quantity(R), Rep> round(const quantity& q) noexcept + requires((!treat_as_floating_point) || requires { round(q.number()); } || + requires { std::round(q.number()); }) && + (To == get_unit(R) || requires { + ::mp_units::floor(q); + quantity_values::one(); + }) +{ + if constexpr (To == get_unit(R)) { + if constexpr (treat_as_floating_point) { + using std::round; + return make_quantity(q.reference)>(static_cast(round(q.number()))); + } else { + return value_cast(q); + } + } else { + const auto res_low = mp_units::floor(q); + const auto res_high = res_low + res_low.one(); + const auto diff0 = q - res_low; + const auto diff1 = res_high - q; + if (diff0 == diff1) { + if (static_cast(res_low.number()) & 1) { + return res_high; + } + return res_low; + } + if (diff0 < diff1) { + return res_low; + } + return res_high; + } +} + +/** + * @brief Computes the square root of the sum of the squares of x and y, + * without undue overflow or underflow at intermediate stages of the computation + */ +template +[[nodiscard]] constexpr QuantityOf auto hypot( + const quantity& x, const quantity& y) noexcept + requires requires { common_reference(R1, R2); } && + ( + requires { hypot(x.number(), y.number()); } || requires { std::hypot(x.number(), y.number()); }) +{ + constexpr auto ref = common_reference(R1, R2); + constexpr auto unit = get_unit(ref); + using std::hypot; + return make_quantity(hypot(x.number_in(unit), y.number_in(unit))); +} + +/** + * @brief Computes the square root of the sum of the squares of x, y, and z, + * without undue overflow or underflow at intermediate stages of the computation + */ +template +[[nodiscard]] constexpr QuantityOf auto hypot( + const quantity& x, const quantity& y, const quantity& z) noexcept + requires requires { common_reference(R1, R2, R3); } && ( + requires { hypot(x.number(), y.number(), z.number()); } || + requires { std::hypot(x.number(), y.number(), z.number()); }) +{ + constexpr auto ref = common_reference(R1, R2); + constexpr auto unit = get_unit(ref); + using std::hypot; + return make_quantity(hypot(x.number_in(unit), y.number_in(unit), z.number_in(unit))); +} + +namespace isq { + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity sin(const quantity& q) noexcept + requires requires { sin(q.number()); } || requires { std::sin(q.number()); } +{ + using std::sin; + return make_quantity(static_cast(sin(q[si::radian].number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity cos(const quantity& q) noexcept + requires requires { cos(q.number()); } || requires { std::cos(q.number()); } +{ + using std::cos; + return make_quantity(static_cast(cos(q[si::radian].number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity tan(const quantity& q) noexcept + requires requires { tan(q.number()); } || requires { std::tan(q.number()); } +{ + using std::tan; + return make_quantity(static_cast(tan(q[si::radian].number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity asin(const quantity& q) noexcept + requires requires { asin(q.number()); } || requires { std::asin(q.number()); } +{ + using std::asin; + return make_quantity(static_cast(asin(value_cast(q).number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity acos(const quantity& q) noexcept + requires requires { acos(q.number()); } || requires { std::acos(q.number()); } +{ + using std::acos; + return make_quantity(static_cast(acos(value_cast(q).number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity atan(const quantity& q) noexcept + requires requires { atan(q.number()); } || requires { std::atan(q.number()); } +{ + using std::atan; + return make_quantity(static_cast(atan(value_cast(q).number()))); +} + +} // namespace isq + +namespace angular { + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity sin(const quantity& q) noexcept + requires requires { sin(q.number()); } || requires { std::sin(q.number()); } +{ + using std::sin; + return make_quantity(static_cast(sin(q[radian].number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity cos(const quantity& q) noexcept + requires requires { cos(q.number()); } || requires { std::cos(q.number()); } +{ + using std::cos; + return make_quantity(static_cast(cos(q[radian].number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity tan(const quantity& q) noexcept + requires requires { tan(q.number()); } || requires { std::tan(q.number()); } +{ + using std::tan; + return make_quantity(static_cast(tan(q[radian].number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity asin(const quantity& q) noexcept + requires requires { asin(q.number()); } || requires { std::asin(q.number()); } +{ + using std::asin; + return make_quantity(static_cast(asin(value_cast(q).number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity acos(const quantity& q) noexcept + requires requires { acos(q.number()); } || requires { std::acos(q.number()); } +{ + using std::acos; + return make_quantity(static_cast(acos(value_cast(q).number()))); +} + +template auto R, typename Rep> + requires treat_as_floating_point +[[nodiscard]] inline quantity atan(const quantity& q) noexcept + requires requires { atan(q.number()); } || requires { std::atan(q.number()); } +{ + using std::atan; + return make_quantity(static_cast(atan(value_cast(q).number()))); +} + +} // namespace angular + +} // namespace mp_units diff --git a/src/core/include/units/random.h b/src/utility/include/mp-units/random.h similarity index 78% rename from src/core/include/units/random.h rename to src/utility/include/mp-units/random.h index 4711695b..efe579f5 100644 --- a/src/core/include/units/random.h +++ b/src/utility/include/mp-units/random.h @@ -22,11 +22,11 @@ #pragma once -#include +#include #include #include -namespace units { +namespace mp_units { namespace detail { template @@ -93,14 +93,14 @@ struct uniform_int_distribution : public std::uniform_int_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q a() const { return Q(base::a()); } - Q b() const { return Q(base::b()); } + Q a() const { return base::a() * Q::reference; } + Q b() const { return base::b() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -115,14 +115,14 @@ struct uniform_real_distribution : public std::uniform_real_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q a() const { return Q(base::a()); } - Q b() const { return Q(base::b()); } + Q a() const { return base::a() * Q::reference; } + Q b() const { return base::b() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -137,13 +137,13 @@ struct binomial_distribution : public std::binomial_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q t() const { return Q(base::t()); } + Q t() const { return base::t() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -158,13 +158,13 @@ struct negative_binomial_distribution : public std::negative_binomial_distributi template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q k() const { return Q(base::k()); } + Q k() const { return base::k() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -179,11 +179,11 @@ struct geometric_distribution : public std::geometric_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -198,11 +198,11 @@ struct poisson_distribution : public std::poisson_distribution template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -217,11 +217,11 @@ struct exponential_distribution : public std::exponential_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -236,11 +236,11 @@ struct gamma_distribution : public std::gamma_distribution { template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -255,11 +255,11 @@ struct weibull_distribution : public std::weibull_distribution template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -277,10 +277,10 @@ struct extreme_value_distribution : public std::extreme_value_distribution @@ -298,11 +298,11 @@ struct normal_distribution : public std::normal_distribution { return Q(base::operator()(g)); } - Q mean() const { return Q(base::mean()); } - Q stddev() const { return Q(base::stddev()); } + Q mean() const { return base::mean() * Q::reference; } + Q stddev() const { return base::stddev() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -317,14 +317,14 @@ struct lognormal_distribution : public std::lognormal_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q m() const { return Q(base::m()); } - Q s() const { return Q(base::s()); } + Q m() const { return base::m() * Q::reference; } + Q s() const { return base::s() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -339,11 +339,11 @@ struct chi_squared_distribution : public std::chi_squared_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -358,14 +358,14 @@ struct cauchy_distribution : public std::cauchy_distribution { template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q a() const { return Q(base::a()); } - Q b() const { return Q(base::b()); } + Q a() const { return base::a() * Q::reference; } + Q b() const { return base::b() * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -380,11 +380,11 @@ struct fisher_f_distribution : public std::fisher_f_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -399,11 +399,11 @@ struct student_t_distribution : public std::student_t_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -430,11 +430,11 @@ struct discrete_distribution : public std::discrete_distribution Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -470,14 +470,14 @@ public: template piecewise_constant_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) : - base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(Q(val)); }) + base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(val * Q::reference); }) { } template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } std::vector intervals() const @@ -486,13 +486,13 @@ public: std::vector intervals_qty; intervals_qty.reserve(intervals_rep.size()); for (const rep& val : intervals_rep) { - intervals_qty.push_back(Q(val)); + intervals_qty.push_back(val * Q::reference); } return intervals_qty; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; template @@ -528,14 +528,14 @@ public: template piecewise_linear_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) : - base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(Q(val)); }) + base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(val * Q::reference); }) { } template Q operator()(Generator& g) { - return Q(base::operator()(g)); + return base::operator()(g) * Q::reference; } std::vector intervals() const @@ -544,13 +544,13 @@ public: std::vector intervals_qty; intervals_qty.reserve(intervals_rep.size()); for (const rep& val : intervals_rep) { - intervals_qty.push_back(Q(val)); + intervals_qty.push_back(val * Q::reference); } return intervals_qty; } - Q min() const { return Q(base::min()); } - Q max() const { return Q(base::max()); } + Q min() const { return base::min() * Q::reference; } + Q max() const { return base::max() * Q::reference; } }; -} // namespace units +} // namespace mp_units diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b90032e9..6ff4d0c9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,4 +24,5 @@ cmake_minimum_required(VERSION 3.2) add_subdirectory(unit_test/runtime) add_subdirectory(unit_test/static) -#add_subdirectory(metabench) + +# add_subdirectory(metabench) diff --git a/test/metabench/CMakeLists.txt b/test/metabench/CMakeLists.txt deleted file mode 100644 index 0186dc1a..00000000 --- a/test/metabench/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2018 Mateusz Pusz -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -cmake_minimum_required(VERSION 3.12) - -function(add_metabench_test target name erb_path range) - metabench_add_dataset(${target} "${erb_path}" "${range}" NAME "${name}") - target_compile_features(${target} PUBLIC cxx_std_20) - target_link_libraries(${target} PUBLIC range-v3::range-v3>) - target_compile_options(${target} PUBLIC -fconcepts) -endfunction() - -include(metabench) -if(NOT METABENCH_DIR) - return() -endif() - -enable_testing() - -add_custom_target(metabench) - -add_subdirectory(list) -add_subdirectory(make_dimension) -add_subdirectory(ratio) diff --git a/test/metabench/list/CMakeLists.txt b/test/metabench/list/CMakeLists.txt deleted file mode 100644 index 383efcad..00000000 --- a/test/metabench/list/CMakeLists.txt +++ /dev/null @@ -1,65 +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) - -add_metabench_test( - metabench.data.list.type_list.concepts_all "all concepts" type_list_concepts_all.cpp.erb "[3, 6, 9, 12, 15]" -) -add_metabench_test( - metabench.data.list.type_list.concepts_iface "concepts in interface" type_list_concepts_iface.cpp.erb - "[3, 6, 9, 12, 15]" -) -add_metabench_test( - metabench.data.list.type_list.concepts_no "no concepts" type_list_concepts_no.cpp.erb "[3, 6, 9, 12, 15]" -) -metabench_add_chart( - metabench.chart.list.concepts - TITLE "Sorting a list of size N" - SUBTITLE "(lower is better)" - DATASETS metabench.data.list.type_list.concepts_all metabench.data.list.type_list.concepts_iface - metabench.data.list.type_list.concepts_no -) - -add_metabench_test( - metabench.data.list.type_list.conditional_std "std::conditional" type_list_conditional_std.cpp.erb - "[3, 6, 9, 12, 15]" -) -add_metabench_test( - metabench.data.list.type_list.conditional_alias "alias conditional" type_list_conditional_alias.cpp.erb - "[3, 6, 9, 12, 15]" -) -add_metabench_test( - metabench.data.list.type_list.conditional_alias_hard "alias conditional hard" - type_list_conditional_alias_hard.cpp.erb "[3, 6, 9, 12, 15]" -) -metabench_add_chart( - metabench.chart.list.conditional - TITLE "Sorting a list of size N" - SUBTITLE "(lower is better)" - DATASETS metabench.data.list.type_list.conditional_std metabench.data.list.type_list.conditional_alias - metabench.data.list.type_list.conditional_alias_hard -) - -add_custom_target(metabench.chart.list DEPENDS metabench.chart.list.concepts metabench.chart.list.conditional) - -add_dependencies(metabench metabench.chart.list) diff --git a/test/metabench/list/type_list_concepts_all.cpp.erb b/test/metabench/list/type_list_concepts_all.cpp.erb deleted file mode 100644 index 142aa11b..00000000 --- a/test/metabench/list/type_list_concepts_all.cpp.erb +++ /dev/null @@ -1,34 +0,0 @@ -#include "type_list_concepts_all.h" - -template -using dim_id = std::integral_constant; - -template -using dim_id_less = std::bool_constant; - -template -struct dimension; - -<% (1..10).each do |k| %> -struct test<%= k %> { - -<% (1..n).each do |i| %> -using <%= "dim#{i}" %> = dimension<<%= - xs = ((1)..(i)).map { |j| "dim_id<#{k*n+i+j}>" } - rng = Random.new(i) - xs.shuffle(random: rng).join(', ') -%>>; -#if defined(METABENCH) -using <%= "result#{i}" %> = units::type_list_sort_t<<%= "dim#{i}" %>, dim_id_less>; -#else -using <%= "result#{i}" %> = void; -#endif -<% end %> - -}; - -<% end %> - -int main() -{ -} diff --git a/test/metabench/list/type_list_concepts_all.h b/test/metabench/list/type_list_concepts_all.h deleted file mode 100644 index d7523912..00000000 --- a/test/metabench/list/type_list_concepts_all.h +++ /dev/null @@ -1,184 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -namespace detail { - -template -struct conditional { - template - using type = F; -}; - -template<> -struct conditional { - template - using type = T; -}; - -template -using conditional_t = conditional::template type; - -} // namespace detail - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -template -struct type_list_push_front; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front, NewTypes...> { - using type = List; -}; - -template -using type_list_push_front_t = type_list_push_front::type; - -// push_back - -template -struct type_list_push_back; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back, NewTypes...> { - using type = List; -}; - -template -using type_list_push_back_t = type_list_push_back::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using base_first = base::first_list; - using base_second = base::second_list; - using first_list = detail::conditional_t < Idx, base_first>; - using second_list = detail::conditional_t < Idx>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -template typename Pred> -struct type_list_merge_sorted; - -template typename Pred> -using type_list_merge_sorted_t = type_list_merge_sorted::type; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted, List, Pred> { - using type = detail::conditional_t< - Pred::value, - type_list_push_front_t, List, Pred>, Lhs1>, - type_list_push_front_t, List, Pred>, Rhs1>>; -}; - -// sort - -template typename Pred> -struct type_list_sort; - -template typename List, template typename Pred> -struct type_list_sort, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort::type; - using right = type_list_sort::type; - using type = type_list_merge_sorted_t; -}; - -template typename Pred> -using type_list_sort_t = type_list_sort::type; - -} // namespace units diff --git a/test/metabench/list/type_list_concepts_iface.cpp.erb b/test/metabench/list/type_list_concepts_iface.cpp.erb deleted file mode 100644 index 649440a9..00000000 --- a/test/metabench/list/type_list_concepts_iface.cpp.erb +++ /dev/null @@ -1,35 +0,0 @@ -#include "type_list_concepts_iface.h" - -template -using dim_id = std::integral_constant; - -template -using dim_id_less = std::bool_constant; - - -template -struct dimension; - -<% (1..10).each do |k| %> -struct test<%= k %> { - -<% (1..n).each do |i| %> -using <%= "dim#{i}" %> = dimension<<%= - xs = ((1)..(i)).map { |j| "dim_id<#{k*n+i+j}>" } - rng = Random.new(i) - xs.shuffle(random: rng).join(', ') -%>>; -#if defined(METABENCH) -using <%= "result#{i}" %> = units::type_list_sort<<%= "dim#{i}" %>, dim_id_less>; -#else -using <%= "result#{i}" %> = void; -#endif -<% end %> - -}; - -<% end %> - -int main() -{ -} diff --git a/test/metabench/list/type_list_concepts_iface.h b/test/metabench/list/type_list_concepts_iface.h deleted file mode 100644 index b30478cb..00000000 --- a/test/metabench/list/type_list_concepts_iface.h +++ /dev/null @@ -1,205 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -namespace detail { - -template -struct conditional { - template - using type = F; -}; - -template<> -struct conditional { - template - using type = T; -}; - -} // namespace detail - -template -using conditional = detail::conditional::template type; - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - units::conditional < - Idx::type, typename base::first_list>; - using second_list = - units::conditional < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = units::conditional< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/list/type_list_concepts_no.cpp.erb b/test/metabench/list/type_list_concepts_no.cpp.erb deleted file mode 100644 index 19cec4f3..00000000 --- a/test/metabench/list/type_list_concepts_no.cpp.erb +++ /dev/null @@ -1,35 +0,0 @@ -#include "type_list_concepts_no.h" - -template -using dim_id = std::integral_constant; - -template -using dim_id_less = std::bool_constant; - - -template -struct dimension; - -<% (1..10).each do |k| %> -struct test<%= k %> { - -<% (1..n).each do |i| %> -using <%= "dim#{i}" %> = dimension<<%= - xs = ((1)..(i)).map { |j| "dim_id<#{k*n+i+j}>" } - rng = Random.new(i) - xs.shuffle(random: rng).join(', ') -%>>; -#if defined(METABENCH) -using <%= "result#{i}" %> = units::type_list_sort<<%= "dim#{i}" %>, dim_id_less>; -#else -using <%= "result#{i}" %> = void; -#endif -<% end %> - -}; - -<% end %> - -int main() -{ -} diff --git a/test/metabench/list/type_list_concepts_no.h b/test/metabench/list/type_list_concepts_no.h deleted file mode 100644 index 4f480405..00000000 --- a/test/metabench/list/type_list_concepts_no.h +++ /dev/null @@ -1,192 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -namespace detail { - -template -struct conditional { - template - using type = F; -}; - -template<> -struct conditional { - template - using type = T; -}; - -} // namespace detail - -template -using conditional = detail::conditional::template type; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - units::conditional < - Idx::type, typename base::first_list>; - using second_list = - units::conditional < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = units::conditional< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/list/type_list_conditional_alias.cpp.erb b/test/metabench/list/type_list_conditional_alias.cpp.erb deleted file mode 100644 index 5738e52e..00000000 --- a/test/metabench/list/type_list_conditional_alias.cpp.erb +++ /dev/null @@ -1,35 +0,0 @@ -#include "type_list_conditional_alias.h" - -template -using dim_id = std::integral_constant; - -template -using dim_id_less = std::bool_constant; - - -template -struct dimension; - -<% (1..10).each do |k| %> -struct test<%= k %> { - -<% (1..n).each do |i| %> -using <%= "dim#{i}" %> = dimension<<%= - xs = ((1)..(i)).map { |j| "dim_id<#{k*n+i+j}>" } - rng = Random.new(i) - xs.shuffle(random: rng).join(', ') -%>>; -#if defined(METABENCH) -using <%= "result#{i}" %> = units::type_list_sort<<%= "dim#{i}" %>, dim_id_less>; -#else -using <%= "result#{i}" %> = void; -#endif -<% end %> - -}; - -<% end %> - -int main() -{ -} diff --git a/test/metabench/list/type_list_conditional_alias.h b/test/metabench/list/type_list_conditional_alias.h deleted file mode 100644 index b30478cb..00000000 --- a/test/metabench/list/type_list_conditional_alias.h +++ /dev/null @@ -1,205 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -namespace detail { - -template -struct conditional { - template - using type = F; -}; - -template<> -struct conditional { - template - using type = T; -}; - -} // namespace detail - -template -using conditional = detail::conditional::template type; - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - units::conditional < - Idx::type, typename base::first_list>; - using second_list = - units::conditional < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = units::conditional< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/list/type_list_conditional_alias_hard.cpp.erb b/test/metabench/list/type_list_conditional_alias_hard.cpp.erb deleted file mode 100644 index 737e2367..00000000 --- a/test/metabench/list/type_list_conditional_alias_hard.cpp.erb +++ /dev/null @@ -1,35 +0,0 @@ -#include "type_list_conditional_alias_hard.h" - -template -using dim_id = std::integral_constant; - -template -using dim_id_less = std::bool_constant; - - -template -struct dimension; - -<% (1..10).each do |k| %> -struct test<%= k %> { - -<% (1..n).each do |i| %> -using <%= "dim#{i}" %> = dimension<<%= - xs = ((1)..(i)).map { |j| "dim_id<#{k*n+i+j}>" } - rng = Random.new(i) - xs.shuffle(random: rng).join(', ') -%>>; -#if defined(METABENCH) -using <%= "result#{i}" %> = units::type_list_sort<<%= "dim#{i}" %>, dim_id_less>; -#else -using <%= "result#{i}" %> = void; -#endif -<% end %> - -}; - -<% end %> - -int main() -{ -} diff --git a/test/metabench/list/type_list_conditional_alias_hard.h b/test/metabench/list/type_list_conditional_alias_hard.h deleted file mode 100644 index e81eb85c..00000000 --- a/test/metabench/list/type_list_conditional_alias_hard.h +++ /dev/null @@ -1,197 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -template -struct conditional { - template - using type = F; -}; - -template<> -struct conditional { - template - using type = T; -}; - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - conditional < Idx::template type::type, - typename base::first_list>; - using second_list = - conditional < Idx::template type::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = units::conditional::value>::template type< - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/list/type_list_conditional_std.cpp.erb b/test/metabench/list/type_list_conditional_std.cpp.erb deleted file mode 100644 index 772c689b..00000000 --- a/test/metabench/list/type_list_conditional_std.cpp.erb +++ /dev/null @@ -1,35 +0,0 @@ -#include "type_list_conditional_std.h" - -template -using dim_id = std::integral_constant; - -template -using dim_id_less = std::bool_constant; - - -template -struct dimension; - -<% (1..10).each do |k| %> -struct test<%= k %> { - -<% (1..n).each do |i| %> -using <%= "dim#{i}" %> = dimension<<%= - xs = ((1)..(i)).map { |j| "dim_id<#{k*n+i+j}>" } - rng = Random.new(i) - xs.shuffle(random: rng).join(', ') -%>>; -#if defined(METABENCH) -using <%= "result#{i}" %> = units::type_list_sort<<%= "dim#{i}" %>, dim_id_less>; -#else -using <%= "result#{i}" %> = void; -#endif -<% end %> - -}; - -<% end %> - -int main() -{ -} diff --git a/test/metabench/list/type_list_conditional_std.h b/test/metabench/list/type_list_conditional_std.h deleted file mode 100644 index 84c4fce3..00000000 --- a/test/metabench/list/type_list_conditional_std.h +++ /dev/null @@ -1,186 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - std::conditional_t < - Idx::type, typename base::first_list>; - using second_list = - std::conditional_t < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = std::conditional_t< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/CMakeLists.txt b/test/metabench/make_dimension/CMakeLists.txt deleted file mode 100644 index 354c7c0a..00000000 --- a/test/metabench/make_dimension/CMakeLists.txt +++ /dev/null @@ -1,40 +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) - -add_metabench_test(metabench.data.make_dimension.no_concepts "no concepts" no_concepts.cpp.erb "[1, 2, 3, 4, 6, 8, 10]") -add_metabench_test( - metabench.data.make_dimension.concepts_iface "concepts iface" concepts_iface.cpp.erb "[1, 2, 3, 4, 6, 8, 10]" -) -add_metabench_test( - metabench.data.make_dimension.concepts_all "concepts all" concepts_all.cpp.erb "[1, 2, 3, 4, 6, 8, 10]" -) -metabench_add_chart( - metabench.chart.make_dimension - TITLE "100 x make_dimension" - SUBTITLE "(lower is better)" - DATASETS metabench.data.make_dimension.no_concepts metabench.data.make_dimension.concepts_iface - metabench.data.make_dimension.concepts_all -) - -add_dependencies(metabench metabench.chart.make_dimension) diff --git a/test/metabench/make_dimension/concepts_all.cpp.erb b/test/metabench/make_dimension/concepts_all.cpp.erb deleted file mode 100644 index cb987f93..00000000 --- a/test/metabench/make_dimension/concepts_all.cpp.erb +++ /dev/null @@ -1,23 +0,0 @@ -#include "dimension_concepts_all.h" - -<% (1..100).each do |k| %> -struct test<%= k %> { - <% (1..n).each do |i| %> - static constexpr units::base_dimension dim<%= i %>{"dim<%= i %>"}; - <% end %> - -#if defined(METABENCH) - using dim = units::make_dimension_t<<%= - xs = ((1)..(n)).map { |j| "units::exponent" } - rng = Random.new(k) - xs.shuffle(random: rng).join(', ') - %>>; -#else - using dim = void; -#endif -}; -<% end %> - -int main() -{ -} diff --git a/test/metabench/make_dimension/concepts_iface.cpp.erb b/test/metabench/make_dimension/concepts_iface.cpp.erb deleted file mode 100644 index 2e63f485..00000000 --- a/test/metabench/make_dimension/concepts_iface.cpp.erb +++ /dev/null @@ -1,23 +0,0 @@ -#include "dimension_concepts_iface.h" - -<% (1..100).each do |k| %> -struct test<%= k %> { - <% (1..n).each do |i| %> - static constexpr units::base_dimension dim<%= i %>{"dim<%= i %>"}; - <% end %> - -#if defined(METABENCH) - using dim = units::make_dimension_t<<%= - xs = ((1)..(n)).map { |j| "units::exponent" } - rng = Random.new(k) - xs.shuffle(random: rng).join(', ') - %>>; -#else - using dim = void; -#endif -}; -<% end %> - -int main() -{ -} diff --git a/test/metabench/make_dimension/dimension_concepts_all.h b/test/metabench/make_dimension/dimension_concepts_all.h deleted file mode 100644 index 7d9ae1f0..00000000 --- a/test/metabench/make_dimension/dimension_concepts_all.h +++ /dev/null @@ -1,211 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "downcasting_concepts_all.h" -#include "ratio_concepts_all.h" -#include "type_list_concepts_all.h" -#include - -namespace units { - -struct base_dimension { - const char* name; -}; - -constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs) -{ - const char* p1 = lhs.name; - const char* p2 = rhs.name; - for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { - if (*p1 != *p2) return false; - } - return *p1 == *p2; -} - -constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs) -{ - const char* p1 = lhs.name; - const char* p2 = rhs.name; - for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { - if (*p1 < *p2) return true; - if (*p2 < *p1) return false; - } - return (*p1 == '\0') && (*p2 != '\0'); -} - -// base_dimension_less - -template - struct base_dimension_less : std::bool_constant < D1 {}; - -// exponent - -template -struct exponent { - static constexpr const base_dimension& dimension = BaseDimension; - static constexpr std::intmax_t num = Num; - static constexpr std::intmax_t den = Den; -}; - -// is_exponent -namespace detail { -template -inline constexpr bool is_exponent = false; - -template -inline constexpr bool is_exponent> = true; -} // namespace detail - -template -concept Exponent = detail::is_exponent; - -// exp_dim_id_less - -template -struct exponent_less : base_dimension_less {}; - -// exponent_invert - -template -struct exponent_invert; - -template -struct exponent_invert> { - using type = exponent; -}; - -template -using exponent_invert_t = exponent_invert::type; - -// dimension - -template -struct dimension : downcast_base> {}; - -// is_dimension -namespace detail { - -template -inline constexpr bool is_dimension = false; - -template -inline constexpr bool is_dimension> = true; - -} // namespace detail - -template -concept Dimension = std::is_empty_v && detail::is_dimension>; - - -// dim_invert - -template -struct dim_invert; - -template -struct dim_invert> : std::type_identity...>>> {}; - -template -using dim_invert_t = dim_invert::type; - - -// make_dimension - -namespace detail { - -template -struct dim_consolidate; - -template -using dim_consolidate_t = dim_consolidate::type; - -template<> -struct dim_consolidate> { - using type = dimension<>; -}; - -template -struct dim_consolidate> { - using type = dimension; -}; - -template -struct dim_consolidate> { - using rest = dim_consolidate_t>; - using type = conditional>, dimension, type_list_push_front>; -}; - -template -struct dim_consolidate, exponent, ERest...>> { - using r1 = std::ratio; - using r2 = std::ratio; - using r = std::ratio_add; - using type = conditional>, - dim_consolidate_t, ERest...>>>; -}; - -} // namespace detail - -template -struct make_dimension { - using type = detail::dim_consolidate_t, exponent_less>>; -}; - -template -using make_dimension_t = make_dimension::type; - -template -struct merge_dimension { - using type = detail::dim_consolidate_t>; -}; - -template -using merge_dimension_t = merge_dimension::type; - -// dimension_multiply - -template -struct dimension_multiply; - -template -struct dimension_multiply, dimension> : - std::type_identity, dimension>>> {}; - -template -using dimension_multiply_t = dimension_multiply::type; - -// dimension_divide - -template -struct dimension_divide; - -template -struct dimension_divide, dimension> : - dimension_multiply, dimension...>> {}; - -template -using dimension_divide_t = dimension_divide::type; - -} // namespace units diff --git a/test/metabench/make_dimension/dimension_concepts_iface.h b/test/metabench/make_dimension/dimension_concepts_iface.h deleted file mode 100644 index 44b20ce5..00000000 --- a/test/metabench/make_dimension/dimension_concepts_iface.h +++ /dev/null @@ -1,211 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "downcasting_concepts_all.h" -#include "ratio_concepts_iface.h" -#include "type_list_concepts_iface.h" -#include - -namespace units { - -struct base_dimension { - const char* name; -}; - -constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs) -{ - const char* p1 = lhs.name; - const char* p2 = rhs.name; - for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { - if (*p1 != *p2) return false; - } - return *p1 == *p2; -} - -constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs) -{ - const char* p1 = lhs.name; - const char* p2 = rhs.name; - for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { - if (*p1 < *p2) return true; - if (*p2 < *p1) return false; - } - return (*p1 == '\0') && (*p2 != '\0'); -} - -// base_dimension_less - -template - struct base_dimension_less : std::bool_constant < D1 {}; - -// exponent - -template -struct exponent { - static constexpr const base_dimension& dimension = BaseDimension; - static constexpr int num = Num; - static constexpr int den = Den; -}; - -// is_exponent -namespace detail { -template -inline constexpr bool is_exponent = false; - -template -inline constexpr bool is_exponent> = true; -} // namespace detail - -template -concept Exponent = detail::is_exponent; - -// exp_dim_id_less - -template -struct exponent_less : base_dimension_less {}; - -// exponent_invert - -template -struct exponent_invert; - -template -struct exponent_invert> { - using type = exponent; -}; - -template -using exponent_invert_t = exponent_invert::type; - -// dimension - -template -struct dimension : downcast_base> {}; - -// is_dimension -namespace detail { - -template -inline constexpr bool is_dimension = false; - -template -inline constexpr bool is_dimension> = true; - -} // namespace detail - -template -concept Dimension = std::is_empty_v && detail::is_dimension>; - - -// dim_invert - -template -struct dim_invert; - -template -struct dim_invert> : std::type_identity...>>> {}; - -template -using dim_invert_t = dim_invert::type; - - -// make_dimension - -namespace detail { - -template -struct dim_consolidate; - -template -using dim_consolidate_t = dim_consolidate::type; - -template<> -struct dim_consolidate> { - using type = dimension<>; -}; - -template -struct dim_consolidate> { - using type = dimension; -}; - -template -struct dim_consolidate> { - using rest = dim_consolidate_t>; - using type = conditional>, dimension, type_list_push_front>; -}; - -template -struct dim_consolidate, exponent, ERest...>> { - using r1 = std::ratio; - using r2 = std::ratio; - using r = std::ratio_add; - using type = conditional>, - dim_consolidate_t, ERest...>>>; -}; - -} // namespace detail - -template -struct make_dimension { - using type = detail::dim_consolidate_t, exponent_less>>; -}; - -template -using make_dimension_t = make_dimension::type; - -template -struct merge_dimension { - using type = detail::dim_consolidate_t>; -}; - -template -using merge_dimension_t = merge_dimension::type; - -// dimension_multiply - -template -struct dimension_multiply; - -template -struct dimension_multiply, dimension> : - std::type_identity, dimension>>> {}; - -template -using dimension_multiply_t = dimension_multiply::type; - -// dimension_divide - -template -struct dimension_divide; - -template -struct dimension_divide, dimension> : - dimension_multiply, dimension...>> {}; - -template -using dimension_divide_t = dimension_divide::type; - -} // namespace units diff --git a/test/metabench/make_dimension/dimension_no_concepts.h b/test/metabench/make_dimension/dimension_no_concepts.h deleted file mode 100644 index d8706535..00000000 --- a/test/metabench/make_dimension/dimension_no_concepts.h +++ /dev/null @@ -1,184 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "downcasting_no_concepts.h" -#include "ratio_no_concepts.h" -#include "type_list_no_concepts.h" -#include - -namespace units { - -struct base_dimension { - const char* name; -}; - -constexpr bool operator==(const base_dimension& lhs, const base_dimension& rhs) -{ - const char* p1 = lhs.name; - const char* p2 = rhs.name; - for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { - if (*p1 != *p2) return false; - } - return *p1 == *p2; -} - -constexpr bool operator<(const base_dimension& lhs, const base_dimension& rhs) -{ - const char* p1 = lhs.name; - const char* p2 = rhs.name; - for (; (*p1 != '\0') && (*p2 != '\0'); ++p1, (void)++p2) { - if (*p1 < *p2) return true; - if (*p2 < *p1) return false; - } - return (*p1 == '\0') && (*p2 != '\0'); -} - -// base_dimension_less - -template - struct base_dimension_less : std::bool_constant < D1 {}; - -// exponent - -template -struct exponent { - static constexpr const base_dimension& dimension = BaseDimension; - static constexpr std::intmax_t num = Num; - static constexpr std::intmax_t den = Den; -}; - -// exp_dim_id_less - -template -struct exponent_less : base_dimension_less {}; - -// exponent_invert - -template -struct exponent_invert; - -template -struct exponent_invert> { - using type = exponent; -}; - -template -using exponent_invert_t = exponent_invert::type; - -// dimension - -template -struct dimension : downcast_base> {}; - -// dim_invert - -template -struct dim_invert; - -template -struct dim_invert> : std::type_identity...>>> {}; - -template -using dim_invert_t = dim_invert::type; - - -// make_dimension - -namespace detail { - -template -struct dim_consolidate; - -template -using dim_consolidate_t = dim_consolidate::type; - -template<> -struct dim_consolidate> { - using type = dimension<>; -}; - -template -struct dim_consolidate> { - using type = dimension; -}; - -template -struct dim_consolidate> { - using rest = dim_consolidate_t>; - using type = conditional>, dimension, type_list_push_front>; -}; - -template -struct dim_consolidate, exponent, ERest...>> { - using r1 = std::ratio; - using r2 = std::ratio; - using r = std::ratio_add; - using type = conditional>, - dim_consolidate_t, ERest...>>>; -}; - -} // namespace detail - -template -struct make_dimension { - using type = detail::dim_consolidate_t, exponent_less>>; -}; - -template -using make_dimension_t = make_dimension::type; - -template -struct merge_dimension { - using type = detail::dim_consolidate_t>; -}; - -template -using merge_dimension_t = merge_dimension::type; - -// dimension_multiply - -template -struct dimension_multiply; - -template -struct dimension_multiply, dimension> : - std::type_identity, dimension>>> {}; - -template -using dimension_multiply_t = dimension_multiply::type; - -// dimension_divide - -template -struct dimension_divide; - -template -struct dimension_divide, dimension> : - dimension_multiply, dimension...>> {}; - -template -using dimension_divide_t = dimension_divide::type; - -} // namespace units diff --git a/test/metabench/make_dimension/downcasting_concepts_all.h b/test/metabench/make_dimension/downcasting_concepts_all.h deleted file mode 100644 index c08161c9..00000000 --- a/test/metabench/make_dimension/downcasting_concepts_all.h +++ /dev/null @@ -1,48 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "hacks.h" -#include - -namespace units { - -template -struct downcast_base { - using downcast_base_type = BaseType; -}; - -template -concept Downcastable = - requires { typename T::downcast_base_type; } && std::derived_from>; - -template -using downcast_base_t = T::downcast_base_type; - -template -struct downcast_traits : std::type_identity {}; - -template -using downcast_traits_t = downcast_traits::type; - -} // namespace units diff --git a/test/metabench/make_dimension/hacks.h b/test/metabench/make_dimension/hacks.h deleted file mode 100644 index b95278a9..00000000 --- a/test/metabench/make_dimension/hacks.h +++ /dev/null @@ -1,36 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace std { - -// concepts -using concepts::convertible_to; -using concepts::derived_from; -using concepts::regular; -using concepts::same_as; -using concepts::totally_ordered; - -} // namespace std diff --git a/test/metabench/make_dimension/no_concepts.cpp.erb b/test/metabench/make_dimension/no_concepts.cpp.erb deleted file mode 100644 index 4f010f0d..00000000 --- a/test/metabench/make_dimension/no_concepts.cpp.erb +++ /dev/null @@ -1,23 +0,0 @@ -#include "dimension_no_concepts.h" - -<% (1..100).each do |k| %> -struct test<%= k %> { - <% (1..n).each do |i| %> - static constexpr units::base_dimension dim<%= i %>{"dim<%= i %>"}; - <% end %> - -#if defined(METABENCH) - using dim = units::make_dimension_t<<%= - xs = ((1)..(n)).map { |j| "units::exponent" } - rng = Random.new(k) - xs.shuffle(random: rng).join(', ') - %>>; -#else - using dim = void; -#endif -}; -<% end %> - -int main() -{ -} diff --git a/test/metabench/make_dimension/ratio_concepts_all.h b/test/metabench/make_dimension/ratio_concepts_all.h deleted file mode 100644 index 344a8511..00000000 --- a/test/metabench/make_dimension/ratio_concepts_all.h +++ /dev/null @@ -1,140 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "hacks.h" -#include -#include -#include - -namespace units { - -namespace detail { - -template -[[nodiscard]] constexpr T abs(T v) noexcept -{ - return v < 0 ? -v : v; -} - -} // namespace detail - -template -struct ratio { - static_assert(Den != 0, "zero denominator"); - static_assert(-INTMAX_MAX <= Num, "numerator too negative"); - static_assert(-INTMAX_MAX <= Den, "denominator too negative"); - - static constexpr std::intmax_t num = Num * (Den < 0 ? -1 : 1) / std::gcd(Num, Den); - static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den); - - using type = ratio; -}; - -// is_ratio - -namespace detail { - -template -inline constexpr bool is_ratio = false; - -template -inline constexpr bool is_ratio> = true; - -} // namespace detail - -template -concept Ratio = detail::is_ratio; - -// ratio_multiply - -namespace detail { - -static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs) -{ - constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4); - - const std::uintmax_t a0 = detail::abs(lhs) % c; - const std::uintmax_t a1 = detail::abs(lhs) / c; - const std::uintmax_t b0 = detail::abs(rhs) % c; - const std::uintmax_t b1 = detail::abs(rhs) / c; - - Expects(a1 == 0 || b1 == 0); // overflow in multiplication - Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication - Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication - Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication - - return lhs * rhs; -} - -template -struct ratio_multiply_impl { -private: - static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den); - static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den); - -public: - using type = ratio; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_multiply = detail::ratio_multiply_impl::type; - -// ratio_divide - -namespace detail { - -template -struct ratio_divide_impl { - static_assert(R2::num != 0, "division by 0"); - using type = ratio_multiply>; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_divide = detail::ratio_divide_impl::type; - -// common_ratio - -namespace detail { - -template -struct common_ratio_impl { - static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num); - static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den); - using type = ratio; -}; - -} // namespace detail - -template -using common_ratio = detail::common_ratio_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/ratio_concepts_iface.h b/test/metabench/make_dimension/ratio_concepts_iface.h deleted file mode 100644 index fe59c2ca..00000000 --- a/test/metabench/make_dimension/ratio_concepts_iface.h +++ /dev/null @@ -1,140 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "hacks.h" -#include -#include -#include - -namespace units { - -namespace detail { - -template -[[nodiscard]] constexpr T abs(T v) noexcept -{ - return v < 0 ? -v : v; -} - -} // namespace detail - -template -struct ratio { - static_assert(Den != 0, "zero denominator"); - static_assert(-INTMAX_MAX <= Num, "numerator too negative"); - static_assert(-INTMAX_MAX <= Den, "denominator too negative"); - - static constexpr std::intmax_t num = Num * (Den < 0 ? -1 : 1) / std::gcd(Num, Den); - static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den); - - using type = ratio; -}; - -// is_ratio - -namespace detail { - -template -inline constexpr bool is_ratio = false; - -template -inline constexpr bool is_ratio> = true; - -} // namespace detail - -template -concept Ratio = detail::is_ratio; - -// ratio_multiply - -namespace detail { - -static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs) -{ - constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4); - - const std::uintmax_t a0 = detail::abs(lhs) % c; - const std::uintmax_t a1 = detail::abs(lhs) / c; - const std::uintmax_t b0 = detail::abs(rhs) % c; - const std::uintmax_t b1 = detail::abs(rhs) / c; - - Expects(a1 == 0 || b1 == 0); // overflow in multiplication - Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication - Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication - Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication - - return lhs * rhs; -} - -template -struct ratio_multiply_impl { -private: - static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den); - static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den); - -public: - using type = ratio; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_multiply = detail::ratio_multiply_impl::type; - -// ratio_divide - -namespace detail { - -template -struct ratio_divide_impl { - static_assert(R2::num != 0, "division by 0"); - using type = ratio_multiply>; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_divide = detail::ratio_divide_impl::type; - -// common_ratio - -namespace detail { - -template -struct common_ratio_impl { - static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num); - static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den); - using type = ratio; -}; - -} // namespace detail - -template -using common_ratio = detail::common_ratio_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/ratio_no_concepts.h b/test/metabench/make_dimension/ratio_no_concepts.h deleted file mode 100644 index fa1b7ba9..00000000 --- a/test/metabench/make_dimension/ratio_no_concepts.h +++ /dev/null @@ -1,125 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "hacks.h" -#include -#include -#include - -namespace units { - -namespace detail { - -template -[[nodiscard]] constexpr T abs(T v) noexcept -{ - return v < 0 ? -v : v; -} - -} // namespace detail - -template -struct ratio { - static_assert(Den != 0, "zero denominator"); - static_assert(-INTMAX_MAX <= Num, "numerator too negative"); - static_assert(-INTMAX_MAX <= Den, "denominator too negative"); - - static constexpr std::intmax_t num = Num * (Den < 0 ? -1 : 1) / std::gcd(Num, Den); - static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den); - - using type = ratio; -}; - -// ratio_multiply - -namespace detail { - -static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs) -{ - constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4); - - const std::uintmax_t a0 = detail::abs(lhs) % c; - const std::uintmax_t a1 = detail::abs(lhs) / c; - const std::uintmax_t b0 = detail::abs(rhs) % c; - const std::uintmax_t b1 = detail::abs(rhs) / c; - - Expects(a1 == 0 || b1 == 0); // overflow in multiplication - Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication - Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication - Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication - - return lhs * rhs; -} - -template -struct ratio_multiply_impl { -private: - static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den); - static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den); - -public: - using type = ratio; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_multiply = detail::ratio_multiply_impl::type; - -// ratio_divide - -namespace detail { - -template -struct ratio_divide_impl { - static_assert(R2::num != 0, "division by 0"); - using type = ratio_multiply>; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_divide = detail::ratio_divide_impl::type; - -// common_ratio - -namespace detail { - -template -struct common_ratio_impl { - static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num); - static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den); - using type = ratio; -}; - -} // namespace detail - -template -using common_ratio = detail::common_ratio_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/type_list_concepts_all.h b/test/metabench/make_dimension/type_list_concepts_all.h deleted file mode 100644 index 80392b3e..00000000 --- a/test/metabench/make_dimension/type_list_concepts_all.h +++ /dev/null @@ -1,186 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "type_traits.h" - -namespace units { - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - conditional < - Idx::type, typename base::first_list>; - using second_list = - conditional < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = conditional< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/type_list_concepts_iface.h b/test/metabench/make_dimension/type_list_concepts_iface.h deleted file mode 100644 index 0737c88b..00000000 --- a/test/metabench/make_dimension/type_list_concepts_iface.h +++ /dev/null @@ -1,186 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "type_traits.h" - -namespace units { - -namespace detail { - -template -inline constexpr bool is_type_list = false; - -template typename T, typename... Types> -inline constexpr bool is_type_list> = true; - -} // namespace detail - -template -concept TypeList = detail::is_type_list; - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - conditional < - Idx::type, typename base::first_list>; - using second_list = - conditional < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = conditional< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/type_list_no_concepts.h b/test/metabench/make_dimension/type_list_no_concepts.h deleted file mode 100644 index 82e40f40..00000000 --- a/test/metabench/make_dimension/type_list_no_concepts.h +++ /dev/null @@ -1,173 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include "type_traits.h" - -namespace units { - -// push_front - -namespace detail { - -template -struct type_list_push_front_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_front_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_front = detail::type_list_push_front_impl::type; - -// push_back - -namespace detail { - -template -struct type_list_push_back_impl; - -template typename List, typename... OldTypes, typename... NewTypes> -struct type_list_push_back_impl, NewTypes...> { - using type = List; -}; - -} // namespace detail - -template -using type_list_push_back = detail::type_list_push_back_impl::type; - -// split - -namespace detail { - -template typename List, std::size_t Idx, std::size_t N, typename... Types> -struct split_impl; - -template typename List, std::size_t Idx, std::size_t N> -struct split_impl { - using first_list = List<>; - using second_list = List<>; -}; - -template typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest> -struct split_impl : split_impl { - using base = split_impl; - using first_list = - conditional < - Idx::type, typename base::first_list>; - using second_list = - conditional < - Idx::type>; -}; - -} // namespace detail - -template -struct type_list_split; - -template typename List, std::size_t N, typename... Types> -struct type_list_split, N> { - static_assert(N <= sizeof...(Types), "Invalid index provided"); - using split = detail::split_impl; - using first_list = split::first_list; - using second_list = split::second_list; -}; - -// split_half - -template -struct type_list_split_half; - -template typename List, typename... Types> -struct type_list_split_half> : type_list_split, (sizeof...(Types) + 1) / 2> {}; - -// merge_sorted - -namespace detail { - -template typename Pred> -struct type_list_merge_sorted_impl; - -template typename List, typename... Lhs, template typename Pred> -struct type_list_merge_sorted_impl, List<>, Pred> { - using type = List; -}; - -template typename List, typename... Rhs, template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = List; -}; - -template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, - template typename Pred> -struct type_list_merge_sorted_impl, List, Pred> { - using type = conditional< - Pred::value, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type, - typename type_list_push_front_impl< - typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type>; -}; - -} // namespace detail - -template typename Pred> -using type_list_merge_sorted = detail::type_list_merge_sorted_impl::type; - - -// sort - -namespace detail { - -template typename Pred> -struct type_list_sort_impl; - -template typename List, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List<>; -}; - -template typename List, typename T, template typename Pred> -struct type_list_sort_impl, Pred> { - using type = List; -}; - -template typename List, typename... Types, template typename Pred> -struct type_list_sort_impl, Pred> { - using types = List; - using split = type_list_split_half>; - using left = type_list_sort_impl::type; - using right = type_list_sort_impl::type; - using type = type_list_merge_sorted_impl::type; -}; - -} // namespace detail - -template typename Pred> -using type_list_sort = detail::type_list_sort_impl::type; - -} // namespace units diff --git a/test/metabench/make_dimension/type_traits.h b/test/metabench/make_dimension/type_traits.h deleted file mode 100644 index 35d7e162..00000000 --- a/test/metabench/make_dimension/type_traits.h +++ /dev/null @@ -1,48 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -namespace units { - -namespace detail { - -template -struct conditional_impl { - template - using type = F; -}; - -template<> -struct conditional_impl { - template - using type = T; -}; - -} // namespace detail - -template -using conditional = TYPENAME detail::conditional_impl::template type; - -} // namespace units diff --git a/test/metabench/ratio/CMakeLists.txt b/test/metabench/ratio/CMakeLists.txt deleted file mode 100644 index a2c38c31..00000000 --- a/test/metabench/ratio/CMakeLists.txt +++ /dev/null @@ -1,86 +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) - -add_metabench_test( - metabench.data.ratio.create.std_ratio "std::ratio" create_std_ratio.cpp.erb "[1000, 2500, 5000, 7500, 10000]" -) -add_metabench_test( - metabench.data.ratio.create.ratio_type_constexpr "ratio with constexpr" create_ratio_type_constexpr.cpp.erb - "[1000, 2500, 5000, 7500, 10000]" -) -metabench_add_chart( - metabench.chart.ratio.create - TITLE "Creation of 2*N ratios" - SUBTITLE "(lower is better)" - DATASETS metabench.data.ratio.create.std_ratio metabench.data.ratio.create.ratio_type_constexpr -) - -add_metabench_test( - metabench.data.ratio.multiply_divide.std_ratio "std::ratio" multiply_divide_std_ratio.cpp.erb - "[10, 50, 100, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000]" -) -add_metabench_test( - metabench.data.ratio.multiply_divide.ratio_type_constexpr "ratio constexpr" - multiply_divide_ratio_type_constexpr.cpp.erb "[10, 50, 100, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000]" -) -metabench_add_chart( - metabench.chart.ratio.multiply_divide - TITLE "N ratio multiply + divide operations" - SUBTITLE "(lower is better)" - DATASETS metabench.data.ratio.multiply_divide.std_ratio metabench.data.ratio.multiply_divide.ratio_type_constexpr -) - -add_metabench_test( - metabench.data.ratio.common_ratio.std_ratio "std::ratio" common_ratio_std_ratio.cpp.erb - "[10, 50, 100, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000]" -) -add_metabench_test( - metabench.data.ratio.common_ratio.ratio_type_constexpr "ratio constexpr" common_ratio_ratio_type_constexpr.cpp.erb - "[10, 50, 100, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000]" -) -metabench_add_chart( - metabench.chart.ratio.common_ratio - TITLE "N common_ratio operations" - SUBTITLE "(lower is better)" - DATASETS metabench.data.ratio.common_ratio.std_ratio metabench.data.ratio.common_ratio.ratio_type_constexpr -) - -add_metabench_test(metabench.data.ratio.all.std_ratio "std::ratio" all_std_ratio.cpp.erb "[10, 50, 100, 500, 1000]") -add_metabench_test( - metabench.data.ratio.all.ratio_type_constexpr "ratio with constexpr" all_ratio_type_constexpr.cpp.erb - "[10, 50, 100, 500, 1000]" -) -metabench_add_chart( - metabench.chart.ratio.all - TITLE "N x all ratio operations" - SUBTITLE "(lower is better)" - DATASETS metabench.data.ratio.all.std_ratio metabench.data.ratio.all.ratio_type_constexpr -) - -add_custom_target( - metabench.chart.ratio DEPENDS metabench.chart.ratio.create metabench.chart.ratio.multiply_divide - metabench.chart.ratio.common_ratio metabench.chart.ratio.all -) - -add_dependencies(metabench metabench.chart.ratio) diff --git a/test/metabench/ratio/all_ratio_type_constexpr.cpp.erb b/test/metabench/ratio/all_ratio_type_constexpr.cpp.erb deleted file mode 100644 index aa036f58..00000000 --- a/test/metabench/ratio/all_ratio_type_constexpr.cpp.erb +++ /dev/null @@ -1,26 +0,0 @@ -#include "ratio_type_constexpr.h" - -<% (1..n).each do |i| %> - struct test<%= i %> { -#if defined(METABENCH) - using r1 = units::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = units::ratio<<%= 2 * i %>, <%= 2 * n %>>; - - using r3 = units::ratio_multiply; - using r4 = units::ratio_divide; - - using r5 = units::common_ratio_t; -#else - using r1 = void; - using r2 = void; - using r3 = void; - using r4 = void; - using r5 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/all_std_ratio.cpp.erb b/test/metabench/ratio/all_std_ratio.cpp.erb deleted file mode 100644 index 2d34bc82..00000000 --- a/test/metabench/ratio/all_std_ratio.cpp.erb +++ /dev/null @@ -1,26 +0,0 @@ -#include "std_ratio.h" - -<% (1..n).each do |i| %> - struct test<%= i %> { -#if defined(METABENCH) - using r1 = std::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = std::ratio<<%= 2 * i %>, <%= 2 * n %>>; - - using r3 = std::ratio_multiply; - using r4 = std::ratio_divide; - - using r5 = units::common_ratio_t; -#else - using r1 = void; - using r2 = void; - using r3 = void; - using r4 = void; - using r5 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/common_ratio_ratio_type_constexpr.cpp.erb b/test/metabench/ratio/common_ratio_ratio_type_constexpr.cpp.erb deleted file mode 100644 index 23daae35..00000000 --- a/test/metabench/ratio/common_ratio_ratio_type_constexpr.cpp.erb +++ /dev/null @@ -1,19 +0,0 @@ -#include "ratio_type_constexpr.h" - -<% (1..n).each do |i| %> - struct test<%= i %> { - using r1 = units::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = units::ratio<<%= 2 * i %>, <%= 2 * n %>>; - -#if defined(METABENCH) - using r3 = units::common_ratio_t; -#else - using r3 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/common_ratio_std_ratio.cpp.erb b/test/metabench/ratio/common_ratio_std_ratio.cpp.erb deleted file mode 100644 index 5885f4f9..00000000 --- a/test/metabench/ratio/common_ratio_std_ratio.cpp.erb +++ /dev/null @@ -1,19 +0,0 @@ -#include "std_ratio.h" - -<% (1..n).each do |i| %> - struct test<%= i %> { - using r1 = std::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = std::ratio<<%= 2 * i %>, <%= 2 * n %>>; - -#if defined(METABENCH) - using r3 = units::common_ratio_t; -#else - using r3 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/create_ratio_type_constexpr.cpp.erb b/test/metabench/ratio/create_ratio_type_constexpr.cpp.erb deleted file mode 100644 index 145cc852..00000000 --- a/test/metabench/ratio/create_ratio_type_constexpr.cpp.erb +++ /dev/null @@ -1,18 +0,0 @@ -#include "ratio_type_constexpr.h" - -<% (1..n).each do |i| %> - struct test<%= i %> { -#if defined(METABENCH) - using r1 = units::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = units::ratio<<%= 2 * i %>, <%= 2 * n %>>; -#else - using r1 = void; - using r2 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/create_std_ratio.cpp.erb b/test/metabench/ratio/create_std_ratio.cpp.erb deleted file mode 100644 index eafe36a1..00000000 --- a/test/metabench/ratio/create_std_ratio.cpp.erb +++ /dev/null @@ -1,18 +0,0 @@ -#include - -<% (1..n).each do |i| %> - struct test<%= i %> { -#if defined(METABENCH) - using r1 = std::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = std::ratio<<%= 2 * i %>, <%= 2 * n %>>; -#else - using r1 = void; - using r2 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/multiply_divide_ratio_type_constexpr.cpp.erb b/test/metabench/ratio/multiply_divide_ratio_type_constexpr.cpp.erb deleted file mode 100644 index 9bdf1577..00000000 --- a/test/metabench/ratio/multiply_divide_ratio_type_constexpr.cpp.erb +++ /dev/null @@ -1,21 +0,0 @@ -#include "ratio_type_constexpr.h" - -<% (1..n).each do |i| %> - struct test<%= i %> { - using r1 = units::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = units::ratio<<%= 2 * i %>, <%= 2 * n %>>; - -#if defined(METABENCH) - using r3 = units::ratio_multiply; - using r4 = units::ratio_divide; -#else - using r3 = void; - using r4 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/multiply_divide_std_ratio.cpp.erb b/test/metabench/ratio/multiply_divide_std_ratio.cpp.erb deleted file mode 100644 index 5a5c2f17..00000000 --- a/test/metabench/ratio/multiply_divide_std_ratio.cpp.erb +++ /dev/null @@ -1,21 +0,0 @@ -#include - -<% (1..n).each do |i| %> - struct test<%= i %> { - using r1 = std::ratio<<%= 2 * i - 1 %>, <%= 2 * n %>>; - using r2 = std::ratio<<%= 2 * i %>, <%= 2 * n %>>; - -#if defined(METABENCH) - using r3 = std::ratio_multiply; - using r4 = std::ratio_divide; -#else - using r3 = void; - using r4 = void; -#endif - }; -<% end %> - - -int main() -{ -} diff --git a/test/metabench/ratio/ratio_type_constexpr.cpp.erb b/test/metabench/ratio/ratio_type_constexpr.cpp.erb deleted file mode 100644 index 2fe0c819..00000000 --- a/test/metabench/ratio/ratio_type_constexpr.cpp.erb +++ /dev/null @@ -1,20 +0,0 @@ -#include "ratio_type_constexpr.h" - -#if defined(METABENCH) -<% (1..n).each do |i| %> - struct test<%= i %> { - using r1 = units::ratio<<%= i %>, <%= n + 1 - i %>>; - using r2 = units::ratio<<%= n + 1 - i %>, <%= i %>>; - - using r3 = units::ratio_multiply; - using r4 = units::ratio_divide; - - using r5 = units::common_ratio_t; - }; -<% end %> -#endif - - -int main() -{ -} diff --git a/test/metabench/ratio/ratio_type_constexpr.h b/test/metabench/ratio/ratio_type_constexpr.h deleted file mode 100644 index 86e2c0d6..00000000 --- a/test/metabench/ratio/ratio_type_constexpr.h +++ /dev/null @@ -1,128 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include -#include -#include - -#define Expects(cond) \ - if (!(cond)) ::std::terminate(); - -namespace units { - -namespace detail { - -template -[[nodiscard]] constexpr T abs(T v) noexcept -{ - return v < 0 ? -v : v; -} - -} // namespace detail - -template -struct ratio { - static_assert(Den != 0, "zero denominator"); - static_assert(-INTMAX_MAX <= Num, "numerator too negative"); - static_assert(-INTMAX_MAX <= Den, "denominator too negative"); - - static constexpr std::intmax_t num = Num * (Den < 0 ? -1 : 1) / std::gcd(Num, Den); - static constexpr std::intmax_t den = detail::abs(Den) / std::gcd(Num, Den); - - using type = ratio; -}; - -// ratio_multiply - -namespace detail { - -static constexpr std::intmax_t safe_multiply(std::intmax_t lhs, std::intmax_t rhs) -{ - constexpr std::uintmax_t c = std::uintmax_t(1) << (sizeof(std::intmax_t) * 4); - - const std::uintmax_t a0 = detail::abs(lhs) % c; - const std::uintmax_t a1 = detail::abs(lhs) / c; - const std::uintmax_t b0 = detail::abs(rhs) % c; - const std::uintmax_t b1 = detail::abs(rhs) / c; - - Expects(a1 == 0 || b1 == 0); // overflow in multiplication - Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication - Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication - Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication - - return lhs * rhs; -} - -template -struct ratio_multiply { -private: - static constexpr std::intmax_t gcd1 = std::gcd(R1::num, R2::den); - static constexpr std::intmax_t gcd2 = std::gcd(R2::num, R1::den); - -public: - using type = ratio; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_multiply = typename detail::ratio_multiply::type; - -// ratio_divide - -namespace detail { - -template -struct ratio_divide { - static_assert(R2::num != 0, "division by 0"); - using type = ratio_multiply>; - static constexpr std::intmax_t num = type::num; - static constexpr std::intmax_t den = type::den; -}; - -} // namespace detail - -template -using ratio_divide = typename detail::ratio_divide::type; - -// common_ratio - -namespace detail { - -template -struct common_ratio_impl { - static constexpr std::intmax_t gcd_num = std::gcd(R1::num, R2::num); - static constexpr std::intmax_t gcd_den = std::gcd(R1::den, R2::den); - using type = ratio; -}; - -} // namespace detail - -template -using common_ratio_t = typename detail::common_ratio_impl::type; - -} // namespace units diff --git a/test/metabench/ratio/std_ratio.h b/test/metabench/ratio/std_ratio.h deleted file mode 100644 index 459b5acd..00000000 --- a/test/metabench/ratio/std_ratio.h +++ /dev/null @@ -1,63 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018 Mateusz Pusz -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -namespace units { - -// static_sign - -template -struct static_sign : std::integral_constant {}; - -// static_abs - -template -struct static_abs : std::integral_constant::value> {}; - -// static_gcd - -template -struct static_gcd : static_gcd {}; - -template -struct static_gcd : std::integral_constant::value> {}; - -template -struct static_gcd<0, Qn> : std::integral_constant::value> {}; - -// common_ratio - -template -struct common_ratio { - using gcd_num = static_gcd; - using gcd_den = static_gcd; - using type = std::ratio; -}; - -template -using common_ratio_t = typename common_ratio::type; - -} // namespace units diff --git a/test/unit_test/runtime/CMakeLists.txt b/test/unit_test/runtime/CMakeLists.txt index 61a67670..ae7936b6 100644 --- a/test/unit_test/runtime/CMakeLists.txt +++ b/test/unit_test/runtime/CMakeLists.txt @@ -24,11 +24,15 @@ cmake_minimum_required(VERSION 3.2) find_package(Catch2 3 CONFIG REQUIRED) -add_executable( - unit_tests_runtime math_test.cpp magnitude_test.cpp fmt_test.cpp fmt_units_test.cpp distribution_test.cpp -) +add_executable(unit_tests_runtime distribution_test.cpp fmt_test.cpp math_test.cpp) target_link_libraries(unit_tests_runtime PRIVATE mp-units::mp-units Catch2::Catch2WithMain) +if(${projectPrefix}BUILD_LA) + find_package(wg21_linear_algebra CONFIG REQUIRED) + target_sources(unit_tests_runtime PRIVATE linear_algebra_test.cpp) + target_link_libraries(unit_tests_runtime PRIVATE wg21_linear_algebra::wg21_linear_algebra) +endif() + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") target_compile_options( unit_tests_runtime PRIVATE /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data diff --git a/test/unit_test/runtime/almost_equals.h b/test/unit_test/runtime/almost_equals.h index 19d4ed8e..1671f39c 100644 --- a/test/unit_test/runtime/almost_equals.h +++ b/test/unit_test/runtime/almost_equals.h @@ -21,16 +21,16 @@ // SOFTWARE. #include -#include -#include +#include +#include -namespace units { +namespace mp_units { template struct AlmostEqualsMatcher : Catch::Matchers::MatcherGenericBase { AlmostEqualsMatcher(const T& target) : target_{target} {} - template U> + template U> requires std::same_as && treat_as_floating_point bool match(const U& other) const { @@ -54,4 +54,4 @@ AlmostEqualsMatcher AlmostEquals(const T& target) return {target}; } -} // namespace units +} // namespace mp_units diff --git a/test/unit_test/runtime/distribution_test.cpp b/test/unit_test/runtime/distribution_test.cpp index 65120cf0..d2b31327 100644 --- a/test/unit_test/runtime/distribution_test.cpp +++ b/test/unit_test/runtime/distribution_test.cpp @@ -21,26 +21,26 @@ // SOFTWARE. #include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include -using namespace units; -using namespace units::isq::si; +using namespace mp_units; TEST_CASE("uniform_int_distribution") { using rep = std::int64_t; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::uniform_int_distribution(); + auto dist = mp_units::uniform_int_distribution(); CHECK(dist.a() == q::zero()); CHECK(dist.b() == q::max()); @@ -52,23 +52,23 @@ TEST_CASE("uniform_int_distribution") constexpr rep b = 5; auto stl_dist = std::uniform_int_distribution(a, b); - auto units_dist = units::uniform_int_distribution(q(a), q(b)); + auto units_dist = mp_units::uniform_int_distribution(a * si::metre, b * si::metre); - CHECK(units_dist.a() == q(stl_dist.a())); - CHECK(units_dist.b() == q(stl_dist.b())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.a() == stl_dist.a() * si::metre); + CHECK(units_dist.b() == stl_dist.b() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("uniform_real_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::uniform_real_distribution(); + auto dist = mp_units::uniform_real_distribution(); CHECK(dist.a() == q::zero()); CHECK(dist.b() == q::one()); @@ -80,23 +80,23 @@ TEST_CASE("uniform_real_distribution") constexpr rep b = 5.0; auto stl_dist = std::uniform_real_distribution(a, b); - auto units_dist = units::uniform_real_distribution(q(a), q(b)); + auto units_dist = mp_units::uniform_real_distribution(a * si::metre, b * si::metre); - CHECK(units_dist.a() == q(stl_dist.a())); - CHECK(units_dist.b() == q(stl_dist.b())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.a() == stl_dist.a() * si::metre); + CHECK(units_dist.b() == stl_dist.b() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("binomial_distribution") { using rep = std::int64_t; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::binomial_distribution(); + auto dist = mp_units::binomial_distribution(); CHECK(dist.p() == 0.5); CHECK(dist.t() == q::one()); @@ -108,23 +108,23 @@ TEST_CASE("binomial_distribution") constexpr double p = 0.25; auto stl_dist = std::binomial_distribution(t, p); - auto units_dist = units::binomial_distribution(q(t), p); + auto units_dist = mp_units::binomial_distribution(t * si::metre, p); CHECK(units_dist.p() == stl_dist.p()); - CHECK(units_dist.t() == q(stl_dist.t())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.t() == stl_dist.t() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("negative_binomial_distribution") { using rep = std::int64_t; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::negative_binomial_distribution(); + auto dist = mp_units::negative_binomial_distribution(); CHECK(dist.p() == 0.5); CHECK(dist.k() == q::one()); @@ -136,23 +136,23 @@ TEST_CASE("negative_binomial_distribution") constexpr double p = 0.25; auto stl_dist = std::negative_binomial_distribution(k, p); - auto units_dist = units::negative_binomial_distribution(q(k), p); + auto units_dist = mp_units::negative_binomial_distribution(k * si::metre, p); CHECK(units_dist.p() == stl_dist.p()); - CHECK(units_dist.k() == q(stl_dist.k())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.k() == stl_dist.k() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("geometric_distribution") { using rep = std::int64_t; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::geometric_distribution(); + auto dist = mp_units::geometric_distribution(); CHECK(dist.p() == 0.5); } @@ -162,22 +162,22 @@ TEST_CASE("geometric_distribution") constexpr double p = 0.25; auto stl_dist = std::geometric_distribution(p); - auto units_dist = units::geometric_distribution(p); + auto units_dist = mp_units::geometric_distribution(p); CHECK(units_dist.p() == stl_dist.p()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("poisson_distribution") { using rep = std::int64_t; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::poisson_distribution(); + auto dist = mp_units::poisson_distribution(); CHECK(dist.mean() == 1.0); } @@ -187,22 +187,22 @@ TEST_CASE("poisson_distribution") constexpr double mean = 5.0; auto stl_dist = std::poisson_distribution(mean); - auto units_dist = units::poisson_distribution(mean); + auto units_dist = mp_units::poisson_distribution(mean); CHECK(units_dist.mean() == stl_dist.mean()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("exponential_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::exponential_distribution(); + auto dist = mp_units::exponential_distribution(); CHECK(dist.lambda() == 1.0); } @@ -212,22 +212,22 @@ TEST_CASE("exponential_distribution") constexpr double lambda = 2.0; auto stl_dist = std::exponential_distribution(lambda); - auto units_dist = units::exponential_distribution(lambda); + auto units_dist = mp_units::exponential_distribution(lambda); CHECK(units_dist.lambda() == stl_dist.lambda()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("gamma_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::gamma_distribution(); + auto dist = mp_units::gamma_distribution(); CHECK(dist.alpha() == 1.0); CHECK(dist.beta() == 1.0); @@ -239,23 +239,23 @@ TEST_CASE("gamma_distribution") constexpr double beta = 2.0; auto stl_dist = std::gamma_distribution(alpha, beta); - auto units_dist = units::gamma_distribution(alpha, beta); + auto units_dist = mp_units::gamma_distribution(alpha, beta); CHECK(units_dist.alpha() == stl_dist.alpha()); CHECK(units_dist.beta() == stl_dist.beta()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("weibull_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::weibull_distribution(); + auto dist = mp_units::weibull_distribution(); CHECK(dist.a() == 1.0); CHECK(dist.b() == 1.0); @@ -267,23 +267,23 @@ TEST_CASE("weibull_distribution") constexpr rep b = 2.0; auto stl_dist = std::weibull_distribution(a, b); - auto units_dist = units::weibull_distribution(a, b); + auto units_dist = mp_units::weibull_distribution(a, b); CHECK(units_dist.a() == stl_dist.a()); CHECK(units_dist.b() == stl_dist.b()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("extreme_value_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::extreme_value_distribution(); + auto dist = mp_units::extreme_value_distribution(); CHECK(dist.a() == q::zero()); CHECK(dist.b() == 1.0); @@ -295,23 +295,23 @@ TEST_CASE("extreme_value_distribution") constexpr rep b = 2.0; auto stl_dist = std::extreme_value_distribution(a, b); - auto units_dist = units::extreme_value_distribution(q(a), b); + auto units_dist = mp_units::extreme_value_distribution(a * si::metre, b); - CHECK(units_dist.a() == q(stl_dist.a())); + CHECK(units_dist.a() == stl_dist.a() * si::metre); CHECK(units_dist.b() == stl_dist.b()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("normal_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::normal_distribution(); + auto dist = mp_units::normal_distribution(); CHECK(dist.mean() == q::zero()); CHECK(dist.stddev() == q::one()); @@ -323,23 +323,23 @@ TEST_CASE("normal_distribution") constexpr rep stddev = 2.0; auto stl_dist = std::normal_distribution(mean, stddev); - auto units_dist = units::normal_distribution(q(mean), q(stddev)); + auto units_dist = mp_units::normal_distribution(mean * si::metre, stddev * si::metre); - CHECK(units_dist.mean() == q(stl_dist.mean())); - CHECK(units_dist.stddev() == q(stl_dist.stddev())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.mean() == stl_dist.mean() * si::metre); + CHECK(units_dist.stddev() == stl_dist.stddev() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("lognormal_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::lognormal_distribution(); + auto dist = mp_units::lognormal_distribution(); CHECK(dist.m() == q::zero()); CHECK(dist.s() == q::one()); @@ -351,23 +351,23 @@ TEST_CASE("lognormal_distribution") constexpr rep s = 2.0; auto stl_dist = std::lognormal_distribution(m, s); - auto units_dist = units::lognormal_distribution(q(m), q(s)); + auto units_dist = mp_units::lognormal_distribution(m * si::metre, s * si::metre); - CHECK(units_dist.m() == q(stl_dist.m())); - CHECK(units_dist.s() == q(stl_dist.s())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.m() == stl_dist.m() * si::metre); + CHECK(units_dist.s() == stl_dist.s() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("chi_squared_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::chi_squared_distribution(); + auto dist = mp_units::chi_squared_distribution(); CHECK(dist.n() == 1.0); } @@ -377,22 +377,22 @@ TEST_CASE("chi_squared_distribution") constexpr rep n = 5.0; auto stl_dist = std::chi_squared_distribution(n); - auto units_dist = units::chi_squared_distribution(n); + auto units_dist = mp_units::chi_squared_distribution(n); CHECK(units_dist.n() == stl_dist.n()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("cauchy_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::cauchy_distribution(); + auto dist = mp_units::cauchy_distribution(); CHECK(dist.a() == q::zero()); CHECK(dist.b() == q::one()); @@ -404,23 +404,23 @@ TEST_CASE("cauchy_distribution") constexpr rep b = 2.0; auto stl_dist = std::cauchy_distribution(a, b); - auto units_dist = units::cauchy_distribution(q(a), q(b)); + auto units_dist = mp_units::cauchy_distribution(a * si::metre, b * si::metre); - CHECK(units_dist.a() == q(stl_dist.a())); - CHECK(units_dist.b() == q(stl_dist.b())); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.a() == stl_dist.a() * si::metre); + CHECK(units_dist.b() == stl_dist.b() * si::metre); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("fisher_f_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::fisher_f_distribution(); + auto dist = mp_units::fisher_f_distribution(); CHECK(dist.m() == 1.0); CHECK(dist.n() == 1.0); @@ -432,23 +432,23 @@ TEST_CASE("fisher_f_distribution") constexpr rep n = 2.0; auto stl_dist = std::fisher_f_distribution(m, n); - auto units_dist = units::fisher_f_distribution(m, n); + auto units_dist = mp_units::fisher_f_distribution(m, n); CHECK(units_dist.m() == stl_dist.m()); CHECK(units_dist.n() == stl_dist.n()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("student_t_distribution") { using rep = long double; - using q = length; + using q = quantity; SECTION("default") { - auto dist = units::student_t_distribution(); + auto dist = mp_units::student_t_distribution(); CHECK(dist.n() == 1.0); } @@ -458,26 +458,26 @@ TEST_CASE("student_t_distribution") constexpr rep n = 2.0; auto stl_dist = std::student_t_distribution(n); - auto units_dist = units::student_t_distribution(n); + auto units_dist = mp_units::student_t_distribution(n); CHECK(units_dist.n() == stl_dist.n()); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); } } TEST_CASE("discrete_distribution") { using rep = std::int64_t; - using q = length; + using q = quantity; SECTION("default") { auto stl_dist = std::discrete_distribution(); - auto units_dist = units::discrete_distribution(); + auto units_dist = mp_units::discrete_distribution(); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); CHECK(units_dist.probabilities() == stl_dist.probabilities()); } @@ -486,7 +486,7 @@ TEST_CASE("discrete_distribution") constexpr std::array weights = {1.0, 2.0, 3.0}; auto stl_dist = std::discrete_distribution(weights.cbegin(), weights.cend()); - auto units_dist = units::discrete_distribution(weights.cbegin(), weights.cend()); + auto units_dist = mp_units::discrete_distribution(weights.cbegin(), weights.cend()); CHECK(units_dist.probabilities() == stl_dist.probabilities()); } @@ -496,7 +496,7 @@ TEST_CASE("discrete_distribution") std::initializer_list weights = {1.0, 2.0, 3.0}; auto stl_dist = std::discrete_distribution(weights); - auto units_dist = units::discrete_distribution(weights); + auto units_dist = mp_units::discrete_distribution(weights); CHECK(units_dist.probabilities() == stl_dist.probabilities()); } @@ -507,7 +507,7 @@ TEST_CASE("discrete_distribution") constexpr double xmin = 1, xmax = 3; auto stl_dist = std::discrete_distribution(count, xmin, xmax, [](double val) { return val; }); - auto units_dist = units::discrete_distribution(count, xmin, xmax, [](double val) { return val; }); + auto units_dist = mp_units::discrete_distribution(count, xmin, xmax, [](double val) { return val; }); CHECK(units_dist.probabilities() == stl_dist.probabilities()); } @@ -516,18 +516,19 @@ TEST_CASE("discrete_distribution") TEST_CASE("piecewise_constant_distribution") { using rep = long double; - using q = length; + using q = quantity; std::vector intervals_rep_vec = {1.0, 2.0, 3.0}; - std::vector intervals_qty_vec = {1.0_q_m, 2.0_q_m, 3.0_q_m}; + std::vector intervals_qty_vec = {1.0 * isq::length[si::metre], 2.0 * isq::length[si::metre], + 3.0 * isq::length[si::metre]}; SECTION("default") { auto stl_dist = std::piecewise_constant_distribution(); - auto units_dist = units::piecewise_constant_distribution(); + auto units_dist = mp_units::piecewise_constant_distribution(); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); CHECK(stl_dist.intervals().size() == 2); CHECK(units_dist.intervals().size() == 2); CHECK(stl_dist.densities().size() == 1); @@ -537,13 +538,14 @@ TEST_CASE("piecewise_constant_distribution") SECTION("parametrized_input_it") { constexpr std::array intervals_rep = {1.0, 2.0, 3.0}; - constexpr std::array intervals_qty = {1.0_q_m, 2.0_q_m, 3.0_q_m}; + constexpr std::array intervals_qty = {1.0 * isq::length[si::metre], 2.0 * isq::length[si::metre], + 3.0 * isq::length[si::metre]}; constexpr std::array weights = {1.0, 2.0, 3.0}; auto stl_dist = std::piecewise_constant_distribution(intervals_rep.cbegin(), intervals_rep.cend(), weights.cbegin()); auto units_dist = - units::piecewise_constant_distribution(intervals_qty.cbegin(), intervals_qty.cend(), weights.cbegin()); + mp_units::piecewise_constant_distribution(intervals_qty.cbegin(), intervals_qty.cend(), weights.cbegin()); CHECK(stl_dist.intervals() == intervals_rep_vec); CHECK(units_dist.intervals() == intervals_qty_vec); @@ -553,10 +555,11 @@ TEST_CASE("piecewise_constant_distribution") SECTION("parametrized_initializer_list") { std::initializer_list intervals_rep = {1.0, 2.0, 3.0}; - std::initializer_list intervals_qty = {1.0_q_m, 2.0_q_m, 3.0_q_m}; + std::initializer_list intervals_qty = {1.0 * isq::length[si::metre], 2.0 * isq::length[si::metre], + 3.0 * isq::length[si::metre]}; auto stl_dist = std::piecewise_constant_distribution(intervals_rep, [](rep val) { return val; }); - auto units_dist = units::piecewise_constant_distribution(intervals_qty, [](q qty) { return qty.number(); }); + auto units_dist = mp_units::piecewise_constant_distribution(intervals_qty, [](q qty) { return qty.number(); }); CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.densities() == stl_dist.densities()); @@ -566,11 +569,11 @@ TEST_CASE("piecewise_constant_distribution") { constexpr std::size_t nw = 2; constexpr rep xmin_rep = 1.0, xmax_rep = 3.0; - constexpr q xmin_qty = 1.0_q_m, xmax_qty = 3.0_q_m; + constexpr q xmin_qty = 1.0 * isq::length[si::metre], xmax_qty = 3.0 * isq::length[si::metre]; auto stl_dist = std::piecewise_constant_distribution(nw, xmin_rep, xmax_rep, [](rep val) { return val; }); auto units_dist = - units::piecewise_constant_distribution(nw, xmin_qty, xmax_qty, [](q qty) { return qty.number(); }); + mp_units::piecewise_constant_distribution(nw, xmin_qty, xmax_qty, [](q qty) { return qty.number(); }); CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.densities() == stl_dist.densities()); @@ -580,18 +583,19 @@ TEST_CASE("piecewise_constant_distribution") TEST_CASE("piecewise_linear_distribution") { using rep = long double; - using q = length; + using q = quantity; std::vector intervals_rep_vec = {1.0, 2.0, 3.0}; - std::vector intervals_qty_vec = {1.0_q_m, 2.0_q_m, 3.0_q_m}; + std::vector intervals_qty_vec = {1.0 * isq::length[si::metre], 2.0 * isq::length[si::metre], + 3.0 * isq::length[si::metre]}; SECTION("default") { auto stl_dist = std::piecewise_linear_distribution(); - auto units_dist = units::piecewise_linear_distribution(); + auto units_dist = mp_units::piecewise_linear_distribution(); - CHECK(units_dist.min() == q(stl_dist.min())); - CHECK(units_dist.max() == q(stl_dist.max())); + CHECK(units_dist.min() == stl_dist.min() * si::metre); + CHECK(units_dist.max() == stl_dist.max() * si::metre); CHECK(stl_dist.intervals().size() == 2); CHECK(units_dist.intervals().size() == 2); CHECK(stl_dist.densities().size() == 2); @@ -601,13 +605,14 @@ TEST_CASE("piecewise_linear_distribution") SECTION("parametrized_input_it") { constexpr std::array intervals_rep = {1.0, 2.0, 3.0}; - constexpr std::array intervals_qty = {1.0_q_m, 2.0_q_m, 3.0_q_m}; + constexpr std::array intervals_qty = {1.0 * isq::length[si::metre], 2.0 * isq::length[si::metre], + 3.0 * isq::length[si::metre]}; constexpr std::array weights = {1.0, 2.0, 3.0}; auto stl_dist = std::piecewise_linear_distribution(intervals_rep.cbegin(), intervals_rep.cend(), weights.cbegin()); auto units_dist = - units::piecewise_linear_distribution(intervals_qty.cbegin(), intervals_qty.cend(), weights.cbegin()); + mp_units::piecewise_linear_distribution(intervals_qty.cbegin(), intervals_qty.cend(), weights.cbegin()); CHECK(stl_dist.intervals() == intervals_rep_vec); CHECK(units_dist.intervals() == intervals_qty_vec); @@ -617,10 +622,11 @@ TEST_CASE("piecewise_linear_distribution") SECTION("parametrized_initializer_list") { std::initializer_list intervals_rep = {1.0, 2.0, 3.0}; - std::initializer_list intervals_qty = {1.0_q_m, 2.0_q_m, 3.0_q_m}; + std::initializer_list intervals_qty = {1.0 * isq::length[si::metre], 2.0 * isq::length[si::metre], + 3.0 * isq::length[si::metre]}; auto stl_dist = std::piecewise_linear_distribution(intervals_rep, [](rep val) { return val; }); - auto units_dist = units::piecewise_linear_distribution(intervals_qty, [](q qty) { return qty.number(); }); + auto units_dist = mp_units::piecewise_linear_distribution(intervals_qty, [](q qty) { return qty.number(); }); CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.densities() == stl_dist.densities()); @@ -630,11 +636,11 @@ TEST_CASE("piecewise_linear_distribution") { constexpr std::size_t nw = 2; constexpr rep xmin_rep = 1.0, xmax_rep = 3.0; - constexpr q xmin_qty = 1.0_q_m, xmax_qty = 3.0_q_m; + constexpr q xmin_qty = 1.0 * isq::length[si::metre], xmax_qty = 3.0 * isq::length[si::metre]; auto stl_dist = std::piecewise_linear_distribution(nw, xmin_rep, xmax_rep, [](rep val) { return val; }); auto units_dist = - units::piecewise_linear_distribution(nw, xmin_qty, xmax_qty, [](q qty) { return qty.number(); }); + mp_units::piecewise_linear_distribution(nw, xmin_qty, xmax_qty, [](q qty) { return qty.number(); }); CHECK(units_dist.intervals() == intervals_qty_vec); CHECK(units_dist.densities() == stl_dist.densities()); diff --git a/test/unit_test/runtime/fmt_test.cpp b/test/unit_test/runtime/fmt_test.cpp index 22e73418..5c9d2409 100644 --- a/test/unit_test/runtime/fmt_test.cpp +++ b/test/unit_test/runtime/fmt_test.cpp @@ -22,20 +22,23 @@ #include #include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -using namespace units; -using namespace units::isq; -using namespace units::isq::si; +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +using namespace mp_units; +using namespace mp_units::si::unit_symbols; TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") { @@ -45,7 +48,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") { SECTION("integral representation") { - const auto q = 60_q_W; + const auto q = 60 * isq::power[W]; os << q; SECTION("iostream") { CHECK(os.str() == "60 W"); } @@ -57,7 +60,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("floating-point representation") { - const auto q = 1023.5_q_Pa; + const auto q = 1023.5 * isq::pressure[Pa]; os << q; SECTION("iostream") { CHECK(os.str() == "1023.5 Pa"); } @@ -70,7 +73,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("quantity with a predefined prefixed unit") { - const auto q = 125_q_us; + const auto q = 125 * isq::time[us]; os << q; SECTION("iostream") { CHECK(os.str() == "125 µs"); } @@ -80,64 +83,13 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } } - SECTION("quantity with a predefined unit + prefix") - { - SECTION("in terms of base units") - { - const length(mag<10>()), metre>> q(123); - os << q; - - SECTION("iostream") { CHECK(os.str() == "123 Mm"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("in terms of derived units") - { - const energy(mag<10>()), joule>> q(60); - os << q; - - SECTION("iostream") { CHECK(os.str() == "60 cJ"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - } - - SECTION("quantity with an alias unit") - { - const auto q = 2_q_l; - os << q; - - SECTION("iostream") { CHECK(os.str() == "2 l"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("quantity with a prefixed alias unit") - { - const auto q = 2_q_ml; - os << q; - - SECTION("iostream") { CHECK(os.str() == "2 ml"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - SECTION("quantity with a derived unit") { SECTION("coherent derived unit") { SECTION("acceleration") { - const auto q = 20_q_m / 2_q_s / 1_q_s; + const auto q = 20 * isq::length[m] / (2 * isq::time[s]) / (1 * isq::time[s]); os << q; SECTION("iostream") { CHECK(os.str() == "10 m/s²"); } @@ -149,7 +101,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("volume") { - const auto q = 2_q_m * 1_q_m * 1_q_m; + const auto q = 2 * isq::length[m] * (1 * isq::length[m]) * (1 * isq::length[m]); os << q; SECTION("iostream") { CHECK(os.str() == "2 m³"); } @@ -161,7 +113,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("surface tension") { - const auto q = 20_q_N / 2_q_m; + const auto q = 20 * isq::force[N] / (2 * isq::length[m]); os << q; SECTION("iostream") { CHECK(os.str() == "10 N/m"); } @@ -172,11 +124,11 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") } } - SECTION("deduced derived unit") + SECTION("scaled derived unit") { SECTION("speed") { - const auto q = 20_q_km / 2_q_h; + const auto q = 20 * isq::length[km] / (2 * isq::time[h]); os << q; SECTION("iostream") { CHECK(os.str() == "10 km/h"); } @@ -186,14 +138,36 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } } - SECTION("surface tension") + SECTION("angular impulse") { - struct newton_per_centimetre : - derived_scaled_unit {}; - const surface_tension q(123); + const auto q = 123 * isq::angular_impulse[N * m * s]; os << q; - SECTION("iostream") { CHECK(os.str() == "123 N/cm"); } + SECTION("iostream") { CHECK(os.str() == "123 N m s"); } + + SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } + + SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } + } + + SECTION("compressibility") + { + const auto q = 123 * isq::compressibility[1 / Pa]; + os << q; + + SECTION("iostream") { CHECK(os.str() == "123 1/Pa"); } + + SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } + + SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } + } + + SECTION("angular acceleration") + { + const auto q = 123 * isq::angular_acceleration[rad / s2]; + os << q; + + SECTION("iostream") { CHECK(os.str() == "123 rad/s²"); } SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } @@ -202,75 +176,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") } } - SECTION("quantity with a predefined dimension but unknown unit") - { - SECTION("unit::ratio as an SI prefix for a dimension with a special symbol") - { - const auto q = 4_q_N * 2_q_cm; - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 cJ"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio for a dimension without a special symbol") - { - const auto q = 2_q_um * 2_q_cm * 2_q_cm; - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 × 10⁻¹⁰ m³"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio::num != 1 && unit::ratio::den == 1") - { - const auto q = 4 * 2_q_min / (2_q_s * 2_q_s); - os << q; - - SECTION("iostream") { CHECK(os.str() == "2 [6 × 10¹] Hz"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio::num == 1 && unit::ratio::den != 1") - { - const auto q = 20_q_J / 2_q_min; - os << q; - - SECTION("iostream") { CHECK(os.str() == "10 [1/6 × 10⁻¹] W"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio::num != 1 && unit::ratio::den != 1") - { - const auto q = 60_q_kJ / 2_q_min; - os << q; - - // TODO(chogg): Reinstate after format/Magnitude design. - // SECTION("iostream") { CHECK(os.str() == "30 [1/6 × 10²] W"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - } SECTION("dimensionless quantity") { SECTION("one with ratio == 1") { - const auto q = 4_q_m / 2_q_m; + const auto q = 4 * isq::length[m] / (2 * isq::length[m]); os << q; SECTION("iostream") { CHECK(os.str() == "2"); } @@ -282,23 +193,19 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("one with ratio.exp != 0") { - const auto q = 4_q_km / 2_q_m; + const auto q = 4 * isq::length[km] / (2 * isq::length[m]); os << q; - SECTION("iostream") { CHECK(os.str() == "2 × 10³"); } + SECTION("iostream") { CHECK(os.str() == "2 km/m"); } SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == "2 × 10³"); } + SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == "2 km/m"); } } SECTION("percents") { -#if UNITS_DOWNCAST_MODE == 0 - const auto q = quantity_cast(15._q_m / 100._q_m); -#else - const auto q = quantity_cast(15._q_m / 100._q_m); -#endif + const auto q = value_cast(15. * isq::length[m] / (100. * isq::length[m])); os << q; SECTION("iostream") { CHECK(os.str() == "15 %"); } @@ -308,243 +215,260 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } } } - - SECTION("quantity with an unkown dimension") - { - SECTION("unit::ratio::num == 1 && unit::ratio::den == 1") - { - SECTION("SI base units") - { - const auto q = 2_q_s * 2_q_m * 2_q_kg; - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 m⋅kg⋅s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("CGS base units") - { - const auto q = 2._q_s * si::cgs::length(2) * si::cgs::mass(2); - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 cm⋅g⋅s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - } - - SECTION("unit::ratio as an SI prefix") - { - const auto q = 4_q_km * 2_q_s; - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 × 10³ m⋅s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio::num != 1 && unit::ratio::den == 1") - { - const auto q = 4_q_kg * 2_q_min / (2_q_s * 2_q_s); - os << q; - - SECTION("iostream") { CHECK(os.str() == "2 [6 × 10¹] kg/s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio::num == 1 && unit::ratio::den != 1") - { - const auto q = 20_q_kg / 2_q_min; - os << q; - - SECTION("iostream") { CHECK(os.str() == "10 [1/6 × 10⁻¹] kg/s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("CGS base units") - { - const auto q = 2._q_s * si::cgs::length(2) * si::cgs::mass(2); - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 × 10⁵ cm⋅g⋅s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("unit::ratio::num != 1 && unit::ratio::den != 1") - { - const auto q = 60_q_min / 2_q_km; - os << q; - - // TODO(chogg): Reinstate after format/Magnitude design. - // SECTION("iostream") { CHECK(os.str() == "30 [6 × 10⁻²] 1/m ⋅ s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("exponent::num == 1 && exponent::den == 1") - { - const auto q = 4_q_m * 2_q_s; - os << q; - - SECTION("iostream") { CHECK(os.str() == "8 m⋅s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("exponent::num == 2 && exponent::den == 1 for positive exponent") - { - const auto q = 4_q_m * 2_q_s * 2_q_s; - os << q; - - SECTION("iostream") { CHECK(os.str() == "16 m⋅s²"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("exponent::num == 2 && exponent::den == 1 for negative exponent (first dimension)") - { - const auto q = 8_q_s / 2_q_m / 2_q_m; - os << q; - - SECTION("iostream") { CHECK(os.str() == "2 1/m²⋅s"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("exponent::num == 2 && exponent::den == 1 for negative exponent (not first dimension)") - { - const auto q = 8_q_m / 2_q_kg / 2_q_kg; - os << q; - - SECTION("iostream") { CHECK(os.str() == "2 m/kg²"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("fractional positive exponent") - { - const auto q = sqrt(9_q_m); - os << q; - - SECTION("iostream") { CHECK(os.str() == "3 m^(1/2)"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - - SECTION("fractional negative exponent") - { - const auto q = sqrt(9 / 1_q_m); - os << q; - - SECTION("iostream") { CHECK(os.str() == "3 1/m^(1/2)"); } - - SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } - - SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } - } - } } TEST_CASE("format string with only %Q should print quantity value only", "[text][fmt]") { SECTION("integral representation") { - SECTION("positive value") { CHECK(UNITS_STD_FMT::format("{:%Q}", 123_q_km_per_h) == "123"); } + SECTION("positive value") { CHECK(UNITS_STD_FMT::format("{:%Q}", 123 * isq::speed[km / h]) == "123"); } - SECTION("negative value") { CHECK(UNITS_STD_FMT::format("{:%Q}", 5_q_m - 10_q_m) == "-5"); } + SECTION("negative value") + { + CHECK(UNITS_STD_FMT::format("{:%Q}", 5 * isq::length[m] - 10 * isq::length[m]) == "-5"); + } } SECTION("floating-point representation") { - SECTION("positive value") { CHECK(UNITS_STD_FMT::format("{:%Q}", 221._q_km / 2_q_h) == "110.5"); } + SECTION("positive value") + { + CHECK(UNITS_STD_FMT::format("{:%Q}", 221. * isq::length[km] / (2 * isq::time[h])) == "110.5"); + } - SECTION("negative value") { CHECK(UNITS_STD_FMT::format("{:%Q}", 3.14_q_m - 10_q_m) == "-6.86"); } + SECTION("negative value") + { + CHECK(UNITS_STD_FMT::format("{:%Q}", 3.14 * isq::length[m] - 10 * isq::length[m]) == "-6.86"); + } SECTION("nan") { - CHECK(UNITS_STD_FMT::format("{:%Q}", length(std::numeric_limits::quiet_NaN())) == "nan"); + CHECK(UNITS_STD_FMT::format("{:%Q}", std::numeric_limits::quiet_NaN() * isq::length[m]) == "nan"); } SECTION("inf") { - CHECK(UNITS_STD_FMT::format("{:%Q}", length(std::numeric_limits::infinity())) == "inf"); + CHECK(UNITS_STD_FMT::format("{:%Q}", std::numeric_limits::infinity() * isq::length[m]) == "inf"); } SECTION("-inf") { - CHECK(UNITS_STD_FMT::format("{:%Q}", length(-std::numeric_limits::infinity())) == "-inf"); + CHECK(UNITS_STD_FMT::format("{:%Q}", -std::numeric_limits::infinity() * isq::length[m]) == "-inf"); } } } TEST_CASE("format string with only %q should print quantity unit symbol only", "[text][fmt]") { - SECTION("standard format for a unit without Unicode symbols") + SECTION("Text encoding") { - CHECK(UNITS_STD_FMT::format("{:%q}", 123_q_km_per_h) == "km/h"); + SECTION("Unicode text output") + { + CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::speed[km / h]) == "km/h"); + // TODO enable this when resistance is defined + // CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::resistance[kilo]) == "kΩ"); + CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::time[us]) == "µs"); + CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::acceleration[m / s2]) == "m/s²"); + } + + SECTION("Unicode text output is used by default") + { + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::speed[km / h]) == "km/h"); + // CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::resistance[kilo]) == "kΩ"); + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::time[us]) == "µs"); + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::acceleration[m / s2]) == "m/s²"); + } + + SECTION("ASCII text output") + { + CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::speed[km / h]) == "km/h"); + // CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::resistance[kilo]) == "kohm"); + CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::time[us]) == "us"); + CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::acceleration[m / s2]) == "m/s^2"); + } } - SECTION("ASCII format for a unit without Unicode symbols") + SECTION("Solidus") { - CHECK(UNITS_STD_FMT::format("{:%Aq}", 123_q_km_per_h) == "km/h"); + SECTION("Solidus for only one element in denominator") + { + CHECK(UNITS_STD_FMT::format("{:%oq}", 123 * isq::speed[km / h]) == "km/h"); + CHECK(UNITS_STD_FMT::format("{:%oq}", 123 * isq::acceleration[m / s2]) == "m/s²"); + CHECK(UNITS_STD_FMT::format("{:%oq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); + } + + SECTION("Solidus for only one element in denominator is used by default") + { + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::speed[km / h]) == "km/h"); + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::acceleration[m / s2]) == "m/s²"); + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); + } + + SECTION("Always use solidus") + { + CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::speed[km / h]) == "km/h"); + CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::acceleration[m / s2]) == "m/s²"); + CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)"); + } + + SECTION("Never use solidus") + { + CHECK(UNITS_STD_FMT::format("{:%nq}", 123 * isq::speed[km / h]) == "km h⁻¹"); + CHECK(UNITS_STD_FMT::format("{:%nq}", 123 * isq::acceleration[m / s2]) == "m s⁻²"); + CHECK(UNITS_STD_FMT::format("{:%nq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); + } } - SECTION("standard format for a unit with Unicode symbols") + SECTION("Separator") { - SECTION("Unicode signs in a unit symbol") { CHECK(UNITS_STD_FMT::format("{:%q}", 123_q_kR) == "kΩ"); } + SECTION("Space") + { + CHECK(UNITS_STD_FMT::format("{:%sq}", 123 * isq::force[kg * m / s2]) == "kg m/s²"); + CHECK(UNITS_STD_FMT::format("{:%sq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); + CHECK(UNITS_STD_FMT::format("{:%asq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)"); + } - SECTION("Unicode signs in a unit symbol prefix") { CHECK(UNITS_STD_FMT::format("{:%q}", 123_q_uV) == "µV"); } + SECTION("Space is used by default") + { + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::force[kg * m / s2]) == "kg m/s²"); + CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); + CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)"); + } + + SECTION("Dot") + { + CHECK(UNITS_STD_FMT::format("{:%dq}", 123 * isq::force[kg * m / s2]) == "kg⋅m/s²"); + CHECK(UNITS_STD_FMT::format("{:%dq}", 123 * isq::pressure[kg / m / s2]) == "kg⋅m⁻¹⋅s⁻²"); + CHECK(UNITS_STD_FMT::format("{:%adq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m⋅s²)"); + } + } +} + +TEST_CASE("unknown unit modifiers should throw", "[text][fmt][exception]") +{ + SECTION("only the invalid modifier") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%xq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); } - SECTION("ASCII format for a unit with Unicode symbols") + SECTION("invalid modifier in the front") { - SECTION("Unicode signs in a unit symbol") { CHECK(UNITS_STD_FMT::format("{:%Aq}", 123_q_kR) == "kohm"); } - - SECTION("Unicode signs in a unit symbol prefix") { CHECK(UNITS_STD_FMT::format("{:%Aq}", 123_q_uV) == "uV"); } + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%xUdaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); } + + SECTION("invalid modifier in the end") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%Udaxq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); + } + + SECTION("invalid modifier in the middle") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%Udxaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); + } +} + +TEST_CASE("repeated unit modifiers should throw", "[text][fmt][exception]") +{ + SECTION("text encoding") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%UdaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); + } + + SECTION("solidus") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%aUdaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%daUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%daaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); + } + + SECTION("separator") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUadq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dadUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%addUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); + } +} + +TEST_CASE("more then one modifier of the same kind should throw", "[text][fmt][exception]") +{ + SECTION("text encoding") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%UdaAq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dAaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dAUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); + } + + SECTION("solidus") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%aUdnq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dnUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%daoUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); + } + + SECTION("separator") + { + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUasq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%sadUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%adsUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); + } +} + +TEST_CASE("dot separator requested for ASCII encoding should throw", "[text][fmt][exception]") +{ + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dAaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), + UNITS_STD_FMT::format_error, + Catch::Matchers::Message("dot unit separator allowed only for Unicode encoding")); } TEST_CASE("%q and %Q can be put anywhere in a format string", "[text][fmt]") { - SECTION("no space") { CHECK(UNITS_STD_FMT::format("{:%Q%q}", 123_q_km_per_h) == "123km/h"); } + SECTION("no space") { CHECK(UNITS_STD_FMT::format("{:%Q%q}", 123 * isq::speed[km / h]) == "123km/h"); } - SECTION("separator") { CHECK(UNITS_STD_FMT::format("{:%Q###%q}", 123_q_km_per_h) == "123###km/h"); } + SECTION("separator") { CHECK(UNITS_STD_FMT::format("{:%Q###%q}", 123 * isq::speed[km / h]) == "123###km/h"); } - SECTION("opposite order") { CHECK(UNITS_STD_FMT::format("{:%q %Q}", 123_q_km_per_h) == "km/h 123"); } - - SECTION("tabulator") { CHECK(UNITS_STD_FMT::format("{:%Q%t%q}", 123_q_km_per_h) == "123\tkm/h"); } - - SECTION("new line") { CHECK(UNITS_STD_FMT::format("{:%Q%n%q}", 123_q_km_per_h) == "123\nkm/h"); } - - SECTION("% sign") { CHECK(UNITS_STD_FMT::format("{:%Q%% %q}", 123_q_km_per_h) == "123% km/h"); } + SECTION("opposite order") { CHECK(UNITS_STD_FMT::format("{:%q %Q}", 123 * isq::speed[km / h]) == "km/h 123"); } } TEST_CASE("fill and align specification", "[text][fmt][ostream]") @@ -555,107 +479,107 @@ TEST_CASE("fill and align specification", "[text][fmt][ostream]") SECTION("width = 10") { - os << "|" << std::setw(10) << 123_q_m << "|"; + os << "|" << std::setw(10) << 123 * isq::length[m] << "|"; CHECK(os.str() == "| 123 m|"); } SECTION("width = 10, align = right") { - os << "|" << std::setw(10) << std::right << 123_q_m << "|"; + os << "|" << std::setw(10) << std::right << 123 * isq::length[m] << "|"; CHECK(os.str() == "| 123 m|"); } SECTION("width = 10, align = left") { - os << "|" << std::setw(10) << std::left << 123_q_m << "|"; + os << "|" << std::setw(10) << std::left << 123 * isq::length[m] << "|"; CHECK(os.str() == "|123 m |"); } SECTION("width = 10, fill = *") { - os << "|" << std::setw(10) << std::setfill('*') << 123_q_m << "|"; + os << "|" << std::setw(10) << std::setfill('*') << 123 * isq::length[m] << "|"; CHECK(os.str() == "|*****123 m|"); } SECTION("width = 10, fill = *, align = right") { - os << "|" << std::setw(10) << std::setfill('*') << std::right << 123_q_m << "|"; + os << "|" << std::setw(10) << std::setfill('*') << std::right << 123 * isq::length[m] << "|"; CHECK(os.str() == "|*****123 m|"); } SECTION("width = 10, fill = *, align = left") { - os << "|" << std::setw(10) << std::setfill('*') << std::left << 123_q_m << "|"; + os << "|" << std::setw(10) << std::setfill('*') << std::left << 123 * isq::length[m] << "|"; CHECK(os.str() == "|123 m*****|"); } } SECTION("default format {} on a quantity") { - CHECK(UNITS_STD_FMT::format("|{:0}|", 123_q_m) == "|123 m|"); - CHECK(UNITS_STD_FMT::format("|{:10}|", 123_q_m) == "| 123 m|"); - CHECK(UNITS_STD_FMT::format("|{:<10}|", 123_q_m) == "|123 m |"); - CHECK(UNITS_STD_FMT::format("|{:>10}|", 123_q_m) == "| 123 m|"); - CHECK(UNITS_STD_FMT::format("|{:^10}|", 123_q_m) == "| 123 m |"); - CHECK(UNITS_STD_FMT::format("|{:*<10}|", 123_q_m) == "|123 m*****|"); - CHECK(UNITS_STD_FMT::format("|{:*>10}|", 123_q_m) == "|*****123 m|"); - CHECK(UNITS_STD_FMT::format("|{:*^10}|", 123_q_m) == "|**123 m***|"); + CHECK(UNITS_STD_FMT::format("|{:0}|", 123 * isq::length[m]) == "|123 m|"); + CHECK(UNITS_STD_FMT::format("|{:10}|", 123 * isq::length[m]) == "| 123 m|"); + CHECK(UNITS_STD_FMT::format("|{:<10}|", 123 * isq::length[m]) == "|123 m |"); + CHECK(UNITS_STD_FMT::format("|{:>10}|", 123 * isq::length[m]) == "| 123 m|"); + CHECK(UNITS_STD_FMT::format("|{:^10}|", 123 * isq::length[m]) == "| 123 m |"); + CHECK(UNITS_STD_FMT::format("|{:*<10}|", 123 * isq::length[m]) == "|123 m*****|"); + CHECK(UNITS_STD_FMT::format("|{:*>10}|", 123 * isq::length[m]) == "|*****123 m|"); + CHECK(UNITS_STD_FMT::format("|{:*^10}|", 123 * isq::length[m]) == "|**123 m***|"); } SECTION("full format {:%Q %q} on a quantity") { - CHECK(UNITS_STD_FMT::format("|{:0%Q%q}|", 123_q_m) == "|123m|"); - CHECK(UNITS_STD_FMT::format("|{:10%Q%q}|", 123_q_m) == "| 123m|"); - CHECK(UNITS_STD_FMT::format("|{:<10%Q%q}|", 123_q_m) == "|123m |"); - CHECK(UNITS_STD_FMT::format("|{:>10%Q%q}|", 123_q_m) == "| 123m|"); - CHECK(UNITS_STD_FMT::format("|{:^10%Q%q}|", 123_q_m) == "| 123m |"); - CHECK(UNITS_STD_FMT::format("|{:*<10%Q%q}|", 123_q_m) == "|123m******|"); - CHECK(UNITS_STD_FMT::format("|{:*>10%Q%q}|", 123_q_m) == "|******123m|"); - CHECK(UNITS_STD_FMT::format("|{:*^10%Q%q}|", 123_q_m) == "|***123m***|"); + CHECK(UNITS_STD_FMT::format("|{:0%Q%q}|", 123 * isq::length[m]) == "|123m|"); + CHECK(UNITS_STD_FMT::format("|{:10%Q%q}|", 123 * isq::length[m]) == "| 123m|"); + CHECK(UNITS_STD_FMT::format("|{:<10%Q%q}|", 123 * isq::length[m]) == "|123m |"); + CHECK(UNITS_STD_FMT::format("|{:>10%Q%q}|", 123 * isq::length[m]) == "| 123m|"); + CHECK(UNITS_STD_FMT::format("|{:^10%Q%q}|", 123 * isq::length[m]) == "| 123m |"); + CHECK(UNITS_STD_FMT::format("|{:*<10%Q%q}|", 123 * isq::length[m]) == "|123m******|"); + CHECK(UNITS_STD_FMT::format("|{:*>10%Q%q}|", 123 * isq::length[m]) == "|******123m|"); + CHECK(UNITS_STD_FMT::format("|{:*^10%Q%q}|", 123 * isq::length[m]) == "|***123m***|"); } SECTION("value only format {:%Q} on a quantity") { - CHECK(UNITS_STD_FMT::format("|{:0%Q}|", 123_q_m) == "|123|"); - CHECK(UNITS_STD_FMT::format("|{:10%Q}|", 123_q_m) == "| 123|"); - CHECK(UNITS_STD_FMT::format("|{:<10%Q}|", 123_q_m) == "|123 |"); - CHECK(UNITS_STD_FMT::format("|{:>10%Q}|", 123_q_m) == "| 123|"); - CHECK(UNITS_STD_FMT::format("|{:^10%Q}|", 123_q_m) == "| 123 |"); - CHECK(UNITS_STD_FMT::format("|{:*<10%Q}|", 123_q_m) == "|123*******|"); - CHECK(UNITS_STD_FMT::format("|{:*>10%Q}|", 123_q_m) == "|*******123|"); - CHECK(UNITS_STD_FMT::format("|{:*^10%Q}|", 123_q_m) == "|***123****|"); + CHECK(UNITS_STD_FMT::format("|{:0%Q}|", 123 * isq::length[m]) == "|123|"); + CHECK(UNITS_STD_FMT::format("|{:10%Q}|", 123 * isq::length[m]) == "| 123|"); + CHECK(UNITS_STD_FMT::format("|{:<10%Q}|", 123 * isq::length[m]) == "|123 |"); + CHECK(UNITS_STD_FMT::format("|{:>10%Q}|", 123 * isq::length[m]) == "| 123|"); + CHECK(UNITS_STD_FMT::format("|{:^10%Q}|", 123 * isq::length[m]) == "| 123 |"); + CHECK(UNITS_STD_FMT::format("|{:*<10%Q}|", 123 * isq::length[m]) == "|123*******|"); + CHECK(UNITS_STD_FMT::format("|{:*>10%Q}|", 123 * isq::length[m]) == "|*******123|"); + CHECK(UNITS_STD_FMT::format("|{:*^10%Q}|", 123 * isq::length[m]) == "|***123****|"); } SECTION("symbol only format {:%q} on a quantity") { - CHECK(UNITS_STD_FMT::format("|{:0%q}|", 123_q_m) == "|m|"); - CHECK(UNITS_STD_FMT::format("|{:10%q}|", 123_q_m) == "|m |"); - CHECK(UNITS_STD_FMT::format("|{:<10%q}|", 123_q_m) == "|m |"); - CHECK(UNITS_STD_FMT::format("|{:>10%q}|", 123_q_m) == "| m|"); - CHECK(UNITS_STD_FMT::format("|{:^10%q}|", 123_q_m) == "| m |"); - CHECK(UNITS_STD_FMT::format("|{:*<10%q}|", 123_q_m) == "|m*********|"); - CHECK(UNITS_STD_FMT::format("|{:*>10%q}|", 123_q_m) == "|*********m|"); - CHECK(UNITS_STD_FMT::format("|{:*^10%q}|", 123_q_m) == "|****m*****|"); + CHECK(UNITS_STD_FMT::format("|{:0%q}|", 123 * isq::length[m]) == "|m|"); + CHECK(UNITS_STD_FMT::format("|{:10%q}|", 123 * isq::length[m]) == "| m|"); + CHECK(UNITS_STD_FMT::format("|{:<10%q}|", 123 * isq::length[m]) == "|m |"); + CHECK(UNITS_STD_FMT::format("|{:>10%q}|", 123 * isq::length[m]) == "| m|"); + CHECK(UNITS_STD_FMT::format("|{:^10%q}|", 123 * isq::length[m]) == "| m |"); + CHECK(UNITS_STD_FMT::format("|{:*<10%q}|", 123 * isq::length[m]) == "|m*********|"); + CHECK(UNITS_STD_FMT::format("|{:*>10%q}|", 123 * isq::length[m]) == "|*********m|"); + CHECK(UNITS_STD_FMT::format("|{:*^10%q}|", 123 * isq::length[m]) == "|****m*****|"); } } TEST_CASE("sign specification", "[text][fmt]") { - length inf(std::numeric_limits::infinity()); - length nan(std::numeric_limits::quiet_NaN()); + auto inf = std::numeric_limits::infinity() * si::metre; + auto nan = std::numeric_limits::quiet_NaN() * si::metre; SECTION("full format {:%Q %q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", 1_q_m) == "1m,+1m,1m, 1m"); - CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", -1_q_m) == "-1m,-1m,-1m,-1m"); + CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", 1 * isq::length[m]) == "1m,+1m,1m, 1m"); + CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", -1 * isq::length[m]) == "-1m,-1m,-1m,-1m"); CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", inf) == "infm,+infm,infm, infm"); CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", nan) == "nanm,+nanm,nanm, nanm"); } SECTION("value only format {:%Q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", 1_q_m) == "1,+1,1, 1"); - CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", -1_q_m) == "-1,-1,-1,-1"); + CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", 1 * isq::length[m]) == "1,+1,1, 1"); + CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", -1 * isq::length[m]) == "-1,-1,-1,-1"); CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", inf) == "inf,+inf,inf, inf"); CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", nan) == "nan,+nan,nan, nan"); } @@ -665,32 +589,24 @@ TEST_CASE("precision specification", "[text][fmt]") { SECTION("full format {:%Q %q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{:%.0Q %q}", 1.2345_q_m) == "1 m"); - CHECK(UNITS_STD_FMT::format("{:%.1Q %q}", 1.2345_q_m) == "1.2 m"); - CHECK(UNITS_STD_FMT::format("{:%.2Q %q}", 1.2345_q_m) == "1.23 m"); -#ifdef UNITS_COMP_MSVC - CHECK(UNITS_STD_FMT::format("{:%.3Q %q}", 1.2345_q_m) == "1.234 m"); -#else - CHECK(UNITS_STD_FMT::format("{:%.3Q %q}", 1.2345_q_m) == "1.235 m"); -#endif - CHECK(UNITS_STD_FMT::format("{:%.4Q %q}", 1.2345_q_m) == "1.2345 m"); - CHECK(UNITS_STD_FMT::format("{:%.5Q %q}", 1.2345_q_m) == "1.23450 m"); - CHECK(UNITS_STD_FMT::format("{:%.10Q %q}", 1.2345_q_m) == "1.2345000000 m"); + CHECK(UNITS_STD_FMT::format("{:%.0Q %q}", 1.2345 * isq::length[m]) == "1 m"); + CHECK(UNITS_STD_FMT::format("{:%.1Q %q}", 1.2345 * isq::length[m]) == "1.2 m"); + CHECK(UNITS_STD_FMT::format("{:%.2Q %q}", 1.2345 * isq::length[m]) == "1.23 m"); + CHECK(UNITS_STD_FMT::format("{:%.3Q %q}", 1.2345 * isq::length[m]) == "1.234 m"); + CHECK(UNITS_STD_FMT::format("{:%.4Q %q}", 1.2345 * isq::length[m]) == "1.2345 m"); + CHECK(UNITS_STD_FMT::format("{:%.5Q %q}", 1.2345 * isq::length[m]) == "1.23450 m"); + CHECK(UNITS_STD_FMT::format("{:%.10Q %q}", 1.2345 * isq::length[m]) == "1.2345000000 m"); } SECTION("value only format {:%Q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{:%.0Q}", 1.2345_q_m) == "1"); - CHECK(UNITS_STD_FMT::format("{:%.1Q}", 1.2345_q_m) == "1.2"); - CHECK(UNITS_STD_FMT::format("{:%.2Q}", 1.2345_q_m) == "1.23"); -#ifdef UNITS_COMP_MSVC - CHECK(UNITS_STD_FMT::format("{:%.3Q}", 1.2345_q_m) == "1.234"); -#else - CHECK(UNITS_STD_FMT::format("{:%.3Q}", 1.2345_q_m) == "1.235"); -#endif - CHECK(UNITS_STD_FMT::format("{:%.4Q}", 1.2345_q_m) == "1.2345"); - CHECK(UNITS_STD_FMT::format("{:%.5Q}", 1.2345_q_m) == "1.23450"); - CHECK(UNITS_STD_FMT::format("{:%.10Q}", 1.2345_q_m) == "1.2345000000"); + CHECK(UNITS_STD_FMT::format("{:%.0Q}", 1.2345 * isq::length[m]) == "1"); + CHECK(UNITS_STD_FMT::format("{:%.1Q}", 1.2345 * isq::length[m]) == "1.2"); + CHECK(UNITS_STD_FMT::format("{:%.2Q}", 1.2345 * isq::length[m]) == "1.23"); + CHECK(UNITS_STD_FMT::format("{:%.3Q}", 1.2345 * isq::length[m]) == "1.234"); + CHECK(UNITS_STD_FMT::format("{:%.4Q}", 1.2345 * isq::length[m]) == "1.2345"); + CHECK(UNITS_STD_FMT::format("{:%.5Q}", 1.2345 * isq::length[m]) == "1.23450"); + CHECK(UNITS_STD_FMT::format("{:%.10Q}", 1.2345 * isq::length[m]) == "1.2345000000"); } } @@ -698,14 +614,14 @@ TEST_CASE("precision specification for integral representation should throw", "[ { SECTION("full format {:%Q %q} on a quantity") { - REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%.1Q %q}", UNITS_STD_FMT::make_format_args(1_q_m)), + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%.1Q %q}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), UNITS_STD_FMT::format_error, Catch::Matchers::Message("precision not allowed for integral quantity representation")); } SECTION("value only format {:%Q} on a quantity") { - REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%.1Q}", UNITS_STD_FMT::make_format_args(1_q_m)), + REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%.1Q}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), UNITS_STD_FMT::format_error, Catch::Matchers::Message("precision not allowed for integral quantity representation")); } @@ -715,84 +631,56 @@ TEST_CASE("type specification", "[text][fmt]") { SECTION("full format {:%Q %q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{:%bQ %q}", 42_q_m) == "101010 m"); - CHECK(UNITS_STD_FMT::format("{:%BQ %q}", 42_q_m) == "101010 m"); - CHECK(UNITS_STD_FMT::format("{:%dQ %q}", 42_q_m) == "42 m"); - CHECK(UNITS_STD_FMT::format("{:%oQ %q}", 42_q_m) == "52 m"); - CHECK(UNITS_STD_FMT::format("{:%xQ %q}", 42_q_m) == "2a m"); - CHECK(UNITS_STD_FMT::format("{:%XQ %q}", 42_q_m) == "2A m"); + CHECK(UNITS_STD_FMT::format("{:%bQ %q}", 42 * isq::length[m]) == "101010 m"); + CHECK(UNITS_STD_FMT::format("{:%BQ %q}", 42 * isq::length[m]) == "101010 m"); + CHECK(UNITS_STD_FMT::format("{:%dQ %q}", 42 * isq::length[m]) == "42 m"); + CHECK(UNITS_STD_FMT::format("{:%oQ %q}", 42 * isq::length[m]) == "52 m"); + CHECK(UNITS_STD_FMT::format("{:%xQ %q}", 42 * isq::length[m]) == "2a m"); + CHECK(UNITS_STD_FMT::format("{:%XQ %q}", 42 * isq::length[m]) == "2A m"); -#ifdef UNITS_COMP_MSVC -#if UNITS_USE_LIBFMT - CHECK(UNITS_STD_FMT::format("{:%aQ %q}", 1.2345678_q_m) == "0x1.3c0ca2a5b1d5dp+0 m"); - CHECK(UNITS_STD_FMT::format("{:%.3aQ %q}", 1.2345678_q_m) == "0x1.3c1p+0 m"); - CHECK(UNITS_STD_FMT::format("{:%AQ %q}", 1.2345678_q_m) == "0X1.3C0CA2A5B1D5DP+0 m"); - CHECK(UNITS_STD_FMT::format("{:%.3AQ %q}", 1.2345678_q_m) == "0X1.3C1P+0 m"); -#else - CHECK(UNITS_STD_FMT::format("{:%aQ %q}", 1.2345678_q_m) == "1.3c0ca2a5b1d5dp+0 m"); - CHECK(UNITS_STD_FMT::format("{:%.3aQ %q}", 1.2345678_q_m) == "1.3c1p+0 m"); - CHECK(UNITS_STD_FMT::format("{:%AQ %q}", 1.2345678_q_m) == "1.3C0CA2A5B1D5DP+0 m"); - CHECK(UNITS_STD_FMT::format("{:%.3AQ %q}", 1.2345678_q_m) == "1.3C1P+0 m"); -#endif // UNITS_USE_LIBFMT -#else - CHECK(UNITS_STD_FMT::format("{:%aQ %q}", 1.2345678_q_m) == "0x9.e065152d8eae841p-3 m"); - CHECK(UNITS_STD_FMT::format("{:%.3aQ %q}", 1.2345678_q_m) == "0x9.e06p-3 m"); - CHECK(UNITS_STD_FMT::format("{:%AQ %q}", 1.2345678_q_m) == "0X9.E065152D8EAE841P-3 m"); - CHECK(UNITS_STD_FMT::format("{:%.3AQ %q}", 1.2345678_q_m) == "0X9.E06P-3 m"); -#endif - CHECK(UNITS_STD_FMT::format("{:%eQ %q}", 1.2345678_q_m) == "1.234568e+00 m"); - CHECK(UNITS_STD_FMT::format("{:%.3eQ %q}", 1.2345678_q_m) == "1.235e+00 m"); - CHECK(UNITS_STD_FMT::format("{:%EQ %q}", 1.2345678_q_m) == "1.234568E+00 m"); - CHECK(UNITS_STD_FMT::format("{:%.3EQ %q}", 1.2345678_q_m) == "1.235E+00 m"); - CHECK(UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678_q_m) == "1.23457 m"); - CHECK(UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678e8_q_m) == "1.23457e+08 m"); - CHECK(UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678_q_m) == "1.23 m"); - CHECK(UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678e8_q_m) == "1.23e+08 m"); - CHECK(UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678_q_m) == "1.23457 m"); - CHECK(UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678e8_q_m) == "1.23457E+08 m"); - CHECK(UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678_q_m) == "1.23 m"); - CHECK(UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678e8_q_m) == "1.23E+08 m"); + CHECK(UNITS_STD_FMT::format("{:%aQ %q}", 1.2345678 * isq::length[m]) == "0x1.3c0ca2a5b1d5dp+0 m"); + CHECK(UNITS_STD_FMT::format("{:%.3aQ %q}", 1.2345678 * isq::length[m]) == "0x1.3c1p+0 m"); + CHECK(UNITS_STD_FMT::format("{:%AQ %q}", 1.2345678 * isq::length[m]) == "0X1.3C0CA2A5B1D5DP+0 m"); + CHECK(UNITS_STD_FMT::format("{:%.3AQ %q}", 1.2345678 * isq::length[m]) == "0X1.3C1P+0 m"); + CHECK(UNITS_STD_FMT::format("{:%eQ %q}", 1.2345678 * isq::length[m]) == "1.234568e+00 m"); + CHECK(UNITS_STD_FMT::format("{:%.3eQ %q}", 1.2345678 * isq::length[m]) == "1.235e+00 m"); + CHECK(UNITS_STD_FMT::format("{:%EQ %q}", 1.2345678 * isq::length[m]) == "1.234568E+00 m"); + CHECK(UNITS_STD_FMT::format("{:%.3EQ %q}", 1.2345678 * isq::length[m]) == "1.235E+00 m"); + CHECK(UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678 * isq::length[m]) == "1.23457 m"); + CHECK(UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678e8 * isq::length[m]) == "1.23457e+08 m"); + CHECK(UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678 * isq::length[m]) == "1.23 m"); + CHECK(UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678e8 * isq::length[m]) == "1.23e+08 m"); + CHECK(UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678 * isq::length[m]) == "1.23457 m"); + CHECK(UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678e8 * isq::length[m]) == "1.23457E+08 m"); + CHECK(UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678 * isq::length[m]) == "1.23 m"); + CHECK(UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678e8 * isq::length[m]) == "1.23E+08 m"); } SECTION("value only format {:%Q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{:%bQ}", 42_q_m) == "101010"); - CHECK(UNITS_STD_FMT::format("{:%BQ}", 42_q_m) == "101010"); - CHECK(UNITS_STD_FMT::format("{:%dQ}", 42_q_m) == "42"); - CHECK(UNITS_STD_FMT::format("{:%oQ}", 42_q_m) == "52"); - CHECK(UNITS_STD_FMT::format("{:%xQ}", 42_q_m) == "2a"); - CHECK(UNITS_STD_FMT::format("{:%XQ}", 42_q_m) == "2A"); + CHECK(UNITS_STD_FMT::format("{:%bQ}", 42 * isq::length[m]) == "101010"); + CHECK(UNITS_STD_FMT::format("{:%BQ}", 42 * isq::length[m]) == "101010"); + CHECK(UNITS_STD_FMT::format("{:%dQ}", 42 * isq::length[m]) == "42"); + CHECK(UNITS_STD_FMT::format("{:%oQ}", 42 * isq::length[m]) == "52"); + CHECK(UNITS_STD_FMT::format("{:%xQ}", 42 * isq::length[m]) == "2a"); + CHECK(UNITS_STD_FMT::format("{:%XQ}", 42 * isq::length[m]) == "2A"); -#ifdef UNITS_COMP_MSVC -#if UNITS_USE_LIBFMT - CHECK(UNITS_STD_FMT::format("{:%aQ}", 1.2345678_q_m) == "0x1.3c0ca2a5b1d5dp+0"); - CHECK(UNITS_STD_FMT::format("{:%.3aQ}", 1.2345678_q_m) == "0x1.3c1p+0"); - CHECK(UNITS_STD_FMT::format("{:%AQ}", 1.2345678_q_m) == "0X1.3C0CA2A5B1D5DP+0"); - CHECK(UNITS_STD_FMT::format("{:%.3AQ}", 1.2345678_q_m) == "0X1.3C1P+0"); -#else - CHECK(UNITS_STD_FMT::format("{:%aQ}", 1.2345678_q_m) == "1.3c0ca2a5b1d5dp+0"); - CHECK(UNITS_STD_FMT::format("{:%.3aQ}", 1.2345678_q_m) == "1.3c1p+0"); - CHECK(UNITS_STD_FMT::format("{:%AQ}", 1.2345678_q_m) == "1.3C0CA2A5B1D5DP+0"); - CHECK(UNITS_STD_FMT::format("{:%.3AQ}", 1.2345678_q_m) == "1.3C1P+0"); -#endif // UNITS_USE_LIBFMT -#else - CHECK(UNITS_STD_FMT::format("{:%aQ}", 1.2345678_q_m) == "0x9.e065152d8eae841p-3"); - CHECK(UNITS_STD_FMT::format("{:%.3aQ}", 1.2345678_q_m) == "0x9.e06p-3"); - CHECK(UNITS_STD_FMT::format("{:%AQ}", 1.2345678_q_m) == "0X9.E065152D8EAE841P-3"); - CHECK(UNITS_STD_FMT::format("{:%.3AQ}", 1.2345678_q_m) == "0X9.E06P-3"); -#endif - CHECK(UNITS_STD_FMT::format("{:%eQ}", 1.2345678_q_m) == "1.234568e+00"); - CHECK(UNITS_STD_FMT::format("{:%.3eQ}", 1.2345678_q_m) == "1.235e+00"); - CHECK(UNITS_STD_FMT::format("{:%EQ}", 1.2345678_q_m) == "1.234568E+00"); - CHECK(UNITS_STD_FMT::format("{:%.3EQ}", 1.2345678_q_m) == "1.235E+00"); - CHECK(UNITS_STD_FMT::format("{:%gQ}", 1.2345678_q_m) == "1.23457"); - CHECK(UNITS_STD_FMT::format("{:%gQ}", 1.2345678e8_q_m) == "1.23457e+08"); - CHECK(UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678_q_m) == "1.23"); - CHECK(UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678e8_q_m) == "1.23e+08"); - CHECK(UNITS_STD_FMT::format("{:%GQ}", 1.2345678_q_m) == "1.23457"); - CHECK(UNITS_STD_FMT::format("{:%GQ}", 1.2345678e8_q_m) == "1.23457E+08"); - CHECK(UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678_q_m) == "1.23"); - CHECK(UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678e8_q_m) == "1.23E+08"); + CHECK(UNITS_STD_FMT::format("{:%aQ}", 1.2345678 * isq::length[m]) == "0x1.3c0ca2a5b1d5dp+0"); + CHECK(UNITS_STD_FMT::format("{:%.3aQ}", 1.2345678 * isq::length[m]) == "0x1.3c1p+0"); + CHECK(UNITS_STD_FMT::format("{:%AQ}", 1.2345678 * isq::length[m]) == "0X1.3C0CA2A5B1D5DP+0"); + CHECK(UNITS_STD_FMT::format("{:%.3AQ}", 1.2345678 * isq::length[m]) == "0X1.3C1P+0"); + CHECK(UNITS_STD_FMT::format("{:%eQ}", 1.2345678 * isq::length[m]) == "1.234568e+00"); + CHECK(UNITS_STD_FMT::format("{:%.3eQ}", 1.2345678 * isq::length[m]) == "1.235e+00"); + CHECK(UNITS_STD_FMT::format("{:%EQ}", 1.2345678 * isq::length[m]) == "1.234568E+00"); + CHECK(UNITS_STD_FMT::format("{:%.3EQ}", 1.2345678 * isq::length[m]) == "1.235E+00"); + CHECK(UNITS_STD_FMT::format("{:%gQ}", 1.2345678 * isq::length[m]) == "1.23457"); + CHECK(UNITS_STD_FMT::format("{:%gQ}", 1.2345678e8 * isq::length[m]) == "1.23457e+08"); + CHECK(UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678 * isq::length[m]) == "1.23"); + CHECK(UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678e8 * isq::length[m]) == "1.23e+08"); + CHECK(UNITS_STD_FMT::format("{:%GQ}", 1.2345678 * isq::length[m]) == "1.23457"); + CHECK(UNITS_STD_FMT::format("{:%GQ}", 1.2345678e8 * isq::length[m]) == "1.23457E+08"); + CHECK(UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678 * isq::length[m]) == "1.23"); + CHECK(UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678e8 * isq::length[m]) == "1.23E+08"); } } @@ -800,20 +688,20 @@ TEST_CASE("different base types with the # specifier", "[text][fmt]") { SECTION("full format {:%Q %q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{:%#bQ %q}", 42_q_m) == "0b101010 m"); - CHECK(UNITS_STD_FMT::format("{:%#BQ %q}", 42_q_m) == "0B101010 m"); - CHECK(UNITS_STD_FMT::format("{:%#oQ %q}", 42_q_m) == "052 m"); - CHECK(UNITS_STD_FMT::format("{:%#xQ %q}", 42_q_m) == "0x2a m"); - CHECK(UNITS_STD_FMT::format("{:%#XQ %q}", 42_q_m) == "0X2A m"); + CHECK(UNITS_STD_FMT::format("{:%#bQ %q}", 42 * isq::length[m]) == "0b101010 m"); + CHECK(UNITS_STD_FMT::format("{:%#BQ %q}", 42 * isq::length[m]) == "0B101010 m"); + CHECK(UNITS_STD_FMT::format("{:%#oQ %q}", 42 * isq::length[m]) == "052 m"); + CHECK(UNITS_STD_FMT::format("{:%#xQ %q}", 42 * isq::length[m]) == "0x2a m"); + CHECK(UNITS_STD_FMT::format("{:%#XQ %q}", 42 * isq::length[m]) == "0X2A m"); } SECTION("value only format {:%Q} on a quantity") { - CHECK(UNITS_STD_FMT::format("{:%#bQ}", 42_q_m) == "0b101010"); - CHECK(UNITS_STD_FMT::format("{:%#BQ}", 42_q_m) == "0B101010"); - CHECK(UNITS_STD_FMT::format("{:%#oQ}", 42_q_m) == "052"); - CHECK(UNITS_STD_FMT::format("{:%#xQ}", 42_q_m) == "0x2a"); - CHECK(UNITS_STD_FMT::format("{:%#XQ}", 42_q_m) == "0X2A"); + CHECK(UNITS_STD_FMT::format("{:%#bQ}", 42 * isq::length[m]) == "0b101010"); + CHECK(UNITS_STD_FMT::format("{:%#BQ}", 42 * isq::length[m]) == "0B101010"); + CHECK(UNITS_STD_FMT::format("{:%#oQ}", 42 * isq::length[m]) == "052"); + CHECK(UNITS_STD_FMT::format("{:%#xQ}", 42 * isq::length[m]) == "0x2a"); + CHECK(UNITS_STD_FMT::format("{:%#XQ}", 42 * isq::length[m]) == "0X2A"); } } @@ -834,18 +722,18 @@ TEST_CASE("localization with the 'L' specifier", "[text][fmt][localization]") SECTION("full format {:%LQ %q} on a quantity") { - CHECK(UNITS_STD_FMT::format(grp2, "{:%LQ %q}", 299792458_q_m_per_s) == "2_99_79_24_58 m/s"); - CHECK(UNITS_STD_FMT::format(grp3, "{:%LQ %q}", 299792458_q_m_per_s) == "299'792'458 m/s"); + CHECK(UNITS_STD_FMT::format(grp2, "{:%LQ %q}", 299'792'458 * isq::speed[m / s]) == "2_99_79_24_58 m/s"); + CHECK(UNITS_STD_FMT::format(grp3, "{:%LQ %q}", 299'792'458 * isq::speed[m / s]) == "299'792'458 m/s"); } } -TEST_CASE("quantity_cast", "[text][ostream]") +TEST_CASE("value_cast", "[text][ostream]") { std::ostringstream os; SECTION("int to double representation") { - const auto q = 121_q_km / 2_q_h; + const auto q = 121 * isq::length[km] / (2 * isq::time[h]); SECTION("original") { @@ -855,20 +743,20 @@ TEST_CASE("quantity_cast", "[text][ostream]") SECTION("int") { - os << quantity_cast(q); + os << value_cast(q); CHECK(os.str() == "60 km/h"); } SECTION("double") { - os << quantity_cast(q); + os << value_cast(q); CHECK(os.str() == "60 km/h"); } } SECTION("double to int representation") { - const auto q = 121._q_km / 2_q_h; + const auto q = 121. * isq::length[km] / (2 * isq::time[h]); SECTION("original") { @@ -878,13 +766,13 @@ TEST_CASE("quantity_cast", "[text][ostream]") SECTION("int") { - os << quantity_cast(q); + os << value_cast(q); CHECK(os.str() == "60 km/h"); } SECTION("double") { - os << quantity_cast(q); + os << value_cast(q); CHECK(os.str() == "60.5 km/h"); } } diff --git a/test/unit_test/runtime/fmt_units_test.cpp b/test/unit_test/runtime/fmt_units_test.cpp deleted file mode 100644 index f238dfee..00000000 --- a/test/unit_test/runtime/fmt_units_test.cpp +++ /dev/null @@ -1,334 +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. - -#include -#include // IWYU pragma: keep -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace units::isq::si; -using namespace units::isq::si::references; -using namespace units::isq::si::international; -using namespace units::isq::si::uscs; -using namespace units::isq::si::iau; -using namespace units::isq::si::imperial; -using namespace units::isq::si::imperial::references; -using namespace units::isq::si::typographic; -using namespace units::isq::iec80000::references; - -TEST_CASE("std::format on synthesized unit symbols", "[text][fmt]") -{ - SECTION("time") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_ns) == "1 ns"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_us) == "1 µs"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_ms) == "1 ms"); - - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_us) == "1 us"); - } - - SECTION("length") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_mm) == "1 mm"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_cm) == "1 cm"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_km) == "1 km"); - CHECK(UNITS_STD_FMT::format("{}", 1 * ft) == "1 ft"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_ft_us) == "1 ft(us)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_yd) == "1 yd"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_in) == "1 in"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_fathom) == "1 fathom"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_fathom_us) == "1 fathom(us)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mi) == "1 mi"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mi_us) == "1 mi(us)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_naut_mi) == "1 mi(naut)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_ch) == "1 ch"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_rd) == "1 rd"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_thou) == "1 thou"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_pc) == "1 pc"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_ly) == "1 ly"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_pc) == "1 pc"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_angstrom) == "1 angstrom"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_au) == "1 au"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_pica_comp) == "1 pica(comp)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_pica_prn) == "1 pica(prn)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_point_comp) == "1 point(comp)"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_point_prn) == "1 point(prn)"); - } - - SECTION("mass") { CHECK(UNITS_STD_FMT::format("{}", 1_q_kg) == "1 kg"); } - - SECTION("area") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_m2) == "1 m²"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mm2) == "1 mm²"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_cm2) == "1 cm²"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_km2) == "1 km²"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_ft2) == "1 ft²"); - - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_m2) == "1 m^2"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_mm2) == "1 mm^2"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_cm2) == "1 cm^2"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_km2) == "1 km^2"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_ft2) == "1 ft^2"); - } - - SECTION("density") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_kg_per_m3) == "1 kg/m³"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_kg_per_m3) == "1 kg/m^3"); - } - - SECTION("resistance") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_R) == "1 Ω"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_kR) == "1 kΩ"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mR) == "1 mΩ"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_MR) == "1 MΩ"); - - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_R) == "1 ohm"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_kR) == "1 kohm"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_mR) == "1 mohm"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_MR) == "1 Mohm"); - } - - SECTION("voltage") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_V) == "1 V"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mV) == "1 mV"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_uV) == "1 µV"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_nV) == "1 nV"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_pV) == "1 pV"); - - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_uV) == "1 uV"); - } - - SECTION("volume") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_m3) == "1 m³"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mm3) == "1 mm³"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_cm3) == "1 cm³"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_km3) == "1 km³"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_ft3) == "1 ft³"); - - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_m3) == "1 m^3"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_mm3) == "1 mm^3"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_cm3) == "1 cm^3"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_km3) == "1 km^3"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_ft3) == "1 ft^3"); - } - - SECTION("frequency") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_mHz) == "1 mHz"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_kHz) == "1 kHz"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_MHz) == "1 MHz"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_GHz) == "1 GHz"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_THz) == "1 THz"); - } - - SECTION("speed") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_m_per_s) == "1 m/s"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_km_per_h) == "1 km/h"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mi_per_h) == "1 mi/h"); - } - - SECTION("acceleration") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_m_per_s2) == "1 m/s²"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_m_per_s2) == "1 m/s^2"); - } - - SECTION("momentum") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_kg_m_per_s) == "1 kg⋅m/s"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_kg_m_per_s) == "1 kg m/s"); - } - - SECTION("energy") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_mJ) == "1 mJ"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_kJ) == "1 kJ"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_MJ) == "1 MJ"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_GJ) == "1 GJ"); - } - - SECTION("power") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_mW) == "1 mW"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_kW) == "1 kW"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_MW) == "1 MW"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_GW) == "1 GW"); - } - - SECTION("surface tension") { CHECK(UNITS_STD_FMT::format("{}", 1_q_N_per_m) == "1 N/m"); } - - SECTION("magnetic induction") { CHECK(UNITS_STD_FMT::format("{}", 1_q_T) == "1 T"); } - - SECTION("magnetic flux") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_Wb) == "1 Wb"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_G) == "1 G"); - } - - SECTION("inductance") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_H) == "1 H"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mH) == "1 mH"); - } - - SECTION("conductance") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_S) == "1 S"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_nS) == "1 nS"); - } - - SECTION("catalytic activity") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_kat) == "1 kat"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_U) == "1 U"); - } - - SECTION("absorbed dose") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_Gy) == "1 Gy"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_kGy) == "1 kGy"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_mGy) == "1 mGy"); - } - - SECTION("addition with common ratio") { CHECK(UNITS_STD_FMT::format("{}", 1_q_in + 1_q_yd) == "37 in"); } - - SECTION("current density") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_A_per_m2) == "1 A/m²"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_A_per_m2) == "1 A/m^2"); - } - - SECTION("concentration") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_mol_per_m3) == "1 mol/m³"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_mol_per_m3) == "1 mol/m^3"); - } - - SECTION("luminance") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_cd_per_m2) == "1 cd/m²"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_cd_per_m2) == "1 cd/m^2"); - } - - SECTION("dynamic viscosity") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_Pa_s) == "1 Pa⋅s"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_Pa_s) == "1 Pa s"); - } - - SECTION("heat capacity") { CHECK(UNITS_STD_FMT::format("{}", 1_q_J_per_K) == "1 J/K"); } - - SECTION("specific heat capacity") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_J_per_kg_K) == "1 J⋅K⁻¹⋅kg⁻¹"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_J_per_kg_K) == "1 J K^-1 kg^-1"); - } - - SECTION("molar heath capacity") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_J_per_mol_K) == "1 J⋅K⁻¹⋅mol⁻¹"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_J_per_mol_K) == "1 J K^-1 mol^-1"); - } - - SECTION("thermal conductivity") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_W_per_m_K) == "1 W⋅m⁻¹⋅K⁻¹"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_W_per_m_K) == "1 W m^-1 K^-1"); - } - - SECTION("electric field strength") { CHECK(UNITS_STD_FMT::format("{}", 1_q_V_per_m) == "1 V/m"); } - - SECTION("charge density") - { - CHECK(UNITS_STD_FMT::format("{}", 1_q_C_per_m3) == "1 C/m³"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_C_per_m3) == "1 C/m^3"); - CHECK(UNITS_STD_FMT::format("{}", 1_q_C_per_m2) == "1 C/m²"); - CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_C_per_m2) == "1 C/m^2"); - } - - SECTION("permittivity") { CHECK(UNITS_STD_FMT::format("{}", 1_q_F_per_m) == "1 F/m"); } - - SECTION("permeability") { CHECK(UNITS_STD_FMT::format("{}", 1_q_H_per_m) == "1 H/m"); } - - SECTION("molar energy") { CHECK(UNITS_STD_FMT::format("{}", 1_q_J_per_mol) == "1 J/mol"); } - - SECTION("torque") { CHECK(UNITS_STD_FMT::format("{}", 1_q_N_m_per_rad) == "1 N⋅m/rad"); } - - SECTION("storage_capacity") - { - CHECK(UNITS_STD_FMT::format("{}", 1 * bit) == "1 bit"); - CHECK(UNITS_STD_FMT::format("{}", 1 * kbit) == "1 kbit"); - CHECK(UNITS_STD_FMT::format("{}", 1 * Tibit) == "1 Tibit"); - CHECK(UNITS_STD_FMT::format("{}", 1 * B) == "1 B"); - CHECK(UNITS_STD_FMT::format("{}", 1 * kB) == "1 kB"); - CHECK(UNITS_STD_FMT::format("{}", 1 * TiB) == "1 TiB"); - } - - SECTION("transfer_rate") - { - CHECK(UNITS_STD_FMT::format("{}", 1 * (B / s)) == "1 B/s"); - CHECK(UNITS_STD_FMT::format("{}", 1 * (kB / s)) == "1 kB/s"); - CHECK(UNITS_STD_FMT::format("{}", 1 * (TB / s)) == "1 TB/s"); - } - - SECTION("traffic_intesity") { CHECK(UNITS_STD_FMT::format("{}", 1 * E) == "1 E"); } - - SECTION("modulation_rate") - { - using namespace units::isq::iec80000; - CHECK(UNITS_STD_FMT::format("{}", 1 * Bd) == "1 Bd"); - CHECK(UNITS_STD_FMT::format("{}", 1 * kBd) == "1 kBd"); - CHECK(UNITS_STD_FMT::format("{}", 1 * TBd) == "1 TBd"); - CHECK(UNITS_STD_FMT::format("{}", quantity_cast(4 / (2 * s))) == "2 Bd"); - } - - SECTION("incoherent units with powers") - { - // TODO(chogg): Reinstate after format/Magnitude redesign. - // CHECK(UNITS_STD_FMT::format("{}", 1_q_mi * 1_q_mi * 1_q_mi) == "1 [15900351812136/3814697265625 × 10⁹] m³"); - // CHECK(UNITS_STD_FMT::format("{}", 1_q_au * 1_q_au) == "1 [2237952291797391849 × 10⁴] m²"); - // - // CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_mi * 1_q_mi * 1_q_mi) == "1 [15900351812136/3814697265625 x 10^9] - // m^3"); CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", 1_q_au * 1_q_au) == "1 [2237952291797391849 x 10^4] m^2"); - } - - SECTION("unknown scaled unit with reference different than the dimension's coherent unit") - { - // TODO(chogg): Reinstate after format/Magnitude redesign. - // constexpr auto mag = units::mag(); - // CHECK(UNITS_STD_FMT::format("{}", mass>(1)) == "1 [2/3 × 10⁻³] kg"); - // CHECK(UNITS_STD_FMT::format("{:%Q %Aq}", mass>(1)) == "1 [2/3 x 10^-3] kg"); - } -} diff --git a/test/unit_test/runtime/linear_algebra_test.cpp b/test/unit_test/runtime/linear_algebra_test.cpp new file mode 100644 index 00000000..b0ee38f8 --- /dev/null +++ b/test/unit_test/runtime/linear_algebra_test.cpp @@ -0,0 +1,483 @@ +// 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. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +template +using vector = STD_LA::fixed_size_column_vector; + +template +inline constexpr bool mp_units::is_vector> = true; + +namespace STD_LA { + +template +std::ostream& operator<<(std::ostream& os, const ::vector& v) +{ + os << "|"; + for (auto i = 0U; i < v.size(); ++i) { + os << UNITS_STD_FMT::format(" {:>9}", v(i)); + } + os << " |"; + return os; +} + +} // namespace STD_LA + +namespace { + +using namespace mp_units; +using namespace mp_units::si::unit_symbols; + +template +[[nodiscard]] auto get_magnitude(const vector& v) +{ + using namespace std; + return hypot(v(0), v(1), v(2)); +} + +template +[[nodiscard]] vector cross_product(const vector& a, const vector& b) +{ + return {a(1) * b(2) - a(2) * b(1), a(2) * b(0) - a(0) * b(2), a(0) * b(1) - a(1) * b(0)}; +} + +template + requires is_vector && is_vector && + requires(typename Q1::rep v1, typename Q2::rep v2) { cross_product(v1, v2); } +[[nodiscard]] QuantityOf auto cross_product(const Q1& q1, const Q2& q2) +{ + return cross_product(q1.number(), q2.number()) * (Q1::reference * Q2::reference); +} + +} // namespace + +TEST_CASE("vector quantity", "[la]") +{ + SECTION("cast of unit") + { + SECTION("non-truncating") + { + const auto v = vector{3, 2, 1} * isq::position_vector[km]; + CHECK(v[m].number() == vector{3000, 2000, 1000}); + } + + SECTION("truncating") + { + const auto v = vector{1001, 1002, 1003} * isq::position_vector[m]; + CHECK(value_cast(v).number() == vector{1, 1, 1}); + } + } + + SECTION("to scalar magnitude") + { + const auto v = vector{2, 3, 6} * isq::velocity[km / h]; + const auto speed = get_magnitude(v.number()) * isq::speed[v.unit]; // TODO can we do better here? + CHECK(speed.number() == 7); + } + + SECTION("multiply by scalar value") + { + const auto v = vector{1, 2, 3} * isq::position_vector[m]; + + SECTION("integral") + { + SECTION("scalar on LHS") { CHECK((2 * v).number() == vector{2, 4, 6}); } + SECTION("scalar on RHS") { CHECK((v * 2).number() == vector{2, 4, 6}); } + } + + SECTION("floating-point") + { + SECTION("scalar on LHS") { CHECK((0.5 * v).number() == vector{0.5, 1., 1.5}); } + SECTION("scalar on RHS") { CHECK((v * 0.5).number() == vector{0.5, 1., 1.5}); } + } + } + + SECTION("divide by scalar value") + { + const auto v = vector{2, 4, 6} * isq::position_vector[m]; + + SECTION("integral") { CHECK((v / 2).number() == vector{1, 2, 3}); } + SECTION("floating-point") { CHECK((v / 0.5).number() == vector{4., 8., 12.}); } + } + + SECTION("add") + { + const auto v = vector{1, 2, 3} * isq::position_vector[m]; + + SECTION("same unit") + { + const auto u = vector{3, 2, 1} * isq::position_vector[m]; + CHECK((v + u).number() == vector{4, 4, 4}); + } + SECTION("different units") + { + const auto u = vector{3, 2, 1} * isq::position_vector[km]; + CHECK((v + u).number() == vector{3001, 2002, 1003}); + } + } + + SECTION("subtract") + { + const auto v = vector{1, 2, 3} * isq::position_vector[m]; + + SECTION("same unit") + { + const auto u = vector{3, 2, 1} * isq::position_vector[m]; + CHECK((v - u).number() == vector{-2, 0, 2}); + } + SECTION("different units") + { + const auto u = vector{3, 2, 1} * isq::position_vector[km]; + CHECK((v - u).number() == vector{-2999, -1998, -997}); + } + } + + SECTION("multiply by scalar quantity") + { + const auto v = vector{1, 2, 3} * isq::velocity[m / s]; + + SECTION("integral") + { + const auto mass = 2 * isq::mass[kg]; + + SECTION("derived_quantity_spec") + { + SECTION("scalar on LHS") { CHECK((mass * v).number() == vector{2, 4, 6}); } + SECTION("scalar on RHS") { CHECK((v * mass).number() == vector{2, 4, 6}); } + } + SECTION("quantity_cast to momentum") + { + SECTION("scalar on LHS") { CHECK(quantity_cast(mass * v).number() == vector{2, 4, 6}); } + SECTION("scalar on RHS") { CHECK(quantity_cast(v * mass).number() == vector{2, 4, 6}); } + } + SECTION("quantity of momentum") + { + SECTION("scalar on LHS") + { + const quantity> momentum = mass * v; + CHECK(momentum.number() == vector{2, 4, 6}); + } + SECTION("scalar on RHS") + { + const quantity> momentum = v * mass; + CHECK(momentum.number() == vector{2, 4, 6}); + } + } + } + + SECTION("floating-point") + { + const auto mass = 0.5 * isq::mass[kg]; + + SECTION("derived_quantity_spec") + { + SECTION("scalar on LHS") { CHECK((mass * v).number() == vector{0.5, 1., 1.5}); } + SECTION("scalar on RHS") { CHECK((v * mass).number() == vector{0.5, 1., 1.5}); } + } + SECTION("quantity_cast to momentum") + { + SECTION("scalar on LHS") + { + CHECK(quantity_cast(mass * v).number() == vector{0.5, 1., 1.5}); + } + SECTION("scalar on RHS") + { + CHECK(quantity_cast(v * mass).number() == vector{0.5, 1., 1.5}); + } + } + SECTION("quantity of momentum") + { + SECTION("scalar on LHS") + { + const quantity> momentum = mass * v; + CHECK(momentum.number() == vector{0.5, 1., 1.5}); + } + SECTION("scalar on RHS") + { + const quantity> momentum = v * mass; + CHECK(momentum.number() == vector{0.5, 1., 1.5}); + } + } + } + } + + SECTION("divide by scalar quantity") + { + const auto pos = vector{30, 20, 10} * isq::position_vector[km]; + + SECTION("integral") + { + const auto dur = 2 * isq::duration[h]; + + SECTION("derived_quantity_spec") { CHECK((pos / dur).number() == vector{15, 10, 5}); } + SECTION("quantity_cast to velocity") + { + CHECK(quantity_cast(pos / dur).number() == vector{15, 10, 5}); + } + SECTION("quantity of velocity") + { + const quantity> v = pos / dur; + CHECK(v.number() == vector{15, 10, 5}); + } + } + + SECTION("floating-point") + { + const auto dur = 0.5 * isq::duration[h]; + + SECTION("derived_quantity_spec") { CHECK((pos / dur).number() == vector{60, 40, 20}); } + SECTION("quantity_cast to velocity") + { + CHECK(quantity_cast(pos / dur).number() == vector{60, 40, 20}); + } + SECTION("quantity of velocity") + { + const quantity> v = pos / dur; + CHECK(v.number() == vector{60, 40, 20}); + } + } + } + + SECTION("cross product with a vector quantity") + { + const auto r = vector{3, 0, 0} * isq::position_vector[m]; + const auto f = vector{0, 10, 0} * isq::force[N]; + + CHECK(cross_product(r, f) == vector{0, 0, 30} * isq::moment_of_force[N * m]); + } +} + +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; + +TEST_CASE("vector of quantities", "[la]") +{ + SECTION("cast of unit") + { + SECTION("non-truncating") + { + const vector> v = {3 * km, 2 * km, 1 * km}; + + CHECK(vector>(v) == + vector>{3000 * m, 2000 * m, 1000 * m}); + } + + // truncating not possible (no way to apply quantity_cast to sub-components of a vector) + } + + SECTION("to scalar magnitude") + { + const vector> v = {2 * (km / h), 3 * (km / h), 6 * (km / h)}; + const auto speed = get_magnitude(v).number() * isq::speed[v(0).unit]; // TODO can we do better here? + CHECK(speed.number() == 7); + } + + SECTION("multiply by scalar value") + { + const vector> v = {1 * m, 2 * m, 3 * m}; + + SECTION("integral") + { + const vector> result = {2 * m, 4 * m, 6 * m}; + + SECTION("scalar on LHS") { CHECK(2 * v == result); } + SECTION("scalar on RHS") { CHECK(v * 2 == result); } + } + + SECTION("floating-point") + { + const vector> result = {0.5 * m, 1. * m, 1.5 * m}; + + SECTION("scalar on LHS") { CHECK(0.5 * v == result); } + SECTION("scalar on RHS") { CHECK(v * 0.5 == result); } + } + } + + SECTION("divide by scalar value") + { + const vector> v = {2 * m, 4 * m, 6 * m}; + + SECTION("integral") { CHECK(v / 2 == vector>{1 * m, 2 * m, 3 * m}); } + SECTION("floating-point") + { + CHECK(v / 0.5 == vector>{4. * m, 8. * m, 12. * m}); + } + } + + SECTION("add") + { + const vector> v = {1 * m, 2 * m, 3 * m}; + + SECTION("same unit") + { + const vector> u = {3 * m, 2 * m, 1 * m}; + + CHECK(v + u == vector>{4 * m, 4 * m, 4 * m}); + } + SECTION("different units") + { + const vector> u = {3 * km, 2 * km, 1 * km}; + + CHECK(v + u == vector>{3001 * m, 2002 * m, 1003 * m}); + } + } + + SECTION("subtract") + { + const vector> v = {1 * m, 2 * m, 3 * m}; + + SECTION("same unit") + { + const vector> u = {3 * m, 2 * m, 1 * m}; + CHECK(v - u == vector>{-2 * m, 0 * m, 2 * m}); + } + SECTION("different units") + { + const vector> u = {3 * km, 2 * km, 1 * km}; + CHECK(v - u == vector>{-2999 * m, -1998 * m, -997 * m}); + } + } + + SECTION("multiply by scalar quantity") + { + const vector> v = {1 * (m / s), 2 * (m / s), 3 * (m / s)}; + + SECTION("integral") + { + const auto mass = 2 * isq::mass[kg]; + const auto result = vector>{2 * (N * s), 4 * (N * s), 6 * (N * s)}; + + SECTION("derived_quantity_spec") + { + SECTION("scalar on LHS") { CHECK(mass * v == result); } + SECTION("scalar on RHS") { CHECK(v * mass == result); } + } + + // no way to apply quantity_cast to sub-components + + SECTION("quantity of momentum") + { + SECTION("scalar on LHS") + { + const vector> momentum = mass * v; + CHECK(momentum == result); + } + SECTION("scalar on RHS") + { + const vector> momentum = v * mass; + CHECK(momentum == result); + } + } + } + + SECTION("floating-point") + { + const auto mass = 0.5 * isq::mass[kg]; + const auto result = vector>{0.5 * (N * s), 1. * (N * s), 1.5 * (N * s)}; + + SECTION("derived_quantity_spec") + { + SECTION("scalar on LHS") { CHECK(mass * v == result); } + SECTION("scalar on RHS") { CHECK(v * mass == result); } + } + + // no way to apply quantity_cast to sub-components + + SECTION("quantity of momentum") + { + SECTION("scalar on LHS") + { + const vector> momentum = mass * v; + CHECK(momentum == result); + } + SECTION("scalar on RHS") + { + const vector> momentum = v * mass; + CHECK(momentum == result); + } + } + } + } + + SECTION("divide by scalar quantity") + { + const vector> pos = {30 * km, 20 * km, 10 * km}; + + SECTION("integral") + { + const auto dur = 2 * isq::duration[h]; + + SECTION("derived_quantity_spec") + { + CHECK(pos / dur == vector>{15 * (km / h), 10 * (km / h), 5 * (km / h)}); + } + + // no way to apply quantity_cast to sub-components + + SECTION("quantity of velocity") + { + const vector> v = pos / dur; + CHECK(v == vector>{15 * (km / h), 10 * (km / h), 5 * (km / h)}); + } + } + + SECTION("floating-point") + { + const auto dur = 0.5 * isq::duration[h]; + + SECTION("derived_quantity_spec") + { + CHECK(pos / dur == + vector>{60. * (km / h), 40. * (km / h), 20. * (km / h)}); + } + + // no way to apply quantity_cast to sub-components + + SECTION("quantity of velocity") + { + const vector> v = pos / dur; + CHECK(v == vector>{60. * (km / h), 40. * (km / h), 20. * (km / h)}); + } + } + } + + SECTION("cross product with a vector of quantities") + { + const vector> r = {3 * m, 0 * m, 0 * m}; + const vector> f = {0 * N, 10 * N, 0 * N}; + + CHECK(cross_product(r, f) == + vector>{0 * (N * m), 0 * (N * m), 30 * (N * m)}); + } +} diff --git a/test/unit_test/runtime/magnitude_test.cpp b/test/unit_test/runtime/magnitude_test.cpp deleted file mode 100644 index dddd2785..00000000 --- a/test/unit_test/runtime/magnitude_test.cpp +++ /dev/null @@ -1,622 +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. - -#include -#include -#include -#include - -using namespace units; -using namespace units::detail; - -template<> -inline constexpr std::optional units::known_first_factor<9223372036854775783> = 9223372036854775783; - -namespace { - -// A set of non-standard bases for testing purposes. -struct noninteger_base { - static constexpr long double value = 1.234L; -}; -struct noncanonical_two_base { - static constexpr long double value = 2.0L; -}; -struct other_noncanonical_two_base { - static constexpr long double value = 2.0L; -}; -struct invalid_zero_base { - static constexpr long double value = 0.0L; -}; -struct invalid_negative_base { - static constexpr long double value = -1.234L; -}; - -template -constexpr auto pi_to_the() -{ - return magnitude{Power}>{}; -} - -template -void check_same_type_and_value(T actual, U expected) -{ - CHECK(std::is_same_v); - CHECK(actual == expected); -} - -template -void check_ratio_round_trip_is_identity() -{ - constexpr Magnitude auto m = mag(); - constexpr ratio round_trip = ratio{ - get_value(numerator(m)), - get_value(denominator(m)), - }; - CHECK(round_trip == R); -} - - -TEST_CASE("base_power") -{ - SECTION("base rep deducible for integral base") - { - CHECK(base_power{2} == base_power{2, ratio{1}}); - CHECK(base_power{2, 3} == base_power{2, ratio{3}}); - CHECK(base_power{2, ratio{3, 4}} == base_power{2, ratio{3, 4}}); - } - - SECTION("get_base retrieves base for integral base") - { - CHECK(base_power{2}.get_base() == 2); - CHECK(base_power{3, 5}.get_base() == 3); - CHECK(base_power{5, ratio{1, 3}}.get_base() == 5); - } - - SECTION("get_base retrieves member value for non-integer base") - { - CHECK(base_power{}.get_base() == 1.234L); - CHECK(base_power{2}.get_base() == 1.234L); - CHECK(base_power{ratio{5, 8}}.get_base() == 1.234L); - } - - SECTION("same-base values not equal if types are different") - { - const auto a = base_power{}; - const auto b = base_power{2}; - const auto c = base_power{}; - - REQUIRE(a.get_base() == b.get_base()); - CHECK(a != b); - - REQUIRE(a.get_base() == c.get_base()); - CHECK(a != c); - } - - SECTION("same-type values not equal if bases are different") - { - CHECK(base_power{2} != base_power{3}); - CHECK(base_power{2, ratio{5, 4}} != base_power{3, ratio{5, 4}}); - } - - SECTION("same-type, same-base values not equal if powers are different") - { - CHECK(base_power{2} != base_power{2, 2}); - CHECK(base_power{} != base_power{ratio{1, 3}}); - } - - SECTION("product with inverse equals identity") - { - auto check_product_with_inverse_is_identity = [](auto x) { CHECK(x * pow<-1>(x) == mag<1>()); }; - - check_product_with_inverse_is_identity(mag<3>()); - check_product_with_inverse_is_identity(mag()); - check_product_with_inverse_is_identity(pi_to_the()); - } - - SECTION("pow() multiplies exponent") - { - CHECK(pow(base_power{2}, 0) == base_power{2, 0}); - CHECK(pow(base_power{2, 3}, ratio{-1, 2}) == base_power{2, ratio{-3, 2}}); - CHECK(pow(base_power{ratio{3, 2}}, ratio{1, 3}) == base_power{ratio{1, 2}}); - } -} - -TEST_CASE("make_ratio performs prime factorization correctly") -{ - SECTION("Performs prime factorization when denominator is 1") - { - CHECK(mag<1>() == magnitude<>{}); - CHECK(mag<2>() == magnitude{}); - CHECK(mag<3>() == magnitude{}); - CHECK(mag<4>() == magnitude{}); - - CHECK(mag<792>() == magnitude{}); - } - - SECTION("Supports fractions") { CHECK(mag() == magnitude{}); } - - SECTION("Can handle prime factor which would be large enough to overflow int") - { - // This was taken from a case which failed when we used `int` for our base to store prime numbers. - // The failure was due to a prime factor which is larger than 2^31. - mag(); - } - - SECTION("Can bypass computing primes by providing known_first_factor") - { - // Sometimes, even wheel factorization isn't enough to handle the compilers' limits on constexpr steps and/or - // iterations. To work around these cases, we can explicitly provide the correct answer directly to the compiler. - // - // In this case, we test that we can represent the largest prime that fits in a signed 64-bit int. The reason this - // test can pass is that we have provided the answer, by specializing the `known_first_factor` variable template - // above in this file. - mag<9'223'372'036'854'775'783>(); - } -} - -TEST_CASE("magnitude converts to numerical value") -{ - SECTION("Positive integer powers of integer bases give integer values") - { - constexpr auto mag_412 = mag<412>(); - check_same_type_and_value(get_value(mag_412), 412); - check_same_type_and_value(get_value(mag_412), std::size_t{412}); - check_same_type_and_value(get_value(mag_412), 412.0f); - check_same_type_and_value(get_value(mag_412), 412.0); - } - - SECTION("Negative integer powers of integer bases compute correct values") - { - constexpr auto mag_0p125 = mag(); - check_same_type_and_value(get_value(mag_0p125), 0.125f); - check_same_type_and_value(get_value(mag_0p125), 0.125); - } - - SECTION("pi to the 1 supplies correct values") - { - check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); - check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); - check_same_type_and_value(get_value(mag_pi), std::numbers::pi_v); - } - - SECTION("pi to arbitrary power performs computations in most accurate type at compile time") - { - if constexpr (sizeof(float) < sizeof(long double)) { - constexpr auto pi_cubed = pi_to_the<3>(); - - auto cube = [](auto x) { return x * x * x; }; - constexpr auto via_float = cube(std::numbers::pi_v); - constexpr auto via_long_double = static_cast(cube(std::numbers::pi_v)); - - constexpr auto pi_cubed_value = get_value(pi_cubed); - REQUIRE(pi_cubed_value != via_float); - CHECK(pi_cubed_value == via_long_double); - } - } - - SECTION("Impossible requests are prevented at compile time") - { - // Naturally, we cannot actually write a test to verify a compiler error. But any of these can - // be uncommented if desired to verify that it breaks the build. - - // get_value(mag<412>()); - - // Would work for pow<62>: - // get_value(pow<63>(mag<2>())); - - // Would work for pow<63>: - // get_value(pow<64>(mag<2>())); - - get_value(pow<308>(mag<10>())); // Compiles, correctly. - // get_value(pow<309>(mag<10>())); - // get_value(pow<3099>(mag<10>())); - // get_value(pow<3099999>(mag<10>())); - - auto sqrt_2 = pow(mag<2>()); - CHECK(!is_integral(sqrt_2)); - // get_value(sqrt_2); - } -} - -TEST_CASE("Equality works for magnitudes") -{ - SECTION("Equivalent ratios are equal") - { - CHECK(mag<1>() == mag<1>()); - CHECK(mag<3>() == mag<3>()); - CHECK(mag() == mag()); - } - - SECTION("Different ratios are unequal") - { - CHECK(mag<3>() != mag<5>()); - CHECK(mag<3>() != mag()); - } - - SECTION("Supports constexpr") - { - constexpr auto eq = (mag() == mag()); - CHECK(!eq); - } -} - -TEST_CASE("Multiplication works for magnitudes") -{ - SECTION("Reciprocals reduce to null magnitude") { CHECK(mag() * mag() == mag<1>()); } - - SECTION("Products work as expected") { CHECK(mag() * mag() == mag()); } - - SECTION("Products handle pi correctly") - { - CHECK(pi_to_the<1>() * mag() * pi_to_the() == - magnitude{ratio{1, 2}}>{}); - } - - SECTION("Supports constexpr") - { - constexpr auto p = mag() * mag(); - CHECK(p == mag()); - } -} - -TEST_CASE("Common Magnitude") -{ - SECTION("Identity for identical magnitudes") - { - CHECK(common_magnitude(mag<1>(), mag<1>()) == mag<1>()); - CHECK(common_magnitude(mag<15>(), mag<15>()) == mag<15>()); - CHECK(common_magnitude(pi_to_the(), pi_to_the()) == pi_to_the()); - } - - SECTION("Greatest Common Factor for integers") - { - CHECK(common_magnitude(mag<24>(), mag<36>()) == mag<12>()); - CHECK(common_magnitude(mag<24>(), mag<37>()) == mag<1>()); - } - - SECTION("Handles fractions") - { - CHECK(common_magnitude(mag(), mag()) == mag()); - } -} - -TEST_CASE("Division works for magnitudes") -{ - SECTION("Dividing anything by itself reduces to null magnitude") - { - CHECK(mag() / mag() == mag<1>()); - CHECK(mag<15>() / mag<15>() == mag<1>()); - } - - SECTION("Quotients work as expected") { CHECK(mag() / mag() == mag()); } - - SECTION("Supports constexpr") - { - constexpr auto q = mag() / mag(); - CHECK(q == mag()); - } -} - -TEST_CASE("Can raise Magnitudes to rational powers") -{ - SECTION("Anything to the 0 is 1") - { - CHECK(pow<0>(mag<1>()) == mag<1>()); - CHECK(pow<0>(mag<123>()) == mag<1>()); - CHECK(pow<0>(mag()) == mag<1>()); - CHECK(pow<0>(pi_to_the()) == mag<1>()); - } - - SECTION("Anything to the 1 is itself") - { - CHECK(pow<1>(mag<1>()) == mag<1>()); - CHECK(pow<1>(mag<123>()) == mag<123>()); - CHECK(pow<1>(mag()) == mag()); - CHECK(pow<1>(pi_to_the()) == pi_to_the()); - } - - SECTION("Can raise to arbitrary rational power") - { - CHECK(pow(pi_to_the()) == pi_to_the()); - } -} - -TEST_CASE("can distinguish integral, rational, and irrational magnitudes") -{ - SECTION("Integer magnitudes are integral and rational") - { - auto check_rational_and_integral = [](Magnitude auto m) { - CHECK(is_integral(m)); - CHECK(is_rational(m)); - }; - check_rational_and_integral(magnitude<>{}); - check_rational_and_integral(mag<1>()); - check_rational_and_integral(mag<3>()); - check_rational_and_integral(mag<8>()); - check_rational_and_integral(mag<412>()); - check_rational_and_integral(mag()); - } - - SECTION("Fractional magnitudes are rational, but not integral") - { - auto check_rational_but_not_integral = [](Magnitude auto m) { - CHECK(!is_integral(m)); - CHECK(is_rational(m)); - }; - check_rational_but_not_integral(mag()); - check_rational_but_not_integral(mag()); - } -} - -TEST_CASE("Constructing ratio from rational magnitude") -{ - SECTION("Round trip is identity") - { - // Note that not every Magnitude can be represented as a ratio. However, if we _start_ with a - // ratio, we must guarantee to recover the same ratio in a round trip. - check_ratio_round_trip_is_identity<1>(); - check_ratio_round_trip_is_identity<9>(); - check_ratio_round_trip_is_identity(); - } - - SECTION("Rational magnitude converts to ratio") - { - constexpr ratio r = as_ratio(mag()); - CHECK(r == ratio{22, 7}); - } - - SECTION("Irrational magnitude does not convert to ratio") - { - // The following code should not compile. - // as_ratio(pow(mag<2>())); - - // The following code should not compile. - // as_ratio(mag<180>() / pi_to_the<1>()); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Detail function tests below. - -TEST_CASE("int_power computes integer powers") -{ - SECTION("handles floating point") - { - check_same_type_and_value(int_power(0.123L, 0), 1.0L); - check_same_type_and_value(int_power(0.246f, 1), 0.246f); - check_same_type_and_value(int_power(0.5f, 3), 0.125f); - check_same_type_and_value(int_power(2.5, 4), 39.0625); - - CHECK(std::is_same_v(base_power{10, 20}))>); - } - - SECTION("handles integral") - { - check_same_type_and_value(int_power(8, 0), 1); - check_same_type_and_value(int_power(9L, 1), 9L); - check_same_type_and_value(int_power(2, 10), 1024); - } -} - -TEST_CASE("integer_part picks out integer part of single-basis magnitude") -{ - SECTION("integer_part of non-integer base is identity magnitude") - { - CHECK(integer_part(pi_to_the<1>()) == magnitude<>{}); - CHECK(integer_part(pi_to_the<-8>()) == magnitude<>{}); - CHECK(integer_part(pi_to_the()) == magnitude<>{}); - } - - SECTION("integer_part of integer base to negative power is identity magnitude") - { - CHECK(integer_part(magnitude{}) == magnitude<>{}); - CHECK(integer_part(magnitude{}) == magnitude<>{}); - } - - SECTION("integer_part of integer base to fractional power is identity magnitude") - { - CHECK(integer_part(magnitude{}) == magnitude<>{}); - } - - SECTION("integer_part of integer base to power at least one takes integer part") - { - CHECK(integer_part(magnitude{}) == magnitude{}); - CHECK(integer_part(magnitude{}) == magnitude{}); - CHECK(integer_part(magnitude{}) == magnitude{}); - } -} - -TEST_CASE("Prime helper functions") -{ - SECTION("multiplicity") - { - CHECK(multiplicity(2, 8) == 3); - CHECK(multiplicity(2, 1024) == 10); - CHECK(multiplicity(11, 6655) == 3); - } - - SECTION("remove_power()") - { - CHECK(remove_power(17, 0, 5) == 5); - CHECK(remove_power(2, 3, 24) == 3); - CHECK(remove_power(11, 3, 6655) == 5); - } -} - -TEST_CASE("Prime factorization") -{ - SECTION("1 factors into the null magnitude") { CHECK(prime_factorization_v<1> == magnitude<>{}); } - - SECTION("Prime numbers factor into themselves") - { - CHECK(prime_factorization_v<2> == magnitude{}); - CHECK(prime_factorization_v<3> == magnitude{}); - CHECK(prime_factorization_v<5> == magnitude{}); - CHECK(prime_factorization_v<7> == magnitude{}); - CHECK(prime_factorization_v<11> == magnitude{}); - - CHECK(prime_factorization_v<41> == magnitude{}); - } - - SECTION("Prime factorization finds factors and multiplicities") - { - CHECK(prime_factorization_v<792> == magnitude{}); - } -} - -TEST_CASE("is_prime detects primes") -{ - SECTION("Non-positive numbers are not prime") - { - CHECK(!is_prime(-1328)); - CHECK(!is_prime(-1)); - CHECK(!is_prime(0)); - } - - SECTION("1 is not prime") { CHECK(!is_prime(1)); } - - SECTION("Discriminates between primes and non-primes") - { - CHECK(is_prime(2)); - CHECK(is_prime(3)); - CHECK(!is_prime(4)); - CHECK(is_prime(5)); - CHECK(!is_prime(6)); - CHECK(is_prime(7)); - CHECK(!is_prime(8)); - CHECK(!is_prime(9)); - - CHECK(is_prime(7919)); - } -} - -TEST_CASE("is_valid_base_power") -{ - SECTION("0 power is invalid") - { - REQUIRE(is_valid_base_power(base_power{2})); - CHECK(!is_valid_base_power(base_power{2, 0})); - - REQUIRE(is_valid_base_power(base_power{41})); - CHECK(!is_valid_base_power(base_power{41, 0})); - - REQUIRE(is_valid_base_power(base_power{})); - CHECK(!is_valid_base_power(base_power{0})); - } - - SECTION("non-prime integers are invalid") - { - CHECK(!is_valid_base_power(base_power{-8})); - CHECK(!is_valid_base_power(base_power{0})); - CHECK(!is_valid_base_power(base_power{1})); - - CHECK(is_valid_base_power(base_power{2})); - CHECK(is_valid_base_power(base_power{3})); - - CHECK(!is_valid_base_power(base_power{4})); - } - - SECTION("non-positive floating point bases are invalid") - { - CHECK(!is_valid_base_power(base_power{})); - CHECK(!is_valid_base_power(base_power{})); - } -} - -TEST_CASE("pairwise_all evaluates all pairs") -{ - const auto all_pairs_return_true = pairwise_all{[](auto, auto) { return true; }}; - const auto all_pairs_return_false = pairwise_all{[](auto, auto) { return false; }}; - const auto all_increasing = pairwise_all{std::less{}}; - - SECTION("always true for empty tuples") - { - CHECK(all_pairs_return_true()); - CHECK(all_pairs_return_false()); - } - - SECTION("always true for single-element tuples") - { - CHECK(all_pairs_return_true(1)); - CHECK(all_pairs_return_false(3.14)); - CHECK(all_pairs_return_true('x')); - } - - SECTION("true for longer tuples iff true for all neighbouring pairs") - { - CHECK(all_increasing(1, 1.5)); - CHECK(all_increasing(1, 1.5, 2)); - - CHECK(!all_increasing(1, 2.0, 2)); - CHECK(!all_increasing(1, 2.5, 2)); - - CHECK(all_pairs_return_true('c', 1, 8.9, 42u)); - CHECK(!all_pairs_return_false('c', 1, 8.9, 42u)); - } -} - -TEST_CASE("strictly_increasing") -{ - SECTION("Empty input is sorted") { CHECK(strictly_increasing()); } - - SECTION("Single-element input is sorted") - { - CHECK(strictly_increasing(3)); - CHECK(strictly_increasing(15.42)); - CHECK(strictly_increasing('c')); - } - - SECTION("Multi-value inputs compare correctly") - { - CHECK(strictly_increasing(3, 3.14)); - CHECK(!strictly_increasing(3, 3.0)); - CHECK(!strictly_increasing(4, 3.0)); - } -} - -TEST_CASE("extract_power_of_10") -{ - SECTION("Picks out positive powers") - { - CHECK(extract_power_of_10(mag<10>()) == 1); - CHECK(extract_power_of_10(mag<20>()) == 1); - CHECK(extract_power_of_10(mag<40>()) == 1); - CHECK(extract_power_of_10(mag<50>()) == 1); - CHECK(extract_power_of_10(mag<100>()) == 2); - } - - SECTION("Picks out negative powers") - { - constexpr auto ONE = mag<1>(); - CHECK(extract_power_of_10(ONE / mag<10>()) == -1); - CHECK(extract_power_of_10(ONE / mag<20>()) == -1); - CHECK(extract_power_of_10(ONE / mag<40>()) == -1); - CHECK(extract_power_of_10(ONE / mag<50>()) == -1); - CHECK(extract_power_of_10(ONE / mag<100>()) == -2); - } - - SECTION("Zero if signs disagree") { CHECK(extract_power_of_10(mag<2>() / mag<5>()) == 0); } - - SECTION("Handles rational powers") { CHECK(extract_power_of_10(sqrt(mag<1000>())) == 1); } -} - -} // namespace diff --git a/test/unit_test/runtime/math_test.cpp b/test/unit_test/runtime/math_test.cpp index cf2e4c3d..a1e93f7d 100644 --- a/test/unit_test/runtime/math_test.cpp +++ b/test/unit_test/runtime/math_test.cpp @@ -22,61 +22,67 @@ #include "almost_equals.h" #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -using namespace units; -using namespace units::isq; -using namespace units::isq::si::literals; +using namespace mp_units; +using namespace mp_units::si::unit_symbols; // classical TEST_CASE("'pow()' on quantity changes the value and the dimension accordingly", "[math][pow]") { - SECTION("'pow<0>(q)' returns '1'") { CHECK(pow<0>(2_q_m) == 1); } + SECTION("'pow<0>(q)' returns '1'") { CHECK(pow<0>(2 * isq::length[m]) == 1); } - SECTION("'pow<1>(q)' returns 'q'") { CHECK(pow<1>(2_q_m) == 2_q_m); } + SECTION("'pow<1>(q)' returns 'q'") { CHECK(pow<1>(2 * isq::length[m]) == 2 * isq::length[m]); } - SECTION("'pow<2>(q)' squares both the value and a dimension") { CHECK(pow<2>(2_q_m) == 4_q_m2); } + SECTION("'pow<2>(q)' squares both the value and a dimension") + { + CHECK(pow<2>(2 * isq::length[m]) == 4 * isq::area[m2]); + } - SECTION("'pow<3>(q)' cubes both the value and a dimension") { CHECK(pow<3>(2_q_m) == 8_q_m3); } + SECTION("'pow<3>(q)' cubes both the value and a dimension") + { + CHECK(pow<3>(2 * isq::length[m]) == 8 * isq::volume[m3]); + } } TEST_CASE("'sqrt()' on quantity changes the value and the dimension accordingly", "[math][sqrt]") { - REQUIRE(sqrt(4_q_m2) == 2_q_m); + REQUIRE(sqrt(4 * isq::area[m2]) == 2 * isq::length[m]); } TEST_CASE("'cbrt()' on quantity changes the value and the dimension accordingly", "[math][cbrt]") { - REQUIRE(cbrt(8_q_m3) == 2_q_m); + REQUIRE(cbrt(8 * isq::volume[m3]) == 2 * isq::length[m]); } TEST_CASE("'pow()' on quantity changes the value and the dimension accordingly", "[math][pow]") { - REQUIRE(pow<1, 4>(16_q_m2) == sqrt(4_q_m)); + REQUIRE(pow<1, 4>(16 * isq::area[m2]) == sqrt(4 * isq::length[m])); } +// TODO add tests for exp() + TEST_CASE("absolute functions on quantity returns the absolute value", "[math][abs][fabs]") { SECTION("'abs()' on a negative quantity returns the abs") { - SECTION("integral representation") { REQUIRE(abs(-1_q_m) == 1_q_m); } + SECTION("integral representation") { REQUIRE(abs(-1 * isq::length[m]) == 1 * isq::length[m]); } - SECTION("floating-point representation") { REQUIRE(abs(-1._q_m) == 1_q_m); } + SECTION("floating-point representation") { REQUIRE(abs(-1. * isq::length[m]) == 1 * isq::length[m]); } } SECTION("'abs()' on a positive quantity returns the abs") { - SECTION("integral representation") { REQUIRE(abs(1_q_m) == 1_q_m); } + SECTION("integral representation") { REQUIRE(abs(1 * isq::length[m]) == 1 * isq::length[m]); } - SECTION("floating-point representation") { REQUIRE(abs(1._q_m) == 1_q_m); } + SECTION("floating-point representation") { REQUIRE(abs(1. * isq::length[m]) == 1 * isq::length[m]); } } } @@ -84,303 +90,345 @@ TEST_CASE("numeric_limits functions", "[limits]") { SECTION("'epsilon' works as expected using default floating type") { - REQUIRE(epsilon().number() == std::numeric_limits::epsilon()); + REQUIRE(epsilon(isq::length[m]).number() == + std::numeric_limits::epsilon()); } SECTION("'epsilon' works as expected using integers") { - REQUIRE(epsilon().number() == std::numeric_limits::epsilon()); - } - SECTION("'epsilon' works as expected using mixed Rep types") - { - REQUIRE(epsilon().number() != std::numeric_limits::epsilon()); + REQUIRE(epsilon(isq::length[m]).number() == std::numeric_limits::epsilon()); } } TEST_CASE("floor functions", "[floor]") { - SECTION("floor 1 second with target unit second should be 1 second") { REQUIRE(floor(1_q_s) == 1_q_s); } + SECTION("floor 1 second with target unit second should be 1 second") + { + REQUIRE(floor(1 * isq::time[s]) == 1 * isq::time[s]); + } SECTION("floor 1000 milliseconds with target unit second should be 1 second") { - REQUIRE(floor(1000_q_ms) == 1_q_s); + REQUIRE(floor(1000 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("floor 1001 milliseconds with target unit second should be 1 second") { - REQUIRE(floor(1001_q_ms) == 1_q_s); + REQUIRE(floor(1001 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("floor 1999 milliseconds with target unit second should be 1 second") { - REQUIRE(floor(1999_q_ms) == 1_q_s); + REQUIRE(floor(1999 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("floor -1000 milliseconds with target unit second should be -1 second") { - REQUIRE(floor(-1000_q_ms) == -1_q_s); + REQUIRE(floor(-1000 * isq::time[ms]) == -1 * isq::time[s]); } SECTION("floor -999 milliseconds with target unit second should be -1 second") { - REQUIRE(floor(-999_q_ms) == -1_q_s); + REQUIRE(floor(-999 * isq::time[ms]) == -1 * isq::time[s]); } SECTION("floor 1.3 seconds with target unit second should be 1 second") { - REQUIRE(floor(1.3_q_s) == 1_q_s); + REQUIRE(floor(1.3 * isq::time[s]) == 1 * isq::time[s]); } SECTION("floor -1.3 seconds with target unit second should be -2 seconds") { - REQUIRE(floor(-1.3_q_s) == -2_q_s); + REQUIRE(floor(-1.3 * isq::time[s]) == -2 * isq::time[s]); } SECTION("floor 1001. milliseconds with target unit second should be 1 second") { - REQUIRE(floor(1001._q_ms) == 1_q_s); + REQUIRE(floor(1001. * isq::time[ms]) == 1 * isq::time[s]); } SECTION("floor 1999. milliseconds with target unit second should be 1 second") { - REQUIRE(floor(1999._q_ms) == 1_q_s); + REQUIRE(floor(1999. * isq::time[ms]) == 1 * isq::time[s]); } SECTION("floor -1000. milliseconds with target unit second should be -1 second") { - REQUIRE(floor(-1000._q_ms) == -1_q_s); + REQUIRE(floor(-1000. * isq::time[ms]) == -1 * isq::time[s]); } SECTION("floor -999. milliseconds with target unit second should be -1 second") { - REQUIRE(floor(-999._q_ms) == -1_q_s); - } - SECTION("floor 1 second with target quantity with unit type second should be 1 second") - { - using showtime = si::time; - REQUIRE(floor(showtime::one()) == showtime::one()); + REQUIRE(floor(-999. * isq::time[ms]) == -1 * isq::time[s]); } + + // TODO Add tests for `N`, `kN` and `kg * m / s2` i `kg * km / s2` } TEST_CASE("ceil functions", "[ceil]") { - SECTION("ceil 1 second with target unit second should be 1 second") { REQUIRE(ceil(1_q_s) == 1_q_s); } + SECTION("ceil 1 second with target unit second should be 1 second") + { + REQUIRE(ceil(1 * isq::time[s]) == 1 * isq::time[s]); + } SECTION("ceil 1000 milliseconds with target unit second should be 1 second") { - REQUIRE(ceil(1000_q_ms) == 1_q_s); + REQUIRE(ceil(1000 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("ceil 1001 milliseconds with target unit second should be 2 seconds") { - REQUIRE(ceil(1001_q_ms) == 2_q_s); + REQUIRE(ceil(1001 * isq::time[ms]) == 2 * isq::time[s]); } SECTION("ceil 1999 milliseconds with target unit second should be 2 seconds") { - REQUIRE(ceil(1999_q_ms) == 2_q_s); + REQUIRE(ceil(1999 * isq::time[ms]) == 2 * isq::time[s]); } SECTION("ceil -1000 milliseconds with target unit second should be -1 second") { - REQUIRE(ceil(-1000_q_ms) == -1_q_s); + REQUIRE(ceil(-1000 * isq::time[ms]) == -1 * isq::time[s]); } SECTION("ceil -999 milliseconds with target unit second should be 0 seconds") { - REQUIRE(ceil(-999_q_ms) == 0_q_s); + REQUIRE(ceil(-999 * isq::time[ms]) == 0 * isq::time[s]); } SECTION("ceil 1.3 seconds with target unit second should be 2 seconds") { - REQUIRE(ceil(1.3_q_s) == 2_q_s); + REQUIRE(ceil(1.3 * isq::time[s]) == 2 * isq::time[s]); } SECTION("ceil -1.3 seconds with target unit second should be -1 second") { - REQUIRE(ceil(-1.3_q_s) == -1_q_s); + REQUIRE(ceil(-1.3 * isq::time[s]) == -1 * isq::time[s]); } SECTION("ceil 1001. milliseconds with target unit second should be 2 seconds") { - REQUIRE(ceil(1001._q_ms) == 2_q_s); + REQUIRE(ceil(1001. * isq::time[ms]) == 2 * isq::time[s]); } SECTION("ceil 1999. milliseconds with target unit second should be 2 seconds") { - REQUIRE(ceil(1999._q_ms) == 2_q_s); + REQUIRE(ceil(1999. * isq::time[ms]) == 2 * isq::time[s]); } SECTION("ceil -1000. milliseconds with target unit second should be -1 second") { - REQUIRE(ceil(-1000._q_ms) == -1_q_s); + REQUIRE(ceil(-1000. * isq::time[ms]) == -1 * isq::time[s]); } SECTION("ceil -999. milliseconds with target unit second should be 0 seconds") { - REQUIRE(ceil(-999._q_ms) == 0_q_s); - } - SECTION("ceil 1 second with target quantity with unit type second should be 1 second") - { - using showtime = si::time; - REQUIRE(ceil(showtime::one()) == showtime::one()); + REQUIRE(ceil(-999. * isq::time[ms]) == 0 * isq::time[s]); } } TEST_CASE("round functions", "[round]") { - SECTION("round 1 second with target unit second should be 1 second") { REQUIRE(round(1_q_s) == 1_q_s); } + SECTION("round 1 second with target unit second should be 1 second") + { + REQUIRE(round(1 * isq::time[s]) == 1 * isq::time[s]); + } SECTION("round 1000 milliseconds with target unit second should be 1 second") { - REQUIRE(round(1000_q_ms) == 1_q_s); + REQUIRE(round(1000 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("round 1001 milliseconds with target unit second should be 1 second") { - REQUIRE(round(1001_q_ms) == 1_q_s); + REQUIRE(round(1001 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("round 1499 milliseconds with target unit second should be 1 second") { - REQUIRE(round(1499_q_ms) == 1_q_s); + REQUIRE(round(1499 * isq::time[ms]) == 1 * isq::time[s]); } SECTION("round 1500 milliseconds with target unit second should be 2 seconds") { - REQUIRE(round(1500_q_ms) == 2_q_s); + REQUIRE(round(1500 * isq::time[ms]) == 2 * isq::time[s]); } SECTION("round 1999 milliseconds with target unit second should be 2 seconds") { - REQUIRE(round(1999_q_ms) == 2_q_s); + REQUIRE(round(1999 * isq::time[ms]) == 2 * isq::time[s]); } SECTION("round -1000 milliseconds with target unit second should be -1 second") { - REQUIRE(round(-1000_q_ms) == -1_q_s); + REQUIRE(round(-1000 * isq::time[ms]) == -1 * isq::time[s]); } SECTION("round -1001 milliseconds with target unit second should be -1 second") { - REQUIRE(round(-1001_q_ms) == -1_q_s); + REQUIRE(round(-1001 * isq::time[ms]) == -1 * isq::time[s]); } SECTION("round -1499 milliseconds with target unit second should be -1 second") { - REQUIRE(round(-1499_q_ms) == -1_q_s); + REQUIRE(round(-1499 * isq::time[ms]) == -1 * isq::time[s]); } SECTION("round -1500 milliseconds with target unit second should be -2 seconds") { - REQUIRE(round(-1500_q_ms) == -2_q_s); + REQUIRE(round(-1500 * isq::time[ms]) == -2 * isq::time[s]); } SECTION("round -1999 milliseconds with target unit second should be -2 seconds") { - REQUIRE(round(-1999_q_ms) == -2_q_s); + REQUIRE(round(-1999 * isq::time[ms]) == -2 * isq::time[s]); } SECTION("round 1000. milliseconds with target unit second should be 1 second") { - REQUIRE(round(1000._q_ms) == 1_q_s); + REQUIRE(round(1000. * isq::time[ms]) == 1 * isq::time[s]); } SECTION("round 1001. milliseconds with target unit second should be 1 second") { - REQUIRE(round(1001._q_ms) == 1_q_s); + REQUIRE(round(1001. * isq::time[ms]) == 1 * isq::time[s]); } SECTION("round 1499. milliseconds with target unit second should be 1 second") { - REQUIRE(round(1499._q_ms) == 1_q_s); + REQUIRE(round(1499. * isq::time[ms]) == 1 * isq::time[s]); } SECTION("round 1500. milliseconds with target unit second should be 2 seconds") { - REQUIRE(round(1500._q_ms) == 2_q_s); + REQUIRE(round(1500. * isq::time[ms]) == 2 * isq::time[s]); } SECTION("round 1999. milliseconds with target unit second should be 2 seconds") { - REQUIRE(round(1999._q_ms) == 2_q_s); + REQUIRE(round(1999. * isq::time[ms]) == 2 * isq::time[s]); } SECTION("round -1000. milliseconds with target unit second should be -1 second") { - REQUIRE(round(-1000._q_ms) == -1_q_s); + REQUIRE(round(-1000. * isq::time[ms]) == -1 * isq::time[s]); } SECTION("round -1001. milliseconds with target unit second should be -1 second") { - REQUIRE(round(-1001._q_ms) == -1_q_s); + REQUIRE(round(-1001. * isq::time[ms]) == -1 * isq::time[s]); } SECTION("round -1499. milliseconds with target unit second should be -1 second") { - REQUIRE(round(-1499._q_ms) == -1_q_s); + REQUIRE(round(-1499. * isq::time[ms]) == -1 * isq::time[s]); } SECTION("round -1500. milliseconds with target unit second should be -2 seconds") { - REQUIRE(round(-1500._q_ms) == -2_q_s); + REQUIRE(round(-1500. * isq::time[ms]) == -2 * isq::time[s]); } SECTION("round -1999. milliseconds with target unit second should be -2 seconds") { - REQUIRE(round(-1999._q_ms) == -2_q_s); - } - SECTION("round 1 second with target quantity with unit type second should be 1 second") - { - using showtime = si::time; - REQUIRE(round(showtime::one()) == showtime::one()); + REQUIRE(round(-1999. * isq::time[ms]) == -2 * isq::time[s]); } } TEST_CASE("hypot functions", "[hypot]") { - using namespace units::aliases::isq::si; - SECTION("hypot should work on the same quantities") { - REQUIRE(hypot(km<>(3.), km<>(4.)) == km<>(5.)); - REQUIRE(hypot(km<>(2.), km<>(3.), km<>(6.)) == km<>(7.)); + REQUIRE(hypot(3. * isq::length[km], 4. * isq::length[km]) == 5. * isq::length[km]); + REQUIRE(hypot(2. * isq::length[km], 3. * isq::length[km], 6. * isq::length[km]) == 7. * isq::length[km]); } SECTION("hypot should work with different units of the same dimension") { - REQUIRE(hypot(km<>(3.), m<>(4000.)) == km<>(5.)); - REQUIRE(hypot(km<>(2.), m<>(3000.), km<>(6.)) == km<>(7.)); - } - SECTION("hypot should work with different but equivalent dimensions") - { - REQUIRE(hypot(km<>(3.), cgs::length::cm<>(400'000.)) == km<>(5.)); - REQUIRE(hypot(km<>(2.), cgs::length::cm<>(300'000.), km<>(6.)) == km<>(7.)); + REQUIRE(hypot(3. * isq::length[km], 4000. * isq::length[m]) == 5. * isq::length[km]); + REQUIRE(hypot(2. * isq::length[km], 3000. * isq::length[m], 6. * isq::length[km]) == 7. * isq::length[km]); } } -TEST_CASE("trigonometric functions", "[trig]") +TEST_CASE("ISQ trigonometric functions", "[trig][isq]") { - using namespace units::aliases; - SECTION("sin") { - REQUIRE_THAT(sin(deg<>(0.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(sin(deg<>(90.)), AlmostEquals(quantity{1.})); - REQUIRE_THAT(sin(deg<>(180.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(sin(deg<>(270.)), AlmostEquals(quantity{-1.})); - - REQUIRE_THAT(sin(grad<>(0.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(sin(grad<>(100.)), AlmostEquals(quantity{1.})); - REQUIRE_THAT(sin(grad<>(200.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(sin(grad<>(300.)), AlmostEquals(quantity{-1.})); + REQUIRE_THAT(isq::sin(0. * isq::angular_measure[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(isq::sin(90. * isq::angular_measure[deg]), AlmostEquals(1. * one)); + REQUIRE_THAT(isq::sin(180. * isq::angular_measure[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(isq::sin(270. * isq::angular_measure[deg]), AlmostEquals(-1. * one)); } SECTION("cos") { - REQUIRE_THAT(cos(deg<>(0.)), AlmostEquals(quantity{1.})); - REQUIRE_THAT(cos(deg<>(90.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(cos(deg<>(180.)), AlmostEquals(quantity{-1.})); - REQUIRE_THAT(cos(deg<>(270.)), AlmostEquals(quantity{0.})); - - REQUIRE_THAT(cos(grad<>(0.)), AlmostEquals(quantity{1.})); - REQUIRE_THAT(cos(grad<>(100.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(cos(grad<>(200.)), AlmostEquals(quantity{-1.})); - REQUIRE_THAT(cos(grad<>(300.)), AlmostEquals(quantity{0.})); + REQUIRE_THAT(isq::cos(0. * isq::angular_measure[deg]), AlmostEquals(1. * one)); + REQUIRE_THAT(isq::cos(90. * isq::angular_measure[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(isq::cos(180. * isq::angular_measure[deg]), AlmostEquals(-1. * one)); + REQUIRE_THAT(isq::cos(270. * isq::angular_measure[deg]), AlmostEquals(0. * one)); } SECTION("tan") { - REQUIRE_THAT(tan(deg<>(0.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(tan(deg<>(45.)), AlmostEquals(quantity{1.})); - REQUIRE_THAT(tan(deg<>(135.)), AlmostEquals(quantity{-1.})); - REQUIRE_THAT(tan(deg<>(180.)), AlmostEquals(quantity{0.})); - - REQUIRE_THAT(tan(grad<>(0.)), AlmostEquals(quantity{0.})); - REQUIRE_THAT(tan(grad<>(50.)), AlmostEquals(quantity{1.})); - REQUIRE_THAT(tan(grad<>(150.)), AlmostEquals(quantity{-1.})); - REQUIRE_THAT(tan(grad<>(200.)), AlmostEquals(quantity{0.})); + REQUIRE_THAT(isq::tan(0. * isq::angular_measure[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(isq::tan(45. * isq::angular_measure[deg]), AlmostEquals(1. * one)); + REQUIRE_THAT(isq::tan(135. * isq::angular_measure[deg]), AlmostEquals(-1. * one)); + REQUIRE_THAT(isq::tan(180. * isq::angular_measure[deg]), AlmostEquals(0. * one)); } } -TEST_CASE("inverse trigonometric functions", "[inv trig]") +TEST_CASE("ISQ inverse trigonometric functions", "[inv trig][isq]") { - using namespace units::aliases; - SECTION("asin") { - REQUIRE_THAT(asin(quantity{-1.}), AlmostEquals(deg<>(-90.))); - REQUIRE_THAT(asin(quantity{0.}), AlmostEquals(deg<>(0.))); - REQUIRE_THAT(asin(quantity{1.}), AlmostEquals(deg<>(90.))); + REQUIRE_THAT(isq::asin(-1. * one), AlmostEquals(-90. * isq::angular_measure[deg])); + REQUIRE_THAT(isq::asin(0. * one), AlmostEquals(0. * isq::angular_measure[deg])); + REQUIRE_THAT(isq::asin(1. * one), AlmostEquals(90. * isq::angular_measure[deg])); } SECTION("acos") { - REQUIRE_THAT(asin(quantity{-1.}), AlmostEquals(deg<>(-90.))); - REQUIRE_THAT(asin(quantity{0.}), AlmostEquals(deg<>(0.))); - REQUIRE_THAT(asin(quantity{1.}), AlmostEquals(deg<>(90.))); + REQUIRE_THAT(isq::asin(-1. * one), AlmostEquals(-90. * isq::angular_measure[deg])); + REQUIRE_THAT(isq::asin(0. * one), AlmostEquals(0. * isq::angular_measure[deg])); + REQUIRE_THAT(isq::asin(1. * one), AlmostEquals(90. * isq::angular_measure[deg])); } SECTION("atan") { - REQUIRE_THAT(atan(quantity{-1.}), AlmostEquals(deg<>(-45.))); - REQUIRE_THAT(atan(quantity{0.}), AlmostEquals(deg<>(0.))); - REQUIRE_THAT(atan(quantity{1.}), AlmostEquals(deg<>(45.))); + REQUIRE_THAT(isq::atan(-1. * one), AlmostEquals(-45. * isq::angular_measure[deg])); + REQUIRE_THAT(isq::atan(0. * one), AlmostEquals(0. * isq::angular_measure[deg])); + REQUIRE_THAT(isq::atan(1. * one), AlmostEquals(45. * isq::angular_measure[deg])); + } +} + + +TEST_CASE("Angle trigonometric functions", "[trig][angle]") +{ + using namespace mp_units::angular; + using namespace mp_units::angular::unit_symbols; + using mp_units::angular::unit_symbols::deg; + + SECTION("sin") + { + REQUIRE_THAT(sin(0. * angle[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(sin(90. * angle[deg]), AlmostEquals(1. * one)); + REQUIRE_THAT(sin(180. * angle[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(sin(270. * angle[deg]), AlmostEquals(-1. * one)); + + REQUIRE_THAT(sin(0. * angle[grad]), AlmostEquals(0. * one)); + REQUIRE_THAT(sin(100. * angle[grad]), AlmostEquals(1. * one)); + REQUIRE_THAT(sin(200. * angle[grad]), AlmostEquals(0. * one)); + REQUIRE_THAT(sin(300. * angle[grad]), AlmostEquals(-1. * one)); + } + + SECTION("cos") + { + REQUIRE_THAT(cos(0. * angle[deg]), AlmostEquals(1. * one)); + REQUIRE_THAT(cos(90. * angle[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(cos(180. * angle[deg]), AlmostEquals(-1. * one)); + REQUIRE_THAT(cos(270. * angle[deg]), AlmostEquals(0. * one)); + + REQUIRE_THAT(cos(0. * angle[grad]), AlmostEquals(1. * one)); + REQUIRE_THAT(cos(100. * angle[grad]), AlmostEquals(0. * one)); + REQUIRE_THAT(cos(200. * angle[grad]), AlmostEquals(-1. * one)); + REQUIRE_THAT(cos(300. * angle[grad]), AlmostEquals(0. * one)); + } + + SECTION("tan") + { + REQUIRE_THAT(tan(0. * angle[deg]), AlmostEquals(0. * one)); + REQUIRE_THAT(tan(45. * angle[deg]), AlmostEquals(1. * one)); + REQUIRE_THAT(tan(135. * angle[deg]), AlmostEquals(-1. * one)); + REQUIRE_THAT(tan(180. * angle[deg]), AlmostEquals(0. * one)); + + REQUIRE_THAT(tan(0. * angle[grad]), AlmostEquals(0. * one)); + REQUIRE_THAT(tan(50. * angle[grad]), AlmostEquals(1. * one)); + REQUIRE_THAT(tan(150. * angle[grad]), AlmostEquals(-1. * one)); + REQUIRE_THAT(tan(200. * angle[grad]), AlmostEquals(0. * one)); + } +} + +TEST_CASE("Angle inverse trigonometric functions", "[inv trig][angle]") +{ + using namespace mp_units::angular; + using namespace mp_units::angular::unit_symbols; + using mp_units::angular::unit_symbols::deg; + + SECTION("asin") + { + REQUIRE_THAT(asin(-1. * one), AlmostEquals(-90. * angle[deg])); + REQUIRE_THAT(asin(0. * one), AlmostEquals(0. * angle[deg])); + REQUIRE_THAT(asin(1. * one), AlmostEquals(90. * angle[deg])); + } + + SECTION("acos") + { + REQUIRE_THAT(asin(-1. * one), AlmostEquals(-90. * angle[deg])); + REQUIRE_THAT(asin(0. * one), AlmostEquals(0. * angle[deg])); + REQUIRE_THAT(asin(1. * one), AlmostEquals(90. * angle[deg])); + } + + SECTION("atan") + { + REQUIRE_THAT(atan(-1. * one), AlmostEquals(-45. * angle[deg])); + REQUIRE_THAT(atan(0. * one), AlmostEquals(0. * angle[deg])); + REQUIRE_THAT(atan(1. * one), AlmostEquals(45. * angle[deg])); } } diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 632592f8..1eea6b74 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -23,11 +23,6 @@ cmake_minimum_required(VERSION 3.2) add_library(unit_tests_static_truncating quantity_test.cpp) - -if(NOT ${projectPrefix}LIBCXX) - target_sources(unit_tests_static_truncating PRIVATE quantity_kind_test.cpp quantity_point_kind_test.cpp) -endif() - target_link_libraries(unit_tests_static_truncating PRIVATE mp-units::mp-units) target_compile_options( unit_tests_static_truncating PRIVATE $,/wd4242 /wd4244,-Wno-conversion> @@ -35,35 +30,40 @@ target_compile_options( add_library( unit_tests_static - angle_test.cpp + angular_test.cpp cgs_test.cpp chrono_test.cpp concepts_test.cpp - custom_rep_test_min_expl.cpp - custom_unit_test.cpp - dimension_op_test.cpp - dimensions_concepts_test.cpp + # custom_rep_test_min_expl.cpp + custom_rep_test_min_impl.cpp + dimension_test.cpp fixed_string_test.cpp - fps_test.cpp + fractional_exponent_quantity.cpp + hep_test.cpp + iau_test.cpp iec80000_test.cpp - kind_test.cpp + imperial_test.cpp + international_test.cpp + isq_test.cpp + isq_angle_test.cpp + # magnitude_test.cpp math_test.cpp - point_origin_test.cpp + natural_test.cpp prime_test.cpp + quantity_spec_test.cpp ratio_test.cpp - references_test.cpp + reference_test.cpp si_test.cpp - si_cgs_test.cpp - si_fps_test.cpp - si_hep_test.cpp symbol_text_test.cpp type_list_test.cpp + typographic_test.cpp unit_test.cpp - us_test.cpp + unit_symbol_test.cpp + usc_test.cpp ) -if(NOT ${projectPrefix}LIBCXX) - target_sources(unit_tests_static PRIVATE custom_rep_test_min_impl.cpp quantity_point_test.cpp) -endif() - +# if(NOT ${projectPrefix}LIBCXX) +# target_sources(unit_tests_static PRIVATE custom_rep_test_min_impl.cpp quantity_point_test.cpp) +# endif() +target_link_libraries(unit_tests_static PRIVATE mp-units::mp-units) target_link_libraries(unit_tests_static PRIVATE unit_tests_static_truncating mp-units::mp-units) diff --git a/src/systems/isq/include/units/isq/dimensions/area.h b/test/unit_test/static/angular_test.cpp similarity index 72% rename from src/systems/isq/include/units/isq/dimensions/area.h rename to test/unit_test/static/angular_test.cpp index f03a4209..c3010dfe 100644 --- a/src/systems/isq/include/units/isq/dimensions/area.h +++ b/test/unit_test/static/angular_test.cpp @@ -20,20 +20,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#pragma once +#include +#include -#include -#include +namespace { -namespace units::isq { +using namespace mp_units::angular::unit_symbols; -template -struct dim_area; +static_assert(360. * deg == 1. * rev); +static_assert(400. * grad == 1. * rev); +static_assert(std::numbers::pi * 2 * rad == 1. * rev); -template L> -struct dim_area : derived_dimension> {}; +static_assert(1 * rad * (1 * rad) == 1 * sr); +static_assert(1 * rad * (1 * rad) == 1 * rad2); +static_assert(1. * deg * (1. * deg) == 1. * deg2); -template -concept Area = QuantityOfT; - -} // namespace units::isq +} // namespace diff --git a/test/unit_test/static/cgs_test.cpp b/test/unit_test/static/cgs_test.cpp index 4a0dc7bb..e0b36fff 100644 --- a/test/unit_test/static/cgs_test.cpp +++ b/test/unit_test/static/cgs_test.cpp @@ -20,84 +20,44 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include -#include -#include +#include "test_tools.h" +#include +#include +#include +#include + +template + requires mp_units::is_scalar +inline constexpr bool mp_units::is_vector = true; namespace { -using namespace units; -using namespace units::isq::si::cgs; +using namespace mp_units; +using namespace mp_units::cgs; +using namespace mp_units::cgs::unit_symbols; -/* ************** BASE DIMENSIONS **************** */ +// https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units#Definitions_and_conversion_factors_of_CGS_units_in_mechanics +static_assert(isq::length(100 * cm) == isq::length(1 * si::metre)); +static_assert(isq::mass(1000 * g) == isq::mass(1 * si::kilogram)); +static_assert(isq::time(1 * s) == isq::time(1 * si::second)); +static_assert(isq::speed(100 * (cm / s)) == isq::speed(1 * (si::metre / si::second))); +static_assert(isq::acceleration(100 * Gal) == isq::acceleration(1 * (si::metre / square(si::second)))); +static_assert(isq::force(100'000 * dyn) == isq::force(1 * si::newton)); +static_assert(isq::energy(10'000'000 * erg) == isq::energy(1 * si::joule)); +static_assert(isq::power(10'000'000 * (erg / s)) == isq::power(1 * si::watt)); +static_assert(isq::pressure(10 * Ba) == isq::pressure(1 * si::pascal)); +static_assert(isq::dynamic_viscosity(10 * P) == isq::dynamic_viscosity(1 * (si::pascal * si::second))); +static_assert(isq::kinematic_viscosity(10'000 * St) == isq::kinematic_viscosity(1 * (square(si::metre) / si::second))); +static_assert(isq::wavenumber(1 * K) == isq::wavenumber(100 * (1 / si::metre))); -// length +static_assert(10'000'000 * erg + 1 * si::joule == 2 * si::joule); +static_assert(1 * si::joule + 10'000'000 * erg == 2 * si::joule); +static_assert(is_of_type<10'000'000 * erg + 1 * si::joule, quantity>); +static_assert(is_of_type<1 * si::joule + 10'000'000 * erg, quantity>); -static_assert(centimetre::symbol == "cm"); - -// mass - -// time - -/* ************** DERIVED DIMENSIONS IN TERMS OF BASE UNITS **************** */ - -// speed - -static_assert((10_q_cm / 5_q_s).number() == 2); -static_assert((2_q_cm_per_s).number() == 2); -static_assert(10_q_cm / 5_q_s == 2_q_cm_per_s); -static_assert(10_q_cm / 2_q_cm_per_s == 5_q_s); -static_assert(10_q_cm == 2_q_cm_per_s * 5_q_s); - -static_assert(detail::unit_text() == "cm/s"); - -// area -static_assert(as_ratio(centimetre::mag / dimension_unit::mag) == ratio(1)); - -static_assert((1_q_cm * 1_q_cm).number() == 1); -static_assert((1_q_cm2).number() == 1); -static_assert(1_q_cm * 1_q_cm == 1_q_cm2); -static_assert(100_q_cm * 100_q_cm == area(1)); -static_assert(100_q_cm * 100_q_cm == length(1) * length(1)); -static_assert(100_q_cm2 / 10_q_cm == 10_q_cm); - -static_assert(detail::unit_text() == basic_symbol_text("cm²", "cm^2")); - -/* ************** DERIVED DIMENSIONS WITH NAMED UNITS **************** */ - -// acceleration - -static_assert(10_q_cm_per_s / 10_q_s == 1_q_Gal); -static_assert(10_q_cm_per_s / 1_q_Gal == 10_q_s); -static_assert(1_q_Gal * 10_q_s == 10_q_cm_per_s); - -// force - -static_assert(10_q_g * 10_q_Gal == 100_q_dyn); -static_assert(100_q_dyn / 10_q_g == 10_q_Gal); -static_assert(100_q_dyn / 10_q_Gal == 10_q_g); - -// pressure - -static_assert(10_q_dyn / 10_q_cm2 == 1_q_Ba); -static_assert(10_q_dyn / 1_q_Ba == 10_q_cm2); -static_assert(1_q_Ba * 10_q_cm2 == 10_q_dyn); - -// energy - -static_assert(10_q_dyn * 10_q_cm == 100_q_erg); -static_assert(100_q_erg / 10_q_cm == 10_q_dyn); -static_assert(100_q_erg / 10_q_dyn == 10_q_cm); - -/* ************** DERIVED DIMENSIONS IN TERMS OF OTHER UNITS **************** */ - -// power - -static_assert(10_q_erg / 10_q_s == 1_q_erg_per_s); -static_assert(1_q_erg_per_s * 10_q_s == 10_q_erg); -static_assert(10_q_erg / 1_q_erg_per_s == 10_q_s); - -static_assert(detail::unit_text() == "erg/s"); +static_assert(1 * K + 100 * (1 / si::metre) == 2 * K); +static_assert(100 * (1 / si::metre) + 1 * K == 2 * K); +static_assert(is_of_type<1 * K + 100 * (1 / si::metre), quantity<1 / si::metre, int>>); +static_assert(is_of_type<100 * (1 / si::metre) + 1 * K, quantity<1 / si::metre, int>>); } // namespace diff --git a/test/unit_test/static/chrono_test.cpp b/test/unit_test/static/chrono_test.cpp index 952ce1fa..e55cb807 100644 --- a/test/unit_test/static/chrono_test.cpp +++ b/test/unit_test/static/chrono_test.cpp @@ -21,95 +21,96 @@ // SOFTWARE. #include "test_tools.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include #include namespace { -using namespace units; -using namespace units::isq; -using namespace units::isq::si::literals; +using namespace mp_units; +using namespace mp_units::si::unit_symbols; using namespace std::chrono_literals; using sys_seconds = std::chrono::time_point; using sys_days = std::chrono::time_point, std::chrono::hours::period>>>; -template -using time_point = quantity_point, U, Rep>; +template +using time_point = quantity_point, Rep>; static_assert(QuantityLike); static_assert(QuantityPointLike); // construction - same rep type -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::hours>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::hours>); -static_assert(!std::convertible_to>); -static_assert(!std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); static_assert( - std::constructible_from, sys_seconds>); + std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::hours>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::hours>); +static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); static_assert( - !std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_days>); -static_assert(!std::constructible_from, sys_days>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_days>); -static_assert(!std::constructible_from, sys_days>); -static_assert(!std::convertible_to>); -static_assert(!std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); + std::constructible_from, sys_seconds>); +static_assert( + !std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_days>); +static_assert(!std::constructible_from, sys_days>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_days>); +static_assert(!std::constructible_from, sys_days>); +static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); // construction - different rep type (integral to a floating-point) -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::hours>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_days>); -static_assert(!std::convertible_to>); -static_assert(std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::hours>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, std::chrono::seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_days>); +static_assert(!std::convertible_to>); +static_assert(std::constructible_from, sys_seconds>); +static_assert(!std::convertible_to>); // CTAD -static_assert(compare>); -static_assert(compare>); -static_assert(compare>); -static_assert(compare>); +static_assert(is_of_type>); +static_assert(is_of_type>); +static_assert( + is_of_type>); +static_assert(is_of_type>); // operators -static_assert(quantity{1s} + 1_q_s == 2_q_s); -static_assert(quantity{1s} + 1_q_min == 61_q_s); -static_assert(10_q_m / quantity{2s} == 5_q_m_per_s); -static_assert(quantity_point{sys_seconds{1s}} + 1_q_s == time_point{2_q_s}); -static_assert(quantity_point{sys_seconds{1s}} + 1_q_min == time_point{61_q_s}); +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)); +static_assert(quantity_point{sys_seconds{1s}} + 1 * s == + time_point{2 * s}); +static_assert(quantity_point{sys_seconds{1s}} + 1 * min == + time_point{61 * s}); -// to_std_duration -static_assert(to_std_duration(1_q_s) == 1s); -static_assert(to_std_duration(2_q_h) == 2h); -static_assert(to_std_duration(3_q_ns) == 3ns); -static_assert(to_std_duration(quantity{1s}) == 1s); -static_assert(to_std_duration(quantity{2h}) == 2h); -static_assert(to_std_duration(quantity{3ns}) == 3ns); -static_assert(is_same_v>); -static_assert(is_same_v>); -static_assert(is_same_v); +// to_chrono_duration +static_assert(to_chrono_duration(1 * s) == 1s); +static_assert(to_chrono_duration(2 * h) == 2h); +static_assert(to_chrono_duration(3 * ns) == 3ns); +static_assert(to_chrono_duration(quantity{1s}) == 1s); +static_assert(to_chrono_duration(quantity{2h}) == 2h); +static_assert(to_chrono_duration(quantity{3ns}) == 3ns); +static_assert(is_same_v>); +static_assert(is_same_v>); +static_assert(is_same_v); -// to_std_time_point -static_assert(to_std_time_point(quantity_point{sys_seconds{1s}}) == sys_seconds{1s}); -static_assert(to_std_time_point(quantity_point{sys_days{sys_days::duration{1}}}) == sys_days{sys_days::duration{1}}); +// to_chrono_time_point +static_assert(to_chrono_time_point(quantity_point{sys_seconds{1s}}) == sys_seconds{1s}); +static_assert(to_chrono_time_point(quantity_point{sys_days{sys_days::duration{1}}}) == sys_days{sys_days::duration{1}}); } // namespace diff --git a/test/unit_test/static/concepts_test.cpp b/test/unit_test/static/concepts_test.cpp index 2e9d66d1..a7b0a6da 100644 --- a/test/unit_test/static/concepts_test.cpp +++ b/test/unit_test/static/concepts_test.cpp @@ -20,126 +20,459 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include -#include // IWYU pragma: keep -#include -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include #include -#include + +template +inline constexpr bool mp_units::is_scalar> = true; namespace { -using namespace units; -using namespace units::isq; +using namespace mp_units; -// Prefix - -static_assert(Prefix); -static_assert(!Prefix); +struct dim_speed : decltype(isq::dim_length / isq::dim_time) {}; // BaseDimension - -static_assert(BaseDimension); -static_assert(!BaseDimension); -static_assert(!BaseDimension); +static_assert(detail::BaseDimension); +static_assert(!detail::BaseDimension>); +static_assert(!detail::BaseDimension>); +static_assert(!detail::BaseDimension(isq::dim_length))>>); +static_assert(!detail::BaseDimension>>); +static_assert(!detail::BaseDimension); +static_assert(!detail::BaseDimension>); +static_assert(!detail::BaseDimension); +static_assert(!detail::BaseDimension); // DerivedDimension - -static_assert(DerivedDimension); -static_assert(!DerivedDimension); -static_assert(!DerivedDimension); +static_assert(detail::DerivedDimension>); +static_assert(detail::DerivedDimension>); +static_assert(detail::DerivedDimension(isq::dim_length))>>); +static_assert(detail::DerivedDimension>>); +static_assert(detail::DerivedDimension); +static_assert(detail::DerivedDimension); +static_assert(!detail::DerivedDimension); +static_assert(!detail::DerivedDimension); +static_assert(!detail::DerivedDimension); // Dimension - -static_assert(Dimension); -static_assert(Dimension); -static_assert(!Dimension); +static_assert(Dimension); +static_assert(Dimension>); +static_assert(Dimension>); +static_assert(Dimension(isq::dim_length))>>); +static_assert(Dimension>>); +static_assert(Dimension); +static_assert(Dimension); +static_assert(!Dimension>); +static_assert(!Dimension); static_assert(!Dimension); -static_assert(!Dimension); + +// QuantitySpec +struct speed : decltype(isq::length / isq::time) {}; // this is not recommended + +static_assert(QuantitySpec); +static_assert(QuantitySpec); +static_assert(QuantitySpec); +static_assert(QuantitySpec)>>); +static_assert(QuantitySpec>); +static_assert(QuantitySpec(isq::length))>>); +static_assert(QuantitySpec); +static_assert(!QuantitySpec); +static_assert(!QuantitySpec); +static_assert(!QuantitySpec); + +// NamedQuantitySpec +static_assert(detail::NamedQuantitySpec); +static_assert(detail::NamedQuantitySpec); +static_assert(detail::NamedQuantitySpec); +static_assert(!detail::NamedQuantitySpec)>>); +static_assert(!detail::NamedQuantitySpec>); +static_assert(!detail::NamedQuantitySpec(isq::length))>>); +static_assert(detail::NamedQuantitySpec); +static_assert(!detail::NamedQuantitySpec); +static_assert(!detail::NamedQuantitySpec); +static_assert(!detail::NamedQuantitySpec); + +// BaseQuantitySpec +static_assert(detail::BaseQuantitySpec); +static_assert(detail::BaseQuantitySpec); +static_assert(!detail::BaseQuantitySpec)>>); +static_assert(!detail::BaseQuantitySpec); +static_assert(!detail::BaseQuantitySpec>); +static_assert(!detail::BaseQuantitySpec(isq::length))>>); +static_assert(!detail::BaseQuantitySpec); +static_assert(!detail::BaseQuantitySpec); +static_assert(!detail::BaseQuantitySpec); +static_assert(!detail::BaseQuantitySpec); + +// IntermediateDerivedQuantitySpec +static_assert(!detail::IntermediateDerivedQuantitySpec); +static_assert(!detail::IntermediateDerivedQuantitySpec); +static_assert(!detail::IntermediateDerivedQuantitySpec)>>); +static_assert(!detail::IntermediateDerivedQuantitySpec); +static_assert(detail::IntermediateDerivedQuantitySpec>); +static_assert(detail::IntermediateDerivedQuantitySpec(isq::length))>>); +static_assert(!detail::IntermediateDerivedQuantitySpec); +static_assert(!detail::IntermediateDerivedQuantitySpec); +static_assert(!detail::IntermediateDerivedQuantitySpec); +static_assert(!detail::IntermediateDerivedQuantitySpec); + +// QuantityKindSpec +static_assert(!detail::QuantityKindSpec); +static_assert(!detail::QuantityKindSpec); +static_assert(detail::QuantityKindSpec)>>); +static_assert(!detail::QuantityKindSpec); +static_assert(!detail::QuantityKindSpec>); +static_assert(!detail::QuantityKindSpec(isq::length))>>); +static_assert(!detail::QuantityKindSpec); +static_assert(!detail::QuantityKindSpec); +static_assert(!detail::QuantityKindSpec); +static_assert(!detail::QuantityKindSpec); // Unit +struct metre_per_second : decltype(si::metre / si::second) {}; -static_assert(Unit); -static_assert(Unit); -static_assert(Unit); -static_assert(Unit); -static_assert(!Unit); +static_assert(Unit); +static_assert(Unit); +static_assert(Unit)>>); +static_assert(Unit); +static_assert(Unit>); +static_assert(Unit>); +static_assert(Unit * si::second)>>); +static_assert(Unit>); +static_assert(Unit(si::metre))>>); +static_assert(Unit); +static_assert(Unit, struct si::second>>); +static_assert(Unit); +static_assert(Unit>>); +static_assert(Unit); +static_assert(!Unit>); +static_assert(!Unit>); +static_assert(!Unit>); +static_assert(!Unit>); +static_assert(!Unit, si::second>>); +static_assert(!Unit); static_assert(!Unit); static_assert(!Unit); // NamedUnit +static_assert(detail::NamedUnit); +static_assert(detail::NamedUnit); +static_assert(!detail::NamedUnit); +static_assert(!detail::NamedUnit)>>); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit * si::second)>>); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit(si::metre))>>); +static_assert(detail::NamedUnit); +static_assert(!detail::NamedUnit, struct si::second>>); +static_assert(!detail::NamedUnit); +static_assert(!detail::NamedUnit>>); +static_assert(!detail::NamedUnit); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit, si::second>>); +static_assert(!detail::NamedUnit); +static_assert(!detail::NamedUnit); +static_assert(!detail::NamedUnit); -static_assert(NamedUnit); -static_assert(NamedUnit); -static_assert(NamedUnit); -static_assert(!NamedUnit); +// PrefixableUnit +static_assert(PrefixableUnit); +static_assert(PrefixableUnit); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit)>>); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit * si::second)>>); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit(si::metre))>>); +static_assert(PrefixableUnit); +static_assert(!PrefixableUnit, struct si::second>>); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit>>); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit, si::second>>); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit); +static_assert(!PrefixableUnit); + +// AssociatedUnit +static_assert(AssociatedUnit); +static_assert(!AssociatedUnit); +static_assert(AssociatedUnit); +static_assert(AssociatedUnit)>>); +static_assert(AssociatedUnit>); +static_assert(AssociatedUnit>); +static_assert(AssociatedUnit * si::second)>>); +static_assert(AssociatedUnit>); +static_assert(AssociatedUnit(si::metre))>>); +static_assert(AssociatedUnit); +static_assert(AssociatedUnit, struct si::second>>); +static_assert(AssociatedUnit); +static_assert(AssociatedUnit>>); +static_assert(AssociatedUnit); +static_assert(!AssociatedUnit>); +static_assert(!AssociatedUnit>); +static_assert(!AssociatedUnit>); +static_assert(!AssociatedUnit>); +static_assert(!AssociatedUnit, si::second>>); +static_assert(!AssociatedUnit); +static_assert(!AssociatedUnit); +static_assert(!AssociatedUnit); // UnitOf +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(UnitOf); +static_assert(!UnitOf); +static_assert(!UnitOf); +static_assert(!UnitOf); -static_assert(UnitOf); -static_assert(UnitOf); -static_assert(UnitOf); -static_assert(!UnitOf); +// Reference +static_assert(Reference); +static_assert(Reference>); +static_assert(Reference>); +static_assert(Reference>); +static_assert(Reference>); +static_assert(!Reference); +static_assert(!Reference); +static_assert(!Reference)>>); +static_assert(!Reference); +static_assert(!Reference); + +// ReferenceOf +static_assert(ReferenceOf); +static_assert(ReferenceOf); +static_assert(!ReferenceOf); +static_assert(ReferenceOf, isq::length>); +static_assert(!ReferenceOf, isq::radius>); +static_assert(ReferenceOf, isq::length>); +static_assert(ReferenceOf, isq::radius>); +static_assert(ReferenceOf); +static_assert(!ReferenceOf); +static_assert(ReferenceOf, isq::dim_length>); +static_assert(ReferenceOf, isq::dim_length>); + +static_assert(ReferenceOf); +static_assert(ReferenceOf); +static_assert(ReferenceOf, dimensionless>); +static_assert(ReferenceOf, dimension_one>); +static_assert(ReferenceOf, isq::rotation>); +static_assert(ReferenceOf, dimensionless>); +static_assert(ReferenceOf, dimension_one>); +static_assert(ReferenceOf); +static_assert(!ReferenceOf); +static_assert(ReferenceOf); +static_assert(ReferenceOf, isq::angular_measure>); +static_assert(!ReferenceOf, dimensionless>); +static_assert(ReferenceOf, dimension_one>); +static_assert(ReferenceOf); +static_assert(ReferenceOf); +static_assert(!ReferenceOf, isq::rotation>); +static_assert(!ReferenceOf, isq::angular_measure>); // Representation - static_assert(Representation); +static_assert(Representation); static_assert(Representation>); -static_assert(!Representation>); -static_assert(!Representation>>); -static_assert(!Representation); +static_assert(!Representation); +static_assert(!Representation>); +static_assert(!Representation); static_assert(!Representation); +// RepresentationOf +static_assert(RepresentationOf); +static_assert(RepresentationOf); +static_assert(RepresentationOf, quantity_character::scalar>); +static_assert(!RepresentationOf); +static_assert(!RepresentationOf, quantity_character::scalar>); +static_assert(!RepresentationOf); +static_assert(!RepresentationOf); + // Quantity - -static_assert(Quantity>); +static_assert(Quantity>); +static_assert(Quantity>); +static_assert(Quantity>); +static_assert(Quantity>); static_assert(!Quantity); -static_assert(!Quantity, si::metre>>); - -// QuantityPoint - -static_assert(QuantityPoint, si::metre>>); -static_assert(!QuantityPoint>); -static_assert(!QuantityPoint); - -// QuantityLike - -static_assert(QuantityLike); -static_assert(QuantityLike); -static_assert(!QuantityLike>); -static_assert(!QuantityLike); - -// WrappedQuantity - -static_assert(wrapped_quantity_>>); -static_assert(!wrapped_quantity_, si::length>>); +static_assert(!Quantity>); +static_assert(!Quantity>); // QuantityOf +static_assert(QuantityOf, isq::length>); +static_assert(QuantityOf, isq::radius>); +static_assert(!QuantityOf, isq::length>); +static_assert(QuantityOf, isq::length>); +static_assert(!QuantityOf, isq::radius>); +static_assert(QuantityOf, isq::length>); +static_assert(QuantityOf, isq::radius>); +static_assert(QuantityOf, isq::dim_length>); +static_assert(!QuantityOf, isq::dim_length>); +static_assert(QuantityOf, isq::dim_length>); +static_assert(QuantityOf, isq::dim_length>); -static_assert(QuantityOf, si::dim_length>); -// TODO it seems `QuantityOf` is a bad name if `si::cgs::length` matches `si::fps::dim_length` -static_assert(QuantityOf, si::dim_length>); -static_assert(QuantityOf, si::dim_length>); -static_assert(QuantityOf, si::fps::dim_length>); -static_assert(!QuantityOf, si::dim_time>); +static_assert(QuantityOf, dimensionless>); +static_assert(QuantityOf, dimension_one>); +static_assert(QuantityOf, dimensionless>); +static_assert(QuantityOf, dimension_one>); +static_assert(QuantityOf, isq::rotation>); +static_assert(QuantityOf, dimensionless>); +static_assert(QuantityOf, dimension_one>); +static_assert(QuantityOf, isq::angular_measure>); +static_assert(!QuantityOf, dimensionless>); +static_assert(QuantityOf, dimension_one>); +static_assert(QuantityOf, isq::angular_measure>); +static_assert(!QuantityOf, dimensionless>); +static_assert(QuantityOf, dimension_one>); +static_assert(QuantityOf, isq::rotation>); +static_assert(QuantityOf, isq::angular_measure>); +static_assert(!QuantityOf, isq::rotation>); +static_assert(!QuantityOf, isq::angular_measure>); +// QuantityLike +static_assert(QuantityLike); +static_assert(QuantityLike); +static_assert(!QuantityLike>); +static_assert(!QuantityLike>); +static_assert(!QuantityLike); + +// QuantityPoint +inline constexpr struct my_origin : absolute_point_origin { + using absolute_point_origin::absolute_point_origin; +} my_origin; + +static_assert(QuantityPoint>); +static_assert(QuantityPoint>); +static_assert(QuantityPoint{}, int>>); +static_assert(QuantityPoint{}, int>>); +static_assert(QuantityPoint>); +static_assert(!QuantityPoint>); +static_assert(!QuantityPoint>); +static_assert(!QuantityPoint); +static_assert(!QuantityPoint); +static_assert(!QuantityPoint>); +static_assert(!QuantityPoint); + +// QuantityPointOf +static_assert(QuantityPointOf, isq::length>); +static_assert(QuantityPointOf, isq::radius>); +static_assert(QuantityPointOf, isq::length>); +static_assert(!QuantityPointOf, isq::radius>); +static_assert(QuantityPointOf, isq::length>); +static_assert(QuantityPointOf, isq::radius>); static_assert( - QuantityPointOf, si::second, int>, dynamic_origin>); -static_assert(QuantityPointOf, si::second, int>, - clock_origin>); -static_assert(!QuantityPointOf, si::second, int>, - clock_origin>); -static_assert(!QuantityPointOf, si::second, int>, - dynamic_origin>); + QuantityPointOf{}, int>, isq::length>); +static_assert( + !QuantityPointOf{}, int>, isq::radius>); +static_assert( + QuantityPointOf{}, int>, isq::length>); +static_assert( + QuantityPointOf{}, int>, isq::radius>); +static_assert(QuantityPointOf, isq::length>); +static_assert(QuantityPointOf, isq::radius>); +static_assert(QuantityPointOf, absolute_point_origin{}>); +static_assert(QuantityPointOf, absolute_point_origin{}>); +static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, absolute_point_origin{}>); +static_assert(!QuantityPointOf, absolute_point_origin{}>); +static_assert(!QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, absolute_point_origin{}>); +static_assert(QuantityPointOf, absolute_point_origin{}>); +static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, absolute_point_origin{}>); +static_assert( + !QuantityPointOf, absolute_point_origin{}>); + +// PointOrigin +static_assert(PointOrigin>); +static_assert(PointOrigin); +static_assert(PointOrigin>); +static_assert(PointOrigin>); +static_assert(PointOrigin{}, int>>); +static_assert(PointOrigin{}, int>>); +static_assert(PointOrigin>); +static_assert(!PointOrigin>); +static_assert(!PointOrigin); +static_assert(!PointOrigin>); +static_assert(!PointOrigin); + +// PointOriginFor +static_assert(PointOriginFor, isq::length>); +static_assert(!PointOriginFor, isq::length>); +static_assert(PointOriginFor, isq::radius>); +static_assert(PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); +static_assert(PointOriginFor); +static_assert(PointOriginFor); +static_assert(!PointOriginFor); +static_assert(PointOriginFor, isq::length>); +static_assert(PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); +static_assert(PointOriginFor, isq::length>); +static_assert(PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); +static_assert(!PointOriginFor, isq::length>); +static_assert(PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); +static_assert( + PointOriginFor{}, int>, isq::length>); +static_assert( + PointOriginFor{}, int>, isq::radius>); +static_assert( + !PointOriginFor{}, int>, isq::time>); +static_assert( + !PointOriginFor{}, int>, isq::length>); +static_assert( + PointOriginFor{}, int>, isq::radius>); +static_assert( + !PointOriginFor{}, int>, isq::time>); +static_assert(PointOriginFor>{}, int>, + isq::length>); +static_assert(PointOriginFor>{}, int>, + isq::radius>); +static_assert(!PointOriginFor< + quantity_point>{}, int>, isq::time>); +static_assert(!PointOriginFor< + quantity_point>{}, int>, isq::length>); +static_assert(PointOriginFor>{}, int>, + isq::radius>); +static_assert( + !PointOriginFor{}, int>, isq::time>); +static_assert(!PointOriginFor, isq::length>); +static_assert(PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); +static_assert(!PointOriginFor, isq::length>); +static_assert(!PointOriginFor); +static_assert(!PointOriginFor, isq::length>); +static_assert(!PointOriginFor); + +// QuantityPointLike +static_assert(QuantityPointLike>); +static_assert(!QuantityPointLike); +static_assert(!QuantityPointLike>); +static_assert(!QuantityPointLike>); +static_assert(!QuantityPointLike); } // namespace diff --git a/test/unit_test/static/custom_rep_test_min_impl.cpp b/test/unit_test/static/custom_rep_test_min_impl.cpp index 62b1ceb2..70166e60 100644 --- a/test/unit_test/static/custom_rep_test_min_impl.cpp +++ b/test/unit_test/static/custom_rep_test_min_impl.cpp @@ -20,8 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include -#include +#include #include namespace { @@ -40,305 +39,231 @@ public: using value_type = T; min_impl() = default; - constexpr min_impl(T v) noexcept : value_(v) {} + constexpr explicit(false) min_impl(T v) noexcept : value_(v) {} template - constexpr min_impl(min_impl i) noexcept : value_(static_cast(i.value_)) + constexpr explicit(false) min_impl(min_impl i) noexcept : value_(static_cast(static_cast(i))) { } - constexpr operator T() const noexcept { return value_; } + constexpr explicit(false) operator T() const noexcept { return value_; } }; } // namespace +template +inline constexpr bool mp_units::is_scalar> = true; + template -struct std::common_type, min_impl> : std::common_type {}; +struct std::common_type, min_impl> : std::type_identity>> {}; template -struct std::common_type, U> : std::common_type {}; +struct std::common_type, U> : std::type_identity>> {}; template -struct std::common_type> : std::common_type {}; +struct std::common_type> : std::type_identity>> {}; namespace { -using namespace units; -using namespace units::isq::si; +using namespace mp_units; static_assert(Representation>); static_assert(Representation>); -// construction from a value -static_assert(std::constructible_from>, min_impl>); -static_assert(!std::convertible_to, length>>); +// construction from a value is not allowed +static_assert(!std::constructible_from>, min_impl>); +static_assert(!std::convertible_to, quantity>>); -static_assert(std::constructible_from>, min_impl>); -static_assert(!std::convertible_to, length>>); +static_assert(!std::constructible_from>, min_impl>); +static_assert(!std::convertible_to, quantity>>); -static_assert(std::constructible_from>, min_impl>); -static_assert(!std::convertible_to, length>>); +// multiply syntax should work +template +concept creates_quantity = requires { T{} * U; }; -static_assert(!std::constructible_from>, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, length>>); +static_assert(creates_quantity, si::metre>); +static_assert(creates_quantity, si::metre>); -// construction from an underlying type -static_assert(std::constructible_from>, int>); -static_assert(!std::convertible_to>>); +// dimensionless quantity is constructible and convertible from a value +static_assert(std::constructible_from>, min_impl>); +static_assert(std::convertible_to, quantity>>); -static_assert(std::constructible_from>, double>); -static_assert(!std::convertible_to>>); +static_assert(std::constructible_from>, min_impl>); +static_assert(std::convertible_to, quantity>>); -static_assert(std::constructible_from>, int>); -static_assert(!std::convertible_to>>); +static_assert(std::constructible_from>, min_impl>); +static_assert(std::convertible_to, quantity>>); -static_assert(!std::constructible_from>, double>); // narrowing conversion -static_assert(!std::convertible_to>>); - -// dimensionless quantity is convertible from a value -static_assert(std::constructible_from>, min_impl>); -static_assert(std::convertible_to, dimensionless>>); - -static_assert(std::constructible_from>, min_impl>); -static_assert(std::convertible_to, dimensionless>>); - -static_assert(std::constructible_from>, min_impl>); -static_assert(std::convertible_to, dimensionless>>); - -static_assert(!std::constructible_from>, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, dimensionless>>); +static_assert(!std::constructible_from>, min_impl>); // narrowing conversion +static_assert(!std::convertible_to, quantity>>); // and underlying type -static_assert(std::constructible_from>, int>); -static_assert(std::convertible_to>>); +static_assert(std::constructible_from>, int>); +static_assert(std::convertible_to>>); -static_assert(std::constructible_from>, double>); -static_assert(std::convertible_to>>); +static_assert(std::constructible_from>, double>); +static_assert(std::convertible_to>>); -static_assert(std::constructible_from>, int>); -static_assert(std::convertible_to>>); +static_assert(std::constructible_from>, int>); +static_assert(std::convertible_to>>); -static_assert(!std::constructible_from>, double>); // narrowing conversion -static_assert(!std::convertible_to>>); +static_assert(!std::constructible_from>, double>); // narrowing conversion +static_assert(!std::convertible_to>>); -// but only for ratio(1), otherwise not convertible -static_assert(std::constructible_from>, min_impl>); -static_assert(!std::convertible_to, dimensionless>>); +// but only for ratio(1) +static_assert(!std::constructible_from>, min_impl>); +static_assert(!std::convertible_to, quantity>>); -static_assert(std::constructible_from>, min_impl>); -static_assert(!std::convertible_to, dimensionless>>); +static_assert(!std::constructible_from>, min_impl>); +static_assert(!std::convertible_to, quantity>>); -static_assert(std::constructible_from>, min_impl>); -static_assert(!std::convertible_to, dimensionless>>); +static_assert(!std::constructible_from>, min_impl>); +static_assert(!std::convertible_to, quantity>>); -static_assert( - !std::constructible_from>, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, dimensionless>>); +static_assert(!std::constructible_from>, min_impl>); // narrowing conversion +static_assert(!std::convertible_to, quantity>>); -// implicit conversion tests -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, length>); - -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, length>); - -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, length>); - -static_assert(!std::constructible_from, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, length>); - -// construction from an underlying type -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, length>); - -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, length>); - -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, length>); - -static_assert(!std::constructible_from, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, length>); - -// dimensionless quantity is convertible from a value -static_assert(std::constructible_from, min_impl>); -static_assert(std::convertible_to, dimensionless>); - -static_assert(std::constructible_from, min_impl>); -static_assert(std::convertible_to, dimensionless>); - -static_assert(std::constructible_from, min_impl>); -static_assert(std::convertible_to, dimensionless>); - -static_assert(!std::constructible_from, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, dimensionless>); - -// but only for ratio(1), otherwise not convertible -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, dimensionless>); - -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, dimensionless>); - -static_assert(std::constructible_from, min_impl>); -static_assert(!std::convertible_to, dimensionless>); - -static_assert(!std::constructible_from, min_impl>); // narrowing conversion -static_assert(!std::convertible_to, dimensionless>); +// multiply syntax +static_assert(creates_quantity, one>); +static_assert(creates_quantity, one>); +static_assert(creates_quantity, percent>); +static_assert(creates_quantity, percent>); // construction from a quantity // min_impl -> min_impl -static_assert(std::constructible_from>, length>>); -static_assert(std::convertible_to>, length>>); +static_assert(std::constructible_from>, quantity>>); +static_assert(std::convertible_to>, quantity>>); -static_assert(std::constructible_from>, length>>); -static_assert(std::convertible_to>, length>>); +static_assert(std::constructible_from>, quantity>>); +static_assert(std::convertible_to>, quantity>>); -static_assert(std::constructible_from>, length>>); -static_assert(std::convertible_to>, length>>); +static_assert(std::constructible_from>, quantity>>); +static_assert(std::convertible_to>, quantity>>); -static_assert( - !std::constructible_from>, length>>); // narrowing conversion -static_assert(!std::convertible_to>, length>>); +static_assert(!std::constructible_from>, + quantity>>); // narrowing conversion +static_assert(!std::convertible_to>, quantity>>); // T -> min_impl -static_assert(std::constructible_from>, length>); -static_assert(std::convertible_to, length>>); +static_assert(std::constructible_from>, quantity>); +static_assert(std::convertible_to, quantity>>); -static_assert(std::constructible_from>, length>); -static_assert(std::convertible_to, length>>); +static_assert(std::constructible_from>, quantity>); +static_assert(std::convertible_to, quantity>>); -static_assert(std::constructible_from>, length>); -static_assert(std::convertible_to, length>>); +static_assert(std::constructible_from>, quantity>); +static_assert(std::convertible_to, quantity>>); -static_assert(!std::constructible_from>, length>); // narrowing conversion -static_assert(!std::convertible_to, length>>); +static_assert( + !std::constructible_from>, quantity>); // narrowing conversion +static_assert(!std::convertible_to, quantity>>); // min_impl -> T -static_assert(std::constructible_from, length>>); -static_assert(std::convertible_to>, length>); +static_assert(std::constructible_from, quantity>>); +static_assert(std::convertible_to>, quantity>); -static_assert(std::constructible_from, length>>); -static_assert(std::convertible_to>, length>); +static_assert(std::constructible_from, quantity>>); +static_assert(std::convertible_to>, quantity>); -static_assert(std::constructible_from, length>>); -static_assert(std::convertible_to>, length>); +static_assert(std::constructible_from, quantity>>); +static_assert(std::convertible_to>, quantity>); -static_assert(!std::constructible_from, length>>); // narrowing conversion -static_assert(!std::convertible_to>, length>); +static_assert( + !std::constructible_from, quantity>>); // narrowing conversion +static_assert(!std::convertible_to>, quantity>); // arithmetic operators -static_assert(length>(1) + length>(1) == length>(2)); -static_assert(length>(1) + length>(1.5) == - length>(2.5)); -static_assert(length(1) + length>(1) == length>(2)); -static_assert(length(1) + length>(1.5) == length>(2.5)); -static_assert(length>(1) + length(1) == length>(2)); -static_assert(length>(1) + length(1.5) == length>(2.5)); -static_assert(length>(1) + length>(1) == length(2)); -static_assert(length>(1) + length>(1.5) == length(2.5)); +static_assert(min_impl{1} * si::metre + min_impl{1} * si::metre == min_impl{2} * si::metre); +static_assert(min_impl{1} * si::metre + min_impl{1.5} * si::metre == min_impl{2.5} * si::metre); +static_assert(1 * si::metre + min_impl{1} * si::metre == min_impl{2} * si::metre); +static_assert(1 * si::metre + min_impl{1.5} * si::metre == min_impl{2.5} * si::metre); +static_assert(min_impl{1} * si::metre + 1 * si::metre == min_impl{2} * si::metre); +static_assert(min_impl{1} * si::metre + double{1.5} * si::metre == min_impl{2.5} * si::metre); +static_assert(min_impl{1} * si::metre + min_impl{1} * si::metre == 2 * si::metre); +static_assert(min_impl{1} * si::metre + min_impl{1.5} * si::metre == double{2.5} * si::metre); -static_assert(length>(1) + length>(1) == - length>(1001)); -static_assert(length>(1) + length>(1.5) == - length>(1001.5)); -static_assert(length(1) + length>(1) == length>(1001)); -static_assert(length(1) + length>(1.5) == - length>(1001.5)); -static_assert(length>(1) + length(1) == length>(1001)); -static_assert(length>(1) + length(1.5) == - length>(1001.5)); -static_assert(length>(1) + length>(1) == length(1001)); -static_assert(length>(1) + length>(1.5) == - length(1001.5)); +static_assert(min_impl{1} * si::kilo + min_impl{1} * si::metre == + min_impl{1'001} * si::metre); +static_assert(min_impl{1} * si::kilo + min_impl{1.5} * si::metre == + min_impl{1001.5} * si::metre); +static_assert(1 * si::kilo + min_impl{1} * si::metre == min_impl{1'001} * si::metre); +static_assert(1 * si::kilo + min_impl{1.5} * si::metre == min_impl{1001.5} * si::metre); +static_assert(min_impl{1} * si::kilo + 1 * si::metre == min_impl{1'001} * si::metre); +static_assert(min_impl{1} * si::kilo + double{1.5} * si::metre == min_impl{1001.5} * si::metre); +static_assert(min_impl{1} * si::kilo + min_impl{1} * si::metre == 1'001 * si::metre); +static_assert(min_impl{1} * si::kilo + min_impl{1.5} * si::metre == double{1001.5} * si::metre); -static_assert(length>(1) + length>(1) == - length>(1001)); -static_assert(length>(1) + length>(1.5) == - length>(1501)); -static_assert(length(1) + length>(1) == length>(1001)); -static_assert(length(1) + length>(1.5) == - length>(1501)); -static_assert(length>(1) + length(1) == length>(1001)); -static_assert(length>(1) + length(1.5) == - length>(1501)); -static_assert(length>(1) + length>(1) == length(1001)); -static_assert(length>(1) + length>(1.5) == - length(1501)); +static_assert(min_impl{1} * si::metre + min_impl{1} * si::kilo == + min_impl{1'001} * si::metre); +static_assert(min_impl{1} * si::metre + min_impl{1.5} * si::kilo == + min_impl{1'501} * si::metre); +static_assert(1 * si::metre + min_impl{1} * si::kilo == min_impl{1'001} * si::metre); +static_assert(1 * si::metre + min_impl{1.5} * si::kilo == min_impl{1'501} * si::metre); +static_assert(min_impl{1} * si::metre + 1 * si::kilo == min_impl{1'001} * si::metre); +static_assert(min_impl{1} * si::metre + double{1.5} * si::kilo == min_impl{1'501} * si::metre); +static_assert(min_impl{1} * si::metre + min_impl{1} * si::kilo == 1'001 * si::metre); +static_assert(min_impl{1} * si::metre + min_impl{1.5} * si::kilo == double{1'501} * si::metre); -static_assert(length>(2) - length>(1) == length>(1)); -static_assert(length>(2) - length>(1.5) == - length>(0.5)); -static_assert(length(2) - length>(1) == length>(1)); -static_assert(length(2) - length>(1.5) == length>(0.5)); -static_assert(length>(2) - length(1) == length>(1)); -static_assert(length>(2) - length(1.5) == length>(0.5)); -static_assert(length>(2) - length>(1) == length(1)); -static_assert(length>(2) - length>(1.5) == length(0.5)); +static_assert(min_impl{2} * si::metre - min_impl{1} * si::metre == min_impl{1} * si::metre); +static_assert(min_impl{2} * si::metre - min_impl{1.5} * si::metre == min_impl{0.5} * si::metre); +static_assert(2 * si::metre - min_impl{1} * si::metre == min_impl{1} * si::metre); +static_assert(2 * si::metre - min_impl{1.5} * si::metre == min_impl{0.5} * si::metre); +static_assert(min_impl{2} * si::metre - 1 * si::metre == min_impl{1} * si::metre); +static_assert(min_impl{2} * si::metre - double{1.5} * si::metre == min_impl{0.5} * si::metre); +static_assert(min_impl{2} * si::metre - min_impl{1} * si::metre == 1 * si::metre); +static_assert(min_impl{2} * si::metre - min_impl{1.5} * si::metre == double{0.5} * si::metre); -static_assert(length>(2) - length>(1) == - length>(1999)); -static_assert(length>(2) - length>(1.5) == - length>(1998.5)); -static_assert(length(2) - length>(1) == length>(1999)); -static_assert(length(2) - length>(1.5) == - length>(1998.5)); -static_assert(length>(2) - length(1) == length>(1999)); -static_assert(length>(2) - length(1.5) == - length>(1998.5)); -static_assert(length>(2) - length>(1) == length(1999)); -static_assert(length>(2) - length>(1.5) == - length(1998.5)); +static_assert(min_impl{2} * si::kilo - min_impl{1} * si::metre == + min_impl{1'999} * si::metre); +static_assert(min_impl{2} * si::kilo - min_impl{1.5} * si::metre == + min_impl{1998.5} * si::metre); +static_assert(2 * si::kilo - min_impl{1} * si::metre == min_impl{1'999} * si::metre); +static_assert(2 * si::kilo - min_impl{1.5} * si::metre == min_impl{1998.5} * si::metre); +static_assert(min_impl{2} * si::kilo - 1 * si::metre == min_impl{1'999} * si::metre); +static_assert(min_impl{2} * si::kilo - double{1.5} * si::metre == min_impl{1998.5} * si::metre); +static_assert(min_impl{2} * si::kilo - min_impl{1} * si::metre == 1'999 * si::metre); +static_assert(min_impl{2} * si::kilo - min_impl{1.5} * si::metre == double{1998.5} * si::metre); -static_assert(length>(2000) - length>(1) == - length>(1000)); -static_assert(length>(2000) - length>(1.5) == - length>(500)); -static_assert(length(2000) - length>(1) == length>(1000)); -static_assert(length(2000) - length>(1.5) == - length>(500)); -static_assert(length>(2000) - length(1) == length>(1000)); -static_assert(length>(2000) - length(1.5) == - length>(500)); -static_assert(length>(2000) - length>(1) == length(1000)); -static_assert(length>(2000) - length>(1.5) == - length(500)); +static_assert(min_impl{2'000} * si::metre - min_impl{1} * si::kilo == + min_impl{1'000} * si::metre); +static_assert(min_impl{2'000} * si::metre - min_impl{1.5} * si::kilo == + min_impl{500} * si::metre); +static_assert(2'000 * si::metre - min_impl{1} * si::kilo == min_impl{1'000} * si::metre); +static_assert(2'000 * si::metre - min_impl{1.5} * si::kilo == min_impl{500} * si::metre); +static_assert(min_impl{2'000} * si::metre - 1 * si::kilo == min_impl{1'000} * si::metre); +static_assert(min_impl{2'000} * si::metre - double{1.5} * si::kilo == + min_impl{500} * si::metre); +static_assert(min_impl{2'000} * si::metre - min_impl{1} * si::kilo == 1'000 * si::metre); +static_assert(min_impl{2'000} * si::metre - min_impl{1.5} * si::kilo == + double{500} * si::metre); -static_assert(length>(123) * min_impl(1.5) == length>(184.5)); -static_assert(length>(123) * 1.5 == length>(184.5)); -static_assert(length(123) * min_impl(1.5) == length>(184.5)); +static_assert(min_impl{123} * si::metre * min_impl(1.5) == min_impl{184.5} * si::metre); +static_assert(min_impl{123} * si::metre * 1.5 == min_impl{184.5} * si::metre); +static_assert(123 * si::metre * min_impl(1.5) == min_impl{184.5} * si::metre); -static_assert(length>(123) * quantity{min_impl(1.5)} == - length>(184.5)); -static_assert(length>(123) * quantity{1.5} == length>(184.5)); -static_assert(length(123) * quantity{min_impl(1.5)} == length>(184.5)); +static_assert(min_impl{123} * si::metre * (min_impl(1.5) * one) == min_impl{184.5} * si::metre); +static_assert(min_impl{123} * si::metre * (1.5 * one) == min_impl{184.5} * si::metre); +static_assert(123 * si::metre * (min_impl(1.5) * one) == min_impl{184.5} * si::metre); -static_assert(min_impl(1.5) * length>(123) == length>(184.5)); -static_assert(min_impl(1.5) * length(123) == length>(184.5)); -static_assert(1.5 * length>(123) == length>(184.5)); +static_assert(min_impl(1.5) * min_impl{123} * si::metre == min_impl{184.5} * si::metre); +static_assert(min_impl(1.5) * 123 * si::metre == min_impl{184.5} * si::metre); +static_assert(1.5 * min_impl{123} * si::metre == min_impl{184.5} * si::metre); -static_assert(quantity{min_impl(1.5)} * length>(123) == - length>(184.5)); -static_assert(quantity{min_impl(1.5)} * length(123) == length>(184.5)); -static_assert(quantity{1.5} * length>(123) == length>(184.5)); +static_assert(min_impl(1.5) * one * (min_impl{123} * si::metre) == min_impl{184.5} * si::metre); +static_assert(min_impl(1.5) * one * (123 * si::metre) == min_impl{184.5} * si::metre); +static_assert(1.5 * one * (min_impl{123} * si::metre) == min_impl{184.5} * si::metre); -static_assert(length>(123) / min_impl(2.) == length>(61.5)); -static_assert(length>(123) / 2. == length>(61.5)); -static_assert(length(123) / min_impl(2.) == length>(61.5)); +static_assert(min_impl{123} * si::metre / min_impl(2.) == min_impl{61.5} * si::metre); +static_assert(min_impl{123} * si::metre / 2. == min_impl{61.5} * si::metre); +static_assert(123 * si::metre / min_impl(2.) == min_impl{61.5} * si::metre); -static_assert(length>(123) / quantity{min_impl(2.)} == - length>(61.5)); -static_assert(length>(123) / quantity{2.} == length>(61.5)); -static_assert(length(123) / quantity{min_impl(2.)} == length>(61.5)); +static_assert(min_impl{123} * si::metre / (min_impl(2.) * one) == min_impl{61.5} * si::metre); +static_assert(min_impl{123} * si::metre / (2. * one) == min_impl{61.5} * si::metre); +static_assert(123 * si::metre / (min_impl(2.) * one) == min_impl{61.5} * si::metre); -static_assert(length>(123) / length>(2.) == 61.5); -static_assert(length>(123) / length(2.) == 61.5); -static_assert(length(123) / length>(2.) == 61.5); +static_assert(min_impl{123} * si::metre / (min_impl{2.} * si::metre) == 61.5); +static_assert(min_impl{123} * si::metre / (double{2.} * si::metre) == 61.5); +static_assert(123 * si::metre / (min_impl{2.} * si::metre) == 61.5); -static_assert(length>(123) % min_impl(100) == length(23)); -static_assert(length>(123) % 100 == length(23)); -static_assert(length(123) % min_impl(100) == length(23)); - -static_assert(length>(123) % quantity{min_impl(100)} == length(23)); -static_assert(length>(123) % quantity{100} == length(23)); -static_assert(length(123) % quantity{min_impl(100)} == length(23)); +static_assert(min_impl{123} * si::metre % (min_impl(100) * si::metre) == 23 * si::metre); +static_assert(min_impl{123} * si::metre % (100 * si::metre) == 23 * si::metre); +static_assert(123 * si::metre % (min_impl(100) * si::metre) == 23 * si::metre); } // namespace diff --git a/test/unit_test/static/custom_unit_test.cpp b/test/unit_test/static/custom_unit_test.cpp deleted file mode 100644 index 474249fb..00000000 --- a/test/unit_test/static/custom_unit_test.cpp +++ /dev/null @@ -1,79 +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. - -#include "test_tools.h" -#include -#include -#include -#include -#include -#include -#include // IWYU pragma: keep -#include - -namespace { - -using namespace units; -using namespace units::isq::si; - -// power spectral density -struct sq_volt_per_hertz : derived_unit {}; -struct dim_power_spectral_density : - derived_dimension, - units::exponent> {}; - -template U, Representation Rep = double> -using power_spectral_density = quantity; - -// amplitude spectral density -struct volt_per_sqrt_hertz : derived_unit {}; -struct dim_amplitude_spectral_density : - derived_dimension, - units::exponent> {}; - -template U, Representation Rep = double> -using amplitude_spectral_density = quantity; - -} // namespace - -namespace { - -static_assert(compare, dim_amplitude_spectral_density>); -static_assert(compare, dim_power_spectral_density>); - -static_assert(compare(amplitude_spectral_density(4))), - decltype(power_spectral_density(16))>); -static_assert(compare(16))), - decltype(amplitude_spectral_density(4))>); - -} // namespace - -namespace { - -struct kilogram_per_second : derived_unit {}; -struct dim_mass_rate : - derived_dimension, units::exponent> { -}; -struct kilogram_per_hour : derived_scaled_unit {}; -[[maybe_unused]] constexpr auto a = 1_q_kg / 1_q_h; - -} // namespace diff --git a/test/unit_test/static/dimension_op_test.cpp b/test/unit_test/static/dimension_op_test.cpp deleted file mode 100644 index fe1561cb..00000000 --- a/test/unit_test/static/dimension_op_test.cpp +++ /dev/null @@ -1,138 +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. - -#include -#include -#include -#include -#include - -using namespace units; - -namespace { - -struct u0 : named_unit {}; -struct d0 : base_dimension<"d0", u0> {}; -struct u1 : named_unit {}; -struct d1 : base_dimension<"d1", u1> {}; -struct u2 : named_unit {}; -struct d2 : base_dimension<"d2", u2> {}; -struct u3 : named_unit {}; -struct d3 : base_dimension<"d3", u3> {}; - -// exponent_invert - -static_assert(is_same_v>, units::exponent>); -static_assert(is_same_v>, units::exponent>); - -// dim_unpack - -template -using dim_unpack = TYPENAME detail::dim_unpack::type; - -template -using derived_dim = detail::derived_dimension_base; - -static_assert(is_same_v, exponent_list<>>); -static_assert(is_same_v>, exponent_list>>); -static_assert(is_same_v, units::exponent>, - exponent_list, units::exponent>>); -using dim1 = derived_dim>; -using dim2 = derived_dim, units::exponent>; -static_assert(is_same_v, units::exponent>, - exponent_list, units::exponent>>); -static_assert(is_same_v, units::exponent, units::exponent>, - exponent_list, units::exponent, units::exponent, - units::exponent>>); - -// dim_invert -static_assert(is_same_v>>, d0>); -static_assert(is_same_v>>, unknown_dimension>>); -static_assert(is_same_v, units::exponent>>, - unknown_dimension, units::exponent>>); - -// make_dimension - -template -using make_dimension = detail::make_dimension; - -static_assert(is_same_v>, derived_dim>>); -static_assert(is_same_v, units::exponent>, - derived_dim, units::exponent>>); -static_assert(is_same_v, units::exponent>, - derived_dim, units::exponent>>); -static_assert( - is_same_v, units::exponent>, derived_dim>>); -static_assert( - is_same_v, units::exponent>, derived_dim>>); -static_assert( - is_same_v, units::exponent>, derived_dim>>); -static_assert( - is_same_v, units::exponent>, derived_dim>>); - -static_assert(is_same_v, units::exponent, units::exponent, - units::exponent>, - derived_dim, units::exponent>>); -static_assert(is_same_v, units::exponent, units::exponent, - units::exponent>, - derived_dim, units::exponent>>); - -static_assert(is_same_v, units::exponent, units::exponent>, - derived_dim>>); -static_assert(is_same_v, units::exponent, units::exponent>, - derived_dim>>); -static_assert(is_same_v, units::exponent, units::exponent>, - derived_dim>>); - -// dimension_multiply - -static_assert(is_same_v>, derived_dim>>, - unknown_dimension, units::exponent>>); -static_assert(is_same_v>, d1>, - unknown_dimension, units::exponent>>); -static_assert(is_same_v>>, - unknown_dimension, units::exponent>>); -static_assert(is_same_v, unknown_dimension, units::exponent>>); -static_assert( - is_same_v< - dimension_multiply, units::exponent, units::exponent>, - derived_dim>>, - unknown_dimension, units::exponent, units::exponent, units::exponent>>); -static_assert( - is_same_v, units::exponent, units::exponent>, - derived_dim>>, - unknown_dimension, units::exponent, units::exponent>>); -static_assert( - is_same_v, units::exponent, units::exponent>, - derived_dim>>, - unknown_dimension, units::exponent>>); -static_assert( - is_same_v>, derived_dim>>, d0>); - -// dimension_divide - -static_assert(is_same_v>, derived_dim>>, - unknown_dimension, units::exponent>>); -static_assert( - is_same_v>, unknown_dimension>>, d0>); - -} // namespace diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp new file mode 100644 index 00000000..d5091f54 --- /dev/null +++ b/test/unit_test/static/dimension_test.cpp @@ -0,0 +1,246 @@ +// 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. + +#include "test_tools.h" +#include +#include +#include +#include +#include + +namespace { + +using namespace mp_units; + +using dimension_one_ = struct dimension_one; + +// clang-format off +inline constexpr struct length_ : base_dimension<"L"> {} length; +inline constexpr struct mass_ : base_dimension<"M"> {} mass; +inline constexpr struct time_ : base_dimension<"T"> {} time; + +QUANTITY_SPEC_(q_time, time); +inline constexpr struct second_ : named_unit<"s", kind_of> {} second; + +inline constexpr auto frequency = 1 / time; +inline constexpr auto action = 1 / time; +inline constexpr auto area = length * length; +inline constexpr auto volume = area * length; +inline constexpr auto speed = length / time; +inline constexpr auto acceleration = speed / time; +inline constexpr auto force = mass * acceleration; +inline constexpr auto moment_of_force = length * force; +inline constexpr auto torque = moment_of_force; +inline constexpr auto pressure = force / area; +inline constexpr auto stress = pressure; +inline constexpr auto strain = stress / stress; +inline constexpr auto power = force * speed; +inline constexpr auto efficiency = power / power; +inline constexpr auto energy = force * length; +// clang-format on + +// concepts verification +static_assert(detail::BaseDimension); +static_assert(!detail::BaseDimension>); +static_assert(!detail::DerivedDimension); +static_assert(detail::DerivedDimension>); +static_assert(Dimension); +static_assert(Dimension>); + +static_assert(detail::DerivedDimension); +static_assert(detail::DerivedDimension); // dimension_one +static_assert(detail::BaseDimension); // length + +// derived dimension expression template syntax verification +static_assert(is_of_type<1 / time, derived_dimension>>); +static_assert(is_of_type<1 / (1 / time), time_>); + +static_assert(is_of_type); +static_assert(is_of_type