diff --git a/.clang-format b/.clang-format index 7abab467..756b6fdc 100644 --- a/.clang-format +++ b/.clang-format @@ -63,7 +63,7 @@ CommentPragmas: '^ NOLINT' # CompactNamespaces: false # ConstructorInitializerAllOnOneLineOrOnePerLine: true # ConstructorInitializerIndentWidth: 4 -# ContinuationIndentWidth: 4 +ContinuationIndentWidth: 2 # Cpp11BracedListStyle: true DeriveLineEnding: false DerivePointerAlignment: false @@ -109,7 +109,7 @@ IndentRequires: true # KeepEmptyLinesAtTheStartOfBlocks: false # MacroBlockBegin: '' # MacroBlockEnd: '' -# MaxEmptyLinesToKeep: 1 +MaxEmptyLinesToKeep: 2 # NamespaceIndentation: None # ObjCBinPackProtocolList: Never # ObjCBlockIndentWidth: 2 diff --git a/.github/workflows/ci-conan.yml b/.github/workflows/ci-conan.yml index d93a3c5d..84052ef7 100644 --- a/.github/workflows/ci-conan.yml +++ b/.github/workflows/ci-conan.yml @@ -78,6 +78,11 @@ jobs: downcast_mode: [ "on", "auto" ] steps: - uses: actions/checkout@v2 + - uses: hendrikmuhs/ccache-action@v1 + 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 }} + max-size: 50M - name: Install Clang if: matrix.config.compiler.type == 'CLANG' shell: bash @@ -121,12 +126,6 @@ jobs: conan profile update settings.compiler.libcxx=${{ matrix.config.lib }} default fi conan profile show default - - name: Add support for clang-12 to Conan's settings.yml - # TODO Remove when Conan will support clang-12 (after clang-12 release) - if: matrix.config.compiler.type == 'CLANG' - shell: bash - run: | - sed -i -e 's/"8", "9", "10", "11"]/"8", "9", "10", "11", "12"]/' ~/.conan/settings.yml - name: Run Conan Package Tools shell: bash env: diff --git a/.github/workflows/ci-test-package-cmake.yml b/.github/workflows/ci-test-package-cmake.yml index c2fcebcf..be5e46f7 100644 --- a/.github/workflows/ci-test-package-cmake.yml +++ b/.github/workflows/ci-test-package-cmake.yml @@ -84,6 +84,7 @@ jobs: CC: ${{ matrix.config.compiler.cc }} CXX: ${{ matrix.config.compiler.cxx }} CMAKE_GENERATOR: Ninja + CONAN_CMAKE_GENERATOR: Ninja steps: - uses: actions/checkout@v2 @@ -143,18 +144,20 @@ jobs: conan profile update settings.compiler.libcxx=${{ matrix.config.lib }} default fi conan profile show default - - name: Add support for clang-12 to Conan's settings.yml - # TODO Remove when Conan will support clang-12 (after clang-12 release) - if: matrix.config.compiler.type == 'CLANG' - shell: bash - run: | - sed -i -e 's/"8", "9", "10", "11"]/"8", "9", "10", "11", "12"]/' ~/.conan/settings.yml - name: Install Conan dependencies shell: bash run: | mkdir -p build/${{ matrix.build_type }} && cd build/${{ matrix.build_type }} conan install ../.. -b outdated -u - name: Configure mp-units CMake + if: matrix.config.compiler.type == 'VISUAL' + shell: cmd + working-directory: build/${{ matrix.build_type }} + run: | + call conanvcvars.bat + cmake ../../src -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake + - name: Configure mp-units CMake + if: matrix.config.compiler.type != 'VISUAL' shell: bash working-directory: build/${{ matrix.build_type }} run: | @@ -164,16 +167,25 @@ jobs: working-directory: build/${{ matrix.build_type }} run: | cmake --install . --prefix test_package - - name: Configure test_package CMake + - name: Install dependencies for test_package shell: bash run: | mkdir -p test_package/build/${{ matrix.build_type }} && cd test_package/build/${{ matrix.build_type }} conan install ../../.. + - name: Build test_package CMake + if: matrix.config.compiler.type == 'VISUAL' + shell: cmd + working-directory: test_package/build/${{ matrix.build_type }} + run: | + call conanvcvars.bat cmake ../.. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_INSTALL_PREFIX=../../../build/${{ matrix.build_type }}/test_package - - name: Build test_package + cmake --build . + - name: Build test_package CMake + if: matrix.config.compiler.type != 'VISUAL' shell: bash working-directory: test_package/build/${{ matrix.build_type }} run: | + cmake ../.. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_INSTALL_PREFIX=../../../build/${{ matrix.build_type }}/test_package cmake --build . - name: Run test_package shell: bash diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 478d0435..2991ab65 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -84,7 +84,7 @@ jobs: pip install -U conan conan config init conan remote add upload https://mpusz.jfrog.io/artifactory/api/conan/conan-oss - conan remote add linear-algebra https://api.bintray.com/conan/twonington/public-conan + conan remote add linear-algebra https://twonington.jfrog.io/artifactory/api/conan/conan-oss mkdir _lgtm_build_dir && cd _lgtm_build_dir conan install .. -s compiler.cppstd=20 -s compiler.libcxx=libstdc++11 -o mp-units:build_docs=False -e mp-units:CONAN_RUN_TESTS=True -b outdated -u conan build .. diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 1229e983..3e003f7b 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -40,6 +40,7 @@ env: CC: gcc-10 CXX: g++-10 CMAKE_GENERATOR: Ninja + CONAN_CMAKE_GENERATOR: Ninja jobs: docs: @@ -75,7 +76,7 @@ jobs: run: | conan config init conan remote add -i 0 upload https://mpusz.jfrog.io/artifactory/api/conan/conan-oss - conan remote add linear-algebra https://api.bintray.com/conan/twonington/public-conan + conan remote add linear-algebra https://twonington.jfrog.io/artifactory/api/conan/conan-oss - name: Install Conan dependencies run: | mkdir build && cd build diff --git a/.gitignore b/.gitignore index 2d2ba83d..319166d5 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ /cmake-build-*/ /build/ /out/ +_build/ # Conan *.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt index 93a07dcc..1ccd73e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,14 @@ project(mp-units-dev list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") +# make sure that the file is being used as an entry point +include(modern_project_structure) +ensure_entry_point() + +# use ccache if available +include(ccache) +enable_ccache(BASE_DIR ${PROJECT_SOURCE_DIR}) + # set restrictive compilation warnings include(warnings) set_warnings() @@ -38,7 +46,7 @@ add_compile_definitions($<$:gsl_CONFIG_CONTRACT_CHECKING_AUDIT>) option(UNITS_IWYU "Enables include-what-you-use" OFF) if(UNITS_IWYU) include(include-what-you-use) - set_iwyu( + enable_iwyu( MAPPING_FILE "${PROJECT_SOURCE_DIR}/.mp-units.imp" NO_FORWARD_DECLARATIONS QUOTED_INCLUDES_FIRST diff --git a/README.md b/README.md index ccaf92f5..4899d9d7 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![Conan CI](https://img.shields.io/github/workflow/status/mpusz/units/Conan%20CI/master?label=Conan%20CI)](https://github.com/mpusz/units/actions?query=workflow%3A%22Conan%20CI%22+branch%3Amaster) [![CMake CI](https://img.shields.io/github/workflow/status/mpusz/units/CMake%20Test%20Package%20CI/master?label=CMake%20CI)](https://github.com/mpusz/units/actions?query=workflow%3A%22CMake+Test+Package+CI%22+branch%3Amaster) [![GitHub Workflow Documentation](https://img.shields.io/github/workflow/status/mpusz/units/Documentation/master?label=Documentation%20CI)](https://github.com/mpusz/units/actions?query=workflow%3ADocumentation+branch%3Amaster) -[![Conan stable](https://img.shields.io/badge/ConanCenter-0.6.0%3Astable-blue)](https://conan.io/center/mp-units) -[![Conan testing](https://img.shields.io/badge/mpusz.jfrog.io-0.7.0%3Atesting-blue)](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units/0.7.0) +[![Conan stable](https://img.shields.io/badge/ConanCenter-0.7.0%3Astable-blue)](https://conan.io/center/mp-units) +[![Conan testing](https://img.shields.io/badge/mpusz.jfrog.io-0.8.0%3Atesting-blue)](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units/0.8.0) # `mp-units` - A Units Library for C++ @@ -28,8 +28,6 @@ analysis and unit/quantity manipulation. The basic idea and design heavily bases Here is a small example of possible operations: ```cpp -#define UNITS_REFERENCES - #include #include #include @@ -58,7 +56,7 @@ static_assert(10 * km / (5 * km) == 2); static_assert(1000 / (1 * s) == 1 * kHz); ``` -_Try it on the [Compiler Explorer](https://godbolt.org/z/53bTahKd8)._ +_Try it on the [Compiler Explorer](https://godbolt.org/z/5dvY8Woh1)._ This library requires some C++20 features (concepts, classes as NTTPs, ...). Thanks to them the user gets a powerful but still easy to use interface and all unit conversions @@ -66,10 +64,6 @@ and dimensional analysis can be performed without sacrificing on accuracy. Pleas the below example for a quick preview of basic library features: ```cpp -#define UNITS_ALIASES -#define UNITS_LITERALS -#define UNITS_REFERENCES - #include #include #include @@ -115,4 +109,4 @@ int main() } ``` -_Try it on the [Compiler Explorer](https://godbolt.org/z/jKnPPPEx6)._ +_Try it on the [Compiler Explorer](https://godbolt.org/z/9fnzfbhb6)._ diff --git a/build.py b/build.py index 052244e3..5660af4e 100644 --- a/build.py +++ b/build.py @@ -36,7 +36,7 @@ if __name__ == "__main__": # dependencies remotes = [ - ("https://api.bintray.com/conan/twonington/public-conan", True, "linear-algebra") + ("https://twonington.jfrog.io/artifactory/api/conan/conan-oss", True, "linear-algebra") ], build_policy = ["mp-units", "outdated"], upload_dependencies = "all", diff --git a/cmake/ccache.cmake b/cmake/ccache.cmake new file mode 100644 index 00000000..c2b5c96c --- /dev/null +++ b/cmake/ccache.cmake @@ -0,0 +1,221 @@ +# The MIT License (MIT) +# +# Copyright (c) 2017 Mateusz Pusz +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION 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.4) + +macro(_enable_ccache_failed) + if(NOT _enable_ccache_QUIET) + message(STATUS "Enabling ccache - failed") + endif() + return() +endmacro() + +# +# enable_ccache([PROGRAM] # ccache by default +# [QUIET] [REQUIRED] +# [MODE DIRECT_PREPROCESSOR|DIRECT_DEPEND|PREPROCESSOR|DEPEND] # DIRECT_PREPROCESSOR by default +# [BASE_DIR dir] +# [ACCOUNT_FOR_COMPILE_TIME_HEADER_CHANGES] +# [ACCOUNT_FOR_PCH] +# [ACCOUNT_FOR_MODULES] +# [PREFIXES prefixes...] +# ) +# +# BASE_DIR +# Set this option to ${CMAKE_BINARY_DIR} if you use FetchContent a lot for many projects with the same build options. +# Otherwise, if most of the sources come from the project itself then the default ${CMAKE_SOURCE_DIR} may be +# a better choice. +# +# ACCOUNT_FOR_COMPILE_TIME_HEADER_CHANGES +# Use it if some header files are being generated by the compilation process. +# +# ACCOUNT_FOR_PCH +# Use it if precompiled headers are enabled in your project. Automatically includes uses +# ACCOUNT_FOR_COMPILE_TIME_HEADER_CHANGES as well. +# See here for details: https://ccache.dev/manual/4.2.1.html#_precompiled_headers +# +# ACCOUNT_FOR_MODULES +# Use it for projects with C++20 modules. Requires DIRECT_DEPEND mode. +# +# PREFIXES +# A list of other tools that should be used together with ccache as a compiler launcher +# (i.e. distcc, icecc, sccache-dist, ...). +# +function(enable_ccache) + if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + message(FATAL_ERROR "'enable_ccache' function should be called from the top-level CMakeLists.txt file!") + # otherwise, it will not work for XCode + endif() + + set(_options QUIET REQUIRED ACCOUNT_FOR_COMPILE_TIME_HEADER_CHANGES ACCOUNT_FOR_PCH ACCOUNT_FOR_MODULES) + set(_one_value_args PROGRAM MODE BASE_DIR) + set(_multi_value_args PREFIXES) + cmake_parse_arguments(PARSE_ARGV 0 _enable_ccache "${_options}" "${_one_value_args}" "${_multi_value_args}") + + # validate and process arguments + if(_enable_ccache_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid arguments '${_enable_ccache_UNPARSED_ARGUMENTS}'") + endif() + + if(_enable_ccache_KEYWORDS_MISSING_VALUES) + message(FATAL_ERROR "No value provided for '${_enable_ccache_KEYWORDS_MISSING_VALUES}'") + endif() + + if(_enable_ccache_MODE) + set(_valid_mode_values DIRECT_PREPROCESSOR DIRECT_DEPEND PREPROCESSOR DEPEND) + if(NOT _enable_ccache_MODE IN_LIST _valid_mode_values) + message(FATAL_ERROR "'MODE' should be one of ${_valid_mode_values}") + endif() + endif() + + if(NOT _enable_ccache_QUIET) + message(STATUS "Enabling ccache") + endif() + + if(${_enable_ccache_REQUIRED}) + set(_error_log_level FATAL_ERROR) + elseif(NOT _enable_ccache_QUIET) + set(_error_log_level STATUS) + endif() + + if(NOT CMAKE_GENERATOR MATCHES "Ninja|Makefiles|Xcode") + if(DEFINED _error_log_level) + message(${_error_log_level} "ccache support not enabled: unsupported generator '${CMAKE_GENERATOR}'") + endif() + _enable_ccache_failed() + endif() + + if(NOT DEFINED _enable_ccache_PROGRAM) + set(_enable_ccache_PROGRAM ccache) + endif() + + find_program(CCACHE_PATH ${_enable_ccache_PROGRAM}) + if(CCACHE_PATH) + if(NOT _enable_ccache_QUIET) + message(STATUS " Executable: ${CCACHE_PATH}") + endif() + + # get version number + execute_process(COMMAND "${CCACHE_PATH}" --version OUTPUT_VARIABLE _output) + string(REPLACE "\n" ";" _output "${_output}") + foreach(_line ${_output}) + string(REGEX REPLACE "ccache version ([\\.0-9]+)$" "\\1" _ccache_version "${_line}") + if(_ccache_version) + if(NOT _enable_ccache_QUIET) + message(STATUS " Version: ${_ccache_version}") + endif() + break() + endif() + endforeach() + else() + if(DEFINED _error_log_level) + message(${_error_log_level} " '${_enable_ccache_PROGRAM}' executable was not found") + endif() + _enable_ccache_failed() + endif() + + if("${_ccache_version}" VERSION_LESS 3.3.0) + list(APPEND _ccacheEnv CCACHE_CPP2=1) # avoids spurious warnings with some compilers for ccache older than 3.3 + endif() + + if(_enable_ccache_MODE STREQUAL DIRECT_DEPEND) + list(APPEND _ccacheEnv CCACHE_DIRECT=1 CCACHE_DEPEND=1) + elseif(_enable_ccache_MODE STREQUAL PREPROCESSOR) + list(APPEND _ccacheEnv CCACHE_NO_DIRECT=1 CCACHE_NO_DEPEND=1) + elseif(_enable_ccache_MODE STREQUAL DEPEND) + list(APPEND _ccacheEnv CCACHE_NO_DIRECT=1 CCACHE_DEPEND=1) + else() + set(_enable_ccache_MODE DIRECT_PREPROCESSOR) + list(APPEND _ccacheEnv CCACHE_DIRECT=1 CCACHE_NO_DEPEND=1) + endif() + + if(_enable_ccache_BASE_DIR) + # CCACHE_ABSSTDERR=1 # reverts absolute paths after applying CCACHE_BASEDIR + if(NOT EXISTS ${_enable_ccache_BASE_DIR}) + message(FATAL_ERROR "Base directory '${_enable_ccache_BASE_DIR}' does not exist") + endif() + list(APPEND _ccacheEnv "CCACHE_BASEDIR=${_enable_ccache_BASE_DIR}") + endif() + + if(_enable_ccache_PREFIXES) + string(REPLACE ";" " " _prefixes_txt "${_enable_ccache_PREFIXES}") + list(APPEND _ccacheEnv "CCACHE_PREFIX=${_prefixes_txt}") + endif() + + if(_enable_ccache_ACCOUNT_FOR_COMPILE_TIME_HEADER_CHANGES) + list(APPEND _sloppiness include_file_mtime include_file_ctime) + endif() + + if(_enable_ccache_ACCOUNT_FOR_PCH) + list(APPEND _sloppiness pch_defines time_macros include_file_mtime include_file_ctime) + endif() + + if(_enable_ccache_ACCOUNT_FOR_MODULES) + if(NOT _enable_ccache_MODE STREQUAL DIRECT_DEPEND) + message(FATAL_ERROR "DIRECT_DEPEND mode required with ACCOUNT_FOR_MODULES option") + endif() + list(APPEND _sloppiness modules) + endif() + + if(_sloppiness) + list(REMOVE_DUPLICATES _sloppiness) + string(REPLACE ";" "," _sloppiness_txt "${_sloppiness}") + list(APPEND _ccacheEnv "CCACHE_SLOPPINESS=${_sloppiness_txt}") + endif() + + if(NOT _enable_ccache_QUIET) + message(STATUS " Environment: ${_ccacheEnv}") + endif() + + if(CMAKE_GENERATOR MATCHES "Ninja|Makefiles") + foreach(_lang IN ITEMS C CXX OBJC OBJCXX CUDA) + set(CMAKE_${_lang}_COMPILER_LAUNCHER + ${CMAKE_COMMAND} -E env + ${_ccacheEnv} ${CCACHE_PATH} + PARENT_SCOPE + ) + endforeach() + elseif(CMAKE_GENERATOR STREQUAL Xcode) + # Each of the Xcode project variables allow specifying only a single value, but the ccache command line needs to have multiple options. + # A separate launch script needs to be written out and the project variables pointed at them. + foreach(_lang IN ITEMS C CXX) + set(launch${_lang} ${CMAKE_BINARY_DIR}/launch-${_lang}) + file(WRITE ${launch${_lang}} "#!/bin/bash\n\n") + foreach(keyVal IN LISTS _ccacheEnv) + file(APPEND ${launch${_lang}} "export ${keyVal}\n") + endforeach() + file(APPEND ${launch${_lang}} + "exec \"${CCACHE_PROGRAM}\" " + "\"${CMAKE_${_lang}_COMPILER}\" \"$@\"\n" + ) + execute_process(COMMAND chmod a+rx ${launch${_lang}}) + endforeach() + set(CMAKE_XCODE_ATTRIBUTE_CC ${launchC} PARENT_SCOPE) + set(CMAKE_XCODE_ATTRIBUTE_CXX ${launchCXX} PARENT_SCOPE) + set(CMAKE_XCODE_ATTRIBUTE_LD ${launchC} PARENT_SCOPE) + set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS ${launchCXX} PARENT_SCOPE) + endif() + + if(NOT _enable_ccache_QUIET) + message(STATUS "Enabling ccache - done") + endif() +endfunction() diff --git a/cmake/documentation.cmake b/cmake/documentation.cmake index a886ca35..9213c9e6 100644 --- a/cmake/documentation.cmake +++ b/cmake/documentation.cmake @@ -49,7 +49,7 @@ function(add_documentation targetName) if(NOT _args_DOXYFILE_TEMPLATE) set(_args_DOXYFILE_TEMPLATE Doxyfile.in) endif() - file(REAL_PATH ${_args_DOXYFILE_TEMPLATE} _doxyfileIn) + get_filename_component(_doxyfileIn ${_args_DOXYFILE_TEMPLATE} REALPATH) if(NOT EXISTS ${_doxyfileIn}) message(FATAL_ERROR "'${_args_DOXYFILE_TEMPLATE}' does not exist") endif() diff --git a/cmake/include-what-you-use.cmake b/cmake/include-what-you-use.cmake index 8c0f81c5..41853ae6 100644 --- a/cmake/include-what-you-use.cmake +++ b/cmake/include-what-you-use.cmake @@ -30,53 +30,82 @@ endif() set(IWYU_VERBOSITY_LEVEL 3 CACHE STRING "IWYU verbosity level (the higher the level, the more output)") -macro(_find_iwyu) - find_program(_iwyu_path NAMES "include-what-you-use") - if(NOT _iwyu_path) - message(WARNING "'include-what-you-use' executable not found!") - return() - endif() -endmacro() - macro(_iwyu_args_append arg) list(APPEND _iwyu_args "-Xiwyu" "${arg}") endmacro() macro(_iwyu_args_append_if_present option arg) - if(_set_iwyu_${option}) + if(_enable_iwyu_${option}) _iwyu_args_append("${arg}") endif() endmacro() -macro(_process_iwyu_arguments offset) - set(_options NO_DEFAULT_MAPPINGS PCH_IN_CODE TRANSITIVE_INCLUDES_ONLY NO_COMMENTS NO_FORWARD_DECLARATIONS CXX17_NAMESPACES QUOTED_INCLUDES_FIRST) - set(_one_value_args MAPPING_FILE MAX_LINE_LENGTH) +macro(_enable_iwyu_failed log_postfix) + if(NOT _enable_iwyu_QUIET) + message(STATUS "Enabling include-what-you-use${log_postfix} - failed") + endif() + return() +endmacro() + +macro(_process_iwyu_arguments offset log_postfix) + set(_options QUIET REQUIRED NO_DEFAULT_MAPPINGS PCH_IN_CODE TRANSITIVE_INCLUDES_ONLY NO_COMMENTS NO_FORWARD_DECLARATIONS CXX17_NAMESPACES QUOTED_INCLUDES_FIRST) + set(_one_value_args PROGRAM MAPPING_FILE MAX_LINE_LENGTH) set(_multi_value_args KEEP) - cmake_parse_arguments(PARSE_ARGV ${offset} _set_iwyu "${_options}" "${_one_value_args}" "${_multi_value_args}") + cmake_parse_arguments(PARSE_ARGV ${offset} _enable_iwyu "${_options}" "${_one_value_args}" "${_multi_value_args}") # validate and process arguments - if(${prefix}_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Invalid arguments '${${prefix}_UNPARSED_ARGUMENTS}'") + if(_enable_iwyu_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid arguments '${_enable_iwyu_UNPARSED_ARGUMENTS}'") endif() - if(_set_iwyu_KEEP) - foreach(_pattern ${_set_iwyu_KEEP}) + if(_enable_iwyu_KEYWORDS_MISSING_VALUES) + message(FATAL_ERROR "No value provided for '${_enable_iwyu_KEYWORDS_MISSING_VALUES}'") + endif() + + if(NOT _enable_iwyu_QUIET) + message(STATUS "Enabling include-what-you-use${log_postfix}") + endif() + + if(${_enable_iwyu_REQUIRED}) + set(_error_log_level FATAL_ERROR) + elseif(NOT _enable_iwyu_QUIET) + set(_error_log_level STATUS) + endif() + + if(NOT DEFINED _enable_iwyu_PROGRAM) + set(_enable_iwyu_PROGRAM include-what-you-use) + endif() + + find_program(IWYU_PATH ${_enable_iwyu_PROGRAM}) + if(IWYU_PATH) + if(NOT _enable_iwyu_QUIET) + message(STATUS " Executable: ${IWYU_PATH}") + endif() + else() + if(DEFINED _error_log_level) + message(${_error_log_level} " '${_enable_iwyu_PROGRAM}' executable was not found") + endif() + _enable_iwyu_failed("${log_postfix}") + endif() + + if(_enable_iwyu_KEEP) + foreach(_pattern ${_enable_iwyu_KEEP}) _iwyu_args_append("--keep=${_pattern}") endforeach() endif() - if(_set_iwyu_MAPPING_FILE) - if(NOT EXISTS ${_set_iwyu_MAPPING_FILE}) - message(FATAL_ERROR "IWYU: Mapping file '${_set_iwyu_MAPPING_FILE}' does not exist") + if(_enable_iwyu_MAPPING_FILE) + if(NOT EXISTS ${_enable_iwyu_MAPPING_FILE}) + message(FATAL_ERROR "IWYU: Mapping file '${_enable_iwyu_MAPPING_FILE}' does not exist") endif() - _iwyu_args_append("--mapping_file=${_set_iwyu_MAPPING_FILE}") + _iwyu_args_append("--mapping_file=${_enable_iwyu_MAPPING_FILE}") endif() - if(_set_iwyu_MAX_LINE_LENGTH) - if(NOT _set_iwyu_MAX_LINE_LENGTH GREATER 0) - message(FATAL_ERROR "IWYU: Invalid MAX_LINE_LENGTH value = '${_set_iwyu_MAX_LINE_LENGTH}") + if(_enable_iwyu_MAX_LINE_LENGTH) + if(NOT _enable_iwyu_MAX_LINE_LENGTH GREATER 0) + message(FATAL_ERROR "IWYU: Invalid MAX_LINE_LENGTH value = '${_enable_iwyu_MAX_LINE_LENGTH}") endif() - _iwyu_args_append("--max_line_length=${_set_iwyu_MAX_LINE_LENGTH}") + _iwyu_args_append("--max_line_length=${_enable_iwyu_MAX_LINE_LENGTH}") endif() _iwyu_args_append_if_present(NO_DEFAULT_MAPPINGS "--no_default_mappings") @@ -88,55 +117,50 @@ macro(_process_iwyu_arguments offset) _iwyu_args_append_if_present(QUOTED_INCLUDES_FIRST "--quoted_includes_first") _iwyu_args_append("--verbose=${IWYU_VERBOSITY_LEVEL}") + + if(NOT _enable_iwyu_QUIET) + message(STATUS " Arguments: ${_iwyu_args}") + message(STATUS "Enabling include-what-you-use${log_postfix} - done") + endif() endmacro() # -# set_target_iwyu(TargetName -# [KEEP pattern...] -# [MAPPING_FILE file] -# [NO_DEFAULT_MAPPINGS] -# [PCH_IN_CODE] -# [TRANSITIVE_INCLUDES_ONLY] -# [MAX_LINE_LENGTH length] -# [NO_COMMENTS] -# [NO_FORWARD_DECLARATIONS] -# [CXX17_NAMESPACES] -# [QUOTED_INCLUDES_FIRST]) +# enable_iwyu([PROGRAM] # include-what-you-use by default +# [QUIET] [REQUIRED] +# [KEEP patterns...] +# [MAPPING_FILE file] +# [NO_DEFAULT_MAPPINGS] +# [PCH_IN_CODE] +# [TRANSITIVE_INCLUDES_ONLY] +# [MAX_LINE_LENGTH length] +# [NO_COMMENTS] +# [NO_FORWARD_DECLARATIONS] +# [CXX17_NAMESPACES] +# [QUOTED_INCLUDES_FIRST]) # -function(set_target_iwyu target) - _find_iwyu() - _process_iwyu_arguments(1) - - message(STATUS "Setting include-what-you-use for '${target}'") - message(STATUS " Path: ${_iwyu_path}") - message(STATUS " Arguments: ${_iwyu_args}") - message(STATUS "Setting include-what-you-use for '${target}' - done") +function(enable_iwyu) + _process_iwyu_arguments(0 "") + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${_iwyu_path};${_iwyu_args}" PARENT_SCOPE) +endfunction() +# +# enable_target_iwyu(TargetName +# [PROGRAM] # include-what-you-use by default +# [QUIET] [REQUIRED] +# [KEEP pattern...] +# [MAPPING_FILE file] +# [NO_DEFAULT_MAPPINGS] +# [PCH_IN_CODE] +# [TRANSITIVE_INCLUDES_ONLY] +# [MAX_LINE_LENGTH length] +# [NO_COMMENTS] +# [NO_FORWARD_DECLARATIONS] +# [CXX17_NAMESPACES] +# [QUOTED_INCLUDES_FIRST]) +# +function(enable_target_iwyu target) + _process_iwyu_arguments(1 " for '${target}'") set_target_properties(${target} PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "${_iwyu_path};${_iwyu_args}" ) endfunction() - -# -# set_target_iwyu([KEEP patterns...] -# [MAPPING_FILE file] -# [NO_DEFAULT_MAPPINGS] -# [PCH_IN_CODE] -# [TRANSITIVE_INCLUDES_ONLY] -# [MAX_LINE_LENGTH length] -# [NO_COMMENTS] -# [NO_FORWARD_DECLARATIONS] -# [CXX17_NAMESPACES] -# [QUOTED_INCLUDES_FIRST]) -# -function(set_iwyu) - _find_iwyu() - _process_iwyu_arguments(0) - - message(STATUS "Setting include-what-you-use") - message(STATUS " Path: ${_iwyu_path}") - message(STATUS " Arguments: ${_iwyu_args}") - message(STATUS "Setting include-what-you-use - done") - - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${_iwyu_path};${_iwyu_args}" PARENT_SCOPE) -endfunction() diff --git a/cmake/modern_project_structure.cmake b/cmake/modern_project_structure.cmake new file mode 100644 index 00000000..09debeb3 --- /dev/null +++ b/cmake/modern_project_structure.cmake @@ -0,0 +1,31 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Mateusz Pusz +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION 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.4) + +function(ensure_entry_point) + if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + message(FATAL_ERROR "'${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt' is meant to be used only " + "as a CMake entry point and should not be included from other CMake files. " + "Include '${CMAKE_CURRENT_SOURCE_DIR}/src/CMaskeLists.txt' directly instead.") + endif() +endfunction() diff --git a/cmake/warnings.cmake b/cmake/warnings.cmake index afe0da47..ce46d8bb 100644 --- a/cmake/warnings.cmake +++ b/cmake/warnings.cmake @@ -22,7 +22,7 @@ # Based on https://github.com/lefticus/cpp_starter_project/blob/master/cmake/CompilerWarnings.cmake -cmake_minimum_required(VERSION 3.3) +cmake_minimum_required(VERSION 3.15) option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" ON) @@ -90,8 +90,6 @@ macro(_set_flags) endif() if(MSVC) - string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE) set(flags ${MSVC_WARNINGS}) elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") set(flags ${CLANG_WARNINGS}) diff --git a/conanfile.py b/conanfile.py index 87d147ba..e3f2cbd8 100644 --- a/conanfile.py +++ b/conanfile.py @@ -22,7 +22,7 @@ from conans import ConanFile, tools from conans.tools import Version, check_min_cppstd -from conan.tools.cmake import CMakeToolchain, CMake, CMakeDeps +from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake from conans.errors import ConanInvalidConfiguration import os, re @@ -58,28 +58,27 @@ class UnitsConan(ConanFile): # } generators = "cmake_paths" - _cmake = None - @property def _run_tests(self): return tools.get_env("CONAN_RUN_TESTS", False) - def _configure_cmake(self): - if not self._cmake: - self._cmake = CMake(self) - if self._run_tests: - # developer's mode (unit tests, examples, documentation, restrictive compilation warnings, ...) - self._cmake.configure() - else: - # consumer's mode (library sources only) - self._cmake.configure(source_folder="src") - return self._cmake - def set_version(self): content = tools.load(os.path.join(self.recipe_folder, "src/CMakeLists.txt")) version = re.search(r"project\([^\)]+VERSION (\d+\.\d+\.\d+)[^\)]*\)", content).group(1) self.version = version.strip() + def requirements(self): + compiler = self.settings.compiler + if compiler == "clang" and compiler.libcxx == "libc++": + self.requires("range-v3/0.11.0") + + def build_requirements(self): + if self._run_tests: + self.build_requires("catch2/2.13.4") + self.build_requires("linear_algebra/0.7.1@conan-oss/stable") + if self.options.build_docs: + self.build_requires("doxygen/1.9.1") + def validate(self): compiler = self.settings.compiler version = Version(self.settings.compiler.version) @@ -102,20 +101,8 @@ class UnitsConan(ConanFile): # # build_docs has sense only in a development or CI build # del self.options.build_docs - def requirements(self): - compiler = self.settings.compiler - if compiler == "clang" and compiler.libcxx == "libc++": - self.requires("range-v3/0.11.0") - - def build_requirements(self): - if self._run_tests: - self.build_requires("catch2/2.13.4") - self.build_requires("linear_algebra/0.7.0@public-conan/stable") - if self.options.build_docs: - self.build_requires("doxygen/1.8.20") - def generate(self): - tc = CMakeToolchain(self) + tc = CMakeToolchain(self, generator=os.getenv("CONAN_CMAKE_GENERATOR")) tc.variables["UNITS_DOWNCAST_MODE"] = str(self.options.downcast_mode).upper() # if self._run_tests: # TODO Enable this when environment is supported in the Conan toolchain tc.variables["UNITS_BUILD_DOCS"] = self.options.build_docs @@ -124,14 +111,16 @@ class UnitsConan(ConanFile): deps.generate() def build(self): - cmake = self._configure_cmake() + cmake = CMake(self) + cmake.configure(source_folder=None if self._run_tests else "src") cmake.build() if self._run_tests: cmake.test(output_on_failure=True) def package(self): self.copy(pattern="LICENSE.md", dst="licenses") - cmake = self._configure_cmake() + cmake = CMake(self) + cmake.configure(source_folder=None if self._run_tests else "src") cmake.install() def package_id(self): diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index da20f0cd..ad028535 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,12 +1,19 @@ # Release notes -- **0.7.0 WIP** +- **0.8.0 WIP** + - (!) fix: add `quantity_point::origin`, like `std::chrono::time_point::clock` + - fix: account for different dimensions in `quantity_point_cast`'s constraint + - build: doxygen updated to 1.9.1 + - build: linear_algebra updated to 0.7.1 + +- **0.7.0 May 11, 2021** - (!) refactor: `ScalableNumber` renamed to `Representation` - (!) refactor: output stream operators moved to the `units/quantity_io.h` header file - (!) refactor: Refactored the library file tree - (!) refactor: `quantity::count()` renamed to `quantity::number()` - (!) refactor: `data` system renamed to `isq::iec80000` (quantity names renamed too) - - (!) refactor: quantity UDLs support has to be enabled with `UNITS_LITERALS` preprocessor define + - (!) refactor: `*deduced_unit` renamed to `*derived_unit` + - (!) refactor: got rid of a `noble_derived_unit` - refactor: quantity (kind) point updated to reflect latest changes to `quantity` - refactor: basic concepts, `quantity` and `quantity_cast` refactored - refactor: `abs()` definition refactored to be more explicit about the return type @@ -17,12 +24,15 @@ - feat: CTAD for dimensionless quantity added - feat: `modulation_rate` support added (thanks [@go2sh](https://github.com/go2sh)) - feat: SI prefixes for `isq::iec80000` support added (thanks [@go2sh](https://github.com/go2sh)) + - feat: a possibility to disable quantity UDLs support with `UNITS_NO_LITERALS` preprocessor define + - feat: a support to define ISQ derived dimensions in terms of different number or order of components - perf: preconditions check do not influence the runtime performance of a Release build - perf: `quantity_cast()` generates less assembly instructions - perf: temporary string creation removed from `quantity::op<<()` - perf: value initialization for quantity value removed (left with a default initialization) - perf: limited the `equivalent` trait usage - perf: limited the C++ Standard Library headers usage + - perf: rvalue references support added for constructors and getters - (!) fix: `exp()` has sense only for dimensionless quantities - (!) fix: `dim_torque` now properly divides by an angle (instead of multiply) + default unit name change - fix: quantity's operators fixed to behave like the underlying types do @@ -30,7 +40,10 @@ - fix: ambiguous case for empty type list resolved - fix: downcasting facility for non-default-constructible types - fix: restore user-warnings within the library implementation + - fix: the text symbol of `foot_pound_force` and `foot_pound_force_per_second` + - fix: quantity modulo arithmetics fixed - (!) build: Conan testing version is now hosted on [Artifactory](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units) + - (!) build: Linear Algebra is now hosted on its [Artifactory](https://twonington.jfrog.io/artifactory/api/conan/conan-oss) - (!) build: `BUILD_DOCS` CMake option renamed to `UNITS_BUILD_DOCS` - build: doxygen updated to 1.8.20 - build: catch2 updated to 2.13.4 @@ -39,6 +52,7 @@ - build: Conan generator switched to `cmake_find_package_multi` - build: Conan CMakeToolchain support added - build: CMake scripts cleanup + - build: ccache support added - ci: CI switched from Travis CI to GitHub Actions - **0.6.0 September 13, 2020** diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index ce627992..9dec7d17 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -91,15 +91,3 @@ WARN_AS_ERROR = NO # The default value is: NO. QUIET = YES - -# The PREDEFINED tag can be used to specify one or more macro names that are -# defined before the preprocessor is started (similar to the -D option of e.g. -# gcc). The argument of the tag is a list of macros of the form: name or -# name=definition (no spaces). If the definition and the "=" are omitted, "=1" -# is assumed. To prevent a macro definition from being undefined via #undef or -# recursively expanded use the := operator instead of the = operator. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -PREDEFINED = UNITS_REFERENCES \ - UNITS_LITERALS \ - UNITS_ALIASES diff --git a/docs/_static/img/concepts.png b/docs/_static/img/concepts.png index 37677310..e8083e02 100644 Binary files a/docs/_static/img/concepts.png and b/docs/_static/img/concepts.png differ diff --git a/docs/_static/img/units.png b/docs/_static/img/units.png index 40727db1..41296df3 100644 Binary files a/docs/_static/img/units.png and b/docs/_static/img/units.png differ diff --git a/docs/examples/basics/avg_speed.rst b/docs/examples/basics/avg_speed.rst index 9eceb60a..46906984 100644 --- a/docs/examples/basics/avg_speed.rst +++ b/docs/examples/basics/avg_speed.rst @@ -1,7 +1,7 @@ avg_speed ========= -.. literalinclude:: ../../example/references/avg_speed.cpp +.. literalinclude:: ../../../example/references/avg_speed.cpp :caption: avg_speed.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/box_example.rst b/docs/examples/basics/box_example.rst index 86fb9b7c..c75116d3 100644 --- a/docs/examples/basics/box_example.rst +++ b/docs/examples/basics/box_example.rst @@ -1,7 +1,7 @@ box_example =========== -.. literalinclude:: ../../example/references/box_example.cpp +.. literalinclude:: ../../../example/references/box_example.cpp :caption: box_example.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/capacitor_time_curve.rst b/docs/examples/basics/capacitor_time_curve.rst index 26fdf7cd..ea9e4f58 100644 --- a/docs/examples/basics/capacitor_time_curve.rst +++ b/docs/examples/basics/capacitor_time_curve.rst @@ -1,7 +1,7 @@ capacitor_time_curve ==================== -.. literalinclude:: ../../example/references/capacitor_time_curve.cpp +.. literalinclude:: ../../../example/references/capacitor_time_curve.cpp :caption: capacitor_time_curve.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/clcpp_response.rst b/docs/examples/basics/clcpp_response.rst index e77b4189..417b8ac0 100644 --- a/docs/examples/basics/clcpp_response.rst +++ b/docs/examples/basics/clcpp_response.rst @@ -1,7 +1,7 @@ clcpp_response ============== -.. literalinclude:: ../../example/references/clcpp_response.cpp +.. literalinclude:: ../../../example/references/clcpp_response.cpp :caption: clcpp_response.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/experimental_angle.rst b/docs/examples/basics/experimental_angle.rst index 46a970e9..71c060b3 100644 --- a/docs/examples/basics/experimental_angle.rst +++ b/docs/examples/basics/experimental_angle.rst @@ -1,7 +1,7 @@ experimental_angle ================== -.. literalinclude:: ../../example/references/experimental_angle.cpp +.. literalinclude:: ../../../example/references/experimental_angle.cpp :caption: experimental_angle.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/foot_pound_second.rst b/docs/examples/basics/foot_pound_second.rst index ba10e747..9d15c786 100644 --- a/docs/examples/basics/foot_pound_second.rst +++ b/docs/examples/basics/foot_pound_second.rst @@ -1,7 +1,7 @@ foot_pound_second ================= -.. literalinclude:: ../../example/references/foot_pound_second.cpp +.. literalinclude:: ../../../example/references/foot_pound_second.cpp :caption: foot_pound_second.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/glide_computer.rst b/docs/examples/basics/glide_computer.rst index 5595bb37..b4139cc2 100644 --- a/docs/examples/basics/glide_computer.rst +++ b/docs/examples/basics/glide_computer.rst @@ -13,7 +13,7 @@ This example presents the usage of: - quantities text output formatting, - cooperation with `std::chrono`. -.. literalinclude:: ../../example/glide_computer/include/glide_computer.h +.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h :caption: glide_computer.h :start-at: #include :end-before: using namespace units; @@ -35,7 +35,7 @@ For example we have 3 for a quantity of length: - ``height`` - a relative altitude difference between 2 points in the air - ``altitude`` - an absolute altitude value measured form the mean sea level (AMSL). -.. literalinclude:: ../../example/glide_computer/include/glide_computer.h +.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h :caption: glide_computer.h :start-at: using namespace units; :end-before: // text output @@ -44,7 +44,7 @@ For example we have 3 for a quantity of length: Next a custom text output is provided both for C++ output streams and the text formatting facility. -.. literalinclude:: ../../example/glide_computer/include/glide_computer.h +.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h :caption: glide_computer.h :start-at: // text output :end-before: // definition of glide computer databases and utilities @@ -58,13 +58,13 @@ convert it to the one required by the engine interface. The glide calculator takes task created as a list of waypoints, glider performance data, weather conditions, safety constraints, and a towing height. -.. literalinclude:: ../../example/glide_computer/include/glide_computer.h +.. literalinclude:: ../../../example/glide_computer/include/glide_computer.h :caption: glide_computer.h :start-at: // definition of glide computer databases and utilities :linenos: :lineno-match: -.. literalinclude:: ../../example/references/glide_computer_example.cpp +.. literalinclude:: ../../../example/references/glide_computer_example.cpp :caption: glide_computer_example.cpp :start-at: #include :linenos: @@ -74,7 +74,7 @@ Having all of that it estimates the number of flight phases (towing, circling, g needed to finish a task. As an output it provides the duration needed to finish the task while flying a selected glider in the specific weather conditions. -.. literalinclude:: ../../example/glide_computer/glide_computer.cpp +.. literalinclude:: ../../../example/glide_computer/glide_computer.cpp :caption: glide_computer.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/hello_units.rst b/docs/examples/basics/hello_units.rst index a6b50b90..ab33ce32 100644 --- a/docs/examples/basics/hello_units.rst +++ b/docs/examples/basics/hello_units.rst @@ -1,7 +1,7 @@ hello_units =========== -.. literalinclude:: ../../example/hello_units.cpp +.. literalinclude:: ../../../example/hello_units.cpp :caption: hello_units.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/total_energy.rst b/docs/examples/basics/total_energy.rst index 1ea5627e..f65cc23d 100644 --- a/docs/examples/basics/total_energy.rst +++ b/docs/examples/basics/total_energy.rst @@ -1,7 +1,7 @@ total_energy ============ -.. literalinclude:: ../../example/references/total_energy.cpp +.. literalinclude:: ../../../example/references/total_energy.cpp :caption: total_energy.cpp :start-at: #include :linenos: diff --git a/docs/examples/basics/unknown_dimension.rst b/docs/examples/basics/unknown_dimension.rst index 9d39427b..27876666 100644 --- a/docs/examples/basics/unknown_dimension.rst +++ b/docs/examples/basics/unknown_dimension.rst @@ -1,7 +1,7 @@ unknown_dimension ================= -.. literalinclude:: ../../example/references/unknown_dimension.cpp +.. literalinclude:: ../../../example/references/unknown_dimension.cpp :caption: unknown_dimension.cpp :start-at: #include :linenos: diff --git a/docs/examples/custom_representation/linear_algebra.rst b/docs/examples/custom_representation/linear_algebra.rst index 07f4c0fc..9bb9ac1e 100644 --- a/docs/examples/custom_representation/linear_algebra.rst +++ b/docs/examples/custom_representation/linear_algebra.rst @@ -1,7 +1,7 @@ linear_algebra ============== -.. literalinclude:: ../../example/references/linear_algebra.cpp +.. literalinclude:: ../../../example/references/linear_algebra.cpp :caption: linear_algebra.cpp :start-at: #include :linenos: diff --git a/docs/examples/custom_representation/measurement.rst b/docs/examples/custom_representation/measurement.rst index c0496e1e..da278975 100644 --- a/docs/examples/custom_representation/measurement.rst +++ b/docs/examples/custom_representation/measurement.rst @@ -1,7 +1,7 @@ measurement =========== -.. literalinclude:: ../../example/measurement.cpp +.. literalinclude:: ../../../example/measurement.cpp :caption: measurement.cpp :start-at: #include :linenos: diff --git a/docs/examples/custom_systems/custom_systems.rst b/docs/examples/custom_systems/custom_systems.rst index a4e93583..673bb0b2 100644 --- a/docs/examples/custom_systems/custom_systems.rst +++ b/docs/examples/custom_systems/custom_systems.rst @@ -1,7 +1,7 @@ custom_systems ============== -.. literalinclude:: ../../example/custom_systems.cpp +.. literalinclude:: ../../../example/custom_systems.cpp :caption: custom_systems.cpp :start-at: #include :linenos: diff --git a/docs/examples/custom_utilities/conversion_factor.rst b/docs/examples/custom_utilities/conversion_factor.rst index 21bbefc5..79de28d2 100644 --- a/docs/examples/custom_utilities/conversion_factor.rst +++ b/docs/examples/custom_utilities/conversion_factor.rst @@ -1,7 +1,7 @@ conversion_factor ================= -.. literalinclude:: ../../example/conversion_factor.cpp +.. literalinclude:: ../../../example/conversion_factor.cpp :caption: conversion_factor.cpp :start-at: #include :linenos: diff --git a/docs/framework/basic_concepts.rst b/docs/framework/basic_concepts.rst index ddff3461..bb3f9708 100644 --- a/docs/framework/basic_concepts.rst +++ b/docs/framework/basic_concepts.rst @@ -23,7 +23,7 @@ The most important concepts in the library are `Unit`, `Dimension`, ] [QuantityPoint| - [quantity_point] + [quantity_point] ] [QuantityKind| @@ -39,6 +39,10 @@ The most important concepts in the library are `Unit`, `Dimension`, [Unit]<-[Quantity] [Quantity]<-[QuantityPoint] + [PointOrigin]<-[QuantityPoint] + [Dimension]<-[PointOrigin] + [PointOrigin]<-[PointKind] + [Kind]<-[QuantityKind] [Dimension]<-[Kind] [Quantity]<-[QuantityKind] @@ -60,7 +64,7 @@ derived dimensions. Examples: ``si::dim_time``, ``si::dim_length``, ``si::dim_sp specific representation. Examples: ``quantity``, ``si::length``, ``si::speed``. -`QuantityPoint` is an absolute `Quantity` with respect to some origin. +`QuantityPoint` is an absolute `Quantity` with respect to an origin. Examples: timestamp (as opposed to duration), absolute temperature (as opposed to temperature difference). @@ -68,6 +72,6 @@ Examples: timestamp (as opposed to duration), absolute temperature distance (``horizonal_kind``) and height (``vertical_kind``) are different kinds of a length quantity. -`QuantityPointKind` is an absolute `QuantityKind` with respect to some origin. +`QuantityPointKind` is an absolute `QuantityKind` with respect to an origin. Examples: altitude is a quantity point of ``vertical_kind`` (as opposed to height). diff --git a/docs/framework/dimensions.rst b/docs/framework/dimensions.rst index 344912a6..4a8ab10a 100644 --- a/docs/framework/dimensions.rst +++ b/docs/framework/dimensions.rst @@ -77,7 +77,7 @@ you can use a quantity argument instead of a quantity kind. :emphasize-lines: 8-9 struct height_kind : kind {}; - struct rate_of_climb_kind : derived_kind {}; + struct rate_of_climb_kind : derived_kind {}; template using height = quantity_kind; template using rate_of_climb = quantity_kind; @@ -90,7 +90,7 @@ you can use a quantity argument instead of a quantity kind. :emphasize-lines: 8-12 struct width_kind : kind {}; - struct horizontal_area_kind : derived_kind {}; + struct horizontal_area_kind : derived_kind {}; template using width = quantity_kind; template using horizontal_area = quantity_kind; @@ -106,8 +106,9 @@ Quantity Points +++++++++++++++ Quantity points have a more restricted set of operations. -Quantity can be added to or subtracted from a quantity point. -The result will always be a quantity point of the same dimension: +Quantity can be added to or subtracted +from a quantity point of the same origin. +The result will always be a quantity point of the same origin: .. code-block:: :emphasize-lines: 3-5 @@ -132,9 +133,10 @@ The result is a relative quantity of the same dimension: It is not allowed to: - - add quantity points - - subtract a quantity point from a quantity: - - multiply nor divide quantity points with anything else. + - add quantity points, + - subtract a quantity point from a quantity, + - multiply nor divide quantity points with anything else, and + - mix quantity points with different origins: .. code-block:: :emphasize-lines: 3-5 @@ -144,6 +146,8 @@ The result is a relative quantity of the same dimension: auto res1 = quantity_point{dist1} + quantity_point{dist2}; // ERROR auto res2 = dist1 - quantity_point{dist2}; // ERROR auto res3 = quantity_point{dist1} / (2 * s); // ERROR + auto res4 = quantity_point{std::chrono::utc_second{1s}} + + quantity_point{std::chrono::sys_second{1s}}; // ERROR Quantity Point Kinds ++++++++++++++++++++ diff --git a/docs/framework/quantities.rst b/docs/framework/quantities.rst index 23786c50..ea880ac2 100644 --- a/docs/framework/quantities.rst +++ b/docs/framework/quantities.rst @@ -70,7 +70,7 @@ Unit-Specific Aliases (Experimental) Additionally to the dimension-specific aliases there are also ones provided for each and every :term:`unit` in the library:: - #ifdef UNITS_ALIASES + #ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline length { @@ -86,7 +86,7 @@ each and every :term:`unit` in the library:: } - #endif // UNITS_ALIASES + #endif // UNITS_NO_ALIASES Using the above our code can look as follows:: @@ -116,7 +116,7 @@ Quantity References (Experimental) Quantity References provide an alternative and simplified way to create quantities. They are defined using the `reference` class template:: - #ifdef UNITS_REFERENCES + #ifndef UNITS_NO_REFERENCES namespace length_references { @@ -131,7 +131,7 @@ They are defined using the `reference` class template:: } // namespace references - #endif // UNITS_REFERENCES + #endif // UNITS_NO_REFERENCES With the above our code can look as follows:: @@ -157,7 +157,7 @@ User Defined Literals (Experimental) Alternatively, to construct quantities with compile-time known values the library provides :abbr:`UDL (User Defined Literal)` s for each :term:`unit` of every :term:`dimension`:: - #ifdef UNITS_LITERALS + #ifndef UNITS_NO_LITERALS inline namespace literals { @@ -169,7 +169,7 @@ Alternatively, to construct quantities with compile-time known values the librar } - #endif // UNITS_LITERALS + #endif // UNITS_NO_LITERALS Thanks to them the same code can be as simple as:: @@ -185,13 +185,6 @@ Thanks to them the same code can be as simple as:: language (i.e. ``F`` (farad), ``J`` (joule), ``W`` (watt), ``K`` (kelvin), ``d`` (day), ``l`` or ``L`` (litre), ``erg``, ``ergps``). This is why the ``_q_`` prefix was consistently applied to all the UDLs. - -.. important:: - - As one can read in the next section UDLs, are considered to be inferior to `Quantity References`_ - and their definition affects compile-time performance a lot. This is why they are an opt-in feature - of the library and in order to use them one has to provide a `UNITS_LITERALS` preprocessor definition. - UDLs vs Quantity References +++++++++++++++++++++++++++ @@ -473,6 +466,19 @@ Summary +-----------------------------------------------+-------------+------------+---------------+ +Don't pay for what you don't use (compile-time performance) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +As noted in the previous chapter, each quantity creation helper has a different impact on the compile-time +performance. Aliases tend to be the fastest to compile but even their definition can be expensive for some +if it is not used in the source code. This is why it is possible to opt-out from each or every quantity +creation helper with the following preprocessor defines:: + + #define UNITS_NO_ALIASES + #define UNITS_NO_REFERENCES + #define UNITS_NO_LITERALS + + Dimension-specific Concepts --------------------------- diff --git a/docs/framework/quantity_points.rst b/docs/framework/quantity_points.rst index 9fd23af1..a13ee71b 100644 --- a/docs/framework/quantity_points.rst +++ b/docs/framework/quantity_points.rst @@ -3,9 +3,20 @@ Quantity Points =============== -A quantity point is an absolute quantity with respect to zero -(which represents some origin) and is represented in the library with a -`quantity_point` class template. +A quantity point is an absolute quantity with respect to an origin +and is represented in the library with a `quantity_point` class template. + +Point Origins +------------- + +We need a `point_origin` to represent the origin of a quantity point:: + + struct mean_sea_level : point_origin {}; + +Quantities points with this origin represent a point from the mean sea level. + +The library offers a `dynamic_origin` +for quantity points whose origin is not specified in the type system. Construction @@ -14,7 +25,7 @@ Construction To create the quantity point object from a `quantity` we just have to pass the value to the `quantity_point` class template explicit constructor:: - quantity_point d(123 * km); + quantity_point, si::kilometre, double> d(123 * km); .. note:: @@ -25,7 +36,7 @@ the value to the `quantity_point` class template explicit constructor:: `copy initialization `_ **does not compile**:: - quantity_point d = 123 * km; // ERROR + quantity_point, si::kilometre, double> d = 123 * km; // ERROR Differences To Quantity diff --git a/docs/framework/units.rst b/docs/framework/units.rst index c4f8380d..014e57a7 100644 --- a/docs/framework/units.rst +++ b/docs/framework/units.rst @@ -8,7 +8,7 @@ compare quantities of the same dimension a notion of a :term:`measurement unit` was introduced. Units are designated by conventionally assigned names and symbols. Thanks to them it is possible to compare two quantities of the same dimension and express the ratio of the second quantity to the first -one as a number. For example ``10s`` is ``10`` times more than ``1s``. +one as a number. For example ``10 s`` is ``10`` times more than ``1 s``. Base quantities are expressed in terms of :term:`base units ` (i.e. ``m`` (meter), ``s`` (second)), while derived quantities are expressed @@ -94,97 +94,14 @@ knows how to convert ``si::metre`` to ``si::centimetre`` and vice versa). :ref:`use_cases/extensions:Custom Systems` chapter. -Derived Units -------------- - -Derived units can be either named or unnamed. - -Derived Named Units -^^^^^^^^^^^^^^^^^^^ - -Derived named units have a unique symbol (i.e. ``N`` (newton) or ``Pa`` -(pascal)) and they are defined in the same way as base units (which -always have to be a named unit):: - - namespace si { - - struct newton : named_unit {}; - - } - - -Derived Unnamed Units -^^^^^^^^^^^^^^^^^^^^^ - -Derived unnamed units are the units where the symbol is derived from the -base quantities symbols and the expression of the dependence of the derived -quantity on the base quantities (i.e. ``m/s`` (metre per second), ``m²`` -(square metre)). To support such use cases a library introduced a notion of -:term:`derived dimension recipe` which stores the information about the -order, exponents, and types of dimensions used to defined this particular -derived dimension. For example each of the below ``momentum`` definitions -will result in a different unnamed unit symbol: - -.. code-block:: - :emphasize-lines: 2-4, 6-8, 10-12 - - struct dim_momentum : derived_dimension, - exponent, - exponent> {}; // kg ⋅ m/s - struct dim_momentum : derived_dimension, - exponent, - exponent> {}; // m ⋅ kg/s - struct dim_momentum : derived_dimension, - exponent, - exponent> {}; // 1/s ⋅ m ⋅ kg - -where ``kilogram_metre_per_second`` is defined as:: - - struct kilogram_metre_per_second : unit {}; - -However, the easiest way to define momentum is just to use the -``si::dim_speed`` derived dimension in the recipe: - -.. code-block:: - :emphasize-lines: 3 - - struct dim_momentum : derived_dimension, - exponent> {}; // kg ⋅ m/s - -In such a case the library will do its magic and will automatically -unpack a provided derived dimension to its base dimensions in order to -end up with a :term:`normalized derived dimension` for a parent entity. - - -The need to support a derived dimension in the recipe is not just a -syntactic sugar that allows us to do less typing. It is worth to notice -here that some of the derived unnamed units are defined in terms of other -derived named units (i.e. surface tension quantity is measured in terms -of ``N/m``): - -.. code-block:: - :emphasize-lines: 2 - - struct dim_surface_tension : derived_dimension, - exponent> {}; // N/m - -If we defined the above in terms of base units we would end up with -a ``kg/s²`` derived unit symbol. - - Scaled Units ------------ -Until now we talked mostly about -:term:`coherent units ` which are units used to -define dimensions and thus, in their system of units, have proportionality -factor/ratio equals one. However quantities of each dimension can also use -other units of measurement to describe their magnitude (numerical value). +Described above base units (in case of base quantities) and +:term:`coherent units ` (in case of derived quantities), +in their system of units, have proportionality factor/ratio equal to one. +However, quantities of such dimensions can also use units of measurement +with other ratios to describe their magnitude (numerical value). Named Scaled Units @@ -289,13 +206,99 @@ example we can define ``si::kilometre`` as:: as ``km²`` would be invalid). -Deduced Units -^^^^^^^^^^^^^ +Derived Units +------------- + +:term:`Derived units ` are the units used to measure +:term:`derived quantities `. They can either have their own unique +names (i.e. ``N`` (newton)) or can be composed from the names of units of quantities +used to define thier derived quantity (i.e. ``km/h``). + + +Derived Named Units +^^^^^^^^^^^^^^^^^^^ + +Derived named units have a unique symbol (i.e. ``N`` (newton) or ``Pa`` +(pascal)) and they are defined in the same way as base units (which +always have to be a named unit):: + + namespace si { + + struct newton : named_unit {}; + + } + + +Derived Unnamed Units +^^^^^^^^^^^^^^^^^^^^^ + +Derived unnamed units are the units where the symbol is derived from the +base quantities symbols and the expression of the dependence of the derived +quantity on the base quantities (i.e. ``m/s`` (metre per second), ``m²`` +(square metre)). To support such use cases a library introduced a notion of +:term:`derived dimension recipe` which stores the information about the +order, exponents, and types of dimensions used to define this particular +derived dimension. For example each of the below ``momentum`` definitions +will result in a different unnamed unit symbol: + +.. code-block:: + :emphasize-lines: 2-4, 6-8, 10-12 + + struct dim_momentum : derived_dimension, + exponent, + exponent> {}; // kg ⋅ m/s + struct dim_momentum : derived_dimension, + exponent, + exponent> {}; // m ⋅ kg/s + struct dim_momentum : derived_dimension, + exponent, + exponent> {}; // 1/s ⋅ m ⋅ kg + +where ``kilogram_metre_per_second`` is defined as:: + + struct kilogram_metre_per_second : unit {}; + +However, the easiest way to define momentum is just to use the +``si::dim_speed`` derived dimension in the recipe: + +.. code-block:: + :emphasize-lines: 3 + + struct dim_momentum : derived_dimension, + exponent> {}; // kg ⋅ m/s + +In such a case the library will do its magic and will automatically +unpack a provided derived dimension to its base dimensions in order to +end up with a :term:`normalized derived dimension` for a parent entity. + +The need to support a derived dimension in the recipe is not just a +syntactic sugar that allows us to do less typing. It is worth to notice +here that some of the derived unnamed units are defined in terms of other +derived named units (i.e. surface tension quantity is measured in terms +of ``N/m``): + +.. code-block:: + :emphasize-lines: 2 + + struct dim_surface_tension : derived_dimension, + exponent> {}; // N/m + +If we defined the above in terms of base units we would end up with +a ``kg/s²`` derived unit symbol. + + +Derived Scaled Units +^^^^^^^^^^^^^^^^^^^^ For some units determining of a correct scaling ratio may not be trivial, and even if done correctly, may be a pain to maintain. For a simple example let's take a "kilometre per hour" unit. What is the easiest to maintain -ratio in reference to "metre per second": +ratio in reference to the "metre per second": - ``1000/3600`` - ``10/36`` @@ -303,30 +306,27 @@ ratio in reference to "metre per second": Whichever, we choose there will always be someone not happy with our choice. -Thanks to a `deduced_unit` class template provided by the library this problem +Thanks to a `derived_unit` class template provided by the library this problem does not exist at all. With it ``si::kilometre_per_hour`` can be defined as:: namespace si { - struct kilometre_per_hour : deduced_unit {}; + struct kilometre_per_hour : derived_unit {}; } -In case the deduced unit should served as a named one we can use ether a -`named_deduced_unit` where the user is able to provide a symbol for the unit -by him/her-self or `noble_deduced_unit` where the symbol is the deduced name -based on the ingredients:: +In case the scaled derived unit should serve as a named one we can use +a `named_derived_unit` where the user is able to provide a symbol for the unit +by him/her-self:: namespace si::fps { - struct nautical_mile_per_hour : named_deduced_unit{}; - struct foot_pound_force : noble_deduced_unit {}; + struct knot : named_derived_unit {}; } -Please note that deduced units are the only unit-related class template that -take a dimension as its parameter. This derived dimension provides a :term:`recipe` +Please note that the dervided scaled units are the only unit-related class templates +that take a dimension as its parameter. This derived dimension provides a :term:`recipe` used for its definition. Based on the information stored in the recipe (order, type, and exponents of composite dimensions) and the ratios of units provided in the template parameter list after the derived dimension parameter, @@ -377,9 +377,8 @@ of a `scaled_unit` class template: [scaled_unit]<:-[named_unit] [scaled_unit]<:-[named_scaled_unit] [scaled_unit]<:-[prefixed_unit] - [scaled_unit]<:-[deduced_unit] - [scaled_unit]<:-[noble_deduced_unit] - [scaled_unit]<:-[named_deduced_unit] + [scaled_unit]<:-[derived_unit] + [scaled_unit]<:-[named_derived_unit] [scaled_unit]<:-[alias_unit] [scaled_unit]<:-[prefixed_alias_unit] diff --git a/docs/quick_start.rst b/docs/quick_start.rst index cced0d9b..54168803 100644 --- a/docs/quick_start.rst +++ b/docs/quick_start.rst @@ -3,8 +3,6 @@ Quick Start Here is a small example of possible operations:: - #define UNITS_REFERENCES - #include #include #include @@ -34,7 +32,7 @@ Here is a small example of possible operations:: .. admonition:: Try it on Compiler Explorer - `Example #1 `_ + `Example #1 `_ This library requires some C++20 features (concepts, classes as :abbr:`NTTP (Non-Type Template Parameter)`, ...). Thanks to them the user gets a powerful @@ -42,10 +40,6 @@ but still easy to use interface where all unit conversions and dimensional analy performed without sacrificing on accuracy. Please see the below example for a quick preview of basic library features:: - #define UNITS_ALIASES - #define UNITS_LITERALS - #define UNITS_REFERENCES - #include #include #include @@ -92,7 +86,7 @@ of basic library features:: .. admonition:: Try it on Compiler Explorer - `Example #2 `_ + `Example #2 `_ .. seealso:: diff --git a/docs/reference/core/types/units.rst b/docs/reference/core/types/units.rst index c7ad4b1d..897fcc85 100644 --- a/docs/reference/core/types/units.rst +++ b/docs/reference/core/types/units.rst @@ -16,13 +16,10 @@ Units .. doxygenstruct:: units::prefixed_unit :members: -.. doxygenstruct:: units::deduced_unit +.. doxygenstruct:: units::derived_unit :members: -.. doxygenstruct:: units::noble_deduced_unit - :members: - -.. doxygenstruct:: units::named_deduced_unit +.. doxygenstruct:: units::named_derived_unit :members: .. doxygenstruct:: units::alias_unit diff --git a/docs/usage.rst b/docs/usage.rst index e074f941..c753f22f 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -92,7 +92,6 @@ in *~/.conan/profiles* directory. An example profile can look as follows: [env] CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 - CONAN_CMAKE_GENERATOR=Ninja .. tip:: @@ -248,7 +247,7 @@ library release the following steps may be performed: :caption: conanfile.txt [requires] - mp-units/0.6.0 + mp-units/0.7.0 [generators] CMakeToolchain @@ -279,7 +278,7 @@ library release the following steps may be performed: .. code-block:: shell - mkdir build && cd build + mkdir my_project/build && cd my_project/build conan install .. -pr -s compiler.cppstd=20 -b=missing cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake cmake --build . @@ -314,7 +313,7 @@ differences: :caption: conanfile.txt [requires] - mp-units/0.7.0@mpusz/testing + mp-units/0.8.0@mpusz/testing [generators] CMakeToolchain @@ -330,12 +329,27 @@ differences: .. code-block:: shell - mkdir build && cd build + mkdir my_project/build && cd my_project/build conan install .. -pr -s compiler.cppstd=20 -b=outdated -u cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake cmake --build . +Install +^^^^^^^ + +In case you don't want to use Conan in your project and just want to install the **mp-units** +library on your file system and use it via ``find_package(mp-units)`` from another repository +to find it, it is enough to perform the following steps: + +.. code-block:: shell + + mkdir units/build && cd units/build + conan install .. -pr -s compiler.cppstd=20 -b=missing + cmake ../src -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake + cmake --install . --prefix + + Contributing (or just building all the tests, examples, and documentation) -------------------------------------------------------------------------- @@ -349,10 +363,10 @@ in **mp-units** repository, you should: .. code-block:: shell - conan remote add linear-algebra https://api.bintray.com/conan/twonington/public-conan + conan remote add linear-algebra https://twonington.jfrog.io/artifactory/api/conan/conan-oss git clone https://github.com/mpusz/units.git && cd units pip3 install -r docs/requirements.txt - mkdir build && cd build + mkdir units/build && cd units/build conan install .. -pr -s compiler.cppstd=20 -e mp-units:CONAN_RUN_TESTS=True -b outdated -u conan build .. @@ -387,4 +401,4 @@ Uploading **mp-units** Package to the Conan Server .. code-block:: shell - conan upload -r --all mp-units/0.7.0@/ + conan upload -r --all mp-units/0.8.0@/ diff --git a/docs/use_cases/extensions.rst b/docs/use_cases/extensions.rst index 7c3f3305..9e07a92a 100644 --- a/docs/use_cases/extensions.rst +++ b/docs/use_cases/extensions.rst @@ -118,7 +118,7 @@ coherent unit:: exponent, exponent> {}; // our unit of interest for a new derived dimension - struct desk_per_hour : deduced_unit {}; + struct desk_per_hour : derived_unit {}; // a quantity of our dimension template U, Representation Rep = double> @@ -167,7 +167,7 @@ With the above we can now define a new derived dimension:: exponent, exponent> {}; - struct person_per_desk : deduced_unit {}; + struct person_per_desk : derived_unit {}; template U, Representation Rep = double> using occupancy_rate = quantity; diff --git a/docs/use_cases/interoperability.rst b/docs/use_cases/interoperability.rst index c5cf5fed..1fd7685c 100644 --- a/docs/use_cases/interoperability.rst +++ b/docs/use_cases/interoperability.rst @@ -56,11 +56,12 @@ such an explicit conversion:: For external quantity point-like types, `quantity_point_like_traits` is also provided. It works just like `quantity_like_traits`, except that -``number(T)`` is replaced with ``relative(T)`` that returns the `QuantityLike` value. +``number(T)`` is replaced with ``relative(T)`` that returns the `QuantityLike` value +and ``dimension`` is replaced with ``origin``. Similar to `quantity` and `quantity_kind`, `quantity_point` and `quantity_kind_point` provide a deduction guide from `QuantityPointLike`:: using namespace std::chrono_literals; - static_assert(quantity_point{std::chrono::sys_seconds{1s}} + 1 * s == quantity_point{2s}); + static_assert((quantity_point{std::chrono::sys_seconds{1s}} + 1 * s).relative() == 2s); diff --git a/docs/use_cases/linear_algebra.rst b/docs/use_cases/linear_algebra.rst index 4d2d9ae3..f1f66f37 100644 --- a/docs/use_cases/linear_algebra.rst +++ b/docs/use_cases/linear_algebra.rst @@ -11,7 +11,7 @@ enough to be used with other Linear Algebra libraries existing on the market. All of the examples provided in this chapter refer to the official proposal of the Linear Algebra Library for the C++23 defined in `P1385 `_ and its latest implementation from `GitHub `_ - or `Conan `_. + or `Conan `_. Also, to simplify the examples all of them assume:: using namespace std::math; diff --git a/example/aliases/CMakeLists.txt b/example/aliases/CMakeLists.txt index a65f3e4d..331b6a84 100644 --- a/example/aliases/CMakeLists.txt +++ b/example/aliases/CMakeLists.txt @@ -28,7 +28,10 @@ cmake_minimum_required(VERSION 3.2) function(add_example target) add_executable(${target}-aliases ${target}.cpp) target_link_libraries(${target}-aliases PRIVATE ${ARGN}) - target_compile_definitions(${target}-aliases PRIVATE UNITS_ALIASES) + target_compile_definitions(${target}-aliases PRIVATE + UNITS_NO_LITERALS + UNITS_NO_REFERENCES + ) endfunction() add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international) @@ -43,7 +46,10 @@ add_example(unknown_dimension mp-units::core-io mp-units::si) if(NOT UNITS_LIBCXX) add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer) - target_compile_definitions(glide_computer_example-aliases PRIVATE UNITS_REFERENCES) + target_compile_definitions(glide_computer_example-aliases PRIVATE + UNITS_NO_LITERALS + UNITS_NO_REFERENCES + ) find_package(linear_algebra CONFIG REQUIRED) add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) diff --git a/example/glide_computer/geographic.cpp b/example/glide_computer/geographic.cpp index 8f39cd8d..5d6073b3 100644 --- a/example/glide_computer/geographic.cpp +++ b/example/glide_computer/geographic.cpp @@ -53,8 +53,8 @@ distance spherical_distance(position from, position to) return distance(earth_radius * central_angle); } else { // the haversine formula - const auto sin_lat = sin(lat2 - lat1) / 2; - const auto sin_lon = sin(lon2 - lon1) / 2; + const auto sin_lat = sin((lat2 - lat1) / 2); + const auto sin_lon = sin((lon2 - lon1) / 2); const auto central_angle = 2 * asin(sqrt(sin_lat * sin_lat + cos(lat1) * cos(lat2) * sin_lon * sin_lon)); return distance(earth_radius * central_angle); } diff --git a/example/glide_computer/include/glide_computer.h b/example/glide_computer/include/glide_computer.h index 40341237..ef9631f7 100644 --- a/example/glide_computer/include/glide_computer.h +++ b/example/glide_computer/include/glide_computer.h @@ -30,6 +30,7 @@ #include // IWYU pragma: end_exports +#include #include #include // IWYU pragma: keep #include @@ -77,8 +78,8 @@ constexpr units::Dimensionless auto operator/(const QK1& lhs, const QK2& rhs) 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 {}; +struct velocity_kind : units::derived_kind {}; +struct rate_of_climb_kind : units::derived_kind {}; // https://en.wikipedia.org/wiki/Flight_planning#Units_of_measurement // length @@ -88,7 +89,7 @@ using altitude = units::quantity_point_kind; -using timestamp = units::quantity_point; +using timestamp = units::quantity_point, units::isq::si::second>; // speed using velocity = units::quantity_kind; diff --git a/example/hello_units.cpp b/example/hello_units.cpp index f7b22988..ec1713fa 100644 --- a/example/hello_units.cpp +++ b/example/hello_units.cpp @@ -20,10 +20,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#define UNITS_ALIASES -#define UNITS_LITERALS -#define UNITS_REFERENCES - #include #include #include // IWYU pragma: keep diff --git a/example/kalman_filter/CMakeLists.txt b/example/kalman_filter/CMakeLists.txt index 2ee45504..d170256a 100644 --- a/example/kalman_filter/CMakeLists.txt +++ b/example/kalman_filter/CMakeLists.txt @@ -28,7 +28,10 @@ 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 UNITS_REFERENCES) + target_compile_definitions(${target} PRIVATE + UNITS_NO_LITERALS + UNITS_NO_ALIASES + ) endfunction() add_example(kalman_filter-example_1 mp-units::core-fmt mp-units::si) diff --git a/example/literals/CMakeLists.txt b/example/literals/CMakeLists.txt index 8ac70781..676c8296 100644 --- a/example/literals/CMakeLists.txt +++ b/example/literals/CMakeLists.txt @@ -28,7 +28,10 @@ cmake_minimum_required(VERSION 3.2) function(add_example target) add_executable(${target}-literals ${target}.cpp) target_link_libraries(${target}-literals PRIVATE ${ARGN}) - target_compile_definitions(${target}-literals PRIVATE UNITS_LITERALS) + target_compile_definitions(${target}-literals PRIVATE + UNITS_NO_REFERENCES + UNITS_NO_ALIASES + ) endfunction() add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international) @@ -42,7 +45,10 @@ add_example(unknown_dimension mp-units::core-io mp-units::si) if(NOT UNITS_LIBCXX) add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer) - target_compile_definitions(glide_computer_example-literals PRIVATE UNITS_LITERALS) + target_compile_definitions(glide_computer_example-literals PRIVATE + UNITS_NO_REFERENCES + UNITS_NO_ALIASES + ) find_package(linear_algebra CONFIG REQUIRED) add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) diff --git a/example/references/CMakeLists.txt b/example/references/CMakeLists.txt index b7cb5c65..56054880 100644 --- a/example/references/CMakeLists.txt +++ b/example/references/CMakeLists.txt @@ -28,7 +28,10 @@ cmake_minimum_required(VERSION 3.2) function(add_example target) add_executable(${target}-references ${target}.cpp) target_link_libraries(${target}-references PRIVATE ${ARGN}) - target_compile_definitions(${target}-references PRIVATE UNITS_REFERENCES) + target_compile_definitions(${target}-references PRIVATE + UNITS_NO_LITERALS + UNITS_NO_ALIASES + ) endfunction() add_example(avg_speed mp-units::core-io mp-units::si mp-units::si-cgs mp-units::si-international) @@ -42,7 +45,10 @@ add_example(unknown_dimension mp-units::core-io mp-units::si) if(NOT UNITS_LIBCXX) add_example(glide_computer_example mp-units::core-fmt mp-units::si-international glide_computer) - target_compile_definitions(glide_computer_example-references PRIVATE UNITS_REFERENCES) + target_compile_definitions(glide_computer_example-references PRIVATE + UNITS_NO_LITERALS + UNITS_NO_ALIASES + ) find_package(linear_algebra CONFIG REQUIRED) add_example(linear_algebra mp-units::core-fmt mp-units::core-io mp-units::si) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a1fd389..fdc84cb4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,7 +22,7 @@ cmake_minimum_required(VERSION 3.15) project(mp-units - VERSION 0.7.0 + VERSION 0.8.0 LANGUAGES CXX ) diff --git a/src/core/include/units/bits/basic_concepts.h b/src/core/include/units/bits/basic_concepts.h index 4ec56115..7b68b994 100644 --- a/src/core/include/units/bits/basic_concepts.h +++ b/src/core/include/units/bits/basic_concepts.h @@ -205,6 +205,52 @@ concept UnitOf = 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 { @@ -216,7 +262,7 @@ struct _kind_base; template typename Base> concept kind_impl_ = is_derived_from_specialization_of && - requires(T* t) { + requires { typename T::base_kind; typename T::dimension; requires Dimension; @@ -236,7 +282,7 @@ concept Kind = // PointKind namespace detail { -template +template struct _point_kind_base; } // namespace detail @@ -247,7 +293,12 @@ struct _point_kind_base; * Satisfied by all point kind types derived from an specialization of @c point_kind. */ template -concept PointKind = kind_impl_; +concept PointKind = + kind_impl_ && + requires { typename T::origin; } && + PointOrigin && + std::same_as && + std::same_as; // Reference namespace detail { diff --git a/src/core/include/units/bits/common_quantity.h b/src/core/include/units/bits/common_quantity.h index 1bcc0cfb..789ff5b1 100644 --- a/src/core/include/units/bits/common_quantity.h +++ b/src/core/include/units/bits/common_quantity.h @@ -31,7 +31,7 @@ namespace units { template U, Representation Rep> class quantity; -template U, Representation Rep> +template U, Representation Rep> class quantity_point; template U, Representation Rep> @@ -99,7 +99,8 @@ template QP2> requires requires { typename common_type_t; } struct common_type { using type = units::quantity_point< - typename common_type_t::dimension, + units::rebind_point_origin_dimension::dimension>, typename common_type_t::unit, typename common_type_t::rep>; }; diff --git a/src/core/include/units/bits/deduced_symbol_text.h b/src/core/include/units/bits/derived_symbol_text.h similarity index 94% rename from src/core/include/units/bits/deduced_symbol_text.h rename to src/core/include/units/bits/derived_symbol_text.h index d4e56d10..50ad7d3a 100644 --- a/src/core/include/units/bits/deduced_symbol_text.h +++ b/src/core/include/units/bits/derived_symbol_text.h @@ -80,16 +80,16 @@ template inline constexpr int negative_exp_count = ((Es::num < 0 ? 1 : 0) + ... + 0); template -constexpr auto deduced_symbol_text(exponent_list, std::index_sequence) +constexpr auto derived_symbol_text(exponent_list, std::index_sequence) { constexpr auto neg_exp = negative_exp_count; return (exp_text() + ...); } template -constexpr auto deduced_symbol_text() +constexpr auto derived_symbol_text() { - return deduced_symbol_text(typename Dim::recipe(), std::index_sequence_for()); + return derived_symbol_text(typename Dim::recipe(), std::index_sequence_for()); } } // namespace units::detail diff --git a/src/core/include/units/bits/deduced_unit.h b/src/core/include/units/bits/derived_unit.h similarity index 96% rename from src/core/include/units/bits/deduced_unit.h rename to src/core/include/units/bits/derived_unit.h index ff3bf5ce..f65b2fdd 100644 --- a/src/core/include/units/bits/deduced_unit.h +++ b/src/core/include/units/bits/derived_unit.h @@ -33,7 +33,7 @@ inline constexpr bool same_scaled_units = false; template inline constexpr bool same_scaled_units, Us...> = (UnitOf && ...); -// deduced_unit +// derived_unit template constexpr ratio inverse_if_negative(const ratio& r) @@ -51,6 +51,6 @@ constexpr ratio derived_ratio(exponent_list) } template -using deduced_unit = scaled_unit(typename D::recipe()), typename D::coherent_unit::reference>; +using derived_unit = scaled_unit(typename D::recipe()), typename D::coherent_unit::reference>; } // namespace units::detail diff --git a/src/core/include/units/bits/equivalent.h b/src/core/include/units/bits/equivalent.h index 80825870..5025ecc7 100644 --- a/src/core/include/units/bits/equivalent.h +++ b/src/core/include/units/bits/equivalent.h @@ -81,29 +81,51 @@ template struct equivalent_unit : std::disjunction, std::bool_constant::ratio == U2::ratio / dimension_unit::ratio>> {}; +// point origins + +template +concept EquivalentPointOrigins = + RebindablePointOriginFor && RebindablePointOriginFor && + std::same_as> && + std::same_as>; + +template +struct equivalent_impl : std::bool_constant< + EquivalentPointOrigins && equivalent_impl::value> {}; + // (point) kinds -template - requires (Kind && Kind) || (PointKind && PointKind) +template struct equivalent_impl : std::conjunction, equivalent_impl> {}; +template +struct equivalent_impl : + std::conjunction, + equivalent_impl> {}; + // quantities, quantity points, quantity (point) kinds -template - requires (Quantity && Quantity) || (QuantityPoint && QuantityPoint) +template struct equivalent_impl : std::conjunction, equivalent_unit> {}; -template - requires (QuantityKind && QuantityKind) || (QuantityPointKind && QuantityPointKind) +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 diff --git a/src/core/include/units/bits/quantity_of.h b/src/core/include/units/bits/quantity_of.h index 832f273f..4ec1368f 100644 --- a/src/core/include/units/bits/quantity_of.h +++ b/src/core/include/units/bits/quantity_of.h @@ -85,21 +85,20 @@ template concept QuantityEquivalentTo = Quantity && QuantityOf; /** - * @brief A concept matching all quantity points with provided dimension + * @brief A concept matching all quantity points of the provided origin * - * Satisfied by all quantity points with a dimension being the instantiation derived from - * the provided dimension type. + * Satisfied by all quantity points with an origin equivalent to the provided one. */ -template -concept QuantityPointOf = QuantityPoint && Dimension && equivalent; +template +concept QuantityPointOf = QuantityPoint && PointOrigin && equivalent; /** * @brief A concept matching two equivalent quantity points * - * Satisfied by quantity points having equivalent dimensions. + * Satisfied by quantity points having equivalent origins. */ template -concept QuantityPointEquivalentTo = QuantityPoint && QuantityPointOf; +concept QuantityPointEquivalentTo = QuantityPoint && QuantityPointOf; /** * @brief A concept matching only quantity kinds of a specific kind. diff --git a/src/core/include/units/bits/unit_text.h b/src/core/include/units/bits/unit_text.h index 208dadef..5fc86bed 100644 --- a/src/core/include/units/bits/unit_text.h +++ b/src/core/include/units/bits/unit_text.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include diff --git a/src/core/include/units/chrono.h b/src/core/include/units/chrono.h index 5e5d14e9..d85496bd 100644 --- a/src/core/include/units/chrono.h +++ b/src/core/include/units/chrono.h @@ -25,6 +25,7 @@ #include // IWYU pragma: begin_exports #include +#include #include // IWYU pragma: end_exports @@ -38,10 +39,13 @@ struct quantity_like_traits> { [[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>> { - using dimension = isq::si::dim_time; - using unit = downcast_unit; + using origin = clock_origin; + using unit = downcast_unit; using rep = Rep; [[nodiscard]] static constexpr auto relative( const std::chrono::time_point>& qp) { @@ -49,4 +53,11 @@ struct quantity_point_like_traits +inline constexpr bool is_quantity_point_like>> = true; + +} // namespace detail + } // namespace units diff --git a/src/core/include/units/customization_points.h b/src/core/include/units/customization_points.h index 5b3a3d56..04827e1f 100644 --- a/src/core/include/units/customization_points.h +++ b/src/core/include/units/customization_points.h @@ -88,7 +88,7 @@ struct quantity_like_traits; /** * @brief Provides support for external quantity point-like types * - * The type trait should provide the following nested type aliases: @c dimension, @c unit, @c rep, + * The type trait should provide the following nested type aliases: @c origin, @c unit, @c rep, * and a static member function @c relative(T) that will return the quantity-like value of the quantity point. * * Usage example can be found in @c units/chrono.h header file. diff --git a/src/core/include/units/generic/angle.h b/src/core/include/units/generic/angle.h index 76bd1f51..00c723dc 100644 --- a/src/core/include/units/generic/angle.h +++ b/src/core/include/units/generic/angle.h @@ -43,7 +43,7 @@ concept Angle = QuantityOfT; template> U, Representation Rep = double> using angle = quantity, U, Rep>; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -53,9 +53,9 @@ constexpr auto operator"" _q_rad(long double l) { return angle +struct dynamic_origin; + namespace detail { template @@ -35,10 +38,11 @@ struct _kind_base : downcast_base<_kind_base> { using dimension = D; }; -template -struct _point_kind_base : downcast_base<_point_kind_base> { +template +struct _point_kind_base : downcast_base<_point_kind_base> { using base_kind = K; using dimension = typename K::dimension; + using origin = O; }; } // namespace detail @@ -47,18 +51,18 @@ template requires Kind>> using downcast_kind = downcast>; -template - requires PointKind>> -using downcast_point_kind = downcast>; +template> + requires PointKind>> +using downcast_point_kind = downcast>; template struct kind : downcast_dispatch> {}; -template +template requires std::same_as struct derived_kind : downcast_dispatch> {}; -template -struct point_kind : downcast_dispatch> {}; +template> +struct point_kind : downcast_dispatch> {}; } // namespace units diff --git a/src/core/include/units/point_origin.h b/src/core/include/units/point_origin.h new file mode 100644 index 00000000..581ccbfc --- /dev/null +++ b/src/core/include/units/point_origin.h @@ -0,0 +1,34 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION 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 point_origin { + using dimension = D; +}; + +} // namespace units diff --git a/src/core/include/units/quantity.h b/src/core/include/units/quantity.h index e4a17536..da3825a1 100644 --- a/src/core/include/units/quantity.h +++ b/src/core/include/units/quantity.h @@ -147,9 +147,10 @@ public: quantity(const quantity&) = default; quantity(quantity&&) = default; - template Value> - constexpr explicit(!(is_same_v && is_same_v)) - quantity(const Value& v) : number_(v) {} + template + requires safe_convertible_to_, rep> + constexpr explicit(!(std::same_as && std::same_as)) + quantity(Value&& v) : number_(std::forward(v)) {} template Q> constexpr explicit(false) quantity(const Q& q) : number_(quantity_cast(q).number()) {} @@ -162,7 +163,10 @@ public: quantity& operator=(quantity&&) = default; // data access - [[nodiscard]] constexpr rep number() const noexcept { return number_; } + [[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 @@ -363,11 +367,12 @@ public: } [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) - requires (!floating_point_) && is_same_v && + requires (!floating_point_) && invoke_result_convertible_to_, rep, rep> { gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return units::quantity(lhs.number() % rhs.number()); + using ret = quantity, rep, rep>>; + return ret(lhs.number() % rhs.number()); } [[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity& rhs) @@ -422,25 +427,15 @@ template return detail::make_quantity(lhs.number() / rhs.number()); } -template - requires (!floating_point_) && (!floating_point_) && - quantity_value_for_, Rep1, Rep2> -[[nodiscard]] constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - using unit = downcast_unit; - using ret = quantity, Rep1, Rep2>>; - return ret(lhs.number() % rhs.number()); -} - -template Q2> +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 = common_quantity_for, Q1, Q2>; - return ret(ret(lhs).number() % ret(rhs).number()); + using ret = quantity, typename Q1::rep, typename Q2::rep>>; + return ret(lhs.number() % rhs.number()); } template Q2> diff --git a/src/core/include/units/quantity_cast.h b/src/core/include/units/quantity_cast.h index 655a0720..1472b701 100644 --- a/src/core/include/units/quantity_cast.h +++ b/src/core/include/units/quantity_cast.h @@ -39,7 +39,7 @@ namespace units { template U, Representation Rep> class quantity; -template U, Representation Rep> +template U, Representation Rep> class quantity_point; template U, Representation Rep> @@ -234,10 +234,12 @@ template Rep * * @tparam CastSpec a target quantity point type to cast to or anything that works for quantity_cast */ -template - requires is_specialization_of || - requires(quantity q) { quantity_cast(q); } -[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& qp) +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())); @@ -261,11 +263,11 @@ template * @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_point_cast(const quantity_point& q) +template + requires equivalent && UnitOf && RebindablePointOriginFor +[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& q) { - return quantity_point_cast>(q); + return quantity_point_cast, ToU, Rep>>(q); } /** @@ -347,7 +349,8 @@ template 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 requires { quantity_kind_cast(qpk.relative()); }; + requires equivalent; } || requires { requires PointKind && UnitOf; } || requires { quantity_kind_cast(qpk.relative()); } // TODO: Simplify when Clang catches up. { diff --git a/src/core/include/units/quantity_kind.h b/src/core/include/units/quantity_kind.h index c6891bd2..50c3f785 100644 --- a/src/core/include/units/quantity_kind.h +++ b/src/core/include/units/quantity_kind.h @@ -93,22 +93,25 @@ public: quantity_kind(const quantity_kind&) = default; quantity_kind(quantity_kind&&) = default; - template Value> - requires is_same_v && std::is_constructible_v - constexpr explicit quantity_kind(const Value& v) : q_(v) {} - - template - requires (Quantity || QuantityLike) && std::is_constructible_v - constexpr explicit quantity_kind(const Q& q) : q_{q} {} + template + requires + (Quantity> || + QuantityLike> || + (Dimensionless && !Quantity>)) && + std::constructible_from + constexpr explicit quantity_kind(T&& t) : q_(std::forward(t)) {} template QK2> - requires std::is_convertible_v - constexpr explicit(false) quantity_kind(const QK2& qk) : q_{qk.common()} {} + 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() const noexcept { return q_; } + [[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(); } @@ -225,22 +228,17 @@ public: q_ %= rhs; return *this; } - template - constexpr quantity_kind& operator%=(const quantity_kind, units::one, Rep2>& rhs) - requires requires(quantity_type q) { q %= rhs.common(); } + + template + constexpr quantity_kind& operator%=(const QK& rhs) + requires (QuantityKindEquivalentTo || std::same_as>) && + requires(quantity_type q) { q %= rhs.common(); } { + gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); q_ %= rhs.common(); return *this; } - constexpr quantity_kind& operator%=(const quantity_kind& qk) - requires requires(quantity_type q) { q %= qk.common(); } - { - gsl_ExpectsAudit(qk.common().number() != quantity_values::zero()); - q_ %= qk.common(); - return *this; - } - // Hidden Friends // Below friend functions are to be found via argument-dependent lookup only template diff --git a/src/core/include/units/quantity_point.h b/src/core/include/units/quantity_point.h index dd1a276f..4da06901 100644 --- a/src/core/include/units/quantity_point.h +++ b/src/core/include/units/quantity_point.h @@ -24,6 +24,7 @@ #pragma once // IWYU pragma: begin_exports +#include #include #include // IWYU pragma: end_exports @@ -34,18 +35,32 @@ namespace units { /** - * @brief A quantity point + * @brief A statically unspecified quantity point origin * - * An absolute quantity with respect to zero (which represents some 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> +template U, Representation Rep = double> class quantity_point { public: - using quantity_type = quantity; + 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; @@ -59,29 +74,27 @@ public: quantity_point(const quantity_point&) = default; quantity_point(quantity_point&&) = default; - template Value> - requires is_same_v && std::is_constructible_v - constexpr explicit quantity_point(const Value& v) : q_(v) {} + template + requires std::constructible_from + constexpr explicit quantity_point(T&& t) : q_(std::forward(t)) {} - constexpr explicit quantity_point(const quantity_type& q) : q_{q} {} - - template - requires std::is_constructible_v - constexpr explicit quantity_point(const Q& q) : q_{q} {} + 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))> - : q_{quantity_point_like_traits::relative(qp)} {} - - template - requires std::is_convertible_v - constexpr explicit(false) quantity_point(const QP2& qp) : q_{qp.relative()} {} + 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() const noexcept { return q_; } + [[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(); } @@ -144,7 +157,8 @@ public: { const auto q = lhs.relative() + rhs; using q_type = decltype(q); - return quantity_point(q); + return quantity_point, typename q_type::unit, + typename q_type::rep>(q); } template @@ -160,48 +174,51 @@ public: { const auto q = lhs.relative() - rhs; using q_type = decltype(q); - return quantity_point(q); + return quantity_point, typename q_type::unit, + typename q_type::rep>(q); } - template + 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 + 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 + 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(false) quantity_point(Rep) -> quantity_point; +explicit quantity_point(Rep) -> quantity_point, one, Rep>; + +template +explicit quantity_point(Q) -> quantity_point, typename Q::unit, typename Q::rep>; template -quantity_point(Q) -> quantity_point::dimension, +explicit quantity_point(Q) -> quantity_point::dimension>, typename quantity_like_traits::unit, typename quantity_like_traits::rep>; template -explicit quantity_point(QP) -> quantity_point::dimension, +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; +template +inline constexpr bool is_quantity_point> = true; } // namespace detail diff --git a/src/core/include/units/quantity_point_kind.h b/src/core/include/units/quantity_point_kind.h index e315ff40..a2c5f1a1 100644 --- a/src/core/include/units/quantity_point_kind.h +++ b/src/core/include/units/quantity_point_kind.h @@ -34,7 +34,7 @@ namespace units { /** * @brief A quantity point kind * - * An absolute quantity kind with respect to zero (which represents some origin). + * 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 @@ -45,6 +45,7 @@ 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; @@ -60,32 +61,28 @@ public: quantity_point_kind(const quantity_point_kind&) = default; quantity_point_kind(quantity_point_kind&&) = default; - template Value> - requires std::is_constructible_v - constexpr explicit quantity_point_kind(const Value& v) : qk_(v) {} + template + requires std::constructible_from + constexpr explicit quantity_point_kind(T&& t) : qk_(std::forward(t)) {} - constexpr explicit quantity_point_kind(const quantity_type& q) : qk_{q} {} - - template - requires std::is_constructible_v - constexpr explicit quantity_point_kind(const Q& q) : qk_{q} {} + 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::is_constructible_v, QP> - constexpr explicit quantity_point_kind(const QP& qp) : qk_{quantity_point_like_traits::relative(qp)} {} + requires std::constructible_from, QP> + constexpr explicit quantity_point_kind(const QP& qp) : qk_(quantity_point_like_traits::relative(qp)) {} - constexpr explicit quantity_point_kind(const quantity_point& qp) : qk_{qp.relative()} {} - - constexpr explicit quantity_point_kind(const quantity_kind_type& qk) : qk_{qk} {} - - template QPK2> - requires std::is_convertible_v - constexpr explicit(false) quantity_point_kind(const QPK2& qpk) : qk_{qpk.relative()} {} + 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() const noexcept { return qk_; } + [[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(); } @@ -163,20 +160,21 @@ public: return units::quantity_point_kind(lhs.relative() - rhs); } - [[nodiscard]] friend constexpr QuantityKind auto operator-(const quantity_point_kind& lhs, const quantity_point_kind& 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 + 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 + template QPK> requires std::equality_comparable_with [[nodiscard]] friend constexpr bool operator==(const quantity_point_kind& lhs, const QPK& rhs) { diff --git a/src/core/include/units/unit.h b/src/core/include/units/unit.h index ef972808..a4a46463 100644 --- a/src/core/include/units/unit.h +++ b/src/core/include/units/unit.h @@ -22,11 +22,11 @@ #pragma once -#include +#include #include // IWYU pragma: begin_exports -#include +#include #include #include #include @@ -155,37 +155,12 @@ struct prefixed_unit : downcast_dispatch requires detail::same_scaled_units && (U::is_named && (URest::is_named && ... && true)) -struct deduced_unit : downcast_dispatch> { +struct derived_unit : downcast_dispatch> { static constexpr bool is_named = false; - static constexpr auto symbol = detail::deduced_symbol_text(); + static constexpr auto symbol = detail::derived_symbol_text(); using prefix_family = no_prefix; }; - -/** - * @brief A unit with a deduced ratio and symbol that can be used as a named unit for children - * - * 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::same_scaled_units && - (U::is_named && (URest::is_named && ... && true)) -// TODO - 'noble' is placeholder to sort of mean can pass its name on to other deduced units -struct noble_deduced_unit : downcast_dispatch> { - static constexpr bool is_named = true; - static constexpr auto symbol = detail::deduced_symbol_text(); - using prefix_family = no_prefix; -}; - - /** * @brief A named unit with a deduced ratio * @@ -203,7 +178,7 @@ struct noble_deduced_unit : downcast_dispatch requires detail::same_scaled_units -struct named_deduced_unit : downcast_dispatch> { +struct named_derived_unit : downcast_dispatch> { static constexpr bool is_named = true; static constexpr auto symbol = Symbol; using prefix_family = PF; 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 index c3b151cc..d0f595dc 100644 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/modulation_rate.h +++ b/src/systems/isq-iec80000/include/units/isq/iec80000/modulation_rate.h @@ -50,7 +50,7 @@ using dim_modulation_rate = si::dim_frequency; template U, Representation Rep = double> using modulation_rate = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -66,9 +66,9 @@ constexpr auto operator"" _q_YBd(unsigned long long l) { gsl_ExpectsAudit(std::i } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace modulation_rate_references { @@ -90,11 +90,11 @@ using namespace modulation_rate_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::iec80000 -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::iec80000::inline modulation_rate { @@ -110,4 +110,4 @@ template using YBd = units::isq::iec80000::modulati } // namespace units::aliases::isq::iec80000::inline modulation_rate -#endif // UNITS_ALIASES +#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 index 7a6e6cd5..7b1c0a2f 100644 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/storage_capacity.h +++ b/src/systems/isq-iec80000/include/units/isq/iec80000/storage_capacity.h @@ -79,7 +79,7 @@ concept StorageCapacity = QuantityOf; template U, Representation Rep = double> using storage_capacity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -123,9 +123,9 @@ constexpr auto operator"" _q_PiB(unsigned long long l) { gsl_ExpectsAudit(std::i } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace storage_capacity_references { @@ -175,11 +175,11 @@ using namespace storage_capacity_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::iec80000 -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::iec80000::inline storage_capacity { @@ -223,4 +223,4 @@ template using PiB = units::isq::iec80000::storage_ } // namespace units::aliases::isq::iec80000::inline storage_capacity -#endif // UNITS_ALIASES +#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 index 541aa505..15b4fa18 100644 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/traffic_intensity.h +++ b/src/systems/isq-iec80000/include/units/isq/iec80000/traffic_intensity.h @@ -43,7 +43,7 @@ concept TrafficIntensity = QuantityOf; template U, Representation Rep = double> using traffic_intensity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,9 +51,9 @@ constexpr auto operator"" _q_E(unsigned long long l) { gsl_ExpectsAudit(std::in_ } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace traffic_intensity_references { @@ -67,11 +67,11 @@ using namespace traffic_intensity_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::iec80000 -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::iec80000::inline traffic_intensity { @@ -79,4 +79,4 @@ template using E = units::isq::iec80000::traffic_in } // namespace units::aliases::isq::iec80000::inline traffic_intensity -#endif // UNITS_ALIASES +#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 index 29f4248a..ac081b86 100644 --- a/src/systems/isq-iec80000/include/units/isq/iec80000/transfer_rate.h +++ b/src/systems/isq-iec80000/include/units/isq/iec80000/transfer_rate.h @@ -37,14 +37,14 @@ namespace units::isq::iec80000 { struct byte_per_second : unit {}; struct dim_transfer_rate : derived_dimension, exponent> {}; -struct kilobyte_per_second : deduced_unit {}; -struct megabyte_per_second : deduced_unit {}; -struct gigabyte_per_second : deduced_unit {}; -struct terabyte_per_second : deduced_unit {}; -struct petabyte_per_second : deduced_unit {}; -struct exabyte_per_second : deduced_unit {}; -struct zettabyte_per_second : deduced_unit {}; -struct yottabyte_per_second : deduced_unit {}; +struct kilobyte_per_second : derived_unit {}; +struct megabyte_per_second : derived_unit {}; +struct gigabyte_per_second : derived_unit {}; +struct terabyte_per_second : derived_unit {}; +struct petabyte_per_second : derived_unit {}; +struct exabyte_per_second : derived_unit {}; +struct zettabyte_per_second : derived_unit {}; +struct yottabyte_per_second : derived_unit {}; template concept TransferRate = QuantityOf; @@ -52,7 +52,7 @@ concept TransferRate = QuantityOf; template U, Representation Rep = double> using transfer_rate = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -68,11 +68,11 @@ constexpr auto operator"" _q_YB_per_s(unsigned long long l) { gsl_ExpectsAudit(s } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS } // namespace units::isq::iec80000 -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::iec80000::inline transfer_rate { @@ -88,4 +88,4 @@ template using YB_per_s = units::isq::iec80000::tra } // namespace units::aliases::isq::iec80000::inline transfer_rate -#endif // UNITS_ALIASES +#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/acceleration.h b/src/systems/isq-natural/include/units/isq/natural/acceleration.h index 735cad68..35f765eb 100644 --- a/src/systems/isq-natural/include/units/isq/natural/acceleration.h +++ b/src/systems/isq-natural/include/units/isq/natural/acceleration.h @@ -40,7 +40,7 @@ struct dim_acceleration : isq::dim_acceleration U, Representation Rep = double> using acceleration = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace acceleration_references { @@ -54,11 +54,11 @@ using namespace acceleration_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline acceleration { @@ -66,4 +66,4 @@ template using GeV = units::isq::natural::accelerat } // namespace units::aliases::isq::natural::inline acceleration -#endif // UNITS_ALIASES +#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/energy.h b/src/systems/isq-natural/include/units/isq/natural/energy.h index f5f9db3d..9924af00 100644 --- a/src/systems/isq-natural/include/units/isq/natural/energy.h +++ b/src/systems/isq-natural/include/units/isq/natural/energy.h @@ -40,7 +40,7 @@ struct dim_energy : isq::dim_energy U, Representation Rep = double> using energy = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace energy_references { @@ -54,11 +54,11 @@ using namespace energy_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline energy { @@ -66,4 +66,4 @@ template using GeV = units::isq::natural::energy U, Representation Rep = double> using force = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace force_references { @@ -54,11 +54,11 @@ using namespace force_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline force { @@ -66,4 +66,4 @@ template using GeV2 = units::isq::natural::force {}; template U, Representation Rep = double> using length = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace length_references { @@ -51,11 +51,11 @@ using namespace length_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline length { @@ -63,4 +63,4 @@ template using inv_GeV = units::isq::natural::lengt } // namespace units::aliases::isq::natural::inline length -#endif // UNITS_ALIASES +#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 index 7efca445..55d8a24f 100644 --- a/src/systems/isq-natural/include/units/isq/natural/mass.h +++ b/src/systems/isq-natural/include/units/isq/natural/mass.h @@ -37,7 +37,7 @@ struct dim_mass : isq::dim_mass {}; template U, Representation Rep = double> using mass = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace mass_references { @@ -51,11 +51,11 @@ using namespace mass_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline mass { @@ -63,4 +63,4 @@ template using GeV = units::isq::natural::mass U, Representation Rep = double> using momentum = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace momentum_references { @@ -54,11 +54,11 @@ using namespace momentum_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline momentum { @@ -66,4 +66,4 @@ template using GeV = units::isq::natural::momentum< } // namespace units::aliases::isq::natural::inline momentum -#endif // UNITS_ALIASES +#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq-natural/include/units/isq/natural/time.h b/src/systems/isq-natural/include/units/isq/natural/time.h index 8c98870d..ea903166 100644 --- a/src/systems/isq-natural/include/units/isq/natural/time.h +++ b/src/systems/isq-natural/include/units/isq/natural/time.h @@ -37,7 +37,7 @@ struct dim_time : isq::dim_time {}; template U, Representation Rep = double> using time = quantity; -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace time_references { @@ -51,11 +51,11 @@ using namespace time_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::natural -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::natural::inline time { @@ -63,4 +63,4 @@ template using inv_GeV = units::isq::natural::time< } // namespace units::aliases::isq::natural::inline time -#endif // UNITS_ALIASES +#endif // UNITS_NO_ALIASES diff --git a/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h b/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h index 8dcb1e6c..633af9a7 100644 --- a/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h +++ b/src/systems/isq/include/units/isq/dimensions/absorbed_dose.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_absorbed_dose; + template E, DimensionOfT M> -struct dim_absorbed_dose : derived_dimension, exponent> {}; +struct dim_absorbed_dose : derived_dimension, exponent> {}; template concept AbsorbedDose = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/acceleration.h b/src/systems/isq/include/units/isq/dimensions/acceleration.h index b639fcca..a122ec6d 100644 --- a/src/systems/isq/include/units/isq/dimensions/acceleration.h +++ b/src/systems/isq/include/units/isq/dimensions/acceleration.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_acceleration; + template L, DimensionOfT T> -struct dim_acceleration : derived_dimension, exponent> {}; +struct dim_acceleration : derived_dimension, exponent> {}; template concept Acceleration = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/angular_velocity.h b/src/systems/isq/include/units/isq/dimensions/angular_velocity.h index dfea55d1..1554dced 100644 --- a/src/systems/isq/include/units/isq/dimensions/angular_velocity.h +++ b/src/systems/isq/include/units/isq/dimensions/angular_velocity.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_angular_velocity; + template A, DimensionOfT T> -struct dim_angular_velocity : derived_dimension, exponent> {}; +struct dim_angular_velocity : derived_dimension, exponent> {}; template concept AngularVelocity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/area.h b/src/systems/isq/include/units/isq/dimensions/area.h index c122a00a..f03a4209 100644 --- a/src/systems/isq/include/units/isq/dimensions/area.h +++ b/src/systems/isq/include/units/isq/dimensions/area.h @@ -27,8 +27,11 @@ namespace units::isq { +template +struct dim_area; + template L> -struct dim_area : derived_dimension> {}; +struct dim_area : derived_dimension> {}; template concept Area = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/capacitance.h b/src/systems/isq/include/units/isq/dimensions/capacitance.h index 8a7f1c72..8f474587 100644 --- a/src/systems/isq/include/units/isq/dimensions/capacitance.h +++ b/src/systems/isq/include/units/isq/dimensions/capacitance.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_capacitance; + template C, DimensionOfT V> -struct dim_capacitance : derived_dimension, exponent> {}; +struct dim_capacitance : derived_dimension, exponent> {}; template concept Capacitance = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h b/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h index 82b21dc1..8a07c879 100644 --- a/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h +++ b/src/systems/isq/include/units/isq/dimensions/catalytic_activity.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_catalytic_activity; + template T, DimensionOfT M> -struct dim_catalytic_activity : derived_dimension, exponent> {}; +struct dim_catalytic_activity : derived_dimension, exponent> {}; template concept CatalyticActivity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/charge_density.h b/src/systems/isq/include/units/isq/dimensions/charge_density.h index 4e2d58b5..8625665a 100644 --- a/src/systems/isq/include/units/isq/dimensions/charge_density.h +++ b/src/systems/isq/include/units/isq/dimensions/charge_density.h @@ -28,11 +28,17 @@ namespace units::isq { -template Q, DimensionOfT L> -struct dim_charge_density : derived_dimension, exponent> {}; +template +struct dim_charge_density; template Q, DimensionOfT L> -struct dim_surface_charge_density : derived_dimension, exponent> {}; +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; diff --git a/src/systems/isq/include/units/isq/dimensions/concentration.h b/src/systems/isq/include/units/isq/dimensions/concentration.h index f1a82a08..f8592d98 100644 --- a/src/systems/isq/include/units/isq/dimensions/concentration.h +++ b/src/systems/isq/include/units/isq/dimensions/concentration.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_concentration; + template M, DimensionOfT L> -struct dim_concentration : derived_dimension, exponent> {}; +struct dim_concentration : derived_dimension, exponent> {}; template concept Concentration = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/conductance.h b/src/systems/isq/include/units/isq/dimensions/conductance.h index 0dea42ff..6d7a71fd 100644 --- a/src/systems/isq/include/units/isq/dimensions/conductance.h +++ b/src/systems/isq/include/units/isq/dimensions/conductance.h @@ -27,8 +27,11 @@ namespace units::isq { +template +struct dim_conductance; + template R> -struct dim_conductance : derived_dimension> {}; +struct dim_conductance : derived_dimension> {}; template concept Conductance = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/current_density.h b/src/systems/isq/include/units/isq/dimensions/current_density.h index e6e1420a..f097de77 100644 --- a/src/systems/isq/include/units/isq/dimensions/current_density.h +++ b/src/systems/isq/include/units/isq/dimensions/current_density.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_current_density; + template I, DimensionOfT L> -struct dim_current_density : derived_dimension, exponent> {}; +struct dim_current_density : derived_dimension, exponent> {}; template concept CurrentDensity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/density.h b/src/systems/isq/include/units/isq/dimensions/density.h index 3b05b5ea..cb5196d9 100644 --- a/src/systems/isq/include/units/isq/dimensions/density.h +++ b/src/systems/isq/include/units/isq/dimensions/density.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_density; + template M, DimensionOfT L> -struct dim_density : derived_dimension, exponent> {}; +struct dim_density : derived_dimension, exponent> {}; template concept Density = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h b/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h index 43add26c..ceac79e5 100644 --- a/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h +++ b/src/systems/isq/include/units/isq/dimensions/dynamic_viscosity.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_dynamic_viscosity; + template P, DimensionOfT T> -struct dim_dynamic_viscosity : derived_dimension, exponent> {}; +struct dim_dynamic_viscosity : derived_dimension, exponent> {}; template concept DynamicViscosity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/electric_charge.h b/src/systems/isq/include/units/isq/dimensions/electric_charge.h index 3f409c87..2c7db791 100644 --- a/src/systems/isq/include/units/isq/dimensions/electric_charge.h +++ b/src/systems/isq/include/units/isq/dimensions/electric_charge.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_electric_charge; + template T, DimensionOfT C> -struct dim_electric_charge : derived_dimension, exponent> {}; +struct dim_electric_charge : derived_dimension, exponent> {}; template concept ElectricCharge = QuantityOfT; 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 index 358e8203..4bcd78f6 100644 --- a/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h +++ b/src/systems/isq/include/units/isq/dimensions/electric_field_strength.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_electric_field_strength; + template V, DimensionOfT L> -struct dim_electric_field_strength : derived_dimension, exponent> {}; +struct dim_electric_field_strength : derived_dimension, exponent> {}; template concept ElectricFieldStrength = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/energy.h b/src/systems/isq/include/units/isq/dimensions/energy.h index 1f88bc16..db090615 100644 --- a/src/systems/isq/include/units/isq/dimensions/energy.h +++ b/src/systems/isq/include/units/isq/dimensions/energy.h @@ -28,8 +28,14 @@ namespace units::isq { +template +struct dim_energy; + template F, DimensionOfT L> -struct dim_energy : derived_dimension, exponent> {}; +struct dim_energy : derived_dimension, exponent> {}; + +template L, DimensionOfT F> +struct dim_energy : derived_dimension, exponent> {}; template concept Energy = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/energy_density.h b/src/systems/isq/include/units/isq/dimensions/energy_density.h index 41fe8a12..aa63cbca 100644 --- a/src/systems/isq/include/units/isq/dimensions/energy_density.h +++ b/src/systems/isq/include/units/isq/dimensions/energy_density.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_energy_density; + template E, DimensionOfT V> -struct dim_energy_density : derived_dimension, exponent> {}; +struct dim_energy_density : derived_dimension, exponent> {}; template concept EnergyDensity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/force.h b/src/systems/isq/include/units/isq/dimensions/force.h index 92fdeb56..c8f11d75 100644 --- a/src/systems/isq/include/units/isq/dimensions/force.h +++ b/src/systems/isq/include/units/isq/dimensions/force.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_force; + template M, DimensionOfT A> -struct dim_force : derived_dimension, exponent> {}; +struct dim_force : derived_dimension, exponent> {}; template concept Force = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/frequency.h b/src/systems/isq/include/units/isq/dimensions/frequency.h index 827e72c1..4b3dc285 100644 --- a/src/systems/isq/include/units/isq/dimensions/frequency.h +++ b/src/systems/isq/include/units/isq/dimensions/frequency.h @@ -27,8 +27,11 @@ namespace units::isq { +template +struct dim_frequency; + template T> -struct dim_frequency : derived_dimension> {}; +struct dim_frequency : derived_dimension> {}; template concept Frequency = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/heat_capacity.h b/src/systems/isq/include/units/isq/dimensions/heat_capacity.h index c838491e..6d96fb40 100644 --- a/src/systems/isq/include/units/isq/dimensions/heat_capacity.h +++ b/src/systems/isq/include/units/isq/dimensions/heat_capacity.h @@ -30,14 +30,23 @@ namespace units::isq { +template +struct dim_heat_capacity; + template E, DimensionOfT T> -struct dim_heat_capacity : derived_dimension, exponent> {}; +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> {}; +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> {}; +struct dim_molar_heat_capacity : derived_dimension, exponent> {}; template concept HeatCapacity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/inductance.h b/src/systems/isq/include/units/isq/dimensions/inductance.h index 6e6ccbea..90ae21cd 100644 --- a/src/systems/isq/include/units/isq/dimensions/inductance.h +++ b/src/systems/isq/include/units/isq/dimensions/inductance.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_inductance; + template F, DimensionOfT I> -struct dim_inductance : derived_dimension, exponent> {}; +struct dim_inductance : derived_dimension, exponent> {}; template concept Inductance = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/luminance.h b/src/systems/isq/include/units/isq/dimensions/luminance.h index 6167591a..5e665d58 100644 --- a/src/systems/isq/include/units/isq/dimensions/luminance.h +++ b/src/systems/isq/include/units/isq/dimensions/luminance.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_luminance; + template I, DimensionOfT L> -struct dim_luminance : derived_dimension, exponent> {}; +struct dim_luminance : derived_dimension, exponent> {}; template concept Luminance = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h b/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h index 2708d0d4..67fe78e2 100644 --- a/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h +++ b/src/systems/isq/include/units/isq/dimensions/magnetic_flux.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_magnetic_flux; + template B, DimensionOfT A> -struct dim_magnetic_flux : derived_dimension, exponent> {}; +struct dim_magnetic_flux : derived_dimension, exponent> {}; template concept MagneticFlux = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h b/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h index 7bd59e41..023fa2fa 100644 --- a/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h +++ b/src/systems/isq/include/units/isq/dimensions/magnetic_induction.h @@ -29,8 +29,11 @@ namespace units::isq { +template +struct dim_magnetic_induction; + template V, DimensionOfT T, DimensionOfT L> -struct dim_magnetic_induction : derived_dimension, exponent, exponent> {}; +struct dim_magnetic_induction : derived_dimension, exponent, exponent> {}; template concept MagneticInduction = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/molar_energy.h b/src/systems/isq/include/units/isq/dimensions/molar_energy.h index b1c18e96..a60bb3df 100644 --- a/src/systems/isq/include/units/isq/dimensions/molar_energy.h +++ b/src/systems/isq/include/units/isq/dimensions/molar_energy.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_molar_energy; + template E, DimensionOfT M> -struct dim_molar_energy : derived_dimension, exponent> {}; +struct dim_molar_energy : derived_dimension, exponent> {}; template concept MolarEnergy = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/momentum.h b/src/systems/isq/include/units/isq/dimensions/momentum.h index 5f3fad25..f7240259 100644 --- a/src/systems/isq/include/units/isq/dimensions/momentum.h +++ b/src/systems/isq/include/units/isq/dimensions/momentum.h @@ -27,8 +27,11 @@ namespace units::isq { +template +struct dim_momentum; + template M, DimensionOfT V> -struct dim_momentum : derived_dimension, exponent> {}; +struct dim_momentum : derived_dimension, exponent> {}; template concept Momentum = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/permeability.h b/src/systems/isq/include/units/isq/dimensions/permeability.h index 8bd2da53..01543a57 100644 --- a/src/systems/isq/include/units/isq/dimensions/permeability.h +++ b/src/systems/isq/include/units/isq/dimensions/permeability.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_permeability; + template H, DimensionOfT L> -struct dim_permeability : derived_dimension, exponent> {}; +struct dim_permeability : derived_dimension, exponent> {}; template concept Permeability = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/permittivity.h b/src/systems/isq/include/units/isq/dimensions/permittivity.h index 4d0cb155..78b0bb44 100644 --- a/src/systems/isq/include/units/isq/dimensions/permittivity.h +++ b/src/systems/isq/include/units/isq/dimensions/permittivity.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_permittivity; + template C, DimensionOfT L> -struct dim_permittivity : derived_dimension, exponent> {}; +struct dim_permittivity : derived_dimension, exponent> {}; template concept Permittivity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/power.h b/src/systems/isq/include/units/isq/dimensions/power.h index 9bef0f74..5a0b24ca 100644 --- a/src/systems/isq/include/units/isq/dimensions/power.h +++ b/src/systems/isq/include/units/isq/dimensions/power.h @@ -28,8 +28,14 @@ namespace units::isq { +template +struct dim_power; + template E, DimensionOfT T> -struct dim_power : derived_dimension, exponent> {}; +struct dim_power : derived_dimension, exponent> {}; + +template L, DimensionOfT F, DimensionOfT T> +struct dim_power : derived_dimension, exponent, exponent> {}; template concept Power = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/pressure.h b/src/systems/isq/include/units/isq/dimensions/pressure.h index 6f5f8934..48858a28 100644 --- a/src/systems/isq/include/units/isq/dimensions/pressure.h +++ b/src/systems/isq/include/units/isq/dimensions/pressure.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_pressure; + template F, DimensionOfT A> -struct dim_pressure : derived_dimension, exponent> {}; +struct dim_pressure : derived_dimension, exponent> {}; template concept Pressure = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/radioactivity.h b/src/systems/isq/include/units/isq/dimensions/radioactivity.h index 3457153a..591a1da9 100644 --- a/src/systems/isq/include/units/isq/dimensions/radioactivity.h +++ b/src/systems/isq/include/units/isq/dimensions/radioactivity.h @@ -27,8 +27,11 @@ namespace units::isq { +template +struct dim_radioactivity; + template T> -struct dim_radioactivity : derived_dimension> {}; +struct dim_radioactivity : derived_dimension> {}; template concept Radioactivity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/resistance.h b/src/systems/isq/include/units/isq/dimensions/resistance.h index 7ec09111..3af040cd 100644 --- a/src/systems/isq/include/units/isq/dimensions/resistance.h +++ b/src/systems/isq/include/units/isq/dimensions/resistance.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_resistance; + template V, DimensionOfT C> -struct dim_resistance : derived_dimension, exponent> {}; +struct dim_resistance : derived_dimension, exponent> {}; template concept Resistance = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/speed.h b/src/systems/isq/include/units/isq/dimensions/speed.h index e226fb04..d681420a 100644 --- a/src/systems/isq/include/units/isq/dimensions/speed.h +++ b/src/systems/isq/include/units/isq/dimensions/speed.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_speed; + template L, DimensionOfT T> -struct dim_speed : derived_dimension, exponent> {}; +struct dim_speed : derived_dimension, exponent> {}; template concept Speed = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/surface_tension.h b/src/systems/isq/include/units/isq/dimensions/surface_tension.h index db46257a..52cdd3f3 100644 --- a/src/systems/isq/include/units/isq/dimensions/surface_tension.h +++ b/src/systems/isq/include/units/isq/dimensions/surface_tension.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_surface_tension; + template F, DimensionOfT L> -struct dim_surface_tension : derived_dimension, exponent> {}; +struct dim_surface_tension : derived_dimension, exponent> {}; template concept SurfaceTension = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h b/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h index b71c37af..f7da8411 100644 --- a/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h +++ b/src/systems/isq/include/units/isq/dimensions/thermal_conductivity.h @@ -29,8 +29,11 @@ namespace units::isq { +template +struct dim_thermal_conductivity; + template P, DimensionOfT L, DimensionOfT T> -struct dim_thermal_conductivity : derived_dimension, exponent, exponent> {}; +struct dim_thermal_conductivity : derived_dimension, exponent, exponent> {}; template concept ThermalConductivity = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/torque.h b/src/systems/isq/include/units/isq/dimensions/torque.h index 0109b822..3a0c3697 100644 --- a/src/systems/isq/include/units/isq/dimensions/torque.h +++ b/src/systems/isq/include/units/isq/dimensions/torque.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_torque; + template F, DimensionOfT L, DimensionOfT A> -struct dim_torque : derived_dimension, exponent, exponent> {}; +struct dim_torque : derived_dimension, exponent, exponent> {}; template concept Torque = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/voltage.h b/src/systems/isq/include/units/isq/dimensions/voltage.h index fd0ba06b..187d5808 100644 --- a/src/systems/isq/include/units/isq/dimensions/voltage.h +++ b/src/systems/isq/include/units/isq/dimensions/voltage.h @@ -28,8 +28,11 @@ namespace units::isq { +template +struct dim_voltage; + template P, DimensionOfT C> -struct dim_voltage : derived_dimension, exponent> {}; +struct dim_voltage : derived_dimension, exponent> {}; template concept Voltage = QuantityOfT; diff --git a/src/systems/isq/include/units/isq/dimensions/volume.h b/src/systems/isq/include/units/isq/dimensions/volume.h index 0972a00f..e8c3149d 100644 --- a/src/systems/isq/include/units/isq/dimensions/volume.h +++ b/src/systems/isq/include/units/isq/dimensions/volume.h @@ -27,8 +27,11 @@ namespace units::isq { +template +struct dim_volume; + template L> -struct dim_volume : derived_dimension> {}; +struct dim_volume : derived_dimension> {}; template concept Volume = QuantityOfT; 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 index fd349032..26c5aea2 100644 --- a/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h +++ b/src/systems/si-cgs/include/units/isq/si/cgs/acceleration.h @@ -40,7 +40,7 @@ struct dim_acceleration : isq::dim_acceleration U, Representation Rep = double> using acceleration = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,9 +50,9 @@ constexpr auto operator"" _q_Gal(long double l) { return acceleration using Gal = units::isq::si::cgs::accelerat } // namespace units::aliases::isq::si::cgs::inline acceleration -#endif // UNITS_ALIASES +#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 index 5f0f1495..ceb567ae 100644 --- a/src/systems/si-cgs/include/units/isq/si/cgs/area.h +++ b/src/systems/si-cgs/include/units/isq/si/cgs/area.h @@ -42,7 +42,7 @@ struct dim_area : isq::dim_area {}; template U, Representation Rep = double> using area = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,9 +52,9 @@ constexpr auto operator"" _q_cm2(long double l) { return area using cm2 = units::isq::si::cgs::area {}; template U, Representation Rep = double> using energy = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,9 +52,9 @@ constexpr auto operator"" _q_erg(long double l) { return energy using erg = units::isq::si::cgs::energy { template U, Representation Rep = double> using force = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -53,9 +53,9 @@ constexpr auto operator"" _q_dyn(long double l) { return force using dyn = units::isq::si::cgs::force {}; template U, Representation Rep = double> using length = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,9 +51,9 @@ constexpr auto operator"" _q_cm(long double l) { return length using cm = units::isq::si::cgs::length {}; template U, Representation Rep = double> using mass = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,9 +51,9 @@ constexpr auto operator"" _q_g(long double l) { return mass(l } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace mass_references { @@ -67,11 +67,11 @@ using namespace mass_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::si::cgs -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::cgs::inline mass { @@ -79,4 +79,4 @@ template using g = units::isq::si::cgs::mass U, Representation Rep = double> using power = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,11 +51,11 @@ constexpr auto operator"" _q_erg_per_s(long double l) { return power using erg_per_s = units::isq::si::cgs::pow } // namespace units::aliases::isq::si::cgs::inline power -#endif // UNITS_ALIASES +#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 index d10ec70c..cae347e9 100644 --- a/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h +++ b/src/systems/si-cgs/include/units/isq/si/cgs/pressure.h @@ -43,7 +43,7 @@ struct dim_pressure : isq::dim_pressure U, Representation Rep = double> using pressure = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -53,9 +53,9 @@ constexpr auto operator"" _q_Ba(long double l) { return pressure using Ba = units::isq::si::cgs::pressure U, Representation Rep = double> using speed = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_cm_per_s(long double l) { return speed using cm_per_s = units::isq::si::cgs::spee } // namespace units::aliases::isq::si::cgs::inline speed -#endif // UNITS_ALIASES +#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 index b3b0c1c4..f721c5b7 100644 --- a/src/systems/si-cgs/include/units/isq/si/cgs/time.h +++ b/src/systems/si-cgs/include/units/isq/si/cgs/time.h @@ -37,7 +37,7 @@ using si::second; using si::dim_time; using si::time; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -45,9 +45,9 @@ using si::literals::operator"" _q_s; } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace time_references { @@ -61,11 +61,11 @@ using namespace time_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::si::cgs -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::cgs::inline time { @@ -73,4 +73,4 @@ using namespace units::aliases::isq::si::time; } // namespace units::aliases::isq::si::cgs::inline time -#endif // UNITS_ALIASES +#endif // UNITS_NO_ALIASES 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 index e6587f58..507495e7 100644 --- a/src/systems/si-fps/include/units/isq/si/fps/acceleration.h +++ b/src/systems/si-fps/include/units/isq/si/fps/acceleration.h @@ -39,7 +39,7 @@ struct dim_acceleration : isq::dim_acceleration U, Representation Rep = double> using acceleration = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -49,11 +49,11 @@ constexpr auto operator"" _q_ft_per_s2(long double l) { return acceleration using ft_per_s2 = units::isq::si::fps::acc } // namespace units::aliases::isq::si::fps::inline acceleration -#endif // UNITS_ALIASES +#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 index 2f967eb2..d02e5732 100644 --- a/src/systems/si-fps/include/units/isq/si/fps/area.h +++ b/src/systems/si-fps/include/units/isq/si/fps/area.h @@ -41,7 +41,7 @@ struct dim_area : isq::dim_area {}; template U, Representation Rep = double> using area = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,9 +51,9 @@ constexpr auto operator"" _q_ft2(long double l) { return area using ft2 = units::isq::si::fps::area U, Representation Rep = double> using density = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,11 +51,11 @@ constexpr auto operator"" _q_lb_per_ft3(long double l) { return density using lb_per_ft3 = units::isq::si::fps::de } // namespace units::aliases::isq::si::fps::inline density -#endif // UNITS_ALIASES +#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 index 1f559b75..7d430d4f 100644 --- a/src/systems/si-fps/include/units/isq/si/fps/energy.h +++ b/src/systems/si-fps/include/units/isq/si/fps/energy.h @@ -37,15 +37,15 @@ namespace units::isq::si::fps { // https://en.wikipedia.org/wiki/Foot-poundal struct foot_poundal : unit {}; -struct dim_energy : isq::dim_energy {}; +struct dim_energy : isq::dim_energy {}; // https://en.wikipedia.org/wiki/Foot-pound_(energy) -struct foot_pound_force : noble_deduced_unit {}; + struct foot_pound_force : derived_unit {}; template U, Representation Rep = double> using energy = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -59,11 +59,11 @@ constexpr auto operator"" _q_ft_lbf(long double l) { return energy using ft_lbf = units::isq::si::fps::energy } // namespace units::aliases::isq::si::fps::inline energy -#endif // UNITS_ALIASES +#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 index 43efd300..43e91a01 100644 --- a/src/systems/si-fps/include/units/isq/si/fps/force.h +++ b/src/systems/si-fps/include/units/isq/si/fps/force.h @@ -52,7 +52,7 @@ struct dim_force : isq::dim_force U, Representation Rep = double> using force = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -70,9 +70,9 @@ constexpr auto operator"" _q_klbf(long double l) { return force using klbf = units::isq::si::fps::force {}; template U, Representation Rep = double> using length = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -100,9 +100,9 @@ constexpr auto operator"" _q_naut_mi(long double l) { return length using naut_mi = units::isq::si::fps::lengt } // namespace units::aliases::isq::si::fps::inline length -#endif // UNITS_ALIASES +#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 index 8471c127..cbf50513 100644 --- a/src/systems/si-fps/include/units/isq/si/fps/mass.h +++ b/src/systems/si-fps/include/units/isq/si/fps/mass.h @@ -58,7 +58,7 @@ struct short_ton : named_scaled_unit{}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -100,9 +100,9 @@ constexpr auto operator"" _q_lton(long double l) { return mass using lton = units::isq::si::fps::mass {}; -struct dim_power : isq::dim_power {}; +struct dim_power : isq::dim_power {}; -struct foot_pound_force_per_second : deduced_unit {}; +struct foot_pound_force_per_second : derived_unit {}; struct horse_power : named_scaled_unit {}; template U, Representation Rep = double> using power = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -64,9 +64,9 @@ constexpr auto operator"" _q_hp(long double l) { return power using hp = units::isq::si::fps::power {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -67,9 +67,9 @@ constexpr auto operator"" _q_kpsi(long double l) { return pressure using kpsi = units::isq::si::fps::pressure } // namespace units::aliases::isq::si::fps::inline pressure -#endif // UNITS_ALIASES +#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 index 16ac98e5..098498d5 100644 --- a/src/systems/si-fps/include/units/isq/si/fps/speed.h +++ b/src/systems/si-fps/include/units/isq/si/fps/speed.h @@ -41,13 +41,11 @@ struct dim_speed : isq::dim_speed U, Representation Rep = double> using speed = quantity; -struct mile_per_hour : deduced_unit{}; - -struct nautical_mile_per_hour : named_deduced_unit{}; - +struct mile_per_hour : derived_unit{}; +struct nautical_mile_per_hour : derived_unit{}; struct knot : alias_unit {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -65,9 +63,9 @@ constexpr auto operator"" _q_knot(long double l) { return speed using knot = units::isq::si::fps::speed {}; struct dim_volume : isq::dim_volume {}; -struct cubic_yard : deduced_unit {}; +struct cubic_yard : derived_unit {}; template U, Representation Rep = double> using volume = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -56,9 +56,9 @@ constexpr auto operator"" _q_yd3(long double l) { return volume using yd3 = units::isq::si::fps::volume {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -62,9 +62,9 @@ constexpr auto operator"" _q_angstrom(long double l) { return si::length using angstrom = units::isq::si::length {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -54,9 +54,9 @@ constexpr auto operator"" _q_rd(long double l) { return si::length using rd = units::isq::si::length {}; +struct square_foot : derived_unit {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -47,9 +47,9 @@ constexpr auto operator"" _q_ft2(long double l) { return si::area using ft2 = units::isq::si::area { // https://en.wikipedia.org/wiki/Thousandth_of_an_inch using mil = thou; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -104,9 +104,9 @@ constexpr auto operator"" _q_mil(long double l) { return si::length using mil = units::isq::si::length {}; +struct mile_per_hour : derived_unit {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -46,11 +46,11 @@ constexpr auto operator"" _q_mi_per_h(long double l) { return si::speed using mi_per_h = units::isq::si::speed {}; +struct cubic_foot : derived_unit {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -47,9 +47,9 @@ constexpr auto operator"" _q_ft3(long double l) { return si::volume using ft3 = units::isq::si::volume {}; struct point_prn : named_scaled_unit {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -63,9 +63,9 @@ constexpr auto operator"" _q_point_prn(long double l) { return si::length using point_prn = units::isq::si::length {}; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -63,9 +63,9 @@ constexpr auto operator"" _q_mi_us(long double l) { return si::length using mi = units::isq::si::length U, Representation Rep = double> using absorbed_dose = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -152,9 +152,9 @@ constexpr auto operator"" _q_YGy(long double l) { return absorbed_dose using YGy = units::isq::si::absorbed_dose< } // namespace units::aliases::isq::si::inline absorbed_dose -#endif // UNITS_ALIASES +#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 index 8cfa0331..c6e8110e 100644 --- a/src/systems/si/include/units/isq/si/acceleration.h +++ b/src/systems/si/include/units/isq/si/acceleration.h @@ -39,7 +39,7 @@ struct dim_acceleration : isq::dim_acceleration U, Representation Rep = double> using acceleration = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -49,11 +49,11 @@ constexpr auto operator"" _q_m_per_s2(long double l) { return acceleration using m_per_s2 = units::isq::si::accelerat } // namespace units::aliases::isq::si::inline acceleration -#endif // UNITS_ALIASES +#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 index b1e074a1..79282af9 100644 --- a/src/systems/si/include/units/isq/si/amount_of_substance.h +++ b/src/systems/si/include/units/isq/si/amount_of_substance.h @@ -41,7 +41,7 @@ struct dim_amount_of_substance : isq::dim_amount_of_substance {}; template U, Representation Rep = double> using amount_of_substance = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,9 +51,9 @@ constexpr auto operator"" _q_mol(long double l) { return amount_of_substance using mol = units::isq::si::amount_of_subs } // namespace units::aliases::isq::si::inline amount_of_substance -#endif // UNITS_ALIASES +#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 index 316708b9..52fd092b 100644 --- a/src/systems/si/include/units/isq/si/angular_velocity.h +++ b/src/systems/si/include/units/isq/si/angular_velocity.h @@ -41,7 +41,7 @@ struct dim_angular_velocity : isq::dim_angular_velocity U, Representation Rep = double> using angular_velocity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,11 +51,11 @@ constexpr auto operator"" _q_rad_per_s(long double l) { return angular_velocity< } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline angular_velocity { @@ -63,4 +63,4 @@ template using rad_per_s = units::isq::si::angular_ } // namespace units::aliases::isq::si::inline angular_velocity -#endif // UNITS_ALIASES +#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 index 3ffb5744..13d21a1a 100644 --- a/src/systems/si/include/units/isq/si/area.h +++ b/src/systems/si/include/units/isq/si/area.h @@ -37,33 +37,33 @@ namespace units::isq::si { struct square_metre : unit {}; struct dim_area : isq::dim_area {}; -struct square_yoctometre : deduced_unit {}; -struct square_zeptometre : deduced_unit {}; -struct square_attometre : deduced_unit {}; -struct square_femtometre : deduced_unit {}; -struct square_picometre : deduced_unit {}; -struct square_nanometre : deduced_unit {}; -struct square_micrometre : deduced_unit {}; -struct square_millimetre : deduced_unit {}; -struct square_centimetre : deduced_unit {}; -struct square_decimetre : deduced_unit {}; -struct square_decametre : deduced_unit {}; -struct square_hectometre : deduced_unit {}; -struct square_kilometre : deduced_unit {}; -struct square_megametre : deduced_unit {}; -struct square_gigametre : deduced_unit {}; -struct square_terametre : deduced_unit {}; -struct square_petametre : deduced_unit {}; -struct square_exametre : deduced_unit {}; -struct square_zettametre : deduced_unit {}; -struct square_yottametre : deduced_unit {}; +struct square_yoctometre : derived_unit {}; +struct square_zeptometre : derived_unit {}; +struct square_attometre : derived_unit {}; +struct square_femtometre : derived_unit {}; +struct square_picometre : derived_unit {}; +struct square_nanometre : derived_unit {}; +struct square_micrometre : derived_unit {}; +struct square_millimetre : derived_unit {}; +struct square_centimetre : derived_unit {}; +struct square_decimetre : derived_unit {}; +struct square_decametre : derived_unit {}; +struct square_hectometre : derived_unit {}; +struct square_kilometre : derived_unit {}; +struct square_megametre : derived_unit {}; +struct square_gigametre : derived_unit {}; +struct square_terametre : derived_unit {}; +struct square_petametre : derived_unit {}; +struct square_exametre : derived_unit {}; +struct square_zettametre : derived_unit {}; +struct square_yottametre : derived_unit {}; struct hectare : alias_unit {}; template U, Representation Rep = double> using area = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -157,9 +157,9 @@ constexpr auto operator"" _q_ha(long double l) { return area using ha = units::isq::si::area U, Representation Rep = double> using capacitance = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -153,9 +153,9 @@ constexpr auto operator"" _q_YF(long double l) { return capacitance using YF = units::isq::si::capacitance U, Representation Rep = double> using catalytic_activity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -159,9 +159,9 @@ constexpr auto operator"" _q_U(long double l) { return catalytic_activity using U = units::isq::si::catalytic_activi } // namespace units::aliases::isq::si::inline catalytic_activity -#endif // UNITS_ALIASES +#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 index 441cb5fc..ec23d422 100644 --- a/src/systems/si/include/units/isq/si/charge_density.h +++ b/src/systems/si/include/units/isq/si/charge_density.h @@ -47,7 +47,7 @@ using charge_density = quantity; template U, Representation Rep = double> using surface_charge_density = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -61,11 +61,11 @@ constexpr auto operator"" _q_C_per_m2(long double l) { return surface_charge_den } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline charge_density { @@ -74,4 +74,4 @@ template using C_per_m2 = units::isq::si::surface_c } // namespace units::aliases::isq::si::inline charge_density -#endif // UNITS_ALIASES +#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 index 99a99ae8..903f943a 100644 --- a/src/systems/si/include/units/isq/si/concentration.h +++ b/src/systems/si/include/units/isq/si/concentration.h @@ -40,7 +40,7 @@ struct dim_concentration : isq::dim_concentration U, Representation Rep = double> using concentration = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_mol_per_m3(long double l) { return concentration using mol_per_m3 = units::isq::si::concent } // namespace units::aliases::isq::si::inline concentration -#endif // UNITS_ALIASES +#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 index 11877476..50fd7dee 100644 --- a/src/systems/si/include/units/isq/si/conductance.h +++ b/src/systems/si/include/units/isq/si/conductance.h @@ -58,7 +58,7 @@ struct dim_conductance : isq::dim_conductance U, Representation Rep = double> using conductance = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -132,9 +132,9 @@ constexpr auto operator"" _q_YS(long double l) { return conductance using YS = units::isq::si::conductance U, Representation Rep = double> using current_density = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,11 +52,11 @@ constexpr auto operator"" _q_A_per_m2(long double l) { return current_density using A_per_m2 = units::isq::si::current_d } // namespace units::aliases::isq::si::inline current_density -#endif // UNITS_ALIASES +#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 index 192c16b6..5b0cf016 100644 --- a/src/systems/si/include/units/isq/si/density.h +++ b/src/systems/si/include/units/isq/si/density.h @@ -42,7 +42,7 @@ struct dim_density : isq::dim_density U, Representation Rep = double> using density = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,11 +52,11 @@ constexpr auto operator"" _q_kg_per_m3(long double l) { return density using kg_per_m3 = units::isq::si::density< } // namespace units::aliases::isq::si::inline density -#endif // UNITS_ALIASES +#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 index 5ee4571f..4b9b4339 100644 --- a/src/systems/si/include/units/isq/si/dynamic_viscosity.h +++ b/src/systems/si/include/units/isq/si/dynamic_viscosity.h @@ -40,7 +40,7 @@ struct dim_dynamic_viscosity : isq::dim_dynamic_viscosity U, Representation Rep = double> using dynamic_viscosity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_Pa_s(long double l) { return dynamic_viscosity using Pa_s = units::isq::si::dynamic_visco } // namespace units::aliases::isq::si::inline dynamic_viscosity -#endif // UNITS_ALIASES +#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 index 7dd60373..6b522952 100644 --- a/src/systems/si/include/units/isq/si/electric_charge.h +++ b/src/systems/si/include/units/isq/si/electric_charge.h @@ -42,7 +42,7 @@ struct dim_electric_charge : isq::dim_electric_charge U, Representation Rep = double> using electric_charge = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,9 +52,9 @@ constexpr auto operator"" _q_C(long double l) { return electric_charge using C = units::isq::si::electric_charge< } // namespace units::aliases::isq::si::inline electric_charge -#endif // UNITS_ALIASES +#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 index f295862a..f71b86bf 100644 --- a/src/systems/si/include/units/isq/si/electric_current.h +++ b/src/systems/si/include/units/isq/si/electric_current.h @@ -61,7 +61,7 @@ struct dim_electric_current : isq::dim_electric_current {}; template U, Representation Rep = double> using electric_current = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -151,9 +151,9 @@ constexpr auto operator"" _q_YA(long double l) { return electric_current using YA = units::isq::si::electric_curren } // namespace units::aliases::isq::si::inline electric_current -#endif // UNITS_ALIASES +#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 index ec11149c..290b4dbb 100644 --- a/src/systems/si/include/units/isq/si/electric_field_strength.h +++ b/src/systems/si/include/units/isq/si/electric_field_strength.h @@ -39,7 +39,7 @@ struct dim_electric_field_strength : isq::dim_electric_field_strength U, Representation Rep = double> using electric_field_strength = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -49,11 +49,11 @@ constexpr auto operator"" _q_V_per_m(long double l) { return electric_field_stre } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline electric_field_strength { @@ -61,4 +61,4 @@ template using V_per_m = units::isq::si::electric_f } // namespace units::aliases::isq::si::inline electric_field_strength -#endif // UNITS_ALIASES +#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 index f4a36b16..ddcbb270 100644 --- a/src/systems/si/include/units/isq/si/energy.h +++ b/src/systems/si/include/units/isq/si/energy.h @@ -61,7 +61,7 @@ struct dim_energy : isq::dim_energy {} template U, Representation Rep = double> using energy = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -143,9 +143,9 @@ constexpr auto operator"" _q_GeV(long double l) { return energy using GeV = units::isq::si::energy U, Representation Rep = double> using energy_density = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_J_per_m3(long double l) { return energy_density using J_per_m3 = units::isq::si::energy_de } // namespace units::aliases::isq::si::inline energy_density -#endif // UNITS_ALIASES +#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 index 09bb70ae..484e7aeb 100644 --- a/src/systems/si/include/units/isq/si/force.h +++ b/src/systems/si/include/units/isq/si/force.h @@ -63,7 +63,7 @@ struct dim_force : isq::dim_force template U, Representation Rep = double> using force = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -153,9 +153,9 @@ constexpr auto operator"" _q_YN(long double l) { return force using YN = units::isq::si::force {}; template U, Representation Rep = double> using frequency = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -131,9 +131,9 @@ constexpr auto operator"" _q_YHz(long double l) { return frequency using YHz = units::isq::si::frequency; template U, Representation Rep = double> using molar_heat_capacity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -71,11 +71,11 @@ constexpr auto operator"" _q_J_per_mol_K(long double l) { return molar_heat_capa } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::heat_capacity { @@ -85,4 +85,4 @@ template using J_per_mol_K = units::isq::si::molar_ } // namespace units::aliases::isq::si::heat_capacity -#endif // UNITS_ALIASES +#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 index 82fcb963..3ca6a0d9 100644 --- a/src/systems/si/include/units/isq/si/inductance.h +++ b/src/systems/si/include/units/isq/si/inductance.h @@ -59,7 +59,7 @@ struct dim_inductance : isq::dim_inductance U, Representation Rep = double> using inductance = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -133,9 +133,9 @@ constexpr auto operator"" _q_YH(long double l) { return inductance using YH = units::isq::si::inductance {}; template U, Representation Rep = double> using length = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -157,9 +157,9 @@ constexpr auto operator"" _q_au(long double l) { return length using au = units::isq::si::length U, Representation Rep = double> using luminance = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_cd_per_m2(long double l) { return luminance using cd_per_m2 = units::isq::si::luminanc } // namespace units::aliases::isq::si::inline luminance -#endif // UNITS_ALIASES +#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 index 85299c40..7d0a78ec 100644 --- a/src/systems/si/include/units/isq/si/luminous_intensity.h +++ b/src/systems/si/include/units/isq/si/luminous_intensity.h @@ -61,7 +61,7 @@ struct dim_luminous_intensity : isq::dim_luminous_intensity {}; template U, Representation Rep = double> using luminous_intensity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -151,9 +151,9 @@ constexpr auto operator"" _q_Ycd(long double l) { return luminous_intensity using Ycd = units::isq::si::luminous_inten } // namespace units::aliases::isq::si::luminous_intensity -#endif // UNITS_ALIASES +#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 index e106f6fd..78f22854 100644 --- a/src/systems/si/include/units/isq/si/magnetic_flux.h +++ b/src/systems/si/include/units/isq/si/magnetic_flux.h @@ -59,7 +59,7 @@ struct dim_magnetic_flux : isq::dim_magnetic_flux U, Representation Rep = double> using magnetic_flux = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -133,9 +133,9 @@ constexpr auto operator"" _q_YWb(long double l) { return magnetic_flux using YWb = units::isq::si::magnetic_flux< } // namespace units::aliases::isq::si::inline magnetic_flux -#endif // UNITS_ALIASES +#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 index cfccd5da..71a3a3e7 100644 --- a/src/systems/si/include/units/isq/si/magnetic_induction.h +++ b/src/systems/si/include/units/isq/si/magnetic_induction.h @@ -63,7 +63,7 @@ struct dim_magnetic_induction : isq::dim_magnetic_induction U, Representation Rep = double> using magnetic_induction = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -141,9 +141,9 @@ constexpr auto operator"" _q_G(long double l) { return magnetic_induction using G = units::isq::si::magnetic_inducti } // namespace units::aliases::isq::si::inline magnetic_induction -#endif // UNITS_ALIASES +#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 index 38fc58f8..a13c4047 100644 --- a/src/systems/si/include/units/isq/si/mass.h +++ b/src/systems/si/include/units/isq/si/mass.h @@ -85,7 +85,7 @@ struct dim_mass : isq::dim_mass {}; template U, Representation Rep = double> using mass = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -264,9 +264,9 @@ constexpr auto operator"" _q_Da(long double l) { return mass using Da = units::isq::si::mass U, Representation Rep = double> using molar_energy = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,11 +52,11 @@ constexpr auto operator"" _q_J_per_mol(long double l) { return molar_energy using J_per_mol = units::isq::si::molar_en } // namespace units::aliases::isq::si::inline molar_energy -#endif // UNITS_ALIASES +#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 index 0123837f..28151b6f 100644 --- a/src/systems/si/include/units/isq/si/momentum.h +++ b/src/systems/si/include/units/isq/si/momentum.h @@ -40,7 +40,7 @@ struct dim_momentum : isq::dim_momentum U, Representation Rep = double> using momentum = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_kg_m_per_s(long double l) { return momentum using kg_m_per_s = units::isq::si::momentu } // namespace units::aliases::isq::si::inline momentum -#endif // UNITS_ALIASES +#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 index 3b16a50b..260e5658 100644 --- a/src/systems/si/include/units/isq/si/permeability.h +++ b/src/systems/si/include/units/isq/si/permeability.h @@ -41,7 +41,7 @@ struct dim_permeability : isq::dim_permeability U, Representation Rep = double> using permeability = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,11 +51,11 @@ constexpr auto operator"" _q_H_per_m(long double l) { return permeability using H_per_m = units::isq::si::permeabili } // namespace units::aliases::isq::si::inline permeability -#endif // UNITS_ALIASES +#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 index d367b518..850430fe 100644 --- a/src/systems/si/include/units/isq/si/permittivity.h +++ b/src/systems/si/include/units/isq/si/permittivity.h @@ -41,7 +41,7 @@ struct dim_permittivity : isq::dim_permittivity U, Representation Rep = double> using permittivity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,11 +51,11 @@ constexpr auto operator"" _q_F_per_m(long double l) { return permittivity using F_per_m = units::isq::si::permittivi } // namespace units::aliases::isq::si::inline permittivity -#endif // UNITS_ALIASES +#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 index 371385fb..ebe1bb03 100644 --- a/src/systems/si/include/units/isq/si/power.h +++ b/src/systems/si/include/units/isq/si/power.h @@ -58,7 +58,7 @@ struct dim_power : isq::dim_power {}; template U, Representation Rep = double> using power = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -132,9 +132,9 @@ constexpr auto operator"" _q_YW(long double l) { return power using YW = units::isq::si::power U, Representation Rep = double> using pressure = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -153,9 +153,9 @@ constexpr auto operator"" _q_YPa(long double l) { return pressure using YPa = units::isq::si::pressure U, Representation Rep = double> using radioactivity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -151,9 +151,9 @@ constexpr auto operator"" _q_YBq(long double l) { return radioactivity using YBq = units::isq::radioactivity U, Representation Rep = double> using resistance = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -133,9 +133,9 @@ constexpr auto operator"" _q_YR(long double l) { return resistance using YR = units::isq::si::resistance {}; struct dim_speed : isq::dim_speed {}; -struct kilometre_per_hour : deduced_unit {}; +struct kilometre_per_hour : derived_unit {}; template U, Representation Rep = double> using speed = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -56,11 +56,11 @@ constexpr auto operator"" _q_km_per_h(long double l) { return speed using km_per_h = units::isq::si::speed U, Representation Rep = double> using surface_tension = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,11 +50,11 @@ constexpr auto operator"" _q_N_per_m(long double l) { return surface_tension using N_per_m = units::isq::si::surface_te } // namespace units::aliases::isq::si::inline surface_tension -#endif // UNITS_ALIASES +#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 index b85eff41..eab781db 100644 --- a/src/systems/si/include/units/isq/si/thermal_conductivity.h +++ b/src/systems/si/include/units/isq/si/thermal_conductivity.h @@ -41,7 +41,7 @@ struct dim_thermal_conductivity : isq::dim_thermal_conductivity U, Representation Rep = double> using thermal_conductivity = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -51,11 +51,11 @@ constexpr auto operator"" _q_W_per_m_K(long double l) { return thermal_conductiv } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline thermal_conductivity { @@ -63,4 +63,4 @@ template using W_per_m_K = units::isq::si::thermal_ } // namespace units::aliases::isq::si::inline thermal_conductivity -#endif // UNITS_ALIASES +#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 index e1cbf0f8..10ee923b 100644 --- a/src/systems/si/include/units/isq/si/thermodynamic_temperature.h +++ b/src/systems/si/include/units/isq/si/thermodynamic_temperature.h @@ -40,7 +40,7 @@ struct dim_thermodynamic_temperature : isq::dim_thermodynamic_temperature U, Representation Rep = double> using thermodynamic_temperature = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,9 +50,9 @@ constexpr auto operator"" _q_K(long double l) { return thermodynamic_temperature } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace thermodynamic_temperature_references { @@ -66,11 +66,11 @@ using namespace thermodynamic_temperature_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline thermodynamic_temperature { @@ -78,4 +78,4 @@ template using K = units::isq::si::thermodynamic_te } // namespace units::aliases::isq::si::inline thermodynamic_temperature -#endif // UNITS_ALIASES +#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 index d9201b67..ebcd163e 100644 --- a/src/systems/si/include/units/isq/si/time.h +++ b/src/systems/si/include/units/isq/si/time.h @@ -52,7 +52,7 @@ struct dim_time : isq::dim_time {}; template U, Representation Rep = double> using time = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -106,9 +106,9 @@ constexpr auto operator"" _q_d(long double l) { return time(l) } // namespace literals -#endif // UNITS_LITERALS +#endif // UNITS_NO_LITERALS -#ifdef UNITS_REFERENCES +#ifndef UNITS_NO_REFERENCES namespace time_references { @@ -133,11 +133,11 @@ using namespace time_references; } // namespace references -#endif // UNITS_REFERENCES +#endif // UNITS_NO_REFERENCES } // namespace units::isq::si -#ifdef UNITS_ALIASES +#ifndef UNITS_NO_ALIASES namespace units::aliases::isq::si::inline time { @@ -156,4 +156,4 @@ template using d = units::isq::si::time U, Representation Rep = double> using torque = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -52,11 +52,11 @@ constexpr auto operator"" _q_N_m_per_rad(long double l) { return torque using N_m_per_rad = units::isq::si::torque } // namespace units::aliases::isq::si::inline torque -#endif // UNITS_ALIASES +#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 index ce50f61e..8f10478f 100644 --- a/src/systems/si/include/units/isq/si/voltage.h +++ b/src/systems/si/include/units/isq/si/voltage.h @@ -63,7 +63,7 @@ struct dim_voltage : isq::dim_voltage U, Representation Rep = double> using voltage = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -153,9 +153,9 @@ constexpr auto operator"" _q_YV(long double l) { return voltage using YV = units::isq::si::voltage {}; struct dim_volume : isq::dim_volume {}; -struct cubic_yoctometre : deduced_unit {}; -struct cubic_zeptometre : deduced_unit {}; -struct cubic_attometre : deduced_unit {}; -struct cubic_femtometre : deduced_unit {}; -struct cubic_picometre : deduced_unit {}; -struct cubic_nanometre : deduced_unit {}; -struct cubic_micrometre : deduced_unit {}; -struct cubic_millimetre : deduced_unit {}; -struct cubic_centimetre : deduced_unit {}; -struct cubic_decimetre : deduced_unit {}; -struct cubic_decametre : deduced_unit {}; -struct cubic_hectometre : deduced_unit {}; -struct cubic_kilometre : deduced_unit {}; -struct cubic_megametre : deduced_unit {}; -struct cubic_gigametre : deduced_unit {}; -struct cubic_terametre : deduced_unit {}; -struct cubic_petametre : deduced_unit {}; -struct cubic_exametre : deduced_unit {}; -struct cubic_zettametre : deduced_unit {}; -struct cubic_yottametre : deduced_unit {}; +struct cubic_yoctometre : derived_unit {}; +struct cubic_zeptometre : derived_unit {}; +struct cubic_attometre : derived_unit {}; +struct cubic_femtometre : derived_unit {}; +struct cubic_picometre : derived_unit {}; +struct cubic_nanometre : derived_unit {}; +struct cubic_micrometre : derived_unit {}; +struct cubic_millimetre : derived_unit {}; +struct cubic_centimetre : derived_unit {}; +struct cubic_decimetre : derived_unit {}; +struct cubic_decametre : derived_unit {}; +struct cubic_hectometre : derived_unit {}; +struct cubic_kilometre : derived_unit {}; +struct cubic_megametre : derived_unit {}; +struct cubic_gigametre : derived_unit {}; +struct cubic_terametre : derived_unit {}; +struct cubic_petametre : derived_unit {}; +struct cubic_exametre : derived_unit {}; +struct cubic_zettametre : derived_unit {}; +struct cubic_yottametre : derived_unit {}; struct litre : alias_unit {}; struct yoctolitre : prefixed_alias_unit {}; @@ -83,7 +83,7 @@ struct yottalitre : prefixed_unit {}; template U, Representation Rep = double> using volume = quantity; -#ifdef UNITS_LITERALS +#ifndef UNITS_NO_LITERALS inline namespace literals { @@ -257,9 +257,9 @@ constexpr auto operator"" _q_Yl(long double l) { return volume using Yl = units::isq::si::volume {}; + struct newton_per_centimetre : derived_unit {}; const surface_tension q(123); os << q; diff --git a/test/unit_test/static/CMakeLists.txt b/test/unit_test/static/CMakeLists.txt index 5a234641..0c5b3d9c 100644 --- a/test/unit_test/static/CMakeLists.txt +++ b/test/unit_test/static/CMakeLists.txt @@ -37,11 +37,6 @@ target_link_libraries(unit_tests_static_truncating PRIVATE target_compile_options(unit_tests_static_truncating PRIVATE $,/wd4242 /wd4244,-Wno-conversion> ) -target_compile_definitions(unit_tests_static_truncating PRIVATE - UNITS_REFERENCES - UNITS_LITERALS - UNITS_ALIASES -) add_library(unit_tests_static cgs_test.cpp @@ -56,6 +51,7 @@ add_library(unit_tests_static iec80000_test.cpp kind_test.cpp math_test.cpp + point_origin_test.cpp ratio_test.cpp references_test.cpp si_test.cpp @@ -78,8 +74,3 @@ target_link_libraries(unit_tests_static PRIVATE unit_tests_static_truncating mp-units::mp-units ) -target_compile_definitions(unit_tests_static PRIVATE - UNITS_REFERENCES - UNITS_LITERALS - UNITS_ALIASES -) diff --git a/test/unit_test/static/chrono_test.cpp b/test/unit_test/static/chrono_test.cpp index ec556723..ed812548 100644 --- a/test/unit_test/static/chrono_test.cpp +++ b/test/unit_test/static/chrono_test.cpp @@ -36,7 +36,7 @@ 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; +template using time_point = quantity_point, U, Rep>; static_assert(QuantityLike); static_assert(QuantityPointLike); @@ -50,14 +50,17 @@ static_assert(std::constructible_from>); 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_days>); -static_assert(!std::convertible_to>); -static_assert(!std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); +static_assert(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>); @@ -66,25 +69,25 @@ 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, 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(is_same_v>); static_assert(is_same_v>); -static_assert(is_same_v>); -static_assert(is_same_v>); +static_assert(is_same_v>); +static_assert(is_same_v>); // 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 == quantity_point{2_q_s}); -static_assert(quantity_point{sys_seconds{1s}} + 1_q_min == quantity_point{61_q_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}); } // namespace diff --git a/test/unit_test/static/concepts_test.cpp b/test/unit_test/static/concepts_test.cpp index fd0ce1f2..a54e3cd5 100644 --- a/test/unit_test/static/concepts_test.cpp +++ b/test/unit_test/static/concepts_test.cpp @@ -27,7 +27,7 @@ #include // IWYU pragma: keep #include #include -#include +#include #include #include #include @@ -112,11 +112,11 @@ static_assert(!Representation); static_assert(Quantity>); static_assert(!Quantity); -static_assert(!Quantity>); +static_assert(!Quantity, si::metre>>); // QuantityPoint -static_assert(QuantityPoint>); +static_assert(QuantityPoint, si::metre>>); static_assert(!QuantityPoint>); static_assert(!QuantityPoint); @@ -141,4 +141,9 @@ static_assert(QuantityOf, si::dim_length>); static_assert(QuantityOf, si::fps::dim_length>); static_assert(!QuantityOf, si::dim_time>); +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>); + } // namespace diff --git a/test/unit_test/static/custom_unit_test.cpp b/test/unit_test/static/custom_unit_test.cpp index 12af712e..ecb68b09 100644 --- a/test/unit_test/static/custom_unit_test.cpp +++ b/test/unit_test/static/custom_unit_test.cpp @@ -65,7 +65,7 @@ namespace { struct kilogram_per_second : unit {}; struct dim_mass_rate : derived_dimension, units::exponent> {}; -struct kilogram_per_hour : deduced_unit {}; +struct kilogram_per_hour : derived_unit {}; [[maybe_unused]] constexpr auto a = 1_q_kg / 1_q_h; } diff --git a/test/unit_test/static/fps_test.cpp b/test/unit_test/static/fps_test.cpp index 054e2a5e..1eb7e541 100644 --- a/test/unit_test/static/fps_test.cpp +++ b/test/unit_test/static/fps_test.cpp @@ -84,6 +84,9 @@ static_assert(10_q_pdl * 10_q_ft == 100_q_ft_pdl); static_assert(100_q_ft_pdl / 10_q_ft == 10_q_pdl); static_assert(100_q_ft_pdl / 10_q_pdl == 10_q_ft); +static_assert(detail::unit_text() == basic_symbol_text("ft ⋅ pdl", "ft pdl")); +static_assert(detail::unit_text() == basic_symbol_text("ft ⋅ lbf", "ft lbf")); + /* ************** DERIVED DIMENSIONS IN TERMS OF OTHER UNITS **************** */ // power @@ -92,6 +95,7 @@ static_assert(10_q_ft_pdl / 10_q_s == 1_q_ft_pdl_per_s); static_assert(1_q_ft_pdl_per_s * 10_q_s == 10_q_ft_pdl); static_assert(10_q_ft_pdl / 1_q_ft_pdl_per_s == 10_q_s); -// static_assert(detail::unit_text() == "ft_lbf/s"); +static_assert(detail::unit_text() == basic_symbol_text("ft ⋅ pdl/s", "ft pdl/s")); +static_assert(detail::unit_text() == basic_symbol_text("ft ⋅ lbf/s", "ft lbf/s")); } diff --git a/test/unit_test/static/kind_test.cpp b/test/unit_test/static/kind_test.cpp index 37d43849..3e9b4eb8 100644 --- a/test/unit_test/static/kind_test.cpp +++ b/test/unit_test/static/kind_test.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include using namespace units; @@ -97,7 +98,6 @@ static_assert(PointKind); static_assert(is_same_v); static_assert(is_same_v); -static_assert(is_same_v>); static_assert(is_same_v>); static_assert(equivalent); @@ -137,7 +137,6 @@ static_assert(PointKind); static_assert(is_same_v); static_assert(is_same_v); -static_assert(is_same_v>); static_assert(is_same_v>); static_assert(equivalent); @@ -151,7 +150,7 @@ static_assert(!equivalent); struct height : kind {}; -struct rate_of_climb : derived_kind {}; // program-defined derived kind +struct rate_of_climb : derived_kind {}; // program-defined derived kind struct velocity_of_climb : point_kind {}; // program-defined derived point kind static_assert(Kind); diff --git a/test/unit_test/static/point_origin_test.cpp b/test/unit_test/static/point_origin_test.cpp new file mode 100644 index 00000000..0b289a75 --- /dev/null +++ b/test/unit_test/static/point_origin_test.cpp @@ -0,0 +1,74 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION 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 + +using namespace units; +namespace si = isq::si; + +namespace { + +struct width : kind {}; +struct abscissa : point_kind {}; + +struct ones_viewpoint1 : point_origin { + template + using rebind = ones_viewpoint1; +}; + +struct ones_viewpoint2 : point_origin { + template + using rebind = ones_viewpoint1; +}; + +static_assert(PointOrigin>); +static_assert(!PointOrigin>); +static_assert(!PointOrigin); +static_assert(!PointOrigin); + +static_assert(RebindablePointOriginFor, si::dim_length>); +static_assert(is_same_v, si::dim_length>, + dynamic_origin>); +static_assert(RebindablePointOriginFor, si::dim_time>); +static_assert(is_same_v, si::dim_time>, + dynamic_origin>); +static_assert(RebindablePointOriginFor); +static_assert(is_same_v, ones_viewpoint1>); +static_assert(RebindablePointOriginFor); +static_assert(is_same_v, ones_viewpoint1>); +static_assert(RebindablePointOriginFor); +static_assert(is_same_v, ones_viewpoint2>); +static_assert(!RebindablePointOriginFor); + +static_assert(equivalent, dynamic_origin>); +static_assert(equivalent, dynamic_origin>); +static_assert(!equivalent, clock_origin>); +static_assert(!equivalent, clock_origin>); +static_assert(!equivalent, dynamic_origin>); +static_assert(!equivalent); + +} // namespace diff --git a/test/unit_test/static/quantity_kind_test.cpp b/test/unit_test/static/quantity_kind_test.cpp index 42c4485d..740d0973 100644 --- a/test/unit_test/static/quantity_kind_test.cpp +++ b/test/unit_test/static/quantity_kind_test.cpp @@ -52,8 +52,8 @@ struct radius_kind : kind {}; struct width_kind : kind {}; struct height_kind : kind {}; -struct horizontal_area_kind : derived_kind {}; -struct rate_of_climb_kind : derived_kind {}; +struct horizontal_area_kind : derived_kind {}; +struct rate_of_climb_kind : derived_kind {}; struct apple : kind {}; struct orange : kind {}; @@ -82,16 +82,16 @@ static_assert(QuantityKind>); static_assert(QuantityKind>); static_assert(!QuantityKind); static_assert(!QuantityKind>); -static_assert(!QuantityKind>); +static_assert(!QuantityKind, metre>>); static_assert(QuantityKindOf, width_kind>); static_assert(!QuantityKindOf, height_kind>); static_assert(!QuantityKindOf, metre>); static_assert(!QuantityKindOf, width_kind>); static_assert(!QuantityKindOf, metre>); -static_assert(!QuantityKindOf, width_kind>); -static_assert(!QuantityKindOf, dim_length>); -static_assert(!QuantityKindOf, metre>); +static_assert(!QuantityKindOf, metre>, width_kind>); +static_assert(!QuantityKindOf, metre>, dim_length>); +static_assert(!QuantityKindOf, metre>, metre>); /////////////// @@ -105,7 +105,7 @@ template concept invalid_types = requires { requires !requires { typename quantity_kind; }; // unit of a different dimension requires !requires { typename quantity_kind>; }; // quantity used as Rep - requires !requires { typename quantity_kind>; }; // quantity point used as Rep + requires !requires { typename quantity_kind, metre>>; }; // quantity point used as Rep requires !requires { typename quantity_kind>; }; // quantity kind used as Rep requires !requires { typename quantity_kind; }; // reordered arguments requires !requires { typename quantity_kind; }; // reordered arguments @@ -454,7 +454,7 @@ concept invalid_compound_assignments = requires(quantity_kind requires invalid_compound_assignments_>; requires invalid_compound_assignments_>; requires invalid_compound_assignments_>; - requires invalid_compound_assignments_>; + requires invalid_compound_assignments_, metre, int>>; requires invalid_compound_assignments_; }; static_assert(invalid_compound_assignments); @@ -475,9 +475,9 @@ static_assert(same(width(2. * m) - width(3 * m), widt static_assert(same(width(2e3 * m) - width(3 * km), width(-1e3 * m))); static_assert(is_same_v< - decltype((width(0 * m) + width(0 * m)).common().number()), int>); + decltype((width(0 * m) + width(0 * m)).common().number()), int&&>); static_assert(is_same_v< - decltype((width(0 * m) - width(0 * m)).common().number()), int>); + decltype((width(0 * m) - width(0 * m)).common().number()), int&&>); static_assert((width(128 * m) + width(128 * m)).common().number() == std::uint8_t(128) + std::uint8_t(128)); static_assert((width(0 * m) - width(1 * m)).common().number() == @@ -485,12 +485,12 @@ static_assert((width(0 * m) - width(1 static_assert(!std::is_invocable_v, width, double>); static_assert(!std::is_invocable_v, width, length>); -static_assert(!std::is_invocable_v, width, quantity_point>); +static_assert(!std::is_invocable_v, width, quantity_point, metre>>); static_assert(!std::is_invocable_v, width, height>); static_assert(!std::is_invocable_v, width, reference>); static_assert(!std::is_invocable_v, width, double>); static_assert(!std::is_invocable_v, width, length>); -static_assert(!std::is_invocable_v, width, quantity_point>); +static_assert(!std::is_invocable_v, width, quantity_point, metre>>); static_assert(!std::is_invocable_v, width, height>); static_assert(!std::is_invocable_v, width, reference>); @@ -612,7 +612,7 @@ static_assert(same(height(2. * m) / (3 * s), rate_of_climb(2 * m) * dimensionless(3), width(6 * cm))); static_assert(same(dimensionless(2) * width(3 * m), width(6 * cm))); static_assert(same(width(2 * m) / dimensionless(3), width(2. / 3 * hm))); -static_assert(same(width(2 * m) % dimensionless(3), width(2 * cm))); +static_assert(same(width(2 * m) % dimensionless(3), width(2 * m))); static_assert(same(height(2 * m) / (3 * m), quantity_kind, one, int>(0))); @@ -646,21 +646,21 @@ static_assert(same(width(3 * m) % width(2 * m), width(0 * m) % width(0 * m)).common().number()), - decltype(std::uint8_t(0) % std::uint8_t(0))>); + decltype(std::uint8_t(0) % std::uint8_t(0))&&>); static_assert(!std::is_invocable_v, reference, width>); static_assert(!std::is_invocable_v, width, height>); -static_assert(!std::is_invocable_v, height, quantity_point>); -static_assert(!std::is_invocable_v, quantity_point, height>); +static_assert(!std::is_invocable_v, height, quantity_point, metre>>); +static_assert(!std::is_invocable_v, quantity_point, metre>, height>); static_assert(!std::is_invocable_v, reference, width>); static_assert(!std::is_invocable_v, width, height>); -static_assert(!std::is_invocable_v, height, quantity_point>); -static_assert(!std::is_invocable_v, quantity_point, height>); +static_assert(!std::is_invocable_v, height, quantity_point, metre>>); +static_assert(!std::is_invocable_v, quantity_point, metre>, height>); static_assert(!std::is_invocable_v, width, reference>); static_assert(!std::is_invocable_v, width, length>); -static_assert(!std::is_invocable_v, width, quantity_point>); +static_assert(!std::is_invocable_v, width, quantity_point, metre, int>>); static_assert(!std::is_invocable_v, width, double>); static_assert(!std::is_invocable_v, width, width>); @@ -801,8 +801,8 @@ concept invalid_cast = requires { requires !requires { quantity_kind_cast>(quantity_kind(1 * m)); }; requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; requires !requires { quantity_kind_cast(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast>(quantity_kind(1 * m)); }; - requires !requires { quantity_kind_cast>(quantity_kind(1 * m)); }; + requires !requires { quantity_kind_cast, metre, int>>(quantity_kind(1 * m)); }; + requires !requires { quantity_kind_cast, one, int>>(quantity_kind(1 * m)); }; }; static_assert(invalid_cast); diff --git a/test/unit_test/static/quantity_point_kind_test.cpp b/test/unit_test/static/quantity_point_kind_test.cpp index df8cb952..73738566 100644 --- a/test/unit_test/static/quantity_point_kind_test.cpp +++ b/test/unit_test/static/quantity_point_kind_test.cpp @@ -54,9 +54,21 @@ struct ordinate_kind : point_kind {}; struct distance_kind : kind {}; struct cgs_width_kind : kind {}; struct cgs_height_kind : kind {}; -struct rate_of_climb_kind : derived_kind {}; +struct rate_of_climb_kind : derived_kind {}; struct altitude_kind : point_kind {}; +struct sea_level_origin : point_origin {}; +struct sea_level_altitude_kind : point_kind {}; + +template +struct screen_origin : point_origin { + template + using rebind = screen_origin; +}; +struct screen_si_width_kind : point_kind> {}; +struct screen_si_cgs_width_kind : + point_kind> {}; + struct apple : kind {}; struct orange : kind {}; struct nth_apple_kind : point_kind {}; @@ -65,6 +77,8 @@ struct nth_orange_kind : point_kind {}; struct time_kind : kind {}; struct time_point_kind : point_kind {}; +struct sys_time_point_kind : point_kind> {}; + template using width = quantity_kind; template using height = quantity_kind; template using abscissa = quantity_point_kind; @@ -76,6 +90,13 @@ template using cgs_height = quantity_kind< template using rate_of_climb = quantity_kind; template using altitude = quantity_point_kind; +template +using sea_level_altitude = quantity_point_kind; +template +using screen_si_width = quantity_point_kind; +template +using screen_si_cgs_width = quantity_point_kind; + template using apples = quantity_kind; template using oranges = quantity_kind; template using nth_apple = quantity_point_kind; @@ -89,7 +110,7 @@ static_assert(QuantityPointKind>); static_assert(QuantityPointKind>); static_assert(!QuantityPointKind); static_assert(!QuantityPointKind>); -static_assert(!QuantityPointKind>); +static_assert(!QuantityPointKind, metre>>); static_assert(!QuantityPointKind>); static_assert(QuantityPointKindOf, abscissa_kind>); @@ -100,9 +121,12 @@ static_assert(!QuantityPointKindOf, metre>); static_assert(!QuantityPointKindOf, abscissa_kind>); static_assert(!QuantityPointKindOf, width_kind>); static_assert(!QuantityPointKindOf, metre>); -static_assert(!QuantityPointKindOf, width_kind>); -static_assert(!QuantityPointKindOf, dim_length>); -static_assert(!QuantityPointKindOf, metre>); +static_assert(!QuantityPointKindOf, sea_level_altitude_kind>); +static_assert(!QuantityPointKindOf, sea_level_altitude_kind>); +static_assert(!QuantityPointKindOf, metre>, width_kind>); +static_assert(!QuantityPointKindOf, metre>, dim_length>); +static_assert(!QuantityPointKindOf, metre>, dynamic_origin>); +static_assert(!QuantityPointKindOf, metre>, metre>); /////////////// @@ -117,7 +141,7 @@ concept invalid_types = requires { requires !requires { typename quantity_point_kind; }; // width_kind is not a point kind requires !requires { typename quantity_point_kind; }; // unit of a different dimension requires !requires { typename quantity_point_kind>; }; // quantity used as Rep - requires !requires { typename quantity_point_kind>; }; // quantity point used as Rep + requires !requires { typename quantity_point_kind, metre>>; }; // quantity point used as Rep requires !requires { typename quantity_point_kind>; }; // quantity kind used as Rep requires !requires { typename quantity_point_kind>; }; // quantity point kind used as Rep requires !requires { typename quantity_point_kind; }; // reordered arguments @@ -160,6 +184,7 @@ static_assert(!std::is_aggregate_v>); static_assert(is_same_v::point_kind_type, abscissa_kind>); static_assert(is_same_v::kind_type, width_kind>); +static_assert(is_same_v::origin, dynamic_origin>); static_assert(is_same_v::quantity_kind_type, width>); static_assert(is_same_v::quantity_type, length>); static_assert(is_same_v::dimension, dim_length>); @@ -287,6 +312,14 @@ static_assert(!constructible_or_convertible_from>(quantity_ static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * (m * m)))); static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * s))); +static_assert(construct_from_only>(quantity_point, metre>(1 * m)) + .relative() + .common() == 1 * m); +static_assert(construct_from_only>(quantity_point, metre>(1 * m)) + .relative() + .common() == 1 * m); +static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * m))); + // clang-format off static_assert(construct_from_only>(quantity_point(1)).relative().common() == 1); static_assert(construct_from_only>(quantity_point(1)).relative().common() == 1); @@ -303,8 +336,12 @@ static_assert(!constructible_or_convertible_from>(quantity_p static_assert(!constructible_or_convertible_from>(quantity_point(dimensionless(1)))); static_assert(!constructible_or_convertible_from>(quantity_point(1.0 * s))); -static_assert(construct_from_only>(sys_seconds{42s}).relative().common() == 42 * s); // clang-format on +static_assert( + construct_from_only>(sys_seconds{42s}).relative().common() == + 42 * s); +static_assert(!constructible_or_convertible_from>(sys_seconds{42s}), + "no implicit conversion to/from dynamic_origin"); ////////////////////////////////////// @@ -365,6 +402,15 @@ static_assert(!constructible_or_convertible_from>(nth_orange static_assert(!constructible_or_convertible_from>(abscissa(1 * m))); // clang-format on +static_assert(!constructible_or_convertible_from>( + quantity_point_kind{}), + "no implicit conversion to/from dynamic_origin"); +static_assert(!constructible_or_convertible_from>( + quantity_point_kind{}), + "no implicit conversion to/from dynamic_origin"); +static_assert(!constructible_or_convertible_from>(screen_si_cgs_width(1 * m)), + "base kinds are not the same (required by equivalent)"); + ////////////////////// // other conversions @@ -375,7 +421,7 @@ static_assert(!std::is_convertible_v, dimensionless, length>); static_assert(!std::is_convertible_v, width>); static_assert(!std::is_convertible_v, height>); -static_assert(!std::is_convertible_v, quantity_point>); +static_assert(!std::is_convertible_v, quantity_point, metre, int>>); //////////////////////// @@ -420,7 +466,7 @@ concept invalid_compound_assignments = requires(quantity_point_kind>; requires invalid_compound_assignments_>; requires invalid_compound_assignments_>; - requires invalid_compound_assignments_>; + requires invalid_compound_assignments_, metre, int>>; requires invalid_compound_assignments_; }; static_assert(invalid_compound_assignments); @@ -447,13 +493,13 @@ static_assert(same(width(2 * km) + abscissa(3e3 * static_assert(same(width(2e3 * m) + abscissa(3 * km), abscissa(5e3 * m))); static_assert(!std::is_invocable_v, abscissa, double>); static_assert(!std::is_invocable_v, abscissa, length>); -static_assert(!std::is_invocable_v, abscissa, quantity_point>); +static_assert(!std::is_invocable_v, abscissa, quantity_point, metre>>); static_assert(!std::is_invocable_v, abscissa, height>); static_assert(!std::is_invocable_v, abscissa, abscissa>); static_assert(!std::is_invocable_v, abscissa, abscissa>); static_assert(!std::is_invocable_v, abscissa, abscissa>); static_assert(!std::is_invocable_v, height, abscissa>); -static_assert(!std::is_invocable_v, quantity_point, abscissa>); +static_assert(!std::is_invocable_v, quantity_point, metre>, abscissa>); static_assert(!std::is_invocable_v, length, abscissa>); static_assert(!std::is_invocable_v, double, abscissa>); @@ -469,14 +515,15 @@ static_assert(same(abscissa(2 * km) - abscissa(3e static_assert(same(abscissa(2e3 * m) - abscissa(3 * km), width(-1e3 * m))); static_assert(!std::is_invocable_v, abscissa, double>); static_assert(!std::is_invocable_v, abscissa, length>); -static_assert(!std::is_invocable_v, abscissa, quantity_point>); +static_assert(!std::is_invocable_v, abscissa, quantity_point, metre>>); static_assert(!std::is_invocable_v, abscissa, height>); static_assert(!std::is_invocable_v, abscissa, ordinate>); static_assert(!std::is_invocable_v, ordinate, abscissa>); static_assert(!std::is_invocable_v, height, abscissa>); -static_assert(!std::is_invocable_v, quantity_point, abscissa>); +static_assert(!std::is_invocable_v, quantity_point, metre>, abscissa>); static_assert(!std::is_invocable_v, length, abscissa>); static_assert(!std::is_invocable_v, double, abscissa>); +static_assert(!std::is_invocable_v, screen_si_width, screen_si_cgs_width>); // clang-format on @@ -496,8 +543,8 @@ static_assert(std::equality_comparable_with, abscissa, abscissa>); static_assert(std::equality_comparable_with, abscissa>); // clang-format on -template -concept invalid_equality = requires(quantity_point_kind x) { +template +concept invalid_equality = requires(quantity_point_kind x, Int i) { requires !requires { x == 1; }; requires !requires { x != 1.0; }; requires !requires { x == 1 * m; }; @@ -516,8 +563,9 @@ concept invalid_equality = requires(quantity_point_kind x) requires !requires { x == quantity_point(dimensionless(1.0)); }; requires !requires { x != quantity_point_kind(cgs_width(1 * m)); }; requires !requires { x == ordinate(1 * m); }; + requires !requires { screen_si_width{} != screen_si_cgs_width{}; }; }; -static_assert(invalid_equality); +static_assert(invalid_equality); // clang-format off static_assert(abscissa(1 * m) < abscissa(2 * m)); @@ -531,8 +579,8 @@ static_assert(std::three_way_comparable_with, abscissa< static_assert(std::three_way_comparable_with, abscissa>); static_assert(std::three_way_comparable_with, abscissa>); // clang-format on -template -concept invalid_relational = requires(quantity_point_kind x) { +template +concept invalid_relational = requires(quantity_point_kind x, Int i) { requires !requires { x < 1; }; requires !requires { x <= 1.0; }; requires !requires { x >= 1 * m; }; @@ -551,8 +599,9 @@ concept invalid_relational = requires(quantity_point_kind requires !requires { x < quantity_point(dimensionless(1.0)); }; requires !requires { x <= quantity_point_kind(cgs_width(1 * m)); }; requires !requires { x >= ordinate(1 * m); }; + requires !requires { screen_si_width{} > screen_si_cgs_width{}; }; }; -static_assert(invalid_relational); +static_assert(invalid_relational); ///////////////////////////// @@ -600,6 +649,7 @@ static_assert(same(quantity_point_kind_cast>(abscissa>(abscissa(1 * m)), abscissa(100 * cm))); static_assert(same(quantity_point_kind_cast>(abscissa(0.01 * m)), abscissa(1 * cm))); static_assert(same(quantity_point_kind_cast>(abscissa(1 * cgs_cm)), abscissa(1 * cgs_cm))); +static_assert(same(quantity_point_kind_cast>(screen_si_width(1 * m)), screen_si_cgs_width(1 * m))); // clang-format on template concept invalid_cast = requires(Int i) { @@ -617,8 +667,9 @@ concept invalid_cast = requires(Int i) { requires !requires { quantity_point_kind_cast>(abscissa(i * m)); }; requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; requires !requires { quantity_point_kind_cast(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast>(abscissa(i * m)); }; - requires !requires { quantity_point_kind_cast>(abscissa(i * m)); }; + requires !requires { quantity_point_kind_cast, metre, Int>>(abscissa(i * m)); }; + requires !requires { quantity_point_kind_cast, one, Int>>(abscissa(i * m)); }; + requires !requires { quantity_point_kind_cast, metre, Int>>(screen_si_width(i * m)); }; }; static_assert(invalid_cast); diff --git a/test/unit_test/static/quantity_point_test.cpp b/test/unit_test/static/quantity_point_test.cpp index ff7771c9..d8e810d9 100644 --- a/test/unit_test/static/quantity_point_test.cpp +++ b/test/unit_test/static/quantity_point_test.cpp @@ -41,72 +41,89 @@ using namespace references; using namespace std::chrono_literals; using sys_seconds = std::chrono::time_point; +struct sea_level_origin : point_origin {}; + // class invariants template concept invalid_types = requires { - requires !requires { typename quantity_point; }; // unit of a different dimension - requires !requires { typename quantity_point>; }; // quantity used as Rep - // quantity point used as Rep - requires !requires { typename quantity_point>; }; - requires !requires { typename quantity; }; // reordered arguments + // unit of a different dimension: + requires !requires { typename quantity_point, second, int>; }; + // quantity used as Rep: + requires !requires { typename quantity_point, metre, quantity>; }; + // quantity point used as Rep: + requires !requires { typename quantity_point, metre, + quantity_point, metre, int>>; }; + // reordered arguments: + requires !requires { typename quantity_point, double>; }; + // dimension used as origin: + requires !requires { typename quantity_point; }; }; static_assert(invalid_types); // member types -static_assert(is_same_v::rep, int>); -static_assert(is_same_v::rep, double>); -static_assert(is_same_v::unit, metre>); -static_assert(is_same_v::unit, kilometre>); -static_assert(is_same_v::dimension, dim_length>); -static_assert(is_same_v::quantity_type, quantity>); +static_assert(is_same_v, metre, int>::rep, int>); +static_assert(is_same_v, metre, double>::rep, double>); +static_assert(is_same_v, metre, int>::unit, metre>); +static_assert(is_same_v, kilometre, int>::unit, kilometre>); +static_assert(is_same_v, metre, int>::dimension, dim_length>); +static_assert(is_same_v, metre, int>::origin, dynamic_origin>); +static_assert(is_same_v, metre, int>::quantity_type, quantity>); // constructors static_assert(quantity_point(1).relative() == quantity(1)); -static_assert(!std::is_convertible_v>); +static_assert(!std::is_convertible_v, one, int>>); static_assert(quantity_point(42s).relative() == 42 * s); static_assert(quantity_point(sys_seconds{42s}).relative() == 42 * s); -static_assert(!std::is_convertible_v>); -static_assert(!std::is_convertible_v>); +static_assert(!std::is_convertible_v, second, std::chrono::seconds::rep>>); +static_assert(!std::is_convertible_v, second, std::chrono::seconds::rep>>); +static_assert(!std::is_convertible_v, second, sys_seconds::rep>>); +static_assert(!std::is_convertible_v, second, sys_seconds::rep>>); -static_assert(quantity_point().relative() == 0_q_m); -constexpr quantity_point km{1000_q_m}; +static_assert(quantity_point, metre, int>().relative() == 0_q_m); +constexpr quantity_point, metre, int> km{1000_q_m}; static_assert(km.relative() == 1000_q_m); -static_assert(quantity_point(km).relative() == km.relative()); +static_assert(quantity_point, metre, int>(km).relative() == km.relative()); -static_assert(quantity_point(1_q_m).relative() == 1_q_m); -static_assert(!std::is_constructible_v, double>); // truncating conversion -static_assert(quantity_point(1.0_q_m).relative() == 1.0_q_m); -static_assert(quantity_point(1_q_m).relative() == 1_q_m); -static_assert(quantity_point(3.14_q_m).relative() == 3.14_q_m); +static_assert(quantity_point, metre, int>(1_q_m).relative() == 1_q_m); +static_assert(!std::is_constructible_v, metre, int>, double>); // truncating conversion +static_assert(quantity_point, metre, double>(1.0_q_m).relative() == 1.0_q_m); +static_assert(quantity_point, metre, double>(1_q_m).relative() == 1_q_m); +static_assert(quantity_point, metre, long double>(3.14_q_m).relative() == 3.14_q_m); -static_assert(quantity_point(km).relative() == 1000_q_m); -static_assert(!std::is_constructible_v, - quantity_point>); // truncating conversion -static_assert(quantity_point(quantity_point(1000.0_q_m)).relative() == 1000.0_q_m); -static_assert(quantity_point(km).relative() == 1000.0_q_m); -static_assert(quantity_point(quantity_point(1_q_km)).relative() == 1000_q_m); -static_assert(!std::is_constructible_v, - quantity_point>); // different dimensions -static_assert(!std::is_constructible_v, - quantity_point>); // truncating conversion +static_assert(quantity_point, metre, int>(km).relative() == 1000_q_m); +static_assert(!std::is_constructible_v, metre, int>, + quantity_point, metre, double>>); // truncating conversion +static_assert(quantity_point, metre, double>(quantity_point(1000.0_q_m)).relative() == 1000.0_q_m); +static_assert(quantity_point, metre, double>(km).relative() == 1000.0_q_m); +static_assert(quantity_point, metre, int>(quantity_point(1_q_km)).relative() == 1000_q_m); +static_assert(!std::is_constructible_v, metre, int>, + quantity_point, second, int>>); // different dimensions +static_assert(!std::is_constructible_v, kilometre, int>, + quantity_point, metre, int>>); // truncating conversion + +static_assert(!std::is_constructible_v, + quantity_point, metre, int>>, + "non-equivalent origins"); +static_assert(!std::is_constructible_v, second, int>, sys_seconds>, + "non-equivalent origins, no implicit conversion from `clock_origin`"); // assignment operator -static_assert([]() { quantity_point l1(1_q_m), l2{}; return l2 = l1; }().relative() == 1_q_m); +static_assert([]() { quantity_point, metre, int> l1(1_q_m), l2{}; return l2 = l1; }().relative() == 1_q_m); // static member functions -static_assert(quantity_point::min().relative().number() == std::numeric_limits::lowest()); -static_assert(quantity_point::max().relative().number() == std::numeric_limits::max()); -static_assert(quantity_point::min().relative().number() == +static_assert(quantity_point, metre, int>::min().relative().number() == std::numeric_limits::lowest()); +static_assert(quantity_point, metre, int>::max().relative().number() == std::numeric_limits::max()); +static_assert(quantity_point, metre, double>::min().relative().number() == std::numeric_limits::lowest()); -static_assert(quantity_point::max().relative().number() == +static_assert(quantity_point, metre, double>::max().relative().number() == std::numeric_limits::max()); // unary member operators @@ -114,19 +131,19 @@ static_assert(quantity_point::max().relative().number static_assert([](auto v) { auto vv = v++; return std::pair(v, vv); -}(km) == std::pair(quantity_point(1001_q_m), quantity_point(1000_q_m))); +}(km) == std::pair(quantity_point, metre, int>(1001_q_m), quantity_point, metre, int>(1000_q_m))); static_assert([](auto v) { auto vv = ++v; return std::pair(v, vv); -}(km) == std::pair(quantity_point(1001_q_m), quantity_point(1001_q_m))); +}(km) == std::pair(quantity_point, metre, int>(1001_q_m), quantity_point, metre, int>(1001_q_m))); static_assert([](auto v) { auto vv = v--; return std::pair(v, vv); -}(km) == std::pair(quantity_point(999_q_m), quantity_point(1000_q_m))); +}(km) == std::pair(quantity_point, metre, int>(999_q_m), quantity_point, metre, int>(1000_q_m))); static_assert([](auto v) { auto vv = --v; return std::pair(v, vv); -}(km) == std::pair(quantity_point(999_q_m), quantity_point(999_q_m))); +}(km) == std::pair(quantity_point, metre, int>(999_q_m), quantity_point, metre, int>(999_q_m))); // compound assignment @@ -135,23 +152,23 @@ static_assert((quantity_point(2_q_m) -= 1_q_m).relative().number() == 1); // non-member arithmetic operators -static_assert(compare() + length()), - quantity_point>); -static_assert(compare() + quantity_point()), - quantity_point>); -static_assert(compare() + length()), - quantity_point>); -static_assert(compare() + quantity_point()), - quantity_point>); -static_assert(compare() - length()), - quantity_point>); -static_assert(compare() - length()), - quantity_point>); +static_assert(compare, metre, int>() + length()), + quantity_point, metre, double>>); +static_assert(compare() + quantity_point, metre, double>()), + quantity_point, metre, double>>); +static_assert(compare, kilometre, int>() + length()), + quantity_point, metre, double>>); +static_assert(compare() + quantity_point, metre, double>()), + quantity_point, metre, double>>); +static_assert(compare, metre, double>() - length()), + quantity_point, metre, double>>); +static_assert(compare, kilometre, double>() - length()), + quantity_point, metre, double>>); static_assert( - compare() - quantity_point()), + compare, metre, double>() - quantity_point, metre, int>()), length>); static_assert( - compare() - quantity_point()), + compare, kilometre, double>() - quantity_point, metre, int>()), length>); static_assert((1_q_m + km).relative().number() == 1001); @@ -159,6 +176,13 @@ static_assert((quantity_point(1_q_m) + 1_q_km).relative().number() == 1001); static_assert((km - 1_q_m).relative().number() == 999); static_assert((quantity_point(1_q_km) - quantity_point(1_q_m)).number() == 999); +template +concept invalid_subtraction = requires(quantity_point, metre, Int> lhs, + quantity_point rhs) { + requires !requires { rhs - lhs; }; +}; +static_assert(invalid_subtraction); + // comparators static_assert(quantity_point(2_q_m) + 1_q_m == quantity_point(3_q_m)); @@ -190,6 +214,14 @@ static_assert(quantity_point(999_q_m) < quantity_point(1_q_km)); static_assert(quantity_point(1000_q_m) >= quantity_point(1_q_km)); static_assert(quantity_point(1000_q_m) <= quantity_point(1_q_km)); +template +concept invalid_comparisons = requires(quantity_point, metre, Int> lhs, + quantity_point rhs) { + requires !requires { lhs == rhs; }; + requires !requires { lhs < rhs; }; +}; +static_assert(invalid_comparisons); + // alias units static_assert(quantity_point(2_q_l) + 2_q_ml == quantity_point(2002_q_ml)); @@ -199,19 +231,19 @@ static_assert(2_q_dm3 + quantity_point(2_q_cm3) == quantity_point(2002_q_ml)); // is_quantity_point -static_assert(QuantityPoint>); +static_assert(QuantityPoint, millimetre, int>>); // common_quantity_point static_assert(compare< - common_quantity_point, quantity_point>, - quantity_point>); -static_assert(compare, - quantity_point>, - quantity_point>); -static_assert(compare, - quantity_point>, - quantity_point>); + common_quantity_point, metre, int>, quantity_point, kilometre, int>>, + quantity_point, metre, int>>); +static_assert(compare, kilometre, long long>, + quantity_point, metre, int>>, + quantity_point, metre, long long>>); +static_assert(compare, kilometre, long long>, + quantity_point, millimetre, double>>, + quantity_point, millimetre, double>>); // common_type @@ -224,11 +256,11 @@ static_assert(std::equality_comparable_with>(quantity_point(2_q_km)).relative().number() == +static_assert(quantity_point_cast, metre, int>>(quantity_point(2_q_km)).relative().number() == 2000); static_assert( - quantity_point_cast>(quantity_point(2000_q_m)).relative().number() == 2); -static_assert(quantity_point_cast>(quantity_point(1.23_q_m)).relative().number() == + quantity_point_cast, kilometre, int>>(quantity_point(2000_q_m)).relative().number() == 2); +static_assert(quantity_point_cast, metre, int>>(quantity_point(1.23_q_m)).relative().number() == 1); static_assert(quantity_point_cast>(quantity_point(2_q_km)).relative().number() == 2000); static_assert(quantity_point_cast>(quantity_point(2000_q_m)).relative().number() == 2); @@ -238,6 +270,13 @@ static_assert(quantity_point_cast(quantity_point(2000_q_m)).relative( static_assert(quantity_point_cast(quantity_point(1.23_q_m)).relative().number() == 1); static_assert(quantity_point_cast(quantity_point(2000.0_q_m / 3600.0_q_s)).relative().number() == 2); +template +concept invalid_cast = requires(Int i) { + requires !requires { quantity_point_cast, second, Int>>(quantity_point(i * m)); }; + requires !requires { quantity_point_cast, metre, Int>>(quantity_point(i * m)); }; +}; +static_assert(invalid_cast); + // time static_assert(quantity_point{1_q_h} == quantity_point{3600_q_s}); @@ -263,6 +302,6 @@ concept dimensional_analysis = requires(T t) pow<2>(t); }; -static_assert(!dimensional_analysis>); +static_assert(!dimensional_analysis, metre, int>>); } // namespace diff --git a/test/unit_test/static/quantity_test.cpp b/test/unit_test/static/quantity_test.cpp index 13ea23aa..c0b458f6 100644 --- a/test/unit_test/static/quantity_test.cpp +++ b/test/unit_test/static/quantity_test.cpp @@ -281,7 +281,7 @@ static_assert([](auto v) { auto vv = ++v; return std::pair(v, vv); }(123_q_m) == static_assert([](auto v) { auto vv = v--; return std::pair(v, vv); }(123_q_m) == std::pair(122_q_m, 123_q_m)); static_assert([](auto v) { auto vv = --v; return std::pair(v, vv); }(123_q_m) == std::pair(122_q_m, 122_q_m)); -static_assert(is_same_v); +static_assert(is_same_v); //////////////////////// @@ -411,20 +411,20 @@ static_assert(is_same_v>); static_assert(compare(1)), length>); static_assert(compare(1) * 1_q_m), length>); static_assert(compare(1)), length>); -static_assert(compare(1)), length>); +static_assert(compare(1)), length>); static_assert(compare>); static_assert(compare>); static_assert(compare>); static_assert(compare>); static_assert(compare(1) / 1_q_s), frequency, std::int64_t>>); -static_assert(is_same_v); -static_assert(is_same_v); +static_assert(is_same_v); +static_assert(is_same_v); static_assert((std::uint8_t(128) * m + std::uint8_t(128) * m).number() == std::uint8_t(128) + std::uint8_t(128)); static_assert((std::uint8_t(0) * m - std::uint8_t(1) * m).number() == std::uint8_t(0) - std::uint8_t(1)); static_assert(is_same_v); + decltype(std::uint8_t(0) % std::uint8_t(0))&&>); // different representation types static_assert(is_same_v>); @@ -445,7 +445,7 @@ static_assert(compare(1) / 1._q_s), frequency, long double>>); static_assert(compare>); static_assert(compare>); -static_assert(compare(1)), length>); +static_assert(compare(1)), length>); static_assert(compare(1)), length>); static_assert(is_same_v>); @@ -487,7 +487,7 @@ static_assert(is_same_v>); static_assert(is_same_v>); static_assert(is_same_v>); -static_assert(is_same_v>); +static_assert(is_same_v>); // different dimensions static_assert(compare>); @@ -557,7 +557,7 @@ static_assert((7_q_m % 2).number() == 1); static_assert((7_q_m % quantity{2}).number() == 1); static_assert((7_q_m % dimensionless(2)).number() == 1); static_assert((7_q_m % 2_q_m).number() == 1); -static_assert((7_q_km % 2000_q_m).number() == 1000); +static_assert((7_q_km % 2000_q_m).number() == 7); static_assert((10_q_km2 * 10_q_km2) / 50_q_km2 == 2_q_km2); @@ -572,8 +572,7 @@ static_assert(quantity_cast(10_q_km / 5_q_m).number() == 2000); static_assert((10_q_s * 2_q_kHz).number() == 20); -// unit constants - +// quantity references static_assert(2_q_m * (1 * m) == (2_q_m2)); static_assert(2_q_m2 / (1 * m) == (2_q_m)); @@ -607,14 +606,14 @@ static_assert(quantity(1) - 2.3 == quantity(1 - 2.3)); static_assert(1.2 + quantity(3) == quantity(1.2 + 3)); static_assert(1.2 - quantity(3) == quantity(1.2 - 3)); -static_assert(is_same_v); -static_assert(is_same_v); +static_assert(is_same_v); +static_assert(is_same_v); static_assert((quantity{std::uint8_t(128)} + quantity{std::uint8_t(128)}).number() == std::uint8_t(128) + std::uint8_t(128)); static_assert((quantity{std::uint8_t(0)} - quantity{std::uint8_t(1)}).number() == std::uint8_t(0) - std::uint8_t(1)); static_assert(is_same_v); + decltype(std::uint8_t(0) % std::uint8_t(0))&&>); static_assert(quantity{2} * (1 * m) == 2_q_m); static_assert(quantity{2} / (1 * m) == 2 / 1_q_m); @@ -799,4 +798,62 @@ static_assert(is_same_v, decltype(3'000 * m)>); + +constexpr auto qr2 = quotient_remainder_theorem(3 * km, 400 * m); +static_assert(qr2 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr3 = quotient_remainder_theorem(3 * km, 2 * m); +static_assert(qr3 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr4 = quotient_remainder_theorem(3 * km, 400'000 * mm); +static_assert(qr4 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr5 = quotient_remainder_theorem(3 * km, 2'000 * mm); +static_assert(qr5 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr6 = quotient_remainder_theorem(3 * km, 400 * mm); +static_assert(qr6 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr7 = quotient_remainder_theorem(3 * km, 2 * mm); +static_assert(qr7 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr8 = quotient_remainder_theorem(3'000 * m, 400); +static_assert(qr8 == 3'000 * m); +static_assert(is_same_v, decltype(3'000 * m)>); + +constexpr auto qr9 = quotient_remainder_theorem(3'000 * m, quantity(400)); +static_assert(qr9 == 3'000 * m); +static_assert(is_same_v, decltype(3'000 * m)>); + +constexpr auto qr10 = quotient_remainder_theorem(3 * km, quantity(400)); +static_assert(qr10 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr11 = quotient_remainder_theorem(3 * km, quantity(2)); +static_assert(qr11 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + +constexpr auto qr12 = quotient_remainder_theorem(3 * km, dimensionless, int>(400)); +static_assert(qr12 == 3 * km); +static_assert(is_same_v, decltype(3 * km)>); + } // namespace diff --git a/test/unit_test/static/si_cgs_test.cpp b/test/unit_test/static/si_cgs_test.cpp index 9907e480..81a67faa 100644 --- a/test/unit_test/static/si_cgs_test.cpp +++ b/test/unit_test/static/si_cgs_test.cpp @@ -107,8 +107,8 @@ namespace cgs_test { // addition -// static_assert(100_q_cm + si::length(1) == si::length(2)); // should not compile (different dimensions) -// static_assert(si::length(1) + 100_q_cm == si::length(2)); // should not compile (different dimensions) +static_assert(100_q_cm + si::length(1) == si::length(2)); +static_assert(si::length(1) + 100_q_cm == si::length(2)); static_assert(quantity_cast>(100_q_cm) + si::length(1) == si::length(2)); static_assert(si::length(1) + quantity_cast>(100_q_cm) == si::length(2)); static_assert(100_q_cm + quantity_cast>(si::length(1)) == 200_q_cm); @@ -116,8 +116,8 @@ static_assert(quantity_cast>(si::length(1) == si::length(4)); // should not compile (different dimensions) -// static_assert(si::length(5) - 100_q_cm == si::length(4)); // should not compile (different dimensions) +static_assert(500_q_cm - si::length(1) == si::length(4)); +static_assert(si::length(5) - 100_q_cm == si::length(4)); static_assert(quantity_cast>(500_q_cm) - si::length(1) == si::length(4)); static_assert(si::length(5) - quantity_cast>(100_q_cm) == si::length(4)); static_assert(500_q_cm - quantity_cast>(si::length(1)) == 400_q_cm); @@ -125,7 +125,7 @@ static_assert(quantity_cast>(si::length(2) == si::area(4)); // should not compile (unknown dimension) +// static_assert(200_q_cm * si::length(2) == si::area(4)); // TODO Add support for comparing of an unknown_dimension static_assert(quantity_cast(200._q_cm) * si::length(2) == si::area(4)); static_assert(200._q_cm * quantity_cast(si::length(2)) == 40'000_q_cm2); @@ -138,7 +138,7 @@ static_assert(200._q_cm * quantity_cast(si::length(4) / 200_q_cm == si::length(2)); // should not compile (unknown dimension) +// static_assert(si::area(4) / 200_q_cm == si::length(2)); // TODO Add support for comparing of an unknown_dimension static_assert(si::area(4) / quantity_cast>(200_q_cm) == si::length(2)); static_assert(quantity_cast>(si::area(4)) / 200._q_cm == 200_q_cm); diff --git a/test/unit_test/static/si_fps_test.cpp b/test/unit_test/static/si_fps_test.cpp index 2af500c6..27fd6dc7 100644 --- a/test/unit_test/static/si_fps_test.cpp +++ b/test/unit_test/static/si_fps_test.cpp @@ -124,8 +124,8 @@ using namespace units::isq::si::fps::references; // addition -// static_assert(si::length(1) + 1 * ft == si::length(1.3048)); // should not compile (different dimensions) -// static_assert(1 * ft / 0.3048 + si::length(1) == si::length(1.3048)); // should not compile (different dimensions) +static_assert(si::length(1) + 1 * ft == si::length(1.3048)); +static_assert(1 * ft + si::length(1) == si::length(1.3048)); static_assert(quantity_cast>(1. * ft / 0.3048) + si::length(1) == si::length(2)); // 1 m in ft + 1 m static_assert(si::length(1) + quantity_cast>(1. * ft / 0.3048) == si::length(2)); // 1 m + 1 m in ft static_assert(1 * ft + quantity_cast>(si::length(0.3048)) == 2 * ft); // 1 ft + 1 ft in m @@ -133,8 +133,8 @@ static_assert(quantity_cast>(si::length(1) == -si::length(0.6952)); // should not compile (different dimensions) -// static_assert(si::length(1) - 1 * ft == si::length(0.6952)); // should not compile (different dimensions) +static_assert(1 * ft - si::length(1) == -si::length(0.6952)); +static_assert(si::length(1) - 1 * ft == si::length(0.6952)); static_assert(quantity_cast>(6. * ft) - si::length(1) > si::length(0.8287) && quantity_cast>(6. * ft) - si::length(1) < si::length(0.8289)); // 6 ft in m - 1 m = ... m static_assert(si::length(5) - quantity_cast>(6 * ft) == si::length(3.1712)); // 5 m - 6 ft in m = ... @@ -143,14 +143,14 @@ static_assert(quantity_cast>(si::length(2) == si::area(1.2192)); // should not compile (unknown dimension) -// static_assert(quantity_cast>(2. * ft) * si::length(2) == si::area(1.2192)); +// static_assert(2 * ft * si::length(2) == si::area(1.2192)); // TODO Add support for comparing of an unknown_dimension +static_assert(quantity_cast>(2. * ft) * si::length(2) == si::area(1.2192)); static_assert(quantity_cast>(2. * ft) * si::length(0.6096) == si::area(0.371612160)); // 2 ft * 2 ft == 4 sq ft static_assert(2. * ft * quantity_cast>(si::length(0.6096)) == 4._q_ft2); // division -// static_assert(si::area(4) / 200_q_cm == si::length(2)); // should not compile (unknown dimension) +// static_assert(si::area(4) / 200_q_cm == si::length(2)); // TODO Add support for comparing of an unknown_dimension static_assert(si::area(1.48644864) / quantity_cast>(4 * ft) == si::length(1.2192)); // 16 ft2 / 4 ft = 4 ft static_assert(quantity_cast>(si::area(1.48644864)) / (4. * ft) == 4. * ft); // 16 ft2 / 4 ft = 4 ft diff --git a/test/unit_test/static/si_test.cpp b/test/unit_test/static/si_test.cpp index 29b27fa7..bc7e16fb 100644 --- a/test/unit_test/static/si_test.cpp +++ b/test/unit_test/static/si_test.cpp @@ -246,17 +246,17 @@ static_assert(kilogray::symbol == "kGy"); static_assert(10_q_m / 5_q_s == 2_q_m_per_s); static_assert(10 / 5_q_s * 1_q_m == 2_q_m_per_s); static_assert(1_q_km / 1_q_s == 1000_q_m_per_s); -// static_assert(1_q_km / 1_q_h == 1_q_km_per_h); // should not compile +static_assert(1_q_km / 1_q_h == 1_q_km_per_h); static_assert(1.0_q_km / 1_q_h == 1_q_km_per_h); static_assert(1000.0_q_m / 3600.0_q_s == 1_q_km_per_h); static_assert(2_q_km_per_h * 2_q_h == 4_q_km); -// static_assert(2_q_km_per_h * 15_q_min == 500_q_m); // should not compile +static_assert(2_q_km_per_h * 15_q_min == 500_q_m); static_assert(2_q_km_per_h * 15.0_q_min == 500_q_m); static_assert(2.0_q_km_per_h * 15_q_min == 500_q_m); static_assert(2_q_km / 2_q_km_per_h == 1_q_h); -// static_assert(2000_q_m / 2_q_km_per_h == 1_q_h); // should not compile +static_assert(2000_q_m / 2_q_km_per_h == 1_q_h); static_assert(quantity_cast(2000_q_m) / 2_q_km_per_h == 1_q_h); static_assert(detail::unit_text() == "m/s"); @@ -382,6 +382,8 @@ static_assert(1_q_J_per_mol * 1_q_mol_per_m3 * 1_q_m3 == 1_q_N * 1_q_m); static_assert(detail::unit_text() == "J/mol"); // angular velocity + static_assert(1_q_rad / 1_q_s == 1_q_rad_per_s); static_assert(detail::unit_text() == basic_symbol_text("ω", "w")); + } // namespace diff --git a/test/unit_test/static/unit_test.cpp b/test/unit_test/static/unit_test.cpp index f8d0315d..ec657dad 100644 --- a/test/unit_test/static/unit_test.cpp +++ b/test/unit_test/static/unit_test.cpp @@ -52,7 +52,7 @@ static_assert([](P) { return !requires { typename prefixed_unit {}; struct dim_speed : derived_dimension, units::exponent> {}; -struct kilometre_per_hour : deduced_unit {}; +struct kilometre_per_hour : derived_unit {}; static_assert(equivalent); static_assert(equivalent); diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index f04c2b0b..8a5eec85 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -29,4 +29,3 @@ find_package(mp-units CONFIG REQUIRED) add_executable(test_package test_package.cpp) target_link_libraries(test_package PRIVATE mp-units::mp-units) -target_compile_definitions(test_package PRIVATE UNITS_REFERENCES) diff --git a/test_package/conanfile.py b/test_package/conanfile.py index d6ed6b6c..f72ce180 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -22,12 +22,13 @@ from conans import ConanFile, tools, RunEnvironment from conan.tools.cmake import CMakeToolchain, CMake, CMakeDeps +import os class TestPackageConan(ConanFile): settings = "os", "compiler", "build_type", "arch" def generate(self): - tc = CMakeToolchain(self) + tc = CMakeToolchain(self, generator=os.getenv("CONAN_CMAKE_GENERATOR")) tc.generate() deps = CMakeDeps(self) deps.generate()