mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-29 18:07:16 +02:00
feat: 💥 API-related Conan, CMake, and preprocessor options redesigned
This commit is contained in:
4
.github/workflows/ci-conan.yml
vendored
4
.github/workflows/ci-conan.yml
vendored
@ -221,13 +221,13 @@ jobs:
|
|||||||
sed -i.backup '/^\[settings\]$/,/^\[/ s/^compiler.cppstd=.*/compiler.cppstd=${{ matrix.std }}/' ~/.conan2/profiles/default
|
sed -i.backup '/^\[settings\]$/,/^\[/ s/^compiler.cppstd=.*/compiler.cppstd=${{ matrix.std }}/' ~/.conan2/profiles/default
|
||||||
sed -i.backup '/^\[settings\]$/,/^\[/ s/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/default
|
sed -i.backup '/^\[settings\]$/,/^\[/ s/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/default
|
||||||
conan profile show -pr default
|
conan profile show -pr default
|
||||||
- run: echo "use_fmtlib=$([ "${{ matrix.formatting }}" == "fmtlib" ] && echo "True" || echo "False")" >> $GITHUB_ENV
|
- run: echo "std_format=$([ "${{ matrix.formatting }}" == "std::format" ] && echo "True" || echo "False")" >> $GITHUB_ENV
|
||||||
- name: Create Conan package
|
- name: Create Conan package
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
conan create . --user mpusz --channel ${CHANNEL} --lockfile-out=package.lock \
|
conan create . --user mpusz --channel ${CHANNEL} --lockfile-out=package.lock \
|
||||||
-b mp-units/* -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" \
|
-b mp-units/* -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" \
|
||||||
-c user.mp-units.build:all=True -o cxx_modules=${{ matrix.config.cxx_modules }} -o use_fmtlib=${{ env.use_fmtlib }} ${{ matrix.config.conan-config }}
|
-c user.mp-units.build:all=True -o cxx_modules=${{ matrix.config.cxx_modules }} -o std_format=${{ env.std_format }} ${{ matrix.config.conan-config }}
|
||||||
- name: Obtain package reference
|
- name: Obtain package reference
|
||||||
id: get-package-ref
|
id: get-package-ref
|
||||||
shell: bash
|
shell: bash
|
||||||
|
4
.github/workflows/ci-test-package-cmake.yml
vendored
4
.github/workflows/ci-test-package-cmake.yml
vendored
@ -215,12 +215,12 @@ jobs:
|
|||||||
sed -i.backup '/^\[settings\]$/,/^\[/ s/^compiler.cppstd=.*/compiler.cppstd=${{ matrix.std }}/' ~/.conan2/profiles/default
|
sed -i.backup '/^\[settings\]$/,/^\[/ s/^compiler.cppstd=.*/compiler.cppstd=${{ matrix.std }}/' ~/.conan2/profiles/default
|
||||||
sed -i.backup '/^\[settings\]$/,/^\[/ s/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/default
|
sed -i.backup '/^\[settings\]$/,/^\[/ s/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/default
|
||||||
conan profile show -pr default
|
conan profile show -pr default
|
||||||
- run: echo "use_fmtlib=$([ "${{ matrix.formatting }}" == "fmtlib" ] && echo "True" || echo "False")" >> $GITHUB_ENV
|
- run: echo "std_format=$([ "${{ matrix.formatting }}" == "std::format" ] && echo "True" || echo "False")" >> $GITHUB_ENV
|
||||||
- name: Install Conan dependencies
|
- name: Install Conan dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
conan install . -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" -c user.mp-units.build:all=False \
|
conan install . -b missing -c tools.cmake.cmaketoolchain:generator="Ninja Multi-Config" -c user.mp-units.build:all=False \
|
||||||
-o cxx_modules=${{ matrix.config.cxx_modules }} -o use_fmtlib=${{ env.use_fmtlib }}
|
-o cxx_modules=${{ matrix.config.cxx_modules }} -o std_format=${{ env.std_format }}
|
||||||
mv CMakeUserPresets.json src
|
mv CMakeUserPresets.json src
|
||||||
- name: Configure mp-units CMake
|
- name: Configure mp-units CMake
|
||||||
if: matrix.config.compiler.type == 'VISUAL' || matrix.config.compiler.type == 'MSVC'
|
if: matrix.config.compiler.type == 'VISUAL' || matrix.config.compiler.type == 'MSVC'
|
||||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@ -105,7 +105,7 @@ jobs:
|
|||||||
conan profile detect --force
|
conan profile detect --force
|
||||||
conan remote add artifactory https://mpusz.jfrog.io/artifactory/api/conan/conan-oss
|
conan remote add artifactory https://mpusz.jfrog.io/artifactory/api/conan/conan-oss
|
||||||
mkdir _lgtm_build_dir && cd _lgtm_build_dir
|
mkdir _lgtm_build_dir && cd _lgtm_build_dir
|
||||||
conan build .. -s compiler.cppstd=20 -c user.mp-units.build:all=True -o use_fmtlib=True -b missing
|
conan build .. -s compiler.cppstd=20 -c user.mp-units.build:all=True -o std_format=False -b missing
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v2
|
||||||
|
32
.gitpod.yml
32
.gitpod.yml
@ -70,17 +70,17 @@ tasks:
|
|||||||
gp sync-await python-init
|
gp sync-await python-init
|
||||||
conan profile detect
|
conan profile detect
|
||||||
conan config install $PWD/.gitpod/conan
|
conan config install $PWD/.gitpod/conan
|
||||||
conan install . -pr gcc12 -o use_fmtlib=True -b missing
|
conan install . -pr gcc12 -o std_format=False -b missing
|
||||||
conan install . -pr gcc12 -o use_fmtlib=True -b missing -s build_type=Debug
|
conan install . -pr gcc12 -o std_format=False -b missing -s build_type=Debug
|
||||||
gp sync-done conan-gcc12-20
|
gp sync-done conan-gcc12-20
|
||||||
conan install . -pr gcc13 -b missing
|
conan install . -pr gcc13 -o std_format=True -b missing
|
||||||
conan install . -pr gcc13 -b missing -s build_type=Debug
|
conan install . -pr gcc13 -o std_format=True -b missing -s build_type=Debug
|
||||||
gp sync-done conan-gcc13-20
|
gp sync-done conan-gcc13-20
|
||||||
conan install . -pr clang16 -o use_fmtlib=True -b missing
|
conan install . -pr clang16 -o std_format=False -b missing
|
||||||
conan install . -pr clang16 -o use_fmtlib=True -b missing -s build_type=Debug
|
conan install . -pr clang16 -o std_format=False -b missing -s build_type=Debug
|
||||||
gp sync-done conan-clang16-20
|
gp sync-done conan-clang16-20
|
||||||
conan install . -pr clang17 -o cxx_modules=True -b missing
|
conan install . -pr clang17 -o std_format=True -o cxx_modules=True -b missing
|
||||||
conan install . -pr clang17 -o cxx_modules=True -b missing -s build_type=Debug
|
conan install . -pr clang17 -o std_format=True -o cxx_modules=True -b missing -s build_type=Debug
|
||||||
gp sync-done conan-clang17-20
|
gp sync-done conan-clang17-20
|
||||||
conan remote login -p $ARTIFACTORY_TOKEN conan-gitpod-mp-units $ARTIFACTORY_USER
|
conan remote login -p $ARTIFACTORY_TOKEN conan-gitpod-mp-units $ARTIFACTORY_USER
|
||||||
conan upload "*" -r conan-gitpod-mp-units -c
|
conan upload "*" -r conan-gitpod-mp-units -c
|
||||||
@ -88,29 +88,29 @@ tasks:
|
|||||||
init: |
|
init: |
|
||||||
gp sync-await conan-gcc12-20
|
gp sync-await conan-gcc12-20
|
||||||
source ${PYTHON_VENV}/bin/activate
|
source ${PYTHON_VENV}/bin/activate
|
||||||
conan build . -pr gcc12 -o use_fmtlib=True
|
conan build . -pr gcc12 -o std_format=False
|
||||||
conan build . -pr gcc12 -o use_fmtlib=True -s build_type=Debug
|
conan build . -pr gcc12 -o std_format=False -s build_type=Debug
|
||||||
echo "🛠️ gcc-12 pre-build done for C++20, header files, and libfmt! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
echo "🛠️ gcc-12 pre-build done for C++20, header files, and libfmt! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
||||||
- name: gcc-13-20
|
- name: gcc-13-20
|
||||||
init: |
|
init: |
|
||||||
gp sync-await conan-gcc13-20
|
gp sync-await conan-gcc13-20
|
||||||
source ${PYTHON_VENV}/bin/activate
|
source ${PYTHON_VENV}/bin/activate
|
||||||
conan build . -pr gcc13
|
conan build . -pr gcc13 -o std_format=True
|
||||||
conan build . -pr gcc13 -s build_type=Debug
|
conan build . -pr gcc13 -o std_format=True -s build_type=Debug
|
||||||
echo "🛠️ gcc-13 pre-build done for C++20 and header files! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
echo "🛠️ gcc-13 pre-build done for C++20 and header files! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
||||||
- name: clang-16-20
|
- name: clang-16-20
|
||||||
init: |
|
init: |
|
||||||
gp sync-await conan-clang16-20
|
gp sync-await conan-clang16-20
|
||||||
source ${PYTHON_VENV}/bin/activate
|
source ${PYTHON_VENV}/bin/activate
|
||||||
conan build . -pr clang16 -o use_fmtlib=True
|
conan build . -pr clang16 -o std_format=False
|
||||||
conan build . -pr clang16 -o use_fmtlib=True -s build_type=Debug
|
conan build . -pr clang16 -o std_format=False -s build_type=Debug
|
||||||
echo "🛠️ clang-16 pre-build done for C++20, header files, and libfmt! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
echo "🛠️ clang-16 pre-build done for C++20, header files, and libfmt! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
||||||
- name: clang-17-20
|
- name: clang-17-20
|
||||||
init: |
|
init: |
|
||||||
gp sync-await conan-clang17-20
|
gp sync-await conan-clang17-20
|
||||||
source ${PYTHON_VENV}/bin/activate
|
source ${PYTHON_VENV}/bin/activate
|
||||||
conan build . -pr clang17 -o cxx_modules=True
|
conan build . -pr clang17 -o std_format=True -o cxx_modules=True
|
||||||
conan build . -pr clang17 -o cxx_modules=True -s build_type=Debug
|
conan build . -pr clang17 -o std_format=True -o cxx_modules=True -s build_type=Debug
|
||||||
echo "🛠️ clang-17 pre-build done for C++20! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
echo "🛠️ clang-17 pre-build done for C++20! You can close this terminal and use 'Build' button in the VSCode status bar for incremental builds. 🛠️"
|
||||||
- name: documentation
|
- name: documentation
|
||||||
init: |
|
init: |
|
||||||
|
@ -77,7 +77,7 @@ Before submission, please remember to check if the code compiles fine on the sup
|
|||||||
The CI will check it anyway but it is good to check at least some of the configurations before pushing changes.
|
The CI will check it anyway but it is good to check at least some of the configurations before pushing changes.
|
||||||
Especially older compilers can be tricky as those do not support all the C++20 features well enough. The official
|
Especially older compilers can be tricky as those do not support all the C++20 features well enough. The official
|
||||||
list of supported compilers can be always found in the
|
list of supported compilers can be always found in the
|
||||||
[Installation And Usage](https://mpusz.github.io/mp-units/latest/getting_started/installation_and_usage/#cpp-compiler-support)
|
[Installation And Usage](https://mpusz.github.io/mp-units/latest/getting_started/cpp_compiler_support)
|
||||||
chapter of our documentation.
|
chapter of our documentation.
|
||||||
|
|
||||||
|
|
||||||
|
167
conanfile.py
167
conanfile.py
@ -25,13 +25,20 @@ import re
|
|||||||
|
|
||||||
from conan import ConanFile
|
from conan import ConanFile
|
||||||
from conan.errors import ConanInvalidConfiguration
|
from conan.errors import ConanInvalidConfiguration
|
||||||
from conan.tools.build import can_run, check_min_cppstd
|
from conan.tools.build import can_run, default_cppstd, valid_min_cppstd
|
||||||
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
|
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
|
||||||
from conan.tools.files import copy, load, rmdir
|
from conan.tools.files import copy, load, rmdir
|
||||||
|
|
||||||
required_conan_version = ">=2.0.0"
|
required_conan_version = ">=2.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
def loose_lt_semver(v1, v2):
|
||||||
|
lv1 = [int(v) for v in v1.split(".")]
|
||||||
|
lv2 = [int(v) for v in v2.split(".")]
|
||||||
|
min_length = min(len(lv1), len(lv2))
|
||||||
|
return lv1[:min_length] < lv2[:min_length]
|
||||||
|
|
||||||
|
|
||||||
class MPUnitsConan(ConanFile):
|
class MPUnitsConan(ConanFile):
|
||||||
name = "mp-units"
|
name = "mp-units"
|
||||||
homepage = "https://github.com/mpusz/mp-units"
|
homepage = "https://github.com/mpusz/mp-units"
|
||||||
@ -54,14 +61,18 @@ class MPUnitsConan(ConanFile):
|
|||||||
url = "https://github.com/mpusz/mp-units"
|
url = "https://github.com/mpusz/mp-units"
|
||||||
settings = "os", "arch", "compiler", "build_type"
|
settings = "os", "arch", "compiler", "build_type"
|
||||||
options = {
|
options = {
|
||||||
"cxx_modules": [True, False],
|
"cxx_modules": ["auto", True, False],
|
||||||
"use_fmtlib": [True, False],
|
"std_format": ["auto", True, False],
|
||||||
|
"string_view_ret": ["auto", True, False],
|
||||||
|
"no_crtp": ["auto", True, False],
|
||||||
}
|
}
|
||||||
default_options = {
|
default_options = {
|
||||||
"cxx_modules": False,
|
"cxx_modules": "auto",
|
||||||
"use_fmtlib": False,
|
"std_format": "auto",
|
||||||
|
"string_view_ret": "auto",
|
||||||
|
"no_crtp": "auto",
|
||||||
}
|
}
|
||||||
tool_requires = "cmake/[>=3.28.1]"
|
tool_requires = "cmake/[>=3.29]"
|
||||||
exports = "LICENSE.md"
|
exports = "LICENSE.md"
|
||||||
exports_sources = (
|
exports_sources = (
|
||||||
"docs/*",
|
"docs/*",
|
||||||
@ -75,27 +86,106 @@ class MPUnitsConan(ConanFile):
|
|||||||
no_copy_source = True
|
no_copy_source = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _minimum_compilers_version(self):
|
def _feature_compatibility(self):
|
||||||
return {
|
return {
|
||||||
"gcc": "12",
|
"minimum_support": {
|
||||||
"clang": "16",
|
"std": "20",
|
||||||
"apple-clang": "15",
|
"compiler": {
|
||||||
# , "msvc": "192"
|
"gcc": "12",
|
||||||
|
"clang": "16",
|
||||||
|
"apple-clang": "15",
|
||||||
|
"msvc": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"std_format": {
|
||||||
|
"std": "20",
|
||||||
|
"compiler": {
|
||||||
|
"gcc": "13",
|
||||||
|
"clang": "17",
|
||||||
|
"apple-clang": "",
|
||||||
|
"msvc": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"cxx_modules": {
|
||||||
|
"std": "20",
|
||||||
|
"compiler": {"gcc": "14", "clang": "17", "apple-clang": "", "msvc": ""},
|
||||||
|
},
|
||||||
|
"static_constexpr_vars_in_constexpr_func": {
|
||||||
|
"std": "23",
|
||||||
|
"compiler": {"gcc": "13", "clang": "17", "apple-clang": "", "msvc": ""},
|
||||||
|
},
|
||||||
|
"explicit_this": {
|
||||||
|
"std": "23",
|
||||||
|
"compiler": {
|
||||||
|
"gcc": "14",
|
||||||
|
"clang": "18",
|
||||||
|
"apple-clang": "",
|
||||||
|
"msvc": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _std_format_minimum_compilers_version(self):
|
def _option_feature_map(self):
|
||||||
return {
|
return {
|
||||||
"gcc": "13",
|
"std_format": "std_format",
|
||||||
"clang": "17",
|
"cxx_modules": "cxx_modules",
|
||||||
# , "apple-clang": "15"
|
"string_view_ret": "static_constexpr_vars_in_constexpr_func",
|
||||||
# , "msvc": "192"
|
"no_crtp": "explicit_this",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _check_feature_supported(self, name, feature_name=name):
|
||||||
|
compiler = self.settings.compiler
|
||||||
|
cppstd = compiler.get_safe("cppstd", default_cppstd(self))
|
||||||
|
feature = self._feature_compatibility[feature_name]
|
||||||
|
|
||||||
|
# check C++ version
|
||||||
|
if not valid_min_cppstd(self, feature["std"]):
|
||||||
|
raise ConanInvalidConfiguration(
|
||||||
|
f"'{name}' requires at least cppstd={feature['std']} ({cppstd} in use)",
|
||||||
|
)
|
||||||
|
|
||||||
|
# check compiler version
|
||||||
|
min_version = feature["compiler"].get(str(compiler))
|
||||||
|
if min_version is None:
|
||||||
|
# not tested compiler being used - use at your own risk
|
||||||
|
return
|
||||||
|
if min_version == "":
|
||||||
|
raise ConanInvalidConfiguration(
|
||||||
|
f"'{name}' is not yet supported by any known {compiler} compiler"
|
||||||
|
)
|
||||||
|
if loose_lt_semver(str(compiler.version), min_version):
|
||||||
|
raise ConanInvalidConfiguration(
|
||||||
|
f"'{name}' requires at least {compiler}-{min_version} ({compiler}-{compiler.version} in use)"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _is_feature_enabled(self, name):
|
||||||
|
compiler = self.settings.compiler
|
||||||
|
opt = self.options.get_safe(name)
|
||||||
|
feature_name = self._option_feature_map[name]
|
||||||
|
feature = self._feature_compatibility[feature_name]
|
||||||
|
min_version = feature["compiler"].get(str(compiler))
|
||||||
|
return bool(
|
||||||
|
opt is True
|
||||||
|
or (
|
||||||
|
opt == "auto"
|
||||||
|
and min_version
|
||||||
|
and not loose_lt_semver(str(compiler.version), min_version)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _build_all(self):
|
def _build_all(self):
|
||||||
return bool(self.conf.get("user.mp-units.build:all", default=False))
|
return bool(self.conf.get("user.mp-units.build:all", default=False))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _build_cxx_modules(self):
|
||||||
|
return self._is_feature_enabled("cxx_modules")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _use_fmtlib(self):
|
||||||
|
return not self._is_feature_enabled("std_format")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _skip_la(self):
|
def _skip_la(self):
|
||||||
return bool(self.conf.get("user.mp-units.build:skip_la", default=False))
|
return bool(self.conf.get("user.mp-units.build:skip_la", default=False))
|
||||||
@ -109,7 +199,7 @@ class MPUnitsConan(ConanFile):
|
|||||||
|
|
||||||
def requirements(self):
|
def requirements(self):
|
||||||
self.requires("gsl-lite/0.41.0")
|
self.requires("gsl-lite/0.41.0")
|
||||||
if self.options.use_fmtlib:
|
if self._use_fmtlib:
|
||||||
self.requires("fmt/10.2.1")
|
self.requires("fmt/10.2.1")
|
||||||
|
|
||||||
def build_requirements(self):
|
def build_requirements(self):
|
||||||
@ -119,27 +209,10 @@ class MPUnitsConan(ConanFile):
|
|||||||
self.test_requires("wg21-linear_algebra/0.7.3")
|
self.test_requires("wg21-linear_algebra/0.7.3")
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
check_min_cppstd(self, "20")
|
self._check_feature_supported("mp-units", "minimum_support")
|
||||||
|
for key, value in self._option_feature_map.items():
|
||||||
def loose_lt_semver(v1, v2):
|
if self.options.get_safe(key) is True:
|
||||||
lv1 = [int(v) for v in v1.split(".")]
|
self._check_feature_supported(key, value)
|
||||||
lv2 = [int(v) for v in v2.split(".")]
|
|
||||||
min_length = min(len(lv1), len(lv2))
|
|
||||||
return lv1[:min_length] < lv2[:min_length]
|
|
||||||
|
|
||||||
compiler = self.settings.compiler
|
|
||||||
min_version = self._minimum_compilers_version.get(str(compiler))
|
|
||||||
if min_version and loose_lt_semver(str(compiler.version), min_version):
|
|
||||||
raise ConanInvalidConfiguration(
|
|
||||||
f"{self.ref} requires at least {compiler} {min_version} ({compiler.version} in use)"
|
|
||||||
)
|
|
||||||
if not self.options.use_fmtlib:
|
|
||||||
min_version = self._std_format_minimum_compilers_version.get(str(compiler))
|
|
||||||
if min_version and loose_lt_semver(str(compiler.version), min_version):
|
|
||||||
raise ConanInvalidConfiguration(
|
|
||||||
f"`std::format` requires at least {compiler} {min_version} ({compiler.version} in use). "
|
|
||||||
"Use `-o use_fmtlib=True` instead."
|
|
||||||
)
|
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
cmake_layout(self)
|
cmake_layout(self)
|
||||||
@ -148,13 +221,19 @@ class MPUnitsConan(ConanFile):
|
|||||||
tc = CMakeToolchain(self)
|
tc = CMakeToolchain(self)
|
||||||
if self._build_all:
|
if self._build_all:
|
||||||
tc.cache_variables["CMAKE_VERIFY_INTERFACE_HEADER_SETS"] = True
|
tc.cache_variables["CMAKE_VERIFY_INTERFACE_HEADER_SETS"] = True
|
||||||
if self.options.cxx_modules:
|
tc.cache_variables["MP_UNITS_DEV_BUILD_LA"] = not self._skip_la
|
||||||
|
if self._build_cxx_modules:
|
||||||
tc.cache_variables["CMAKE_CXX_SCAN_FOR_MODULES"] = True
|
tc.cache_variables["CMAKE_CXX_SCAN_FOR_MODULES"] = True
|
||||||
tc.cache_variables["MP_UNITS_BUILD_CXX_MODULES"] = True
|
tc.cache_variables["MP_UNITS_BUILD_CXX_MODULES"] = str(
|
||||||
tc.cache_variables["MP_UNITS_DEV_BUILD_LA"] = (
|
self.options.cxx_modules
|
||||||
self._build_all and not self._skip_la
|
).upper()
|
||||||
)
|
tc.cache_variables["MP_UNITS_API_STD_FORMAT"] = str(
|
||||||
tc.cache_variables["MP_UNITS_USE_FMTLIB"] = bool(self.options.use_fmtlib)
|
self.options.std_format
|
||||||
|
).upper()
|
||||||
|
tc.cache_variables["MP_UNITS_API_STRING_VIEW_RET"] = str(
|
||||||
|
self.options.string_view_ret
|
||||||
|
).upper()
|
||||||
|
tc.cache_variables["MP_UNITS_API_NO_CRTP"] = str(self.options.no_crtp).upper()
|
||||||
tc.generate()
|
tc.generate()
|
||||||
deps = CMakeDeps(self)
|
deps = CMakeDeps(self)
|
||||||
deps.generate()
|
deps.generate()
|
||||||
|
90
docs/getting_started/cpp_compiler_support.md
Normal file
90
docs/getting_started/cpp_compiler_support.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# C++ compiler support (API/ABI) { #cpp-compiler-support }
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
**mp-units** library tries to provide the best user experience possible with the C++ language.
|
||||||
|
To achieve that, it extensively uses the latest C++ language features.
|
||||||
|
|
||||||
|
Even though the library benefits from the latest C++ versions (if available), C++20 is enough
|
||||||
|
to compile and use all of the library's functionality. Newer features can be hidden behind
|
||||||
|
some [preprocessor macros](../users_guide/use_cases/wide_compatibility.md#compatibility-macros)
|
||||||
|
providing a backward-compatible way to use them.
|
||||||
|
|
||||||
|
The table below provides the minimum compiler version required to compile the code using a specific
|
||||||
|
C++ feature:
|
||||||
|
|
||||||
|
| C++ Feature | C++ version | gcc | clang | apple-clang | MSVC |
|
||||||
|
|-----------------------------------------------------------|:-----------:|:---:|:-----:|:-----------:|:----:|
|
||||||
|
| **Minimum support** | 20 | 12 | 16 | 15 | None |
|
||||||
|
| **`std::format`** | 20 | 13 | 17 | None | None |
|
||||||
|
| **C++ modules** | 20 | 14 | 17 | None | None |
|
||||||
|
| **Static `constexpr` variables in `constexpr` functions** | 23 | 13 | 17 | None | None |
|
||||||
|
| **Explicit `this` parameter** | 23 | 14 | 18 | None | None |
|
||||||
|
|
||||||
|
!!! important
|
||||||
|
|
||||||
|
Enabling/disabling features listed above may influence the API of the library and the ABI of
|
||||||
|
the customers' projects.
|
||||||
|
|
||||||
|
|
||||||
|
## `std::format`
|
||||||
|
|
||||||
|
- Provides [powerful text formatting capabilities](../users_guide/framework_basics/text_output.md#stdformat)
|
||||||
|
for C++.
|
||||||
|
- An alternative [fmtlib](https://github.com/fmtlib/fmt) library can be used instead if
|
||||||
|
- the C++ language feature is not supported,
|
||||||
|
- the customer's project did not switch to `std::format` yet (even when the compiler
|
||||||
|
supports it).
|
||||||
|
- To write code with wide compatibility
|
||||||
|
a [dedicated macro may be used](../users_guide/use_cases/wide_compatibility.md#mp_units_std_fmt).
|
||||||
|
- Tested with `__cpp_lib_format` [feature test macro](https://en.cppreference.com/w/cpp/feature_test).
|
||||||
|
- Related build options:
|
||||||
|
- Conan: [std_format](installation_and_usage.md#std_format)
|
||||||
|
- CMake: [MP_UNITS_API_STD_FORMAT](installation_and_usage.md#MP_UNITS_API_STD_FORMAT)
|
||||||
|
|
||||||
|
|
||||||
|
## C++ modules
|
||||||
|
|
||||||
|
- Provide new way to share declarations and definitions across translation units.
|
||||||
|
- If used, the library will distribute both "old-style" headers and module interface units
|
||||||
|
- associated with the same CMake targets.
|
||||||
|
- Even with full compiler support, a user may still decide to not pay for C++ modules compilation
|
||||||
|
if they are not needed by the customer's project.
|
||||||
|
- Feature test macro is not used for testing here because even if the compiler does not support
|
||||||
|
the entire C++ feature (e.g. header units), it is enough to build modules for this library.
|
||||||
|
- Related build options:
|
||||||
|
- Conan: [cxx_modules](installation_and_usage.md#cxx_modules)
|
||||||
|
- CMake: [MP_UNITS_BUILD_CXX_MODULES](installation_and_usage.md#MP_UNITS_BUILD_CXX_MODULES)
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
More requirements for C++ modules support can be found in the
|
||||||
|
[CMake's documentation](https://cmake.org/cmake/help/latest/manual/cmake-cxxmodules.7.html).
|
||||||
|
|
||||||
|
|
||||||
|
## Static `constexpr` variables in `constexpr` functions
|
||||||
|
|
||||||
|
- Allows returning `std::string_view` from the
|
||||||
|
[`unit_symbol()`](../users_guide/framework_basics/text_output.md#unit_symbol)
|
||||||
|
and [`dimension_symbol()`](../users_guide/framework_basics/text_output.md#dimension_symbol)
|
||||||
|
functions
|
||||||
|
- `std::string_view` type has a reference semantics so it has to point to a storage with
|
||||||
|
a longer lifetime.
|
||||||
|
- If this feature is not available, the API returns `mp_units::basic_fixed_string<CharT, N>` instead.
|
||||||
|
- Tested as `__cpp_constexpr >= 202211L` [feature test macro](https://en.cppreference.com/w/cpp/feature_test).
|
||||||
|
- Related build options:
|
||||||
|
- Conan: [string_view_ret](installation_and_usage.md#string_view_ret)
|
||||||
|
- CMake: [MP_UNITS_API_STRING_VIEW_RET](installation_and_usage.md#MP_UNITS_API_STRING_VIEW_RET)
|
||||||
|
|
||||||
|
## Explicit `this` parameter
|
||||||
|
|
||||||
|
- This feature removes the need for the usage of the CRTP idiom in the
|
||||||
|
[`quantity_spec` definitions](../users_guide/framework_basics/systems_of_quantities.md#defining-quantities).
|
||||||
|
- To write code with wide compatibility
|
||||||
|
a [dedicated macro may be used](../users_guide/use_cases/wide_compatibility.md#QUANTITY_SPEC).
|
||||||
|
- Tested with `__cpp_explicit_this_parameter` [feature test macro](https://en.cppreference.com/w/cpp/feature_test).
|
||||||
|
- Related build options:
|
||||||
|
- Conan: [no_crtp](installation_and_usage.md#no_crtp)
|
||||||
|
- CMake: [MP_UNITS_API_NO_CRTP](installation_and_usage.md#MP_UNITS_API_NO_CRTP)
|
||||||
|
|
||||||
|
*[CRTP]: Curiously Recurring Template Parameter
|
@ -3,60 +3,12 @@
|
|||||||
This chapter provides all the necessary information to obtain and build the code using **mp-units**.
|
This chapter provides all the necessary information to obtain and build the code using **mp-units**.
|
||||||
It also describes how to build or distribute the library and generate its documentation.
|
It also describes how to build or distribute the library and generate its documentation.
|
||||||
|
|
||||||
## C++ compiler support { #cpp-compiler-support }
|
|
||||||
|
|
||||||
!!! info
|
|
||||||
|
|
||||||
**mp-units** library tries to provide the best user experience possible with the C++ language.
|
|
||||||
To achieve that, it extensively uses C++20 features and the
|
|
||||||
[explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter)
|
|
||||||
from C++23.
|
|
||||||
|
|
||||||
Even though the library benefits from C++23 (if available), C++20 is enough to compile and
|
|
||||||
use all of the library's functionality. C++23 features are hidden behind
|
|
||||||
a [preprocessor macro](../users_guide/framework_basics/systems_of_quantities.md#defining-quantities)
|
|
||||||
providing a backward-compatible way to use it.
|
|
||||||
|
|
||||||
The below table provides the minimum compiler version required to compile the code using the
|
|
||||||
specific feature:
|
|
||||||
|
|
||||||
| Feature | gcc | clang | apple-clang | MSVC |
|
|
||||||
|----------------------|:---:|:-----:|:-----------:|:----:|
|
|
||||||
| **Minimum support** | 12 | 16 | 15 | None |
|
|
||||||
| **`std::format`** | 13 | 17 | None | None |
|
|
||||||
| **C++ modules** | 14 | 17 | None | None |
|
|
||||||
| **C++23 extensions** | 14 | 18 | None | None |
|
|
||||||
|
|
||||||
More requirements for C++ modules support can be found in the
|
|
||||||
[CMake's documentation](https://cmake.org/cmake/help/latest/manual/cmake-cxxmodules.7.html).
|
|
||||||
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
|
|
||||||
The **mp-units** library provides the following C++ modules.
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart TD
|
|
||||||
mp_units --- mp_units.systems --- mp_units.core
|
|
||||||
```
|
|
||||||
|
|
||||||
| C++ Module | CMake Target | Contents |
|
|
||||||
|--------------------|----------------------|----------------------------------------------------------|
|
|
||||||
| `mp_units.core` | `mp-units::core` | Core library framework and systems-independent utilities |
|
|
||||||
| `mp_units.systems` | `mp-units::systems` | All the systems of quantities and units |
|
|
||||||
| `mp_units` | `mp-units::mp-units` | Core + Systems |
|
|
||||||
|
|
||||||
!!! note
|
|
||||||
|
|
||||||
C++ modules are provided within the package only when [`cxx_modules`](#cxx_modules) Conan
|
|
||||||
option is set to `True`.
|
|
||||||
|
|
||||||
|
|
||||||
## Repository structure and dependencies
|
## Repository structure and dependencies
|
||||||
|
|
||||||
This repository contains three independent CMake-based projects:
|
This repository contains three independent CMake-based projects:
|
||||||
|
|
||||||
- _./src_
|
- **_./src_**
|
||||||
|
|
||||||
- header-only project containing whole **mp-units** library
|
- header-only project containing whole **mp-units** library
|
||||||
- _./src/CMakeList.txt_ file is intended as an **entry point for library users**
|
- _./src/CMakeList.txt_ file is intended as an **entry point for library users**
|
||||||
@ -68,7 +20,7 @@ This repository contains three independent CMake-based projects:
|
|||||||
- [{fmt}](https://github.com/fmtlib/fmt) to provide text formatting of quantities
|
- [{fmt}](https://github.com/fmtlib/fmt) to provide text formatting of quantities
|
||||||
(if `std::format` is not supported yet on a specific compiler).
|
(if `std::format` is not supported yet on a specific compiler).
|
||||||
|
|
||||||
- _._
|
- **_._**
|
||||||
|
|
||||||
- project used as an **entry point for library development and CI/CD**
|
- project used as an **entry point for library development and CI/CD**
|
||||||
- it wraps _./src_ project together with usage examples and tests
|
- it wraps _./src_ project together with usage examples and tests
|
||||||
@ -79,7 +31,7 @@ This repository contains three independent CMake-based projects:
|
|||||||
library based on proposal [P1385](https://wg21.link/P1385) used in some examples
|
library based on proposal [P1385](https://wg21.link/P1385) used in some examples
|
||||||
and tests.
|
and tests.
|
||||||
|
|
||||||
- *./test_package*
|
- **_./test_package_**
|
||||||
|
|
||||||
- CMake library installation and Conan package verification.
|
- CMake library installation and Conan package verification.
|
||||||
|
|
||||||
@ -104,6 +56,27 @@ This repository contains three independent CMake-based projects:
|
|||||||
[FAQ](faq.md#why-dont-we-have-cmake-options-to-disable-building-of-tests-and-examples).
|
[FAQ](faq.md#why-dont-we-have-cmake-options-to-disable-building-of-tests-and-examples).
|
||||||
|
|
||||||
|
|
||||||
|
## Modules
|
||||||
|
|
||||||
|
The **mp-units** library provides the following C++ modules:
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
mp_units --- mp_units.systems --- mp_units.core
|
||||||
|
```
|
||||||
|
|
||||||
|
| C++ Module | CMake Target | Contents |
|
||||||
|
|--------------------|----------------------|----------------------------------------------------------|
|
||||||
|
| `mp_units.core` | `mp-units::core` | Core library framework and systems-independent utilities |
|
||||||
|
| `mp_units.systems` | `mp-units::systems` | All the systems of quantities and units |
|
||||||
|
| `mp_units` | `mp-units::mp-units` | Core + Systems |
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
C++ modules are provided within the package only when [`cxx_modules`](#cxx_modules) Conan
|
||||||
|
option is set to `True`.
|
||||||
|
|
||||||
|
|
||||||
## Obtaining dependencies
|
## Obtaining dependencies
|
||||||
|
|
||||||
This library assumes that most of the dependencies will be provided by the
|
This library assumes that most of the dependencies will be provided by the
|
||||||
@ -118,7 +91,7 @@ The rest of the dependencies responsible for documentation generation are provid
|
|||||||
In case you are not familiar with Conan, to install it (or upgrade) just do:
|
In case you are not familiar with Conan, to install it (or upgrade) just do:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
pip3 install -U conan
|
pip install -U conan
|
||||||
```
|
```
|
||||||
|
|
||||||
After that, you might need to add a custom profile file for your development environment
|
After that, you might need to add a custom profile file for your development environment
|
||||||
@ -173,30 +146,59 @@ tools.build:compiler_executables={"c": "gcc-12", "cpp": "g++-12"}
|
|||||||
|
|
||||||
## Build options
|
## Build options
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
Most of the below options are related to the C++ language features available in the compilers.
|
||||||
|
Please refer to the [C++ compiler support](cpp_compiler_support.md) chapter to learn more
|
||||||
|
about which C++ features are required and which compiler support them.
|
||||||
|
|
||||||
### Conan options
|
### Conan options
|
||||||
|
|
||||||
[cxx_modules](#cxx_modules){ #cxx_modules }
|
[cxx_modules](#cxx_modules){ #cxx_modules }
|
||||||
|
|
||||||
: [:octicons-tag-24: 2.2.0][cxx modules support] · :octicons-milestone-24: `True`/`False` (Default: `False`)
|
: [:octicons-tag-24: 2.2.0][conan C++ modules support] · :octicons-milestone-24: `auto`/`True`/`False` (Default: `auto`)
|
||||||
|
|
||||||
Configures CMake to add C++ modules to the list of default targets.
|
Configures CMake to add C++ modules to the list of default targets.
|
||||||
|
|
||||||
[cxx modules support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
[conan C++ modules support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
[use_fmtlib](#use_fmtlib){ #use_fmtlib }
|
[std_format](#std_format){ #std_format }
|
||||||
|
|
||||||
: [:octicons-tag-24: 2.2.0][use fmtlib support] · :octicons-milestone-24: `True`/`False` (Default: `False`)
|
: [:octicons-tag-24: 2.2.0][conan std::format support] · :octicons-milestone-24: `auto`/`True`/`False` (Default: `auto`)
|
||||||
|
|
||||||
Forces usage of [{fmt}](https://github.com/fmtlib/fmt) library instead of the C++20 Standard
|
Enables the usage of [`std::format`](https://en.cppreference.com/w/cpp/utility/format/format)
|
||||||
Library features.
|
and associated facilities for text formatting. If it is not supported, then
|
||||||
|
the [{fmt}](https://github.com/fmtlib/fmt) library is used instead.
|
||||||
|
|
||||||
|
[conan std::format support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
[string_view_ret](#string_view_ret){ #string_view_ret }
|
||||||
|
|
||||||
|
: [:octicons-tag-24: 2.2.0][conan returning string_view] · :octicons-milestone-24: `auto`/`True`/`False` (Default: `auto`)
|
||||||
|
|
||||||
|
Enables returning `std::string_view` from the
|
||||||
|
[`unit_symbol()`](../users_guide/framework_basics/text_output.md#unit_symbol)
|
||||||
|
and [`dimension_symbol()`](../users_guide/framework_basics/text_output.md#dimension_symbol)
|
||||||
|
functions. If this feature is not available, those functions will return
|
||||||
|
`mp_units::basic_fixed_string<CharT, N>` instead.
|
||||||
|
|
||||||
|
[conan returning string_view]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
[no_crtp](#no_crtp){ #no_crtp }
|
||||||
|
|
||||||
|
: [:octicons-tag-24: 2.2.0][conan no crtp support] · :octicons-milestone-24: `auto`/`True`/`False` (Default: `auto`)
|
||||||
|
|
||||||
|
Removes the need for the usage of the CRTP idiom in the
|
||||||
|
[`quantity_spec` definitions](../users_guide/framework_basics/systems_of_quantities.md#defining-quantities).
|
||||||
|
|
||||||
|
[conan no crtp support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
[use fmtlib support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
|
||||||
|
|
||||||
### Conan configuration properties
|
### Conan configuration properties
|
||||||
|
|
||||||
[`user.mp-units.build:all`](#user.mp-units.build-all){ #user.mp-units.build-all }
|
[`user.mp-units.build:all`](#user.mp-units.build-all){ #user.mp-units.build-all }
|
||||||
|
|
||||||
: [:octicons-tag-24: 2.2.0][build all support] · :octicons-milestone-24: `True`/`False` (Default: `False`)
|
: [:octicons-tag-24: 2.2.0][conan build all support] · :octicons-milestone-24: `True`/`False` (Default: `False`)
|
||||||
|
|
||||||
Enables compilation of all the source code, including tests and examples. To support this, it requires some additional Conan build dependencies described in
|
Enables compilation of all the source code, including tests and examples. To support this, it requires some additional Conan build dependencies described in
|
||||||
[Repository Structure and Dependencies](#repository-structure-and-dependencies).
|
[Repository Structure and Dependencies](#repository-structure-and-dependencies).
|
||||||
@ -204,19 +206,19 @@ tools.build:compiler_executables={"c": "gcc-12", "cpp": "g++-12"}
|
|||||||
[`tools.build:skip_test`](https://docs.conan.io/2/reference/commands/config.html?highlight=tools.build:skip_test#conan-config-list)
|
[`tools.build:skip_test`](https://docs.conan.io/2/reference/commands/config.html?highlight=tools.build:skip_test#conan-config-list)
|
||||||
configuration property is set to `True`).
|
configuration property is set to `True`).
|
||||||
|
|
||||||
[build all support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
[conan build all support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
|
||||||
[`user.mp-units.build:skip_la`](#user-skip-la){ #user-skip-la }
|
[`user.mp-units.build:skip_la`](#user-skip-la){ #user-skip-la }
|
||||||
|
|
||||||
: [:octicons-tag-24: 2.2.0][skip la support] · :octicons-milestone-24: `True`/`False` (Default: `False`)
|
: [:octicons-tag-24: 2.2.0][conan skip la support] · :octicons-milestone-24: `True`/`False` (Default: `False`)
|
||||||
|
|
||||||
If `user.mp-units.build:all` is enabled, among others, Conan installs the external
|
If `user.mp-units.build:all` is enabled, among others, Conan installs the external
|
||||||
[wg21-linear_algebra](https://conan.io/center/recipes/wg21-linear_algebra)
|
[wg21-linear_algebra](https://conan.io/center/recipes/wg21-linear_algebra)
|
||||||
dependency and enables the compilation of linear algebra-based tests and usage examples.
|
dependency and enables the compilation of linear algebra-based tests and usage examples.
|
||||||
Such behavior can be disabled with this option.
|
Such behavior can be disabled with this option.
|
||||||
|
|
||||||
[skip la support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
[conan skip la support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
|
||||||
### CMake options
|
### CMake options
|
||||||
@ -229,16 +231,37 @@ tools.build:compiler_executables={"c": "gcc-12", "cpp": "g++-12"}
|
|||||||
|
|
||||||
[build_cxx_modules support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
[build_cxx_modules support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
[`MP_UNITS_API_STD_FORMAT`](#MP_UNITS_API_STD_FORMAT){ #MP_UNITS_API_STD_FORMAT }
|
||||||
|
|
||||||
[`MP_UNITS_USE_FMTLIB`](#MP_UNITS_USE_FMTLIB){ #MP_UNITS_USE_FMTLIB }
|
: [:octicons-tag-24: 2.2.0][use fmtlib support] · :octicons-milestone-24: `AUTO`/`ON`/`OFF` (Default: `AUTO`)
|
||||||
|
|
||||||
: [:octicons-tag-24: 2.2.0][use fmtlib support] · :octicons-milestone-24: `ON`/`OFF` (Default: `OFF`)
|
Enables the usage of [`std::format`](https://en.cppreference.com/w/cpp/utility/format/format)
|
||||||
|
and associated facilities for text formatting. If it is not supported, then
|
||||||
Forces usage of [{fmt}](https://github.com/fmtlib/fmt) library instead of the C++20 Standard
|
the [{fmt}](https://github.com/fmtlib/fmt) library is used instead.
|
||||||
Library features.
|
|
||||||
|
|
||||||
[use fmtlib support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
[use fmtlib support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
[`MP_UNITS_API_STRING_VIEW_RET`](#MP_UNITS_API_STRING_VIEW_RET){ #MP_UNITS_API_STRING_VIEW_RET }
|
||||||
|
|
||||||
|
: [:octicons-tag-24: 2.2.0][cmake returning string_view] · :octicons-milestone-24: `AUTO`/`ON`/`OFF` (Default: `AUTO`)
|
||||||
|
|
||||||
|
Enables returning `std::string_view` from the
|
||||||
|
[`unit_symbol()`](../users_guide/framework_basics/text_output.md#unit_symbol)
|
||||||
|
and [`dimension_symbol()`](../users_guide/framework_basics/text_output.md#dimension_symbol)
|
||||||
|
functions. If this feature is not available, those functions will return
|
||||||
|
`mp_units::basic_fixed_string<CharT, N>` instead.
|
||||||
|
|
||||||
|
[cmake returning string_view]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
|
[`MP_UNITS_API_NO_CRTP`](#MP_UNITS_API_NO_CRTP){ #MP_UNITS_API_NO_CRTP }
|
||||||
|
|
||||||
|
: [:octicons-tag-24: 2.2.0][cmake no crtp support] · :octicons-milestone-24: `AUTO`/`ON`/`OFF` (Default: `AUTO`)
|
||||||
|
|
||||||
|
Removes the need for the usage of the CRTP idiom in the
|
||||||
|
[`quantity_spec` definitions](../users_guide/framework_basics/systems_of_quantities.md#defining-quantities).
|
||||||
|
|
||||||
|
[cmake no crtp support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||||
|
|
||||||
#### Options for mp-units project developers
|
#### Options for mp-units project developers
|
||||||
|
|
||||||
[`MP_UNITS_DEV_BUILD_LA`](#MP_UNITS_DEV_BUILD_LA){ #MP_UNITS_DEV_BUILD_LA }
|
[`MP_UNITS_DEV_BUILD_LA`](#MP_UNITS_DEV_BUILD_LA){ #MP_UNITS_DEV_BUILD_LA }
|
||||||
|
@ -16,27 +16,13 @@ The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units)
|
|||||||
??? info "Supported compilers"
|
??? info "Supported compilers"
|
||||||
|
|
||||||
This library tries to provide the best user experience possible with the C++ language.
|
This library tries to provide the best user experience possible with the C++ language.
|
||||||
To achieve that, it extensively uses C++20 features and the
|
To achieve that, it extensively uses the latest C++ language features.
|
||||||
[explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter)
|
|
||||||
from C++23.
|
|
||||||
|
|
||||||
Even though the library benefits from C++23 (if available), C++20 is enough to compile and
|
Even though the library benefits from the latest C++ versions (if available), C++20 is enough
|
||||||
use all of the library's functionality. C++23 features are hidden behind
|
to compile and use all of the library's functionality.
|
||||||
a [preprocessor macro](users_guide/framework_basics/systems_of_quantities.md#defining-quantities)
|
|
||||||
providing a backward-compatible way to use it.
|
|
||||||
|
|
||||||
The below table provides the minimum compiler version required to compile the code using the
|
Please refer to [C++ compiler support chapter](getting_started/cpp_compiler_support.md)
|
||||||
specific feature:
|
for more details.
|
||||||
|
|
||||||
| Feature | gcc | clang | apple-clang | MSVC |
|
|
||||||
|----------------------|:---:|:-----:|:-----------:|:----:|
|
|
||||||
| **Minimum support** | 12 | 16 | 15 | None |
|
|
||||||
| **`std::format`** | 13 | 17 | None | None |
|
|
||||||
| **C++ modules** | 14 | 17 | None | None |
|
|
||||||
| **C++23 extensions** | 14 | 18 | None | None |
|
|
||||||
|
|
||||||
More requirements for C++ modules support can be found in the
|
|
||||||
[CMake's documentation](https://cmake.org/cmake/help/latest/manual/cmake-cxxmodules.7.html).
|
|
||||||
|
|
||||||
=== "C++ modules"
|
=== "C++ modules"
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
**mp-units** usage example applications are meant to be built on all of
|
**mp-units** usage example applications are meant to be built on all of
|
||||||
[the supported compilers](../../getting_started/installation_and_usage.md#cpp-compiler-support).
|
[the supported compilers](../../getting_started/cpp_compiler_support.md).
|
||||||
This is why they benefit from the [Wide Compatibility](../use_cases/wide_compatibility.md) mode.
|
This is why they benefit from the [Wide Compatibility](../use_cases/wide_compatibility.md) mode.
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
|
@ -132,10 +132,15 @@ from such an instantiation.
|
|||||||
Quantity specification definitions benefit from an
|
Quantity specification definitions benefit from an
|
||||||
[explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter)
|
[explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter)
|
||||||
added in C++23 to remove the need for CRTP idiom, which significantly simplifies the code.
|
added in C++23 to remove the need for CRTP idiom, which significantly simplifies the code.
|
||||||
However, as C++23 is far from being mainstream today, a portability macro `QUANTITY_SPEC()`
|
However, as C++23 is far from being mainstream today,
|
||||||
|
a [portability macro `QUANTITY_SPEC()`](../use_cases/wide_compatibility.md#QUANTITY_SPEC)
|
||||||
is provided and used consistently through the library to allow the code to compile with C++20
|
is provided and used consistently through the library to allow the code to compile with C++20
|
||||||
compilers, thanks to the CRTP usage under the hood.
|
compilers, thanks to the CRTP usage under the hood.
|
||||||
|
|
||||||
|
See more in the
|
||||||
|
[C++ compiler support](../../getting_started/cpp_compiler_support.md#explicit-this-parameter)
|
||||||
|
chapter.
|
||||||
|
|
||||||
*[CRTP]: Curiously Recurring Template Parameter
|
*[CRTP]: Curiously Recurring Template Parameter
|
||||||
|
|
||||||
For example, here is how the above quantity kind tree can be modeled in the library:
|
For example, here is how the above quantity kind tree can be modeled in the library:
|
||||||
|
@ -11,7 +11,7 @@ macros that can be used to ensure the wide compatibility of our code.
|
|||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
Those macros are used in our short [example applications](../examples/tags_index.md) as those are meant
|
Those macros are used in our short [example applications](../examples/tags_index.md) as those are meant
|
||||||
to be built on all of [the supported compilers](../../getting_started/installation_and_usage.md#cpp-compiler-support).
|
to be built on all of [the supported compilers](../../getting_started/cpp_compiler_support.md).
|
||||||
Some still do not support `std::format`, C++ modules, or C++ versions newer than C++20.
|
Some still do not support `std::format`, C++ modules, or C++ versions newer than C++20.
|
||||||
|
|
||||||
|
|
||||||
@ -155,5 +155,5 @@ use [fmtlib](https://github.com/fmtlib/fmt) as their primary formatting facility
|
|||||||
from additional features provided with the library).
|
from additional features provided with the library).
|
||||||
|
|
||||||
This macro resolves to either the `std` or `fmt` namespace, depending on the value of
|
This macro resolves to either the `std` or `fmt` namespace, depending on the value of
|
||||||
[MP_UNITS_USE_FMTLIB](../../getting_started/installation_and_usage.md#MP_UNITS_USE_FMTLIB)
|
[MP_UNITS_API_STD_FORMAT](../../getting_started/installation_and_usage.md#MP_UNITS_API_STD_FORMAT)
|
||||||
CMake option.
|
CMake option.
|
||||||
|
@ -130,6 +130,7 @@ nav:
|
|||||||
- Introduction: getting_started/introduction.md
|
- Introduction: getting_started/introduction.md
|
||||||
- Quick Start: getting_started/quick_start.md
|
- Quick Start: getting_started/quick_start.md
|
||||||
- Look and Feel: getting_started/look_and_feel.md
|
- Look and Feel: getting_started/look_and_feel.md
|
||||||
|
- C++ compiler support (API/ABI): getting_started/cpp_compiler_support.md
|
||||||
- Installation and Usage: getting_started/installation_and_usage.md
|
- Installation and Usage: getting_started/installation_and_usage.md
|
||||||
- FAQ: getting_started/faq.md
|
- FAQ: getting_started/faq.md
|
||||||
- User's Guide:
|
- User's Guide:
|
||||||
|
@ -31,43 +31,67 @@ include(CheckCXXFeatureSupported)
|
|||||||
include(AddMPUnitsModule)
|
include(AddMPUnitsModule)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
# project options
|
# check if libc++ is being used
|
||||||
|
include(CheckLibcxxInUse)
|
||||||
|
check_libcxx_in_use(${projectPrefix}LIBCXX)
|
||||||
|
|
||||||
|
# project build options
|
||||||
option(${projectPrefix}BUILD_CXX_MODULES "Add C++ modules to the list of default targets" OFF)
|
option(${projectPrefix}BUILD_CXX_MODULES "Add C++ modules to the list of default targets" OFF)
|
||||||
message(STATUS "${projectPrefix}BUILD_CXX_MODULES: ${${projectPrefix}BUILD_CXX_MODULES}")
|
message(STATUS "${projectPrefix}BUILD_CXX_MODULES: ${${projectPrefix}BUILD_CXX_MODULES}")
|
||||||
|
|
||||||
option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF)
|
# project API settings
|
||||||
message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}")
|
function(cache_var_values name)
|
||||||
|
set_property(CACHE ${projectPrefix}${name} PROPERTY STRINGS ${ARGN})
|
||||||
|
if(NOT ${projectPrefix}${name} IN_LIST ARGN)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Invalid value '${${projectPrefix}${name}}' provided for a cache variable ${projectPrefix}${name} (${ARGN} allowed)"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
message(STATUS "${projectPrefix}${name}: ${${projectPrefix}${name}}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
option(${projectPrefix}USE_FMTLIB "Enables usage of fmtlib instead of the 'std::format' facilities" OFF)
|
set(${projectPrefix}API_STD_FORMAT AUTO CACHE STRING "Enable `std::format` support")
|
||||||
message(STATUS "${projectPrefix}USE_FMTLIB: ${${projectPrefix}USE_FMTLIB}")
|
cache_var_values(API_STD_FORMAT AUTO TRUE FALSE)
|
||||||
|
|
||||||
|
set(${projectPrefix}API_STRING_VIEW_RET AUTO CACHE STRING
|
||||||
|
"Enable returning `std::string_view` from `constexpr` functions"
|
||||||
|
)
|
||||||
|
cache_var_values(API_STRING_VIEW_RET AUTO TRUE FALSE)
|
||||||
|
|
||||||
|
set(${projectPrefix}API_NO_CRTP AUTO CACHE STRING "Enable class definitions without CRTP idiom")
|
||||||
|
cache_var_values(API_NO_CRTP AUTO TRUE FALSE)
|
||||||
|
|
||||||
# C++ features
|
# C++ features
|
||||||
check_cxx_feature_supported(__cpp_explicit_this_parameter ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
check_cxx_feature_supported(__cpp_lib_format ${projectPrefix}LIB_FORMAT_SUPPORTED)
|
||||||
check_cxx_feature_supported("__cpp_constexpr >= 202211L" ${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
|
check_cxx_feature_supported("__cpp_constexpr >= 202211L" ${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
|
||||||
|
check_cxx_feature_supported(__cpp_explicit_this_parameter ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||||
|
|
||||||
if(${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
# validate settings
|
||||||
message(STATUS "API/ABI: `quantity_spec` uses explicit `this` parameter in its definition")
|
if(${projectPrefix}API_STD_FORMAT STREQUAL "TRUE"
|
||||||
else()
|
AND NOT
|
||||||
message(STATUS "API/ABI: `quantity_spec` uses CRTP in its definition")
|
(${projectPrefix}LIB_FORMAT_SUPPORTED
|
||||||
|
# libc++ has a basic supports for std::format but does not set __cpp_lib_format
|
||||||
|
# https://github.com/llvm/llvm-project/issues/77773
|
||||||
|
OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "17"
|
||||||
|
AND ${projectPrefix}LIBCXX))
|
||||||
|
)
|
||||||
|
message(FATAL_ERROR "`std::format` enabled but not supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
|
if(${projectPrefix}API_STRING_VIEW_RET STREQUAL "TRUE" AND NOT
|
||||||
message(STATUS "API/ABI: `unit_symbol()` returns `std::string_view`")
|
${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS
|
||||||
else()
|
)
|
||||||
message(STATUS "API/ABI: `unit_symbol()` returns `fixed_string`")
|
message(FATAL_ERROR "`std::string_view` returns enabled but not supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# C++ modules
|
if(${projectPrefix}API_NO_CRTP STREQUAL "TRUE" AND NOT ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||||
if(${projectPrefix}BUILD_CXX_MODULES)
|
message(FATAL_ERROR "`NO_CRTP` mode enabled but explicit `this` parameter is not supported")
|
||||||
if(CMAKE_VERSION VERSION_LESS "3.28.1")
|
endif()
|
||||||
message(FATAL_ERROR, "CMake versions before 3.28.1 do not support C++ modules properly")
|
|
||||||
|
if(${projectPrefix}BUILD_CXX_MODULES STREQUAL "TRUE")
|
||||||
|
if(CMAKE_VERSION VERSION_LESS "3.29")
|
||||||
|
message(FATAL_ERROR "CMake versions before 3.29 do not support C++ modules properly")
|
||||||
endif()
|
endif()
|
||||||
cmake_minimum_required(VERSION 3.28.1)
|
|
||||||
|
|
||||||
# # none of the below seems to work
|
|
||||||
# cmake_policy(VERSION 3.28.1)
|
|
||||||
# cmake_policy(SET CMP0155 NEW)
|
|
||||||
|
|
||||||
set(${projectPrefix}TARGET_SCOPE "PUBLIC")
|
set(${projectPrefix}TARGET_SCOPE "PUBLIC")
|
||||||
else()
|
else()
|
||||||
set(${projectPrefix}TARGET_SCOPE "INTERFACE")
|
set(${projectPrefix}TARGET_SCOPE "INTERFACE")
|
||||||
|
41
src/cmake/CheckLibcxxInUse.cmake
Normal file
41
src/cmake/CheckLibcxxInUse.cmake
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# The MIT License (MIT)
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Mateusz Pusz
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION 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.15)
|
||||||
|
|
||||||
|
function(check_libcxx_in_use variable)
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
message(CHECK_START "Checking if libc++ is being used")
|
||||||
|
list(APPEND CMAKE_MESSAGE_INDENT " ")
|
||||||
|
|
||||||
|
include(CheckCXXSymbolExists)
|
||||||
|
check_cxx_symbol_exists(_LIBCPP_VERSION "ciso646" ${variable})
|
||||||
|
set(${variable} ${${variable}} PARENT_SCOPE)
|
||||||
|
|
||||||
|
list(POP_BACK CMAKE_MESSAGE_INDENT)
|
||||||
|
if(${variable})
|
||||||
|
message(CHECK_PASS "found")
|
||||||
|
else()
|
||||||
|
message(CHECK_FAIL "not found")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
@ -22,6 +22,15 @@
|
|||||||
|
|
||||||
cmake_minimum_required(VERSION 3.23)
|
cmake_minimum_required(VERSION 3.23)
|
||||||
|
|
||||||
|
function(set_feature_flag name)
|
||||||
|
set(val_list "TRUE" "FALSE")
|
||||||
|
if(${projectPrefix}${name} IN_LIST val_list)
|
||||||
|
target_compile_definitions(
|
||||||
|
mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}${name}=$<BOOL:${${projectPrefix}${name}}>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# find dependencies
|
# find dependencies
|
||||||
if(NOT TARGET gsl::gsl-lite)
|
if(NOT TARGET gsl::gsl-lite)
|
||||||
find_package(gsl-lite REQUIRED)
|
find_package(gsl-lite REQUIRED)
|
||||||
@ -78,11 +87,13 @@ add_mp_units_module(
|
|||||||
MODULE_INTERFACE_UNIT mp-units-core.cpp
|
MODULE_INTERFACE_UNIT mp-units-core.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(
|
set_feature_flag(API_STD_FORMAT)
|
||||||
mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}USE_FMTLIB=$<BOOL:${${projectPrefix}USE_FMTLIB}>
|
set_feature_flag(API_STRING_VIEW_RET)
|
||||||
)
|
set_feature_flag(API_NO_CRTP)
|
||||||
|
|
||||||
if(${projectPrefix}USE_FMTLIB)
|
if(${projectPrefix}API_STD_FORMAT STREQUAL "FALSE" OR (${projectPrefix}API_STD_FORMAT STREQUAL "AUTO"
|
||||||
|
AND NOT ${projectPrefix}LIB_FORMAT_SUPPORTED)
|
||||||
|
)
|
||||||
if(NOT TARGET fmt::fmt)
|
if(NOT TARGET fmt::fmt)
|
||||||
find_package(fmt REQUIRED)
|
find_package(fmt REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
12
src/core/include/mp-units/bits/external/hacks.h
vendored
12
src/core/include/mp-units/bits/external/hacks.h
vendored
@ -110,3 +110,15 @@
|
|||||||
#define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X) X
|
#define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X) X
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined MP_UNITS_API_STRING_VIEW_RET && __cpp_constexpr >= 202211L
|
||||||
|
|
||||||
|
#define MP_UNITS_API_STRING_VIEW_RET 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined MP_UNITS_API_NO_CRTP && __cpp_explicit_this_parameter
|
||||||
|
|
||||||
|
#define MP_UNITS_API_NO_CRTP 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mp-units/bits/external/hacks.h>
|
||||||
#include <mp-units/bits/dimension_concepts.h>
|
#include <mp-units/bits/dimension_concepts.h>
|
||||||
#include <mp-units/bits/expression_template.h>
|
#include <mp-units/bits/expression_template.h>
|
||||||
#include <mp-units/bits/module_macros.h>
|
#include <mp-units/bits/module_macros.h>
|
||||||
@ -29,7 +30,7 @@
|
|||||||
namespace mp_units {
|
namespace mp_units {
|
||||||
|
|
||||||
MP_UNITS_EXPORT
|
MP_UNITS_EXPORT
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<auto...>
|
template<auto...>
|
||||||
#else
|
#else
|
||||||
template<typename, auto...>
|
template<typename, auto...>
|
||||||
@ -50,7 +51,7 @@ inline constexpr bool is_specialization_of_kind_of<kind_of_<Q>> = true;
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept QuantityKindSpec = is_specialization_of_kind_of<T>;
|
concept QuantityKindSpec = is_specialization_of_kind_of<T>;
|
||||||
|
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<auto... Args>
|
template<auto... Args>
|
||||||
void to_base_specialization_of_quantity_spec(const volatile quantity_spec<Args...>*);
|
void to_base_specialization_of_quantity_spec(const volatile quantity_spec<Args...>*);
|
||||||
#else
|
#else
|
||||||
@ -65,7 +66,7 @@ inline constexpr bool is_derived_from_specialization_of_quantity_spec =
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_specialization_of_quantity_spec = false;
|
inline constexpr bool is_specialization_of_quantity_spec = false;
|
||||||
|
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<auto... Args>
|
template<auto... Args>
|
||||||
inline constexpr bool is_specialization_of_quantity_spec<quantity_spec<Args...>> = true;
|
inline constexpr bool is_specialization_of_quantity_spec<quantity_spec<Args...>> = true;
|
||||||
#else
|
#else
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <mp-units/bits/external/hacks.h>
|
#include <mp-units/bits/external/hacks.h>
|
||||||
|
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
|
|
||||||
#define QUANTITY_SPEC(name, ...) \
|
#define QUANTITY_SPEC(name, ...) \
|
||||||
inline constexpr struct name : ::mp_units::quantity_spec<__VA_ARGS__> { \
|
inline constexpr struct name : ::mp_units::quantity_spec<__VA_ARGS__> { \
|
||||||
@ -38,6 +38,14 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined MP_UNITS_API_STD_FORMAT || !MP_UNITS_API_STD_FORMAT
|
||||||
|
|
||||||
|
#if __has_include(<fmt/format.h>)
|
||||||
|
#define MP_UNITS_USE_FMTLIB 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MP_UNITS_USE_FMTLIB
|
#if MP_UNITS_USE_FMTLIB
|
||||||
|
|
||||||
MP_UNITS_DIAGNOSTIC_PUSH
|
MP_UNITS_DIAGNOSTIC_PUSH
|
||||||
|
@ -319,7 +319,7 @@ MP_UNITS_EXPORT template<dimension_symbol_formatting fmt = dimension_symbol_form
|
|||||||
return buffer.size();
|
return buffer.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __cpp_constexpr >= 202211L // Permitting static constexpr variables in constexpr functions
|
#if MP_UNITS_API_STRING_VIEW_RET // Permitting static constexpr variables in constexpr functions
|
||||||
static constexpr std::size_t size = get_size();
|
static constexpr std::size_t size = get_size();
|
||||||
static constexpr auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(D{});
|
static constexpr auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(D{});
|
||||||
return std::string_view(buffer.data(), size);
|
return std::string_view(buffer.data(), size);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <mp-units/bits/expression_template.h>
|
#include <mp-units/bits/expression_template.h>
|
||||||
#include <mp-units/bits/external/algorithm.h>
|
#include <mp-units/bits/external/algorithm.h>
|
||||||
|
#include <mp-units/bits/external/hacks.h>
|
||||||
#include <mp-units/bits/external/type_name.h>
|
#include <mp-units/bits/external/type_name.h>
|
||||||
#include <mp-units/bits/external/type_traits.h>
|
#include <mp-units/bits/external/type_traits.h>
|
||||||
#include <mp-units/bits/get_common_base.h>
|
#include <mp-units/bits/get_common_base.h>
|
||||||
@ -107,11 +108,11 @@ using to_dimension = std::remove_const_t<decltype(Q::dimension)>;
|
|||||||
template<AssociatedUnit U>
|
template<AssociatedUnit U>
|
||||||
[[nodiscard]] consteval auto get_associated_quantity(U);
|
[[nodiscard]] consteval auto get_associated_quantity(U);
|
||||||
|
|
||||||
#ifndef __cpp_explicit_this_parameter
|
#ifndef MP_UNITS_API_NO_CRTP
|
||||||
template<typename Self>
|
template<typename Self>
|
||||||
#endif
|
#endif
|
||||||
struct quantity_spec_interface {
|
struct quantity_spec_interface {
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<typename Self, UnitOf<Self{}> U>
|
template<typename Self, UnitOf<Self{}> U>
|
||||||
[[nodiscard]] consteval Reference auto operator[](this Self self, U u)
|
[[nodiscard]] consteval Reference auto operator[](this Self self, U u)
|
||||||
{
|
{
|
||||||
@ -166,7 +167,7 @@ MP_UNITS_EXPORT_BEGIN
|
|||||||
* types `speed` and `velocity` are considered not equal to `derived_dimension<length, per<time>>` or
|
* types `speed` and `velocity` are considered not equal to `derived_dimension<length, per<time>>` or
|
||||||
* to each other.
|
* to each other.
|
||||||
*/
|
*/
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<auto...>
|
template<auto...>
|
||||||
#else
|
#else
|
||||||
template<typename, auto...>
|
template<typename, auto...>
|
||||||
@ -211,7 +212,7 @@ MP_UNITS_EXPORT_END
|
|||||||
* @tparam BaseDimension base dimension for which a base quantity is being defined
|
* @tparam BaseDimension base dimension for which a base quantity is being defined
|
||||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||||
*/
|
*/
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<detail::BaseDimension auto Dim, one_of<quantity_character> auto... Args>
|
template<detail::BaseDimension auto Dim, one_of<quantity_character> auto... Args>
|
||||||
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
||||||
struct quantity_spec<Dim, Args...> : detail::quantity_spec_interface {
|
struct quantity_spec<Dim, Args...> : detail::quantity_spec_interface {
|
||||||
@ -254,7 +255,7 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
|||||||
* @tparam Eq quantity equation specification of a derived quantity
|
* @tparam Eq quantity equation specification of a derived quantity
|
||||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||||
*/
|
*/
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<detail::IntermediateDerivedQuantitySpec auto Eq, one_of<quantity_character> auto... Args>
|
template<detail::IntermediateDerivedQuantitySpec auto Eq, one_of<quantity_character> auto... Args>
|
||||||
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
||||||
struct quantity_spec<Eq, Args...> : detail::quantity_spec_interface {
|
struct quantity_spec<Eq, Args...> : detail::quantity_spec_interface {
|
||||||
@ -295,7 +296,7 @@ struct quantity_spec<Self, Eq, Args...> : detail::quantity_spec_interface<Self>
|
|||||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||||
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
||||||
*/
|
*/
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<detail::NamedQuantitySpec auto QS, one_of<quantity_character, struct is_kind> auto... Args>
|
template<detail::NamedQuantitySpec auto QS, one_of<quantity_character, struct is_kind> auto... Args>
|
||||||
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
||||||
struct quantity_spec<QS, Args...> : std::remove_const_t<decltype(QS)> {
|
struct quantity_spec<QS, Args...> : std::remove_const_t<decltype(QS)> {
|
||||||
@ -307,7 +308,7 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
|
|||||||
static constexpr auto _parent_ = QS;
|
static constexpr auto _parent_ = QS;
|
||||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(QS.character);
|
static constexpr quantity_character character = detail::quantity_character_init<Args...>(QS.character);
|
||||||
|
|
||||||
#ifndef __cpp_explicit_this_parameter
|
#ifndef MP_UNITS_API_NO_CRTP
|
||||||
template<typename Self_ = Self, UnitOf<Self_{}> U>
|
template<typename Self_ = Self, UnitOf<Self_{}> U>
|
||||||
[[nodiscard]] MP_UNITS_CONSTEVAL Reference auto operator[](U u) const
|
[[nodiscard]] MP_UNITS_CONSTEVAL Reference auto operator[](U u) const
|
||||||
{
|
{
|
||||||
@ -353,7 +354,7 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
|
|||||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||||
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
||||||
*/
|
*/
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<detail::NamedQuantitySpec auto QS, detail::IntermediateDerivedQuantitySpec auto Eq,
|
template<detail::NamedQuantitySpec auto QS, detail::IntermediateDerivedQuantitySpec auto Eq,
|
||||||
one_of<quantity_character, struct is_kind> auto... Args>
|
one_of<quantity_character, struct is_kind> auto... Args>
|
||||||
requires(!requires { QS._equation_; } ||
|
requires(!requires { QS._equation_; } ||
|
||||||
@ -418,7 +419,7 @@ struct quantity_spec<Self, QS, Eq, Args...> : quantity_spec<Self, QS, Args...> {
|
|||||||
*/
|
*/
|
||||||
template<detail::IntermediateDerivedQuantitySpecExpr... Expr>
|
template<detail::IntermediateDerivedQuantitySpecExpr... Expr>
|
||||||
struct derived_quantity_spec :
|
struct derived_quantity_spec :
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
detail::quantity_spec_interface,
|
detail::quantity_spec_interface,
|
||||||
#else
|
#else
|
||||||
detail::quantity_spec_interface<derived_quantity_spec<Expr...>>,
|
detail::quantity_spec_interface<derived_quantity_spec<Expr...>>,
|
||||||
@ -456,7 +457,7 @@ template<QuantitySpec Q>
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<typename Q>
|
template<typename Q>
|
||||||
requires detail::QuantitySpecWithNoSpecifiers<Q> && (detail::get_kind_tree_root(Q{}) == Q{})
|
requires detail::QuantitySpecWithNoSpecifiers<Q> && (detail::get_kind_tree_root(Q{}) == Q{})
|
||||||
struct kind_of_<Q> : Q {
|
struct kind_of_<Q> : Q {
|
||||||
@ -1430,7 +1431,7 @@ template<QuantitySpec Q>
|
|||||||
requires requires(Q q) { get_kind_tree_root(q); }
|
requires requires(Q q) { get_kind_tree_root(q); }
|
||||||
using to_kind = std::remove_const_t<decltype(get_kind_tree_root(Q{}))>;
|
using to_kind = std::remove_const_t<decltype(get_kind_tree_root(Q{}))>;
|
||||||
|
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
template<NamedQuantitySpec auto QS, auto... Args>
|
template<NamedQuantitySpec auto QS, auto... Args>
|
||||||
[[nodiscard]] consteval bool defined_as_kind(quantity_spec<QS, Args...>)
|
[[nodiscard]] consteval bool defined_as_kind(quantity_spec<QS, Args...>)
|
||||||
#else
|
#else
|
||||||
|
@ -840,7 +840,7 @@ MP_UNITS_EXPORT template<unit_symbol_formatting fmt = unit_symbol_formatting{},
|
|||||||
return buffer.size();
|
return buffer.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __cpp_constexpr >= 202211L // Permitting static constexpr variables in constexpr functions
|
#if MP_UNITS_API_STRING_VIEW_RET // Permitting static constexpr variables in constexpr functions
|
||||||
static constexpr std::size_t size = get_size();
|
static constexpr std::size_t size = get_size();
|
||||||
static constexpr auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(U{});
|
static constexpr auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(U{});
|
||||||
return std::string_view(buffer.data(), size);
|
return std::string_view(buffer.data(), size);
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
include(CMakeFindDependencyMacro)
|
include(CMakeFindDependencyMacro)
|
||||||
|
|
||||||
if(MP_UNITS_USE_FMTLIB)
|
if(MP_UNITS_API_STD_FORMAT)
|
||||||
find_dependency(fmt)
|
find_dependency(fmt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -22,13 +22,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mp-units/bits/external/hacks.h>
|
||||||
#include <mp-units/quantity_spec.h>
|
#include <mp-units/quantity_spec.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
template<auto V, typename T>
|
template<auto V, typename T>
|
||||||
inline constexpr bool is_of_type = std::is_same_v<std::remove_cvref_t<decltype(V)>, T>;
|
inline constexpr bool is_of_type = std::is_same_v<std::remove_cvref_t<decltype(V)>, T>;
|
||||||
|
|
||||||
#ifdef __cpp_explicit_this_parameter
|
#ifdef MP_UNITS_API_NO_CRTP
|
||||||
|
|
||||||
#define QUANTITY_SPEC_(name, ...) \
|
#define QUANTITY_SPEC_(name, ...) \
|
||||||
inline constexpr struct name##_ : quantity_spec<__VA_ARGS__> { \
|
inline constexpr struct name##_ : quantity_spec<__VA_ARGS__> { \
|
||||||
|
@ -27,4 +27,4 @@ find_package(mp-units REQUIRED)
|
|||||||
|
|
||||||
add_executable(test_package test_package.cpp)
|
add_executable(test_package test_package.cpp)
|
||||||
target_link_libraries(test_package PRIVATE mp-units::mp-units)
|
target_link_libraries(test_package PRIVATE mp-units::mp-units)
|
||||||
target_compile_definitions(test_package PRIVATE MP_UNITS_USE_FMTLIB=$<BOOL:${MP_UNITS_USE_FMTLIB}>)
|
target_compile_definitions(test_package PRIVATE MP_UNITS_API_STD_FORMAT=$<BOOL:${MP_UNITS_API_STD_FORMAT}>)
|
||||||
|
@ -39,8 +39,8 @@ class TestPackageConan(ConanFile):
|
|||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
tc = CMakeToolchain(self)
|
tc = CMakeToolchain(self)
|
||||||
tc.variables["MP_UNITS_USE_FMTLIB"] = bool(
|
tc.variables["MP_UNITS_API_STD_FORMAT"] = bool(
|
||||||
self.dependencies["mp-units"].options.use_fmtlib
|
self.dependencies["mp-units"].options.std_format
|
||||||
)
|
)
|
||||||
tc.generate()
|
tc.generate()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user