Merge branch 'master' into chiphogg/docs

This commit is contained in:
Chip Hogg
2022-08-04 18:29:44 +00:00
74 changed files with 819 additions and 1421 deletions
+3 -500
View File
@@ -1,488 +1,11 @@
# -*- coding: utf-8 -*-
"""
pygments.lexers.c_cpp
~~~~~~~~~~~~~~~~~~~~~
Lexers for C/C++ languages.
:copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import re
import subprocess
from pygments.lexer import (
RegexLexer,
bygroups,
default,
include,
inherit,
this,
using,
words,
)
from pygments.token import (
Comment,
Error,
Keyword,
Name,
Number,
Operator,
Punctuation,
String,
Text,
)
from pygments.util import get_bool_opt
from sphinx.highlighting import lexers
class MyCFamilyLexer(RegexLexer):
#: optional Comment or Whitespace
_ws = r"(?:\s|//.*?\n|/[*].*?[*]/)+"
# The trailing ?, rather than *, avoids a geometric performance drop here.
#: only one /* */ style comment
_ws1 = r"\s*(?:/[*].*?[*]/\s*)?"
tokens = {
"whitespace": [
# preprocessor directives: without whitespace
(r"^#if\s+0", Comment.Preproc, "if0"),
("^#", Comment.Preproc, "macro"),
# or with whitespace
(
"^(" + _ws1 + r")(#if\s+0)",
bygroups(using(this), Comment.Preproc),
"if0",
),
("^(" + _ws1 + ")(#)", bygroups(using(this), Comment.Preproc), "macro"),
(r"\n", Text),
(r"\s+", Text),
(r"\\\n", Text), # line continuation
(r"//(\n|[\w\W]*?[^\\]\n)", Comment.Single),
(r"/(\\\n)?[*][\w\W]*?[*](\\\n)?/", Comment.Multiline),
# Open until EOF, so no ending delimeter
(r"/(\\\n)?[*][\w\W]*", Comment.Multiline),
],
"statements": [
(r'(L?)(")', bygroups(String.Affix, String), "string"),
(
r"(L?)(')(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])(')",
bygroups(String.Affix, String.Char, String.Char, String.Char),
),
(r"\*/", Error),
(r"[~!%^&*+=|?:<>/-]", Operator),
(r"[()\[\],.]", Punctuation),
(
words(
(
"asm",
"auto",
"break",
"case",
"const",
"continue",
"default",
"do",
"else",
"enum",
"extern",
"for",
"goto",
"if",
"register",
"restricted",
"return",
"sizeof",
"static",
"struct",
"switch",
"typedef",
"union",
"volatile",
"while",
),
suffix=r"\b",
),
Keyword,
),
(
r"(bool|int|long|float|short|double|char|unsigned|signed|void)\b",
Keyword.Type,
),
(
words(
(
"inline",
"_inline",
"__inline",
"naked",
"restrict",
"thread",
"typename",
),
suffix=r"\b",
),
Keyword.Reserved,
),
# Vector intrinsics
(r"(__m(128i|128d|128|64))\b", Keyword.Reserved),
# Microsoft-isms
(
words(
(
"asm",
"int8",
"based",
"except",
"int16",
"stdcall",
"cdecl",
"fastcall",
"int32",
"declspec",
"finally",
"int64",
"try",
"leave",
"wchar_t",
"w64",
"unaligned",
"raise",
"noop",
"identifier",
"forceinline",
"assume",
),
prefix=r"__",
suffix=r"\b",
),
Keyword.Reserved,
),
(r"(true|false|NULL)\b", Name.Builtin),
(r"([a-zA-Z_]\w*)(\s*)(:)(?!:)", bygroups(Name.Label, Text, Punctuation)),
(r"[a-zA-Z_]\w*", Name),
],
"root": [
include("whitespace"),
# functions
(
r"((?:[\w*\s])+?(?:\s|[*]))" # return arguments
r"([a-zA-Z_]\w*)" # method name
r"(\s*\([^;]*?\))" # signature
r"([^;{]*)(\{)",
bygroups(
using(this), Name.Function, using(this), using(this), Punctuation
),
"function",
),
# function declarations
(
r"((?:[\w*\s])+?(?:\s|[*]))" # return arguments
r"([a-zA-Z_]\w*)" # method name
r"(\s*\([^;]*?\))" # signature
r"([^;]*)(;)",
bygroups(
using(this), Name.Function, using(this), using(this), Punctuation
),
),
default("statement"),
],
"statement": [
include("whitespace"),
include("statements"),
("[{}]", Punctuation),
(";", Punctuation, "#pop"),
],
"function": [
include("whitespace"),
include("statements"),
(";", Punctuation),
(r"\{", Punctuation, "#push"),
(r"\}", Punctuation, "#pop"),
],
"string": [
(r'"', String, "#pop"),
(
r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|'
r"u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|[0-7]{1,3})",
String.Escape,
),
(r'[^\\"\n]+', String), # all other characters
(r"\\\n", String), # line continuation
(r"\\", String), # stray backslash
],
"macro": [
(
r"(include)(" + _ws1 + r")([^\n]+)",
bygroups(Comment.Preproc, Text, Comment.PreprocFile),
),
(r"[^/\n]+", Comment.Preproc),
(r"/[*](.|\n)*?[*]/", Comment.Multiline),
(r"//.*?\n", Comment.Single, "#pop"),
(r"/", Comment.Preproc),
(r"(?<=\\)\n", Comment.Preproc),
(r"\n", Comment.Preproc, "#pop"),
],
"if0": [
(r"^\s*#if.*?(?<!\\)\n", Comment.Preproc, "#push"),
(r"^\s*#el(?:se|if).*\n", Comment.Preproc, "#pop"),
(r"^\s*#endif.*?(?<!\\)\n", Comment.Preproc, "#pop"),
(r".*?\n", Comment),
],
}
stdlib_types = {
"size_t",
"ssize_t",
"off_t",
"wchar_t",
"ptrdiff_t",
"sig_atomic_t",
"fpos_t",
"clock_t",
"time_t",
"va_list",
"jmp_buf",
"FILE",
"DIR",
"div_t",
"ldiv_t",
"mbstate_t",
"wctrans_t",
"wint_t",
"wctype_t",
}
c99_types = {
"_Bool",
"_Complex",
"int8_t",
"int16_t",
"int32_t",
"int64_t",
"uint8_t",
"uint16_t",
"uint32_t",
"uint64_t",
"int_least8_t",
"int_least16_t",
"int_least32_t",
"int_least64_t",
"uint_least8_t",
"uint_least16_t",
"uint_least32_t",
"uint_least64_t",
"int_fast8_t",
"int_fast16_t",
"int_fast32_t",
"int_fast64_t",
"uint_fast8_t",
"uint_fast16_t",
"uint_fast32_t",
"uint_fast64_t",
"intptr_t",
"uintptr_t",
"intmax_t",
"uintmax_t",
}
linux_types = {
"clockid_t",
"cpu_set_t",
"cpumask_t",
"dev_t",
"gid_t",
"id_t",
"ino_t",
"key_t",
"mode_t",
"nfds_t",
"pid_t",
"rlim_t",
"sig_t",
"sighandler_t",
"siginfo_t",
"sigset_t",
"sigval_t",
"socklen_t",
"timer_t",
"uid_t",
}
def __init__(self, **options):
self.stdlibhighlighting = get_bool_opt(options, "stdlibhighlighting", True)
self.c99highlighting = get_bool_opt(options, "c99highlighting", True)
self.platformhighlighting = get_bool_opt(options, "platformhighlighting", True)
RegexLexer.__init__(self, **options)
def get_tokens_unprocessed(self, text):
for index, token, value in RegexLexer.get_tokens_unprocessed(self, text):
if token is Name:
if self.stdlibhighlighting and value in self.stdlib_types:
token = Keyword.Type
elif self.c99highlighting and value in self.c99_types:
token = Keyword.Type
elif self.platformhighlighting and value in self.linux_types:
token = Keyword.Type
yield index, token, value
class MyCppLexer(MyCFamilyLexer):
"""
For C++ source code with preprocessor directives.
"""
name = "My C++"
aliases = ["cpp", "c++"]
filenames = [
"*.cpp",
"*.hpp",
"*.c++",
"*.h++",
"*.cc",
"*.hh",
"*.cxx",
"*.hxx",
"*.C",
"*.H",
"*.cp",
"*.CPP",
]
mimetypes = ["text/x-c++hdr", "text/x-c++src"]
priority = 0.1
tokens = {
"statements": [
(
words(
(
"catch",
"const_cast",
"delete",
"dynamic_cast",
"explicit",
"export",
"friend",
"mutable",
"namespace",
"new",
"operator",
"private",
"protected",
"public",
"reinterpret_cast",
"restrict",
"static_cast",
"template",
"this",
"throw",
"throws",
"try",
"typeid",
"typename",
"using",
"virtual",
"constexpr",
"nullptr",
"decltype",
"thread_local",
"alignas",
"alignof",
"static_assert",
"noexcept",
"override",
"final",
"constinit",
"consteval",
"constinit",
"concept",
"co_await",
"co_return",
"co_yield",
"requires",
"import",
"module",
),
suffix=r"\b",
),
Keyword,
),
(r"char(16_t|32_t|8_t)\b", Keyword.Type),
(r"(class)(\s+)", bygroups(Keyword, Text), "classname"),
# C++11 raw strings
(
r'(R)(")([^\\()\s]{,16})(\()((?:.|\n)*?)(\)\3)(")',
bygroups(
String.Affix,
String,
String.Delimiter,
String.Delimiter,
String,
String.Delimiter,
String,
),
),
# C++11 UTF-8/16/32 strings
(r'(u8|u|U)(")', bygroups(String.Affix, String), "string"),
# C++14 number separators
(
r"(\d[\d\']*\.[\d\']*|\.\d[\d\']*|\d[\d\']*)[eE][+-]?\d[\d\']*[LlUu]*",
Number.Float,
),
(r"(\d[\d\']*\.[\d\']*|\.\d[\d\']*|\d[\d\']*[fF])[fF]?", Number.Float),
(r"0x[0-9a-fA-F\']+[LlUu]*", Number.Hex),
(r"0[0-7\']+[LlUu]*", Number.Oct),
(r"\d[\d\']*[LlUu]*", Number.Integer),
inherit,
],
"root": [
inherit,
# C++ Microsoft-isms
(
words(
(
"virtual_inheritance",
"uuidof",
"super",
"single_inheritance",
"multiple_inheritance",
"interface",
"event",
),
prefix=r"__",
suffix=r"\b",
),
Keyword.Reserved,
),
# Offload C++ extensions, http://offload.codeplay.com/
(r"__(offload|blockingoffload|outer)\b", Keyword.Pseudo),
],
"classname": [
(r"[a-zA-Z_]\w*", Name.Class, "#pop"),
# template specification
(r"\s*(?=>)", Text, "#pop"),
],
}
def analyse_text(text):
if re.search("#include <[a-z_]+>", text):
return 0.2
if re.search("using namespace ", text):
return 0.4
lexers["cpp"] = MyCppLexer(startinline=True)
# TODO Remove the above when Pygments release with fixes is available
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options.
# For a full list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import re
def get_version():
try:
@@ -598,29 +121,9 @@ html_css_files = ["css/custom.css"]
# -- Breathe configuration ---------------------------------------------------
def configureDoxyfile(input_dir, output_dir):
with open("Doxyfile.in", "r") as file:
filedata = file.read()
filedata = filedata.replace("@DOXYGEN_INPUT_DIR@", input_dir)
filedata = filedata.replace("@DOXYGEN_OUTPUT_DIR@", output_dir)
with open("Doxyfile", "w") as file:
file.write(filedata)
# Check if we're running on Read the Docs' servers
read_the_docs_build = os.environ.get("READTHEDOCS", None) == "True"
# This should be a dictionary in which the keys are project names and the values
# are paths to the folder containing the doxygen output for that project.
breathe_projects = {}
if read_the_docs_build:
input_dir = "../src"
output_dir = "build"
configureDoxyfile(input_dir, output_dir)
subprocess.call("doxygen", shell=True)
breathe_projects["mp-units"] = output_dir + "/xml"
breathe_projects = {"mp-units": "build/xml"}
# This should match one of the keys in the breathe_projects dictionary and
# indicates which project should be used when the project is not specified on
-3
View File
@@ -188,9 +188,6 @@ and define units like::
struct electronvolt : named_scaled_unit<electronvolt, "eV", prefix,
ratio(1'602'176'634, 1'000'000'000, -19), joule> {};
..
TODO Submit a bug for above lexing problem
Finally, the last of the `named_scaled_unit` class template parameters
provide a reference unit for scaling. Please note that it can be a dimension's
base/coherent unit (like ``si::second``) or any other unit (i.e. ``si::minute``,
+10
View File
@@ -45,6 +45,11 @@ Concepts
A concept matching all unit types that have an atomic text symbol that can be used to aggregate it with
other named units to form a final symbol of a derived unit.
.. concept:: template<typename T> AliasUnit
A concept matching all alias unit types in the library. Satisfied by all unit types derived
from the instantiation of :class:`alias_unit`.
.. concept:: template<typename U, typename D> UnitOf
A concept matching only units of a specified dimension. Satisfied by all unit types that
@@ -63,6 +68,11 @@ Concepts
A concept matching all quantity-like types other than specialization of :class:`quantity`. Satisfied by
all types for which a correct specialization of :class:`quantity_like_traits` type trait is provided.
.. concept:: template<typename T> QuantityPointLike
A concept matching all quantity-point-like types other than specialization of :class:`quantity_point`.
Satisfied by all types for which a correct specialization of :class:`quantity_point_like_traits` type trait is provided.
.. concept:: template<typename T> WrappedQuantity
A concept matching types that wrap quantity objects. Satisfied by all wrapper types that
+119 -66
View File
@@ -22,8 +22,8 @@ This repository contains three independent CMake-based projects:
- when this library will become part of the C++ standard it will have no external dependencies
but until then it depends on:
- `{fmt} <https://github.com/fmtlib/fmt>`_ to provide text formatting of quantities.
- `gsl-lite <https://github.com/gsl-lite/gsl-lite>`_ to verify runtime contracts with the ``gsl_Expects`` macro.
- [for compilers other than VS2022] `{fmt} <https://github.com/fmtlib/fmt>`_ to provide text formatting of quantities.
- [only for clang < 14 with libc++] `range-v3 <https://github.com/ericniebler/range-v3>`_ to provide needed C++20 concepts and utilities.
- *.*
@@ -36,9 +36,13 @@ This repository contains three independent CMake-based projects:
- `linear algebra <https://github.com/BobSteagall/wg21/tree/master/include>`_
library based on proposal `P1385 <https://wg21.link/P1385>`_ used in some examples
and tests.
- in case you also want to build the project's documentation you will need:
- `Doxygen <http://www.doxygen.nl>`_ to extract C++ entities information from the source
code.
- `Sphinx <https://www.sphinx-doc.org>`_ to build the documentation.
- `Sphinx ReadTheDocs Theme <https://sphinx-rtd-theme.readthedocs.io/>`_
- `Sphinx recommonmark <https://recommonmark.readthedocs.io>`_.
- `Breathe <https://breathe.readthedocs.io/>`_ as a bridge between the Sphinx and Doxygen
documentation systems.
@@ -82,47 +86,47 @@ in *~/.conan/profiles* directory. An example profile can look as follows:
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=10
compiler.version=12
compiler.cppstd=20
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
[env]
CC=/usr/bin/gcc-10
CXX=/usr/bin/g++-10
CC=/usr/bin/gcc-12
CXX=/usr/bin/g++-12
.. tip::
Please note that **mp-units** library requires C++20 to be set either in a Conan profile or forced
via Conan command line. If you do the former, you will not need to provide ``-s compiler.cppstd=20``
every time your run a Conan command line (as it is suggested below).
every time your run a Conan command line (as provided in the command line instructions below).
Additionally, it is recommended to set Ninja as a CMake generator for Conan. To do so you should create
a *~/.conan/global.conf* file that will set ``tools.cmake.cmaketoolchain:generator`` to one of Ninja
generators. For example:
.. code-block:: text
tools.cmake.cmaketoolchain:generator="Ninja Multi-Config"
.. note::
*~/.conan/global.conf* file may also set ``tools.cmake.cmake_layout:build_folder_vars``` which
`makes working with several compilers or build configurations easier
<https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmake_layout.html#multi-setting-option-cmake-layout>`_.
For example the below line will force Conan to generate separate CMake presets and folders for each compiler:
.. code-block:: text
tools.cmake.cmake_layout:build_folder_vars=["settings.compiler", "settings.compiler.version"]
In such a case you will need to use a configuration specific preset name in the Conan instructions provided below
rather then just ``default`` and ``release`` (i.e. ``gcc-11`` and ``gcc-11-release``)
Build Options
-------------
Environment Variables
^^^^^^^^^^^^^^^^^^^^^
CONAN_RUN_TESTS
+++++++++++++++
**Values**: ``True``/``False``
**Defaulted to**: ``False``
Enables compilation of all the source code (tests and examples) and building the documentation.
To support this it requires some additional Conan build dependencies described in
`Repository Structure and Dependencies`_.
It also runs unit tests during Conan build.
Conan Options
^^^^^^^^^^^^^
@@ -139,15 +143,30 @@ Specifies how :ref:`design/downcasting:The Downcasting Facility` works:
- ``on`` - downcasting always forced -> compile-time errors in case of duplicated definitions
- ``automatic`` - downcasting automatically enabled if no collisions are present
build_docs
++++++++++
Conan Configuration Properties
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
build_all
+++++++++
**Values**: ``True``/``False``
**Defaulted to**: ``True``
**Defaulted to**: ``False``
If enabled, Conan installs the documentation generation dependencies (i.e. doxygen).
Additionally, enables project documentation generation when the project is being built by Conan.
Enables compilation of all the source code (tests and examples) and generating the documentation.
To support this it requires some additional Conan build dependencies described in
`Repository Structure and Dependencies`_.
It also runs unit tests during Conan build (unless ``tools.build:skip_test`` configuration property is set to ``True``)
skip_docs
+++++++++
**Values**: ``True``/``False``
**Defaulted to**: ``False``
If `build_all`_ is enabled, among others, Conan installs the documentation generation dependencies (i.e. doxygen) and
turns on the project documentation generation. Such behavior can be disabled with this option.
CMake Options
^^^^^^^^^^^^^
@@ -203,6 +222,21 @@ UNITS_USE_LIBFMT
Enables usage of `{fmt} <https://github.com/fmtlib/fmt>`_ library instead of the C++20 Standard Library feature.
CMake with Presets Support
--------------------------
It is recommended to use at least CMake 3.23 to build this project as this version introduced a support
for CMake Presets schema version 4 used now by Conan to generate presets files. All build instructions
below assume that you have such a support. If not, your CMake invocations have to be replaced to something
like:
.. code-block:: shell
mkdir build && cd build
cmake .. -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=<path_to_generators_dir>/conan_toolchain.cmake
cmake --build . --config Release
Installation and Reuse
----------------------
@@ -294,8 +328,8 @@ library release the following steps may be performed:
mkdir my_project/build && cd my_project/build
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -b=missing
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .
cmake .. -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
cmake --build . --config Release
Conan + CMake (Live At Head)
@@ -329,6 +363,9 @@ differences:
[requires]
mp-units/0.8.0@mpusz/testing
[layout]
cmake_layout
[generators]
CMakeToolchain
CMakeDeps
@@ -343,10 +380,9 @@ differences:
.. code-block:: shell
mkdir my_project/build && cd my_project/build
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -b=outdated -u
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .
conan install . -pr <your_conan_profile> -s compiler.cppstd=20 -b=outdated -u
cmake --preset default
cmake --build --preset release
Install
@@ -358,43 +394,60 @@ to find it, it is enough to perform the following steps:
.. code-block:: shell
mkdir units/build && cd units/build
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -b=missing
cmake ../src -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --install . --prefix <install_dir>
conan install . -pr <your_conan_profile> -s compiler.cppstd=20 -b=missing
mv CMakeUserPresets.json src
cd src
cmake --preset default -DCMAKE_INSTALL_PREFIX=<your_installation_path>
cmake --build --preset release --target install
Contributing (or just building all the tests, examples, and documentation)
--------------------------------------------------------------------------
Contributing (or just building all the tests and examples)
----------------------------------------------------------
In case you would like to build all the source code (with unit tests and examples) and documentation
in **mp-units** repository, you should:
In case you would like to build all the source code (with unit tests and examples) in **mp-units** repository,
you should:
1. Add remotes of additional Conan dependencies.
2. Use the *CMakeLists.txt* from the top-level directory.
3. Obtain Python dependencies.
4. Run Conan with `CONAN_RUN_TESTS`_ = ``True``.
1. Use the *CMakeLists.txt* from the top-level directory.
2. Run Conan with `build_all`_ = ``True``
(use ``-o build_docs=False`` if you want to skip the documentation generation).
.. code-block:: shell
git clone https://github.com/mpusz/units.git && cd units
conan install . -pr <your_conan_profile> -s compiler.cppstd=20 -c mp-units:user.build:all=True -c user.build:skip_docs=True -b outdated -u
conan build .
The above will download and install all of the dependencies needed for the development of the library,
build all of the source code and run unit tests.
If you prefer to build the project via CMake rather then Conan, then you should replace the last ``conan build .``
step with the explicit CMake build:
.. code-block:: shell
cmake --preset default
cmake --build --preset release
cmake --build --preset release --target test
Building documentation
----------------------
In case you would like to build the project's documentation, you should:
1. Use the *CMakeLists.txt* from the top-level directory.
2. Obtain Python dependencies.
3. Run Conan with `build_all`_ = ``True``.
.. code-block:: shell
git clone https://github.com/mpusz/units.git && cd units
pip3 install -r docs/requirements.txt
mkdir units/build && cd units/build
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -e mp-units:CONAN_RUN_TESTS=True -b outdated -u
conan build ..
conan install . -pr <your_conan_profile> -s compiler.cppstd=20 -c mp-units:user.build:all=True -b missing
cmake --preset default
cmake --build --preset release --target documentation
The above will download and install all of the dependencies needed for the development of the library,
build all of the source code and documentation, and run unit tests.
If you prefer to build the project via CMake rather then Conan, then you should replace the last ``conan build ..``
step with the CMake build:
.. code-block:: shell
# ...
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .
ctest
The above will download and install all of the dependencies needed and build the documentation.
Packaging
@@ -404,7 +457,7 @@ To test CMake installation and Conan packaging or create a Conan package run:
.. code-block:: shell
conan create . <username>/<channel> -pr <your_conan_profile> -s compiler.cppstd=20 -e mp-units:CONAN_RUN_TESTS=True -b outdated -u
conan create . <username>/<channel> -pr <your_conan_profile> -s compiler.cppstd=20 -c mp-units:user.build:all=True -c user.build:skip_docs=True -b outdated -u
The above will create a Conan package and run tests provided in *./test_package* directory.
+6 -6
View File
@@ -258,14 +258,14 @@ Even though the base dimension of ``si::fps`` is defined in terms of
``si::metre`` foot is preserved as the base unit of length in both systems::
constexpr auto fps_yard = fps::length<fps::yard>(1.);
constexpr auto fps_area = quantity_cast<unknown_coherent_unit>(fps_yard * fps_yard);
std::cout << fps_yard << "\n"; // 1 yd
std::cout << fps_area << "\n"; // 9 ft²
constexpr auto fps_area = fps_yard * fps_yard;
std::cout << fps_yard << "\n"; // 1 yd
std::cout << quantity_cast<decltype(fps_area)::dimension::coherent_unit>(fps_area) << "\n"; // 9 ft²
constexpr auto si_fps_yard = si::fps::length<si::fps::yard>(1.);
constexpr auto si_fps_area = quantity_cast<unknown_coherent_unit>(si_fps_yard * si_fps_yard);
std::cout << si_fps_yard << "\n"; // 1 yd
std::cout << si_fps_area << "\n"; // 9 ft²
constexpr auto si_fps_area = si_fps_yard * si_fps_yard;
std::cout << si_fps_yard << "\n"; // 1 yd
std::cout << quantity_cast<decltype(si_fps_area)::dimension::coherent_unit>(si_fps_area) << "\n"; // 9 ft²
In most cases we want conversions between systems and that is why nearly all
systems provided with this library are implemented in terms on the :term:`SI`
+1 -1
View File
@@ -59,7 +59,7 @@ It works just like `quantity_like_traits`, except that
``number(T)`` is replaced with ``relative(T)`` that returns the `QuantityLike` value
and ``dimension`` is replaced with ``origin``.
Similar to `quantity` and `quantity_kind`, `quantity_point` and `quantity_kind_point`
Similar to `quantity` and `quantity_kind`, `quantity_point` and `quantity_point_kind`
provide a deduction guide from `QuantityPointLike`::
using namespace std::chrono_literals;
+2 -2
View File
@@ -52,7 +52,7 @@ dimensions used in the division operation:
static_assert(std::is_same_v<decltype(result)::dimension,
unknown_dimension<exponent<dim_length, 1>, exponent<dim_time, -1>>>);
static_assert(std::is_same_v<decltype(result)::unit,
scaled_unit<ratio(1, 36, 1), unknown_coherent_unit>>);
scaled_unit<ratio(1, 36, 1), unknown_coherent_unit<exponent<dim_length, 1>, exponent<dim_time, -1>>>>>);
.. important::
@@ -81,7 +81,7 @@ this particular unknown derived dimension.
In case we would like to print the result in terms of base units we can simply do the
following::
auto s = quantity_cast<unknown_coherent_unit>(result);
auto s = quantity_cast<decltype(result)::dimension::coherent_unit>(result);
std::cout << "Speed: " << s << '\n'; // prints 'Speed: 20 m/s'
.. seealso::