mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +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/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/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
|
||||
shell: bash
|
||||
run: |
|
||||
conan create . --user mpusz --channel ${CHANNEL} --lockfile-out=package.lock \
|
||||
-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
|
||||
id: get-package-ref
|
||||
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/^build_type=.*/build_type=${{ matrix.build_type }}/' ~/.conan2/profiles/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
|
||||
shell: bash
|
||||
run: |
|
||||
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
|
||||
- name: Configure mp-units CMake
|
||||
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 remote add artifactory https://mpusz.jfrog.io/artifactory/api/conan/conan-oss
|
||||
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
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
32
.gitpod.yml
32
.gitpod.yml
@ -70,17 +70,17 @@ tasks:
|
||||
gp sync-await python-init
|
||||
conan profile detect
|
||||
conan config install $PWD/.gitpod/conan
|
||||
conan install . -pr gcc12 -o use_fmtlib=True -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
|
||||
conan install . -pr gcc12 -o std_format=False -b missing -s build_type=Debug
|
||||
gp sync-done conan-gcc12-20
|
||||
conan install . -pr gcc13 -b missing
|
||||
conan install . -pr gcc13 -b missing -s build_type=Debug
|
||||
conan install . -pr gcc13 -o std_format=True -b missing
|
||||
conan install . -pr gcc13 -o std_format=True -b missing -s build_type=Debug
|
||||
gp sync-done conan-gcc13-20
|
||||
conan install . -pr clang16 -o use_fmtlib=True -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
|
||||
conan install . -pr clang16 -o std_format=False -b missing -s build_type=Debug
|
||||
gp sync-done conan-clang16-20
|
||||
conan install . -pr clang17 -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
|
||||
conan install . -pr clang17 -o std_format=True -o cxx_modules=True -b missing -s build_type=Debug
|
||||
gp sync-done conan-clang17-20
|
||||
conan remote login -p $ARTIFACTORY_TOKEN conan-gitpod-mp-units $ARTIFACTORY_USER
|
||||
conan upload "*" -r conan-gitpod-mp-units -c
|
||||
@ -88,29 +88,29 @@ tasks:
|
||||
init: |
|
||||
gp sync-await conan-gcc12-20
|
||||
source ${PYTHON_VENV}/bin/activate
|
||||
conan build . -pr gcc12 -o use_fmtlib=True
|
||||
conan build . -pr gcc12 -o use_fmtlib=True -s build_type=Debug
|
||||
conan build . -pr gcc12 -o std_format=False
|
||||
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. 🛠️"
|
||||
- name: gcc-13-20
|
||||
init: |
|
||||
gp sync-await conan-gcc13-20
|
||||
source ${PYTHON_VENV}/bin/activate
|
||||
conan build . -pr gcc13
|
||||
conan build . -pr gcc13 -s build_type=Debug
|
||||
conan build . -pr gcc13 -o std_format=True
|
||||
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. 🛠️"
|
||||
- name: clang-16-20
|
||||
init: |
|
||||
gp sync-await conan-clang16-20
|
||||
source ${PYTHON_VENV}/bin/activate
|
||||
conan build . -pr clang16 -o use_fmtlib=True
|
||||
conan build . -pr clang16 -o use_fmtlib=True -s build_type=Debug
|
||||
conan build . -pr clang16 -o std_format=False
|
||||
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. 🛠️"
|
||||
- name: clang-17-20
|
||||
init: |
|
||||
gp sync-await conan-clang17-20
|
||||
source ${PYTHON_VENV}/bin/activate
|
||||
conan build . -pr clang17 -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
|
||||
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. 🛠️"
|
||||
- name: documentation
|
||||
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.
|
||||
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
|
||||
[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.
|
||||
|
||||
|
||||
|
167
conanfile.py
167
conanfile.py
@ -25,13 +25,20 @@ import re
|
||||
|
||||
from conan import ConanFile
|
||||
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.files import copy, load, rmdir
|
||||
|
||||
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):
|
||||
name = "mp-units"
|
||||
homepage = "https://github.com/mpusz/mp-units"
|
||||
@ -54,14 +61,18 @@ class MPUnitsConan(ConanFile):
|
||||
url = "https://github.com/mpusz/mp-units"
|
||||
settings = "os", "arch", "compiler", "build_type"
|
||||
options = {
|
||||
"cxx_modules": [True, False],
|
||||
"use_fmtlib": [True, False],
|
||||
"cxx_modules": ["auto", True, False],
|
||||
"std_format": ["auto", True, False],
|
||||
"string_view_ret": ["auto", True, False],
|
||||
"no_crtp": ["auto", True, False],
|
||||
}
|
||||
default_options = {
|
||||
"cxx_modules": False,
|
||||
"use_fmtlib": False,
|
||||
"cxx_modules": "auto",
|
||||
"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_sources = (
|
||||
"docs/*",
|
||||
@ -75,27 +86,106 @@ class MPUnitsConan(ConanFile):
|
||||
no_copy_source = True
|
||||
|
||||
@property
|
||||
def _minimum_compilers_version(self):
|
||||
def _feature_compatibility(self):
|
||||
return {
|
||||
"gcc": "12",
|
||||
"clang": "16",
|
||||
"apple-clang": "15",
|
||||
# , "msvc": "192"
|
||||
"minimum_support": {
|
||||
"std": "20",
|
||||
"compiler": {
|
||||
"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
|
||||
def _std_format_minimum_compilers_version(self):
|
||||
def _option_feature_map(self):
|
||||
return {
|
||||
"gcc": "13",
|
||||
"clang": "17",
|
||||
# , "apple-clang": "15"
|
||||
# , "msvc": "192"
|
||||
"std_format": "std_format",
|
||||
"cxx_modules": "cxx_modules",
|
||||
"string_view_ret": "static_constexpr_vars_in_constexpr_func",
|
||||
"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
|
||||
def _build_all(self):
|
||||
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
|
||||
def _skip_la(self):
|
||||
return bool(self.conf.get("user.mp-units.build:skip_la", default=False))
|
||||
@ -109,7 +199,7 @@ class MPUnitsConan(ConanFile):
|
||||
|
||||
def requirements(self):
|
||||
self.requires("gsl-lite/0.41.0")
|
||||
if self.options.use_fmtlib:
|
||||
if self._use_fmtlib:
|
||||
self.requires("fmt/10.2.1")
|
||||
|
||||
def build_requirements(self):
|
||||
@ -119,27 +209,10 @@ class MPUnitsConan(ConanFile):
|
||||
self.test_requires("wg21-linear_algebra/0.7.3")
|
||||
|
||||
def validate(self):
|
||||
check_min_cppstd(self, "20")
|
||||
|
||||
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]
|
||||
|
||||
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."
|
||||
)
|
||||
self._check_feature_supported("mp-units", "minimum_support")
|
||||
for key, value in self._option_feature_map.items():
|
||||
if self.options.get_safe(key) is True:
|
||||
self._check_feature_supported(key, value)
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
@ -148,13 +221,19 @@ class MPUnitsConan(ConanFile):
|
||||
tc = CMakeToolchain(self)
|
||||
if self._build_all:
|
||||
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["MP_UNITS_BUILD_CXX_MODULES"] = True
|
||||
tc.cache_variables["MP_UNITS_DEV_BUILD_LA"] = (
|
||||
self._build_all and not self._skip_la
|
||||
)
|
||||
tc.cache_variables["MP_UNITS_USE_FMTLIB"] = bool(self.options.use_fmtlib)
|
||||
tc.cache_variables["MP_UNITS_BUILD_CXX_MODULES"] = str(
|
||||
self.options.cxx_modules
|
||||
).upper()
|
||||
tc.cache_variables["MP_UNITS_API_STD_FORMAT"] = str(
|
||||
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()
|
||||
deps = CMakeDeps(self)
|
||||
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**.
|
||||
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
|
||||
|
||||
This repository contains three independent CMake-based projects:
|
||||
|
||||
- _./src_
|
||||
- **_./src_**
|
||||
|
||||
- header-only project containing whole **mp-units** library
|
||||
- _./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
|
||||
(if `std::format` is not supported yet on a specific compiler).
|
||||
|
||||
- _._
|
||||
- **_._**
|
||||
|
||||
- project used as an **entry point for library development and CI/CD**
|
||||
- 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
|
||||
and tests.
|
||||
|
||||
- *./test_package*
|
||||
- **_./test_package_**
|
||||
|
||||
- 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).
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
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:
|
||||
|
||||
```shell
|
||||
pip3 install -U conan
|
||||
pip install -U conan
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
!!! 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
|
||||
|
||||
[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.
|
||||
|
||||
[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
|
||||
Library features.
|
||||
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
|
||||
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
|
||||
|
||||
[`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
|
||||
[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)
|
||||
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 }
|
||||
|
||||
: [: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
|
||||
[wg21-linear_algebra](https://conan.io/center/recipes/wg21-linear_algebra)
|
||||
dependency and enables the compilation of linear algebra-based tests and usage examples.
|
||||
Such behavior can be disabled with this option.
|
||||
|
||||
[skip la support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||
[conan skip la support]: https://github.com/mpusz/mp-units/releases/tag/v2.2.0
|
||||
|
||||
|
||||
### 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
|
||||
|
||||
[`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`)
|
||||
|
||||
Forces usage of [{fmt}](https://github.com/fmtlib/fmt) library instead of the C++20 Standard
|
||||
Library features.
|
||||
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
|
||||
the [{fmt}](https://github.com/fmtlib/fmt) library is used instead.
|
||||
|
||||
[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
|
||||
|
||||
[`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"
|
||||
|
||||
This library tries to provide the best user experience possible with the C++ language.
|
||||
To achieve that, it extensively uses C++20 features and the
|
||||
[explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter)
|
||||
from C++23.
|
||||
To achieve that, it extensively uses the latest C++ language features.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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).
|
||||
Please refer to [C++ compiler support chapter](getting_started/cpp_compiler_support.md)
|
||||
for more details.
|
||||
|
||||
=== "C++ modules"
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
!!! note
|
||||
|
||||
**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.
|
||||
|
||||
!!! tip
|
||||
|
@ -132,10 +132,15 @@ from such an instantiation.
|
||||
Quantity specification definitions benefit from an
|
||||
[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.
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@ -155,5 +155,5 @@ use [fmtlib](https://github.com/fmtlib/fmt) as their primary formatting facility
|
||||
from additional features provided with the library).
|
||||
|
||||
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.
|
||||
|
@ -130,6 +130,7 @@ nav:
|
||||
- Introduction: getting_started/introduction.md
|
||||
- Quick Start: getting_started/quick_start.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
|
||||
- FAQ: getting_started/faq.md
|
||||
- User's Guide:
|
||||
|
@ -31,43 +31,67 @@ include(CheckCXXFeatureSupported)
|
||||
include(AddMPUnitsModule)
|
||||
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)
|
||||
message(STATUS "${projectPrefix}BUILD_CXX_MODULES: ${${projectPrefix}BUILD_CXX_MODULES}")
|
||||
|
||||
option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF)
|
||||
message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}")
|
||||
# project API settings
|
||||
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)
|
||||
message(STATUS "${projectPrefix}USE_FMTLIB: ${${projectPrefix}USE_FMTLIB}")
|
||||
set(${projectPrefix}API_STD_FORMAT AUTO CACHE STRING "Enable `std::format` support")
|
||||
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
|
||||
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_explicit_this_parameter ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||
|
||||
if(${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||
message(STATUS "API/ABI: `quantity_spec` uses explicit `this` parameter in its definition")
|
||||
else()
|
||||
message(STATUS "API/ABI: `quantity_spec` uses CRTP in its definition")
|
||||
# validate settings
|
||||
if(${projectPrefix}API_STD_FORMAT STREQUAL "TRUE"
|
||||
AND NOT
|
||||
(${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()
|
||||
|
||||
if(${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
|
||||
message(STATUS "API/ABI: `unit_symbol()` returns `std::string_view`")
|
||||
else()
|
||||
message(STATUS "API/ABI: `unit_symbol()` returns `fixed_string`")
|
||||
if(${projectPrefix}API_STRING_VIEW_RET STREQUAL "TRUE" AND NOT
|
||||
${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS
|
||||
)
|
||||
message(FATAL_ERROR "`std::string_view` returns enabled but not supported")
|
||||
endif()
|
||||
|
||||
# C++ modules
|
||||
if(${projectPrefix}BUILD_CXX_MODULES)
|
||||
if(CMAKE_VERSION VERSION_LESS "3.28.1")
|
||||
message(FATAL_ERROR, "CMake versions before 3.28.1 do not support C++ modules properly")
|
||||
if(${projectPrefix}API_NO_CRTP STREQUAL "TRUE" AND NOT ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||
message(FATAL_ERROR "`NO_CRTP` mode enabled but explicit `this` parameter is not supported")
|
||||
endif()
|
||||
|
||||
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()
|
||||
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")
|
||||
else()
|
||||
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)
|
||||
|
||||
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
|
||||
if(NOT TARGET gsl::gsl-lite)
|
||||
find_package(gsl-lite REQUIRED)
|
||||
@ -78,11 +87,13 @@ add_mp_units_module(
|
||||
MODULE_INTERFACE_UNIT mp-units-core.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(
|
||||
mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}USE_FMTLIB=$<BOOL:${${projectPrefix}USE_FMTLIB}>
|
||||
)
|
||||
set_feature_flag(API_STD_FORMAT)
|
||||
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)
|
||||
find_package(fmt REQUIRED)
|
||||
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
|
||||
|
||||
#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
|
||||
|
||||
#include <mp-units/bits/external/hacks.h>
|
||||
#include <mp-units/bits/dimension_concepts.h>
|
||||
#include <mp-units/bits/expression_template.h>
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
@ -29,7 +30,7 @@
|
||||
namespace mp_units {
|
||||
|
||||
MP_UNITS_EXPORT
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<auto...>
|
||||
#else
|
||||
template<typename, auto...>
|
||||
@ -50,7 +51,7 @@ inline constexpr bool is_specialization_of_kind_of<kind_of_<Q>> = true;
|
||||
template<typename T>
|
||||
concept QuantityKindSpec = is_specialization_of_kind_of<T>;
|
||||
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<auto... Args>
|
||||
void to_base_specialization_of_quantity_spec(const volatile quantity_spec<Args...>*);
|
||||
#else
|
||||
@ -65,7 +66,7 @@ inline constexpr bool is_derived_from_specialization_of_quantity_spec =
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_quantity_spec = false;
|
||||
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<auto... Args>
|
||||
inline constexpr bool is_specialization_of_quantity_spec<quantity_spec<Args...>> = true;
|
||||
#else
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <mp-units/bits/external/hacks.h>
|
||||
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
|
||||
#define QUANTITY_SPEC(name, ...) \
|
||||
inline constexpr struct name : ::mp_units::quantity_spec<__VA_ARGS__> { \
|
||||
@ -38,6 +38,14 @@
|
||||
|
||||
#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
|
||||
|
||||
MP_UNITS_DIAGNOSTIC_PUSH
|
||||
|
@ -319,7 +319,7 @@ MP_UNITS_EXPORT template<dimension_symbol_formatting fmt = dimension_symbol_form
|
||||
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 auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(D{});
|
||||
return std::string_view(buffer.data(), size);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <mp-units/bits/expression_template.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_traits.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>
|
||||
[[nodiscard]] consteval auto get_associated_quantity(U);
|
||||
|
||||
#ifndef __cpp_explicit_this_parameter
|
||||
#ifndef MP_UNITS_API_NO_CRTP
|
||||
template<typename Self>
|
||||
#endif
|
||||
struct quantity_spec_interface {
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<typename Self, UnitOf<Self{}> 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
|
||||
* to each other.
|
||||
*/
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<auto...>
|
||||
#else
|
||||
template<typename, auto...>
|
||||
@ -211,7 +212,7 @@ MP_UNITS_EXPORT_END
|
||||
* @tparam BaseDimension base dimension for which a base quantity is being defined
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
*/
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<detail::BaseDimension auto Dim, one_of<quantity_character> auto... Args>
|
||||
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
||||
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 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>
|
||||
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
||||
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
|
||||
* 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>
|
||||
requires(... && !QuantitySpec<std::remove_const_t<decltype(Args)>>)
|
||||
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 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>
|
||||
[[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
|
||||
* 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,
|
||||
one_of<quantity_character, struct is_kind> auto... Args>
|
||||
requires(!requires { QS._equation_; } ||
|
||||
@ -418,7 +419,7 @@ struct quantity_spec<Self, QS, Eq, Args...> : quantity_spec<Self, QS, Args...> {
|
||||
*/
|
||||
template<detail::IntermediateDerivedQuantitySpecExpr... Expr>
|
||||
struct derived_quantity_spec :
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
detail::quantity_spec_interface,
|
||||
#else
|
||||
detail::quantity_spec_interface<derived_quantity_spec<Expr...>>,
|
||||
@ -456,7 +457,7 @@ template<QuantitySpec Q>
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#ifdef __cpp_explicit_this_parameter
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<typename Q>
|
||||
requires detail::QuantitySpecWithNoSpecifiers<Q> && (detail::get_kind_tree_root(Q{}) == Q{})
|
||||
struct kind_of_<Q> : Q {
|
||||
@ -1430,7 +1431,7 @@ template<QuantitySpec Q>
|
||||
requires requires(Q q) { 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>
|
||||
[[nodiscard]] consteval bool defined_as_kind(quantity_spec<QS, Args...>)
|
||||
#else
|
||||
|
@ -840,7 +840,7 @@ MP_UNITS_EXPORT template<unit_symbol_formatting fmt = unit_symbol_formatting{},
|
||||
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 auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(U{});
|
||||
return std::string_view(buffer.data(), size);
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
if(MP_UNITS_USE_FMTLIB)
|
||||
if(MP_UNITS_API_STD_FORMAT)
|
||||
find_dependency(fmt)
|
||||
endif()
|
||||
|
||||
|
@ -22,13 +22,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mp-units/bits/external/hacks.h>
|
||||
#include <mp-units/quantity_spec.h>
|
||||
#include <type_traits>
|
||||
|
||||
template<auto V, typename 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, ...) \
|
||||
inline constexpr struct name##_ : quantity_spec<__VA_ARGS__> { \
|
||||
|
@ -27,4 +27,4 @@ find_package(mp-units REQUIRED)
|
||||
|
||||
add_executable(test_package test_package.cpp)
|
||||
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):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.variables["MP_UNITS_USE_FMTLIB"] = bool(
|
||||
self.dependencies["mp-units"].options.use_fmtlib
|
||||
tc.variables["MP_UNITS_API_STD_FORMAT"] = bool(
|
||||
self.dependencies["mp-units"].options.std_format
|
||||
)
|
||||
tc.generate()
|
||||
|
||||
|
Reference in New Issue
Block a user