Sphinx-based documentation added
@ -19,5 +19,6 @@ if [[ "$(uname -s)" == 'Darwin' ]]; then
|
||||
pyenv activate conan
|
||||
fi
|
||||
|
||||
pip install -r docs/requirements.txt
|
||||
pip install -U conan_package_tools
|
||||
conan user
|
||||
|
11
CHANGELOG.md
@ -1,6 +1,6 @@
|
||||
# Release notes
|
||||
|
||||
- 0.5.0 ???
|
||||
- 0.5.0 WIP
|
||||
- Major refactoring and rewrite of the library
|
||||
- Units are now independent from dimensions
|
||||
- Dimensions now depend on units (base or coherent units are provided in a class template)
|
||||
@ -9,12 +9,17 @@
|
||||
- Added official CGS system support
|
||||
- Added official data information system support
|
||||
- Repository file tree cleanup
|
||||
- `ratio` refactored to contain `Exp` template parameter
|
||||
- `ratio` refactored to contain `Exp` template parameter (thanks a lot @oschonrock!)
|
||||
- SI fundamental constants added
|
||||
- `q_` prefix applied to all the UDLs
|
||||
- `q_` prefix applied to all the UDLs (thanks @kwikius)
|
||||
- `unknown_unit` renamed to `unknown_coherent_unit`
|
||||
- Project documentation extended and switched to Sphinx
|
||||
- A few more usage examples added
|
||||
- ...
|
||||
|
||||
Many thanks to GitHub users @oschonrock and @kwikius for their support in drafting
|
||||
a new library design.
|
||||
|
||||
- 0.4.0 Nov 17, 2019
|
||||
- Support for derived dimensions in `exp` added
|
||||
- Added `pow()` and `sqrt()` operations on quantities
|
||||
|
@ -48,3 +48,6 @@ add_subdirectory(test)
|
||||
|
||||
# add usage example
|
||||
add_subdirectory(example)
|
||||
|
||||
# generate project documentation
|
||||
add_subdirectory(docs)
|
||||
|
198
README.md
@ -8,10 +8,35 @@
|
||||
|
||||
## TL;DR
|
||||
|
||||
This library is the subject of this ISO C++ proposal: [P1935](https://wg21.link/p1935). It is
|
||||
explained in this [CppCon 2019 talk](https://youtu.be/0YW6yxkdhlU) (slightly dated see below).
|
||||
We are working towards potentially having it standardized for C++23 and are actively looking
|
||||
for parties interested in field trialing the library.
|
||||
`mp-units` is a compile-time enabled Modern C++ library that provides compile-time dimensional
|
||||
analysis and unit/quantity manipulation. The basic idea and design heavily bases on
|
||||
`std::chrono::duration` and extends it to work properly with many dimensions.
|
||||
|
||||
Here is a small example of possible operations:
|
||||
|
||||
```cpp
|
||||
// simple numeric operations
|
||||
static_assert(10q_km / 2 == 5q_km);
|
||||
|
||||
// unit conversions
|
||||
static_assert(1q_h == 3600q_s);
|
||||
static_assert(1q_km + 1q_m == 1001q_m);
|
||||
|
||||
// dimension conversions
|
||||
static_assert(2q_m * 3q_m == 6q_m2);
|
||||
static_assert(10q_km / 5q_km == 2);
|
||||
static_assert(1000 / 1q_s == 1q_kHz);
|
||||
static_assert(1q_km / 1q_s == 1000q_mps);
|
||||
static_assert(2q_kmph * 2q_h == 4q_km);
|
||||
static_assert(2q_km / 2q_kmph == 1q_h);
|
||||
```
|
||||
|
||||
_Try it on the [Compiler Explorer](???)._
|
||||
|
||||
This library requires some C++20 features (concepts, classes as NTTPs, ...). Thanks to
|
||||
them the user gets a powerful but still easy to use interface and all unit conversions
|
||||
and dimensional analysis can be performed without sacrificing on accuracy. Please see
|
||||
the below example for a quick preview of basic library features:
|
||||
|
||||
```cpp
|
||||
#include <units/physical/si/velocity.h>
|
||||
@ -40,156 +65,29 @@ int main()
|
||||
}
|
||||
```
|
||||
|
||||
Try it on [Compiler Explorer](https://godbolt.org/z/_Yx6D7).
|
||||
_Try it on the [Compiler Explorer](https://godbolt.org/z/_Yx6D7)._
|
||||
|
||||
**The mp-units library is the subject of this ISO C++ paper: [P1935](https://wg21.link/p1935).
|
||||
It is explained in this [CppCon 2019 talk](https://youtu.be/0YW6yxkdhlU) (slightly dated now).
|
||||
We are working towards potentially having it standardized for C++23 and are actively looking
|
||||
for parties interested in field trialing the library.**
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
`mp-units` is a compile-time enabled Modern C++ library that provides compile-time dimensional
|
||||
analysis and unit/quantity manipulation. The basic idea and design heavily bases on
|
||||
`std::chrono::duration` and extends it to work properly with many dimensions.
|
||||
|
||||
Here is a small example of possible operations:
|
||||
|
||||
```cpp
|
||||
// simple numeric operations
|
||||
static_assert(10q_km / 2 == 5q_km);
|
||||
|
||||
// unit conversions
|
||||
static_assert(1q_h == 3600q_s);
|
||||
static_assert(1q_km + 1q_m == 1001q_m);
|
||||
|
||||
// dimension conversions
|
||||
static_assert(1q_km / 1q_s == 1000q_mps);
|
||||
static_assert(2q_kmph * 2q_h == 4q_km);
|
||||
static_assert(2q_km / 2q_kmph == 1q_h);
|
||||
|
||||
static_assert(1000 / 1q_s == 1q_kHz);
|
||||
|
||||
static_assert(10q_km / 5q_km == 2);
|
||||
```
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
The library framework consists of a few concepts: quantities, units, dimensions and their
|
||||
exponents. From the user's point of view the most important is a `quantity`.
|
||||
|
||||
A quantity is a concrete amount of a unit for a specified dimension with a specific representation:
|
||||
|
||||
```cpp
|
||||
units::quantity<units::si::dim_length, units::si::kilometre, double> d(123);
|
||||
```
|
||||
|
||||
To simplify quantity creation the library provides helper aliases for quantities of different
|
||||
dimensions. Thanks to then the above example can be rewritten as follows:
|
||||
|
||||
```cpp
|
||||
units::si::length<units::si::kilometre, double> d(123);
|
||||
```
|
||||
|
||||
To simplify creations of compile-time known constants the library provides UDLs for each unit.
|
||||
Thanks to them the same code can be as simple as:
|
||||
|
||||
```cpp
|
||||
using namespace units::si::literals;
|
||||
auto d = 123q_km; // units::length<units::si::kilometre, std::int64_t>
|
||||
```
|
||||
|
||||
For brevity, the next examples will assume:
|
||||
|
||||
```cpp
|
||||
using namespace units;
|
||||
```
|
||||
|
||||
Let's assume that the user wants to write the following code:
|
||||
|
||||
```cpp
|
||||
int main()
|
||||
{
|
||||
using namespace si::literals;
|
||||
auto v1 = avg_speed(220q_km, 2q_h);
|
||||
auto v2 = avg_speed(140q_mi, 2q_h);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
`avg_speed` is a simple function calculating an average speed from a distance and duration. It can
|
||||
be implemented as:
|
||||
|
||||
```cpp
|
||||
constexpr si::velocity<si::metre_per_second, int> avg_speed(si::length<si::metre> d, si::time<si::second> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
```
|
||||
|
||||
However, this function will perform unnecessary intermediate conversions (from kilometers to meters,
|
||||
from hours to seconds, and from meters per second to kilometers per hour). To eliminate all that
|
||||
overhead we have to write a template function:
|
||||
|
||||
```cpp
|
||||
template<typename U1, typename R1, typename U2, typename R2>
|
||||
constexpr auto avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
```
|
||||
|
||||
This function will work for every SI unit and representation without any unnecessary overhead.
|
||||
It is also simple enough to ensure that the returned type is actually a velocity. However,
|
||||
it might not always be the case. For more complicated calculations we would like to ensure
|
||||
that we are returning a correct type and also inform the user of that fact in the function
|
||||
template interface. Also we might want to implement a truly generic function that will work
|
||||
efficiently not only with SI units but also with other systems of units like CGS. The solution
|
||||
to this are C++20 concepts and generic functions.
|
||||
|
||||
```cpp
|
||||
constexpr Velocity auto avg_speed(Length auto d, Time auto t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
```
|
||||
|
||||
The units library also tries really hard to print any quantity in the most user friendly
|
||||
fashion:
|
||||
|
||||
```cpp
|
||||
int main()
|
||||
{
|
||||
using namespace si::literals;
|
||||
using namespace international::literals;
|
||||
Velocity auto v1 = avg_speed(220q_km, 2q_h);
|
||||
Velocity auto v2 = avg_speed(140q_mi, 2q_h);
|
||||
|
||||
std::cout << v1 << '\n'; // 110 km/h
|
||||
std::cout << quantity_cast<si::metre_per_second>(speed) << '\n'; // 30.5556 m/s
|
||||
std::cout << v2 << '\n'; // 70 mi/h
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Library design
|
||||
|
||||
A detailed `mp-units` library design rationale and documentation can be found in
|
||||
[doc/DESIGN.md](doc/DESIGN.md)
|
||||
|
||||
|
||||
## Repository structure
|
||||
|
||||
This repository contains three independent `cmake`-based projects:
|
||||
1. `./src` - header-only project containing whole `mp-units` library
|
||||
2. `.` - project used as an entry point for library development (it wraps `./src` project
|
||||
together with usage examples and tests)
|
||||
3. `./test_package` - library installation and Conan package verification
|
||||
|
||||
NOTE: Please note that this repository depends on a git submodule in the `./cmake/common`
|
||||
subdirectory.
|
||||
|
||||
|
||||
## Building, testing, and installation
|
||||
## Downloading, Building, Testing, and Installation
|
||||
|
||||
For a detailed information on project compilation, testing and reuse please refer to
|
||||
[doc/INSTALL.md](doc/INSTALL.md).
|
||||
|
||||
NOTE: This library as of now compiles correctly only with gcc-9.1 and newer.
|
||||
|
||||
|
||||
## User Guide
|
||||
|
||||
A detailed `mp-units` library design rationale and documentation can be found in
|
||||
[doc/DESIGN.md](doc/DESIGN.md)
|
||||
|
||||
|
||||
## Library Design
|
||||
|
||||
A detailed `mp-units` library design rationale and documentation can be found in
|
||||
[doc/DESIGN.md](doc/DESIGN.md)
|
||||
|
11
cmake/FindSphinx.cmake
Normal file
@ -0,0 +1,11 @@
|
||||
# Look for an executable called sphinx-build
|
||||
find_program(SPHINX_EXECUTABLE
|
||||
NAMES sphinx-build
|
||||
DOC "Path to sphinx-build executable")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
# Handle standard arguments to find_package like REQUIRED and QUIET
|
||||
find_package_handle_standard_args(Sphinx
|
||||
"Failed to find sphinx-build executable"
|
||||
SPHINX_EXECUTABLE)
|
@ -63,7 +63,7 @@ class UnitsConan(ConanFile):
|
||||
def _configure_cmake(self, folder="src"):
|
||||
cmake = CMake(self)
|
||||
if self._run_tests:
|
||||
# developer's mode (unit tests, examples, restrictive compilation warnings, ...)
|
||||
# developer's mode (unit tests, examples, documentation, restrictive compilation warnings, ...)
|
||||
cmake.configure()
|
||||
else:
|
||||
# consumer's mode (library sources only)
|
||||
@ -87,6 +87,8 @@ class UnitsConan(ConanFile):
|
||||
def build_requirements(self):
|
||||
if self._run_tests:
|
||||
self.build_requires("Catch2/2.11.0@catchorg/stable")
|
||||
# TODO update doxygen to the latest version when available
|
||||
self.build_requires("doxygen_installer/1.8.17@bincrafters/stable")
|
||||
|
||||
def build(self):
|
||||
cmake = self._configure_cmake()
|
||||
|
1
docs/CHANGELOG.md
Symbolic link
@ -0,0 +1 @@
|
||||
../CHANGELOG.md
|
104
docs/CMakeLists.txt
Normal file
@ -0,0 +1,104 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2018 Mateusz Pusz
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
find_package(Doxygen REQUIRED)
|
||||
find_package(Sphinx REQUIRED)
|
||||
|
||||
set(DOXYGEN_INPUT_DIR "${PROJECT_SOURCE_DIR}/src")
|
||||
set(DOXYGEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doxygen")
|
||||
set(DOXYGEN_INDEX_FILE "${DOXYGEN_OUTPUT_DIR}/xml/index.xml")
|
||||
set(DOXYFILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in")
|
||||
set(DOXYFILE_OUT "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||
|
||||
# Find all the public headers
|
||||
file(GLOB_RECURSE UNITS_PUBLIC_HEADERS ${DOXYGEN_INPUT_DIR}/*.h)
|
||||
|
||||
# Replace variables inside @@ with the current values
|
||||
configure_file("${DOXYFILE_IN}" "${DOXYFILE_OUT}" @ONLY)
|
||||
|
||||
# Doxygen won't create this for us
|
||||
file(MAKE_DIRECTORY "${DOXYGEN_OUTPUT_DIR}")
|
||||
|
||||
# Only regenerate Doxygen when the Doxyfile or public headers change
|
||||
add_custom_command(OUTPUT "${DOXYGEN_INDEX_FILE}"
|
||||
DEPENDS ${UNITS_PUBLIC_HEADERS}
|
||||
COMMAND "${DOXYGEN_EXECUTABLE}" "${DOXYFILE_OUT}"
|
||||
MAIN_DEPENDENCY "${DOXYFILE_OUT}" "${DOXYFILE_IN}"
|
||||
COMMENT "Generating docs:"
|
||||
VERBATIM)
|
||||
|
||||
# Nice named target so we can run the job easily
|
||||
add_custom_target(doxygen ALL DEPENDS "${DOXYGEN_INDEX_FILE}")
|
||||
|
||||
set(SPHINX_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(SPHINX_BUILD "${CMAKE_CURRENT_BINARY_DIR}/sphinx")
|
||||
set(SPHINX_INDEX_FILE "${SPHINX_BUILD}/index.html")
|
||||
|
||||
# Only regenerate Sphinx when:
|
||||
# - Doxygen has rerun
|
||||
# - Our doc files have been updated
|
||||
# - The Sphinx config has been updated
|
||||
add_custom_command(OUTPUT "${SPHINX_INDEX_FILE}"
|
||||
COMMAND
|
||||
"${SPHINX_EXECUTABLE}" -b html -j auto -Dbreathe_projects.mp-units="${DOXYGEN_OUTPUT_DIR}/xml" "${SPHINX_SOURCE}" "${SPHINX_BUILD}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/_static/css/custom.css"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/design.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/design/quantity.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/examples.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_units.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/examples/avg_speed.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/faq.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework/basic_concepts.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework/conversions_and_casting.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework/dimensions.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework/quantities.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework/text_output.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/framework/units.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/genindex.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/glossary.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/index.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/introduction.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/quick_start.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/reference/concepts.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/reference/functions.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/reference/systems.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/reference/types.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/extensions.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/legacy_interfaces.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/unknown_units_and_dimensions.rst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/usage.rst"
|
||||
"${DOXYGEN_INDEX_FILE}"
|
||||
MAIN_DEPENDENCY "${SPHINX_SOURCE}/conf.py"
|
||||
COMMENT "Generating documentation with Sphinx")
|
||||
|
||||
# Nice named target so we can run the job easily
|
||||
add_custom_target(sphinx ALL DEPENDS ${SPHINX_INDEX_FILE})
|
||||
|
||||
# Add an install target to install the docs
|
||||
include(GNUInstallDirs)
|
||||
install(DIRECTORY ${SPHINX_BUILD}
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
@ -961,3 +961,5 @@ struct quantity_values;
|
||||
with the same unit (i.e. `GeV`). Also if someone will decide to implement a systems where
|
||||
SI quantities of the same kind are expressed as different dimensions (i.e. height, width,
|
||||
and depth) all of them will just be measured in meters.
|
||||
|
||||
3. Why do we spell `metre` instead of `meter`?
|
86
docs/Doxyfile.in
Normal file
@ -0,0 +1,86 @@
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIR@"
|
||||
|
||||
# The INPUT tag is used to specify the files and/or directories that contain
|
||||
# documented source files. You may enter file names like myfile.cpp or
|
||||
# directories like /usr/src/myproject. Separate the files or directories with
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = "@DOXYGEN_INPUT_DIR@"
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
# The default value is: NO.
|
||||
|
||||
RECURSIVE = YES
|
||||
|
||||
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
|
||||
# to include (a tag file for) the STL sources as input, then you should set this
|
||||
# tag to YES in order to let doxygen match functions declarations and
|
||||
# definitions whose arguments contain STL classes (e.g. func(std::string);
|
||||
# versus func(std::string) {}). This also make the inheritance and collaboration
|
||||
# diagrams that involve STL classes more complete and accurate.
|
||||
# The default value is: NO.
|
||||
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
|
||||
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
|
||||
# The default value is: YES.
|
||||
|
||||
GENERATE_HTML = NO
|
||||
|
||||
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
|
||||
# The default value is: YES.
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
|
||||
# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
|
||||
# captures the structure of the code including all documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
GENERATE_XML = YES
|
||||
|
||||
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
|
||||
# documentation are documented, even if no documentation was available. Private
|
||||
# class members and static file members will be hidden unless the
|
||||
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
|
||||
# Note: This will also disable the warnings about undocumented members that are
|
||||
# normally produced when WARNINGS is set to YES.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_ALL = YES
|
||||
|
||||
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
|
||||
# included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_STATIC = YES
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||
# AClass::ANamespace, ANamespace::*Test
|
||||
#
|
||||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories use the pattern */test/*
|
||||
|
||||
EXCLUDE_SYMBOLS = units::detail
|
||||
|
||||
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
|
||||
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
|
||||
# will automatically be disabled.
|
||||
# The default value is: YES.
|
||||
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_AS_ERROR = NO
|
@ -1,5 +1,20 @@
|
||||
# Installation Guide
|
||||
|
||||
## Repository structure
|
||||
|
||||
This repository contains three independent `cmake`-based projects:
|
||||
1. `./src`
|
||||
- header-only project containing whole `mp-units` library
|
||||
2. `.`
|
||||
- project used as an entry point for library development (it wraps `./src` project
|
||||
together with usage examples and tests)
|
||||
|
||||
3. `./test_package` - library installation and Conan package verification
|
||||
|
||||
NOTE: Please note that this repository depends on a git submodule in the `./cmake/common`
|
||||
subdirectory.
|
||||
|
||||
|
||||
## Installation and Reuse
|
||||
|
||||
There are a few different ways of installing/reusing `units` in your project.
|
115
docs/README.md
Normal file
@ -0,0 +1,115 @@
|
||||
# `mp-units` - Documentation
|
||||
|
||||
## How to build?
|
||||
|
||||
1. Install the requirements (Sphinx) with:
|
||||
|
||||
```shell
|
||||
pip3 install -r docs/requirements.txt
|
||||
```
|
||||
|
||||
2. Install all dependencies with Conan for a developer's build:
|
||||
|
||||
```shell
|
||||
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -e CONAN_RUN_TESTS=True -b outdated
|
||||
```
|
||||
|
||||
3. Install Python 3
|
||||
4. Build the documentation with a regular CMake build
|
||||
|
||||
|
||||
## How to contribute?
|
||||
|
||||
To make any contribution to **mp-units** documentation please fork this repository and open
|
||||
a Pull Request.
|
||||
|
||||
### Style Guidelines
|
||||
|
||||
This guidelines are just general good practices for the formatting and structure of the whole
|
||||
documentation and do not pretend to be a stopper for any helpful contribution. Any contribution
|
||||
that may include relevant information for **mp-units** users will always be welcomed.
|
||||
|
||||
**mp-units** documentation is written in [reStructuredText](http://docutils.sourceforge.net/rst.html)
|
||||
and follows [reStructuredText Markup Specification](http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html).
|
||||
|
||||
[Quick reStructuredText](http://docutils.sourceforge.net/docs/user/rst/quickref.html) is also
|
||||
used for reference.
|
||||
|
||||
Any detail not covered by this guidelines will follow the aforementioned rules.
|
||||
|
||||
#### Section titles
|
||||
|
||||
Use section titles in this level of importance:
|
||||
|
||||
```rst
|
||||
Section Title
|
||||
=============
|
||||
|
||||
Subsection Title
|
||||
----------------
|
||||
|
||||
Subsubsection Title
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
#### Text emphasis/highlighting
|
||||
|
||||
- **Bold text** to highlight important text:
|
||||
|
||||
```rst
|
||||
**mp-units** is a compile-time enabled Modern C++ library that provides compile-time dimensional
|
||||
analysis and unit/quantity manipulation.
|
||||
```
|
||||
|
||||
- *Italics* to refer to file names, directory names, and paths.
|
||||
|
||||
```rst
|
||||
Create Conan configuration file (either *conanfile.txt* or *conanfile.py*) in your project's
|
||||
top-level directory...
|
||||
```
|
||||
|
||||
- ``Inline literals`` to refer to the in examples that is not a part of the **mp-units** library:
|
||||
|
||||
```rst
|
||||
Let's assume that the user wants to implement an ``avg_speed`` function that will
|
||||
be calculating the average speed based on provided distance and duration quantities.
|
||||
```
|
||||
|
||||
#### Literal blocks
|
||||
|
||||
Most of the C++ code examples should be provided as literal blocks after double `::` symbol:
|
||||
|
||||
```rst
|
||||
For this dimension-specific concepts come handy again and with usage of C++20 generic
|
||||
functions our function can look as simple as::
|
||||
|
||||
constexpr Velocity auto avg_speed(Length auto d, Time auto t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
```
|
||||
|
||||
#### code-blocks
|
||||
|
||||
Use code-blocks for exceptional cases like code samples in other languages or a need
|
||||
to emphasize specific lines of code:
|
||||
|
||||
```rst
|
||||
Quantities of the same dimension can be easily added or subtracted with
|
||||
each other and the result will always be a quantity of the same dimension:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 3-4
|
||||
|
||||
Length auto dist1 = 2q_m;
|
||||
Length auto dist2 = 1q_m;
|
||||
Length auto res1 = dist1 + dist2;
|
||||
Length auto res2 = dist1 - dist2;
|
||||
```
|
||||
|
||||
#### Indentation and line length
|
||||
|
||||
Make sure all indentation is done with spaces. Normally 2 space indentation for bulleted lists
|
||||
and 4 space indentation for code blocks and RST directives contents:
|
||||
|
||||
Do not leave any unnecessary or trailing spaces.
|
20
docs/_static/css/custom.css
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
@import 'theme.css';
|
||||
|
||||
a.reference.internal + code.sig-name.descname {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.breatheparameterlist li tt + p {
|
||||
display: inline;
|
||||
}
|
||||
.breatheenumvalues li tt + p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.rst-content .admonition-try-it-on-compiler-explorer {
|
||||
background-color: #e2f6d5;
|
||||
}
|
||||
|
||||
.rst-content .admonition-try-it-on-compiler-explorer > .admonition-title {
|
||||
background-color: #66c52a;
|
||||
}
|
0
doc/design.png → docs/_static/img/design.png
vendored
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
32
docs/_themes/sphinx_rtd_theme/__init__.py
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
"""
|
||||
Sphinx Read the Docs theme.
|
||||
|
||||
From https://github.com/ryan-roemer/sphinx-bootstrap-theme.
|
||||
"""
|
||||
|
||||
from os import path
|
||||
|
||||
import sphinx
|
||||
|
||||
|
||||
__version__ = '0.4.3.dev0'
|
||||
__version_full__ = __version__
|
||||
|
||||
|
||||
def get_html_theme_path():
|
||||
"""Return list of HTML theme paths."""
|
||||
cur_dir = path.abspath(path.dirname(path.dirname(__file__)))
|
||||
return cur_dir
|
||||
|
||||
|
||||
# See http://www.sphinx-doc.org/en/stable/theming.html#distribute-your-theme-as-a-python-package
|
||||
def setup(app):
|
||||
app.add_html_theme('sphinx_rtd_theme', path.abspath(path.dirname(__file__)))
|
||||
|
||||
if sphinx.version_info >= (1, 8, 0):
|
||||
# Add Sphinx message catalog for newer versions of Sphinx
|
||||
# See http://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_message_catalog
|
||||
rtd_locale_path = path.join(path.abspath(path.dirname(__file__)), 'locale')
|
||||
app.add_message_catalog('sphinx', rtd_locale_path)
|
||||
|
||||
return {'parallel_read_safe': True, 'parallel_write_safe': True}
|
82
docs/_themes/sphinx_rtd_theme/breadcrumbs.html
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
{# Support for Sphinx 1.3+ page_source_suffix, but don't break old builds. #}
|
||||
|
||||
{% if page_source_suffix %}
|
||||
{% set suffix = page_source_suffix %}
|
||||
{% else %}
|
||||
{% set suffix = source_suffix %}
|
||||
{% endif %}
|
||||
|
||||
{% if meta is defined and meta is not none %}
|
||||
{% set check_meta = True %}
|
||||
{% else %}
|
||||
{% set check_meta = False %}
|
||||
{% endif %}
|
||||
|
||||
{% if check_meta and 'github_url' in meta %}
|
||||
{% set display_github = True %}
|
||||
{% endif %}
|
||||
|
||||
{% if check_meta and 'bitbucket_url' in meta %}
|
||||
{% set display_bitbucket = True %}
|
||||
{% endif %}
|
||||
|
||||
{% if check_meta and 'gitlab_url' in meta %}
|
||||
{% set display_gitlab = True %}
|
||||
{% endif %}
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
|
||||
<ul class="wy-breadcrumbs">
|
||||
{% block breadcrumbs %}
|
||||
<li><a href="{{ pathto(master_doc) }}" class="icon icon-home"></a> »</li>
|
||||
{% for doc in parents %}
|
||||
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a> »</li>
|
||||
{% endfor %}
|
||||
<li>{{ title }}</li>
|
||||
{% endblock %}
|
||||
{% block breadcrumbs_aside %}
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
{% if hasdoc(pagename) %}
|
||||
{% if display_github %}
|
||||
{% if check_meta and 'github_url' in meta %}
|
||||
<!-- User defined GitHub URL -->
|
||||
<a href="{{ meta['github_url'] }}" class="fa fa-github"> {{ _('Edit on GitHub') }}</a>
|
||||
{% else %}
|
||||
<a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/{{ theme_vcs_pageview_mode|default("blob") }}/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-github"> {{ _('Edit on GitHub') }}</a>
|
||||
{% endif %}
|
||||
{% elif display_bitbucket %}
|
||||
{% if check_meta and 'bitbucket_url' in meta %}
|
||||
<!-- User defined Bitbucket URL -->
|
||||
<a href="{{ meta['bitbucket_url'] }}" class="fa fa-bitbucket"> {{ _('Edit on Bitbucket') }}</a>
|
||||
{% else %}
|
||||
<a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ suffix }}?mode={{ theme_vcs_pageview_mode|default("view") }}" class="fa fa-bitbucket"> {{ _('Edit on Bitbucket') }}</a>
|
||||
{% endif %}
|
||||
{% elif display_gitlab %}
|
||||
{% if check_meta and 'gitlab_url' in meta %}
|
||||
<!-- User defined GitLab URL -->
|
||||
<a href="{{ meta['gitlab_url'] }}" class="fa fa-gitlab"> {{ _('Edit on GitLab') }}</a>
|
||||
{% else %}
|
||||
<a href="https://{{ gitlab_host|default("gitlab.com") }}/{{ gitlab_user }}/{{ gitlab_repo }}/{{ theme_vcs_pageview_mode|default("blob") }}/{{ gitlab_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-gitlab"> {{ _('Edit on GitLab') }}</a>
|
||||
{% endif %}
|
||||
{% elif show_source and source_url_prefix %}
|
||||
<a href="{{ source_url_prefix }}{{ pagename }}{{ suffix }}">{{ _('View page source') }}</a>
|
||||
{% elif show_source and has_source and sourcename %}
|
||||
<a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> {{ _('View page source') }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endblock %}
|
||||
</ul>
|
||||
|
||||
{% if (theme_prev_next_buttons_location == 'top' or theme_prev_next_buttons_location == 'both') and (next or prev) %}
|
||||
<div class="rst-breadcrumbs-buttons" role="navigation" aria-label="breadcrumb navigation">
|
||||
{% if next %}
|
||||
<a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n">{{ _('Next') }} <span class="fa fa-arrow-circle-right"></span></a>
|
||||
{% endif %}
|
||||
{% if prev %}
|
||||
<a href="{{ prev.link|e }}" class="btn btn-neutral float-left" title="{{ prev.title|striptags|e }}" accesskey="p"><span class="fa fa-arrow-circle-left"></span> {{ _('Previous') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr/>
|
||||
</div>
|
56
docs/_themes/sphinx_rtd_theme/footer.html
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<footer>
|
||||
{% if (theme_prev_next_buttons_location == 'bottom' or theme_prev_next_buttons_location == 'both') and (next or prev) %}
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
{% if next %}
|
||||
<a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n" rel="next">{{ _('Next') }} <span class="fa fa-arrow-circle-right"></span></a>
|
||||
{% endif %}
|
||||
{% if prev %}
|
||||
<a href="{{ prev.link|e }}" class="btn btn-neutral float-left" title="{{ prev.title|striptags|e }}" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> {{ _('Previous') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
{%- if show_copyright %}
|
||||
{%- if hasdoc('copyright') %}
|
||||
{% set path = pathto('copyright') %}
|
||||
{% set copyright = copyright|e %}
|
||||
© <a href="{{ path }}">{% trans %}Copyright{% endtrans %}</a> {{ copyright }}
|
||||
{%- else %}
|
||||
{% set copyright = copyright|e %}
|
||||
© {% trans %}Copyright{% endtrans %} {{ copyright }}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
{%- if build_id and build_url %}
|
||||
<span class="build">
|
||||
{# Translators: Build is a noun, not a verb #}
|
||||
{% trans %}Build{% endtrans %}
|
||||
<a href="{{ build_url }}">{{ build_id }}</a>.
|
||||
</span>
|
||||
{%- elif commit %}
|
||||
<span class="commit">
|
||||
{% trans %}Revision{% endtrans %} <code>{{ commit }}</code>.
|
||||
</span>
|
||||
{%- elif last_updated %}
|
||||
<span class="lastupdated">
|
||||
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
|
||||
</span>
|
||||
{%- endif %}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{%- if show_sphinx %}
|
||||
{% set sphinx_web = '<a href="http://sphinx-doc.org/">Sphinx</a>' %}
|
||||
{% set readthedocs_web = '<a href="https://readthedocs.org">Read the Docs</a>' %}
|
||||
{% trans sphinx_web=sphinx_web, readthedocs_web=readthedocs_web %}Built with {{ sphinx_web }} using a{% endtrans %} <a href="https://github.com/rtfd/sphinx_rtd_theme">{% trans %}theme{% endtrans %}</a> {% trans %}provided by {{ readthedocs_web }}{% endtrans %}.
|
||||
{%- endif %}
|
||||
|
||||
{%- block extrafooter %} {% endblock %}
|
||||
|
||||
</footer>
|
||||
|
240
docs/_themes/sphinx_rtd_theme/layout.html
vendored
Normal file
@ -0,0 +1,240 @@
|
||||
{# TEMPLATE VAR SETTINGS #}
|
||||
{%- set url_root = pathto('', 1) %}
|
||||
{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
|
||||
{%- if not embedded and docstitle %}
|
||||
{%- set titlesuffix = " — "|safe + docstitle|e %}
|
||||
{%- else %}
|
||||
{%- set titlesuffix = "" %}
|
||||
{%- endif %}
|
||||
{%- set lang_attr = 'en' if language == None else (language | replace('_', '-')) %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ lang_attr }}" >
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{{ metatags }}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% block htmltitle %}
|
||||
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
|
||||
{% endblock %}
|
||||
|
||||
{# CSS #}
|
||||
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
|
||||
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
|
||||
{%- for css in css_files %}
|
||||
{%- if css|attr("rel") %}
|
||||
<link rel="{{ css.rel }}" href="{{ pathto(css.filename, 1) }}" type="text/css"{% if css.title is not none %} title="{{ css.title }}"{% endif %} />
|
||||
{%- else %}
|
||||
<link rel="stylesheet" href="{{ pathto(css, 1) }}" type="text/css" />
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- for cssfile in extra_css_files %}
|
||||
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
|
||||
{%- endfor %}
|
||||
|
||||
{# FAVICON #}
|
||||
{% if favicon %}
|
||||
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
|
||||
{% endif %}
|
||||
{# CANONICAL URL #}
|
||||
{% if theme_canonical_url %}
|
||||
<link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html"/>
|
||||
{% endif %}
|
||||
|
||||
{# JAVASCRIPTS #}
|
||||
{%- block scripts %}
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{ pathto('_static/js/html5shiv.min.js', 1) }}"></script>
|
||||
<![endif]-->
|
||||
{%- if not embedded %}
|
||||
{# XXX Sphinx 1.8.0 made this an external js-file, quick fix until we refactor the template to inherert more blocks directly from sphinx #}
|
||||
{% if sphinx_version >= "1.8.0" %}
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
|
||||
{%- for scriptfile in script_files %}
|
||||
{{ js_tag(scriptfile) }}
|
||||
{%- endfor %}
|
||||
{% else %}
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'{{ url_root }}',
|
||||
VERSION:'{{ release|e }}',
|
||||
LANGUAGE:'{{ language }}',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
|
||||
HAS_SOURCE: {{ has_source|lower }},
|
||||
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
|
||||
};
|
||||
</script>
|
||||
{%- for scriptfile in script_files %}
|
||||
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
<script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
|
||||
|
||||
{# OPENSEARCH #}
|
||||
{%- if use_opensearch %}
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
|
||||
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block linktags %}
|
||||
{%- if hasdoc('about') %}
|
||||
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
|
||||
{%- endif %}
|
||||
{%- if hasdoc('genindex') %}
|
||||
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
|
||||
{%- endif %}
|
||||
{%- if hasdoc('search') %}
|
||||
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
|
||||
{%- endif %}
|
||||
{%- if hasdoc('copyright') %}
|
||||
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
|
||||
{%- endif %}
|
||||
{%- if next %}
|
||||
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
|
||||
{%- endif %}
|
||||
{%- if prev %}
|
||||
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
{%- block extrahead %} {% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
{% block extrabody %} {% endblock %}
|
||||
<div class="wy-grid-for-nav">
|
||||
{# SIDE NAV, TOGGLES ON MOBILE #}
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" {% if theme_style_nav_header_background %} style="background: {{theme_style_nav_header_background}}" {% endif %}>
|
||||
{% block sidebartitle %}
|
||||
|
||||
{% if logo and theme_logo_only %}
|
||||
<a href="{{ pathto(master_doc) }}">
|
||||
{% else %}
|
||||
<a href="{{ pathto(master_doc) }}" class="icon icon-home" alt="{{ _("Documentation Home") }}"> {{ project }}
|
||||
{% endif %}
|
||||
|
||||
{% if logo %}
|
||||
{# Not strictly valid HTML, but it's the only way to display/scale
|
||||
it properly, without weird scripting or heaps of work
|
||||
#}
|
||||
<img src="{{ pathto('_static/' + logo, 1) }}" class="logo" alt="{{ _('Logo') }}"/>
|
||||
{% endif %}
|
||||
</a>
|
||||
|
||||
{% if theme_display_version %}
|
||||
{%- set nav_version = version %}
|
||||
{% if READTHEDOCS and current_version %}
|
||||
{%- set nav_version = current_version %}
|
||||
{% endif %}
|
||||
{% if nav_version %}
|
||||
<div class="version">
|
||||
{{ nav_version }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% include "searchbox.html" %}
|
||||
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
{% block navigation %}
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
{% block menu %}
|
||||
{#
|
||||
The singlehtml builder doesn't handle this toctree call when the
|
||||
toctree is empty. Skip building this for now.
|
||||
#}
|
||||
{% if 'singlehtml' not in builder %}
|
||||
{% set global_toc = toctree(maxdepth=theme_navigation_depth|int,
|
||||
collapse=theme_collapse_navigation|tobool,
|
||||
includehidden=theme_includehidden|tobool,
|
||||
titles_only=theme_titles_only|tobool) %}
|
||||
{% endif %}
|
||||
{% if global_toc %}
|
||||
{{ global_toc }}
|
||||
{% else %}
|
||||
<!-- Local TOC -->
|
||||
<div class="local-toc">{{ toc }}</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
{# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
|
||||
<nav class="wy-nav-top" aria-label="top navigation">
|
||||
{% block mobile_nav %}
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="{{ pathto(master_doc) }}">{{ project }}</a>
|
||||
{% endblock %}
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
{%- block content %}
|
||||
{% if theme_style_external_links|tobool %}
|
||||
<div class="rst-content style-external-links">
|
||||
{% else %}
|
||||
<div class="rst-content">
|
||||
{% endif %}
|
||||
{% include "breadcrumbs.html" %}
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
{%- block document %}
|
||||
<div itemprop="articleBody">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
{% if self.comments()|trim %}
|
||||
<div class="articleComments">
|
||||
{% block comments %}{% endblock %}
|
||||
</div>
|
||||
{% endif%}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
{% include "footer.html" %}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
{% include "versions.html" %}
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable({{ 'true' if theme_sticky_navigation|tobool else 'false' }});
|
||||
});
|
||||
</script>
|
||||
|
||||
{# Do not conflict with RTD insertion of analytics script #}
|
||||
{% if not READTHEDOCS %}
|
||||
{% if theme_analytics_id %}
|
||||
<!-- Theme Analytics -->
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '{{ theme_analytics_id }}', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{%- block footer %} {% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
docs/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.mo
vendored
Normal file
208
docs/_themes/sphinx_rtd_theme/locale/de/LC_MESSAGES/sphinx.po
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
# German translations for sphinx_rtd_theme.
|
||||
# Copyright (C) 2018 Read the Docs
|
||||
# This file is distributed under the same license as the sphinx_rtd_theme
|
||||
# project.
|
||||
# Dennis Wegner <dennis@instant-thinking.de>, 2018.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sphinx_rtd_theme 0.2.4\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-07-24 23:51-0600\n"
|
||||
"PO-Revision-Date: 2020-01-30 12:53+0100\n"
|
||||
"Last-Translator: Jan Niklas Hasse <jhasse@bixense.com>\n"
|
||||
"Language-Team: German Team\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Generated-By: Babel 2.4.0\n"
|
||||
"X-Generator: Poedit 2.2.4\n"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:31
|
||||
msgid "Docs"
|
||||
msgstr "Dokumente"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
|
||||
msgid "Edit on GitHub"
|
||||
msgstr "Auf GitHub bearbeiten"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
|
||||
msgid "Edit on Bitbucket"
|
||||
msgstr "Auf Bitbucket bearbeiten"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
|
||||
msgid "Edit on GitLab"
|
||||
msgstr "Auf GitLab bearbeiten"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
|
||||
msgid "View page source"
|
||||
msgstr "Seitenquelltext anzeigen"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
|
||||
msgid "Next"
|
||||
msgstr "Weiter"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
|
||||
msgid "Previous"
|
||||
msgstr "Zurück"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
|
||||
#: sphinx_rtd_theme/layout.html:92
|
||||
msgid "Copyright"
|
||||
msgstr "Copyright"
|
||||
|
||||
#. Build is a noun, not a verb
|
||||
#: sphinx_rtd_theme/footer.html:31
|
||||
msgid "Build"
|
||||
msgstr "Build"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:36
|
||||
msgid "Revision"
|
||||
msgstr "Revision"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:40
|
||||
#, python-format
|
||||
msgid "Last updated on %(last_updated)s."
|
||||
msgstr "Zuletzt aktualisiert am %(last_updated)s."
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "Built with %(sphinx_web)s using a"
|
||||
msgstr "Erstellt mit %(sphinx_web)s unter Verwendung eines"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
msgid "theme"
|
||||
msgstr "Themes"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "provided by %(readthedocs_web)s"
|
||||
msgstr "von %(readthedocs_web)s"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:61
|
||||
#, python-format
|
||||
msgid "Search within %(docstitle)s"
|
||||
msgstr "Suche in %(docstitle)s"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:83
|
||||
msgid "About these documents"
|
||||
msgstr "Über diese Dokumente"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:86
|
||||
msgid "Index"
|
||||
msgstr "Index"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:89 sphinx_rtd_theme/search.html:11
|
||||
msgid "Search"
|
||||
msgstr "Suche"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:124
|
||||
msgid "Logo"
|
||||
msgstr "Logo"
|
||||
|
||||
#: sphinx_rtd_theme/search.html:26
|
||||
msgid "Please activate JavaScript to enable the search functionality."
|
||||
msgstr "Bitte JavaScript aktivieren um die Suchfunktion zu ermöglichen."
|
||||
|
||||
#. Search is a noun, not a verb
|
||||
#: sphinx_rtd_theme/search.html:34
|
||||
msgid "Search Results"
|
||||
msgstr "Suchergebnisse"
|
||||
|
||||
#: sphinx_rtd_theme/search.html:36
|
||||
msgid ""
|
||||
"Your search did not match any documents. Please make sure that all words are "
|
||||
"spelled correctly and that you've selected enough categories."
|
||||
msgstr ""
|
||||
"Deine Suche ergab keine Treffer. Bitte stelle sicher, dass alle Wörter "
|
||||
"richtig geschrieben sind und du genug Kategorien ausgewählt hast."
|
||||
|
||||
#: sphinx_rtd_theme/searchbox.html:4
|
||||
msgid "Search docs"
|
||||
msgstr "Dokumentation durchsuchen"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:11
|
||||
msgid "Versions"
|
||||
msgstr "Versionen"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:17
|
||||
msgid "Downloads"
|
||||
msgstr "Downloads"
|
||||
|
||||
#. The phrase "Read the Docs" is not translated
|
||||
#: sphinx_rtd_theme/versions.html:24
|
||||
msgid "On Read the Docs"
|
||||
msgstr "Auf Read the Docs"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:26
|
||||
msgid "Project Home"
|
||||
msgstr "Projektseite"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:29
|
||||
msgid "Builds"
|
||||
msgstr "Builds"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:33
|
||||
msgid "Free document hosting provided by"
|
||||
msgstr "Kostenloses Dokumenten-Hosting von"
|
||||
|
||||
#~ msgid "© <a href=\"%(path)s\">Copyright</a> %(copyright)s."
|
||||
#~ msgstr "© <a href=\\\"%(path)s\\\">Copyright</a> %(copyright)s."
|
||||
|
||||
#~ msgid "© Copyright %(copyright)s."
|
||||
#~ msgstr "© Copyright %(copyright)s."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ " <span class=\"build\">\n"
|
||||
#~ " Build\n"
|
||||
#~ " <a href=\"%(build_url)s\">%(build_id)s</a>.\n"
|
||||
#~ " </span>\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ " <span class=\"build\">\n"
|
||||
#~ " Build\n"
|
||||
#~ " <a href=\"%(build_url)s\">%(build_id)s</a>.\n"
|
||||
#~ " </span>\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ " <span class=\"commit\">\n"
|
||||
#~ " Revision <code>%(commit)s</code>.\n"
|
||||
#~ " </span>\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ " <span class=\"commit\">\n"
|
||||
#~ " Revision <code>%(commit)s</code>.\n"
|
||||
#~ " </span>\n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a> using a <a href="
|
||||
#~ "\"https://github.com/snide/sphinx_rtd_theme\">theme</a> provided by <a "
|
||||
#~ "href=\"https://readthedocs.org\">Read the Docs</a>"
|
||||
#~ msgstr ""
|
||||
#~ "Erstellt mit <a href=\"http://sphinx-doc.org/\">Sphinx</a> unter "
|
||||
#~ "Verwendung eines <a href=\"https://github.com/snide/sphinx_rtd_theme"
|
||||
#~ "\">Themes</a> von <a href=\"https://readthedocs.org\">Read the Docs</a>"
|
||||
|
||||
#~ msgid "Navigation"
|
||||
#~ msgstr "Navigation"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> "
|
||||
#~ "%(sphinx_version)s."
|
||||
#~ msgstr ""
|
||||
#~ "Erstellt mit <a href=\"http://sphinx-doc.org/\">Sphinx</a> "
|
||||
#~ "%(sphinx_version)s."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Free document hosting provided by <a href=\"http://www.readthedocs.org"
|
||||
#~ "\">Read the Docs</a>."
|
||||
#~ msgstr ""
|
||||
#~ "Dokumentationshosting gratis bei <a href=\"http://www.readthedocs.org"
|
||||
#~ "\">Read the Docs</a>."
|
BIN
docs/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.mo
vendored
Normal file
147
docs/_themes/sphinx_rtd_theme/locale/en/LC_MESSAGES/sphinx.po
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
# English translations for sphinx_rtd_theme.
|
||||
# Copyright (C) 2019 ORGANIZATION
|
||||
# This file is distributed under the same license as the sphinx_rtd_theme
|
||||
# project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-07-24 23:51-0600\n"
|
||||
"PO-Revision-Date: 2019-07-16 15:43-0600\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: en\n"
|
||||
"Language-Team: en <LL@li.org>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:31
|
||||
msgid "Docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
|
||||
msgid "Edit on GitHub"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
|
||||
msgid "Edit on Bitbucket"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
|
||||
msgid "Edit on GitLab"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
|
||||
msgid "View page source"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
|
||||
#: sphinx_rtd_theme/layout.html:92
|
||||
msgid "Copyright"
|
||||
msgstr ""
|
||||
|
||||
#. Build is a noun, not a verb
|
||||
#: sphinx_rtd_theme/footer.html:31
|
||||
msgid "Build"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:36
|
||||
msgid "Revision"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:40
|
||||
#, python-format
|
||||
msgid "Last updated on %(last_updated)s."
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "Built with %(sphinx_web)s using a"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
msgid "theme"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "provided by %(readthedocs_web)s"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:61
|
||||
#, python-format
|
||||
msgid "Search within %(docstitle)s"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:83
|
||||
msgid "About these documents"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:86
|
||||
msgid "Index"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:89 sphinx_rtd_theme/search.html:11
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:124
|
||||
msgid "Logo"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/search.html:26
|
||||
msgid "Please activate JavaScript to enable the search functionality."
|
||||
msgstr ""
|
||||
|
||||
#. Search is a noun, not a verb
|
||||
#: sphinx_rtd_theme/search.html:34
|
||||
msgid "Search Results"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/search.html:36
|
||||
msgid ""
|
||||
"Your search did not match any documents. Please make sure that all words "
|
||||
"are spelled correctly and that you've selected enough categories."
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/searchbox.html:4
|
||||
msgid "Search docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:11
|
||||
msgid "Versions"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:17
|
||||
msgid "Downloads"
|
||||
msgstr ""
|
||||
|
||||
#. The phrase "Read the Docs" is not translated
|
||||
#: sphinx_rtd_theme/versions.html:24
|
||||
msgid "On Read the Docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:26
|
||||
msgid "Project Home"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:29
|
||||
msgid "Builds"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:33
|
||||
msgid "Free document hosting provided by"
|
||||
msgstr ""
|
||||
|
BIN
docs/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.mo
vendored
Normal file
149
docs/_themes/sphinx_rtd_theme/locale/es/LC_MESSAGES/sphinx.po
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
# Spanish translations for sphinx_rtd_theme.
|
||||
# Copyright (C) 2019 Read the Docs, Inc
|
||||
# This file is distributed under the same license as the sphinx_rtd_theme
|
||||
# project.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
|
||||
"Report-Msgid-Bugs-To: support@readthedocs.org\n"
|
||||
"POT-Creation-Date: 2019-07-24 23:51-0600\n"
|
||||
"PO-Revision-Date: 2019-07-16 21:44+0000\n"
|
||||
"Last-Translator: Anthony <aj@ohess.org>, 2019\n"
|
||||
"Language: es\n"
|
||||
"Language-Team: Spanish "
|
||||
"(https://www.transifex.com/readthedocs/teams/101354/es/)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:31
|
||||
msgid "Docs"
|
||||
msgstr "Documentos"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
|
||||
msgid "Edit on GitHub"
|
||||
msgstr "Editar en GitHub"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
|
||||
msgid "Edit on Bitbucket"
|
||||
msgstr "Editar en Bitbucket"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
|
||||
msgid "Edit on GitLab"
|
||||
msgstr "Editar en GitLab"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
|
||||
msgid "View page source"
|
||||
msgstr "Ver código fuente de la página"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
|
||||
msgid "Next"
|
||||
msgstr "Siguiente"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
|
||||
msgid "Previous"
|
||||
msgstr "Anterior"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
|
||||
#: sphinx_rtd_theme/layout.html:92
|
||||
msgid "Copyright"
|
||||
msgstr "Derechos de autor"
|
||||
|
||||
#. Build is a noun, not a verb
|
||||
#: sphinx_rtd_theme/footer.html:31
|
||||
msgid "Build"
|
||||
msgstr "Construido"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:36
|
||||
msgid "Revision"
|
||||
msgstr "Revisión"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:40
|
||||
#, python-format
|
||||
msgid "Last updated on %(last_updated)s."
|
||||
msgstr "Actualizado por última vez en %(last_updated)s."
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "Built with %(sphinx_web)s using a"
|
||||
msgstr "Construido con %(sphinx_web)s usando un"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
msgid "theme"
|
||||
msgstr "tema"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "provided by %(readthedocs_web)s"
|
||||
msgstr "proporcionado por %(readthedocs_web)s"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:61
|
||||
#, python-format
|
||||
msgid "Search within %(docstitle)s"
|
||||
msgstr "Buscar en %(docstitle)s"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:83
|
||||
msgid "About these documents"
|
||||
msgstr "Sobre esta documentación"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:86
|
||||
msgid "Index"
|
||||
msgstr "Índice"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:89 sphinx_rtd_theme/search.html:11
|
||||
msgid "Search"
|
||||
msgstr "Búsqueda"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:124
|
||||
msgid "Logo"
|
||||
msgstr "Logotipo"
|
||||
|
||||
#: sphinx_rtd_theme/search.html:26
|
||||
msgid "Please activate JavaScript to enable the search functionality."
|
||||
msgstr "Por favor, active JavaScript para habilitar la funcionalidad de búsqueda."
|
||||
|
||||
#. Search is a noun, not a verb
|
||||
#: sphinx_rtd_theme/search.html:34
|
||||
msgid "Search Results"
|
||||
msgstr "Resultados de la búsqueda"
|
||||
|
||||
#: sphinx_rtd_theme/search.html:36
|
||||
msgid ""
|
||||
"Your search did not match any documents. Please make sure that all words "
|
||||
"are spelled correctly and that you've selected enough categories."
|
||||
msgstr ""
|
||||
"Su búsqueda no coincide con ningún documento. Por favor, asegúrese de que"
|
||||
" todas las palabras estén correctamente escritas y que usted haya "
|
||||
"seleccionado las suficientes categorías."
|
||||
|
||||
#: sphinx_rtd_theme/searchbox.html:4
|
||||
msgid "Search docs"
|
||||
msgstr "Buscar documentos"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:11
|
||||
msgid "Versions"
|
||||
msgstr "Versiones"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:17
|
||||
msgid "Downloads"
|
||||
msgstr "Descargas"
|
||||
|
||||
#. The phrase "Read the Docs" is not translated
|
||||
#: sphinx_rtd_theme/versions.html:24
|
||||
msgid "On Read the Docs"
|
||||
msgstr "En Read the Docs"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:26
|
||||
msgid "Project Home"
|
||||
msgstr "Página de Proyecto"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:29
|
||||
msgid "Builds"
|
||||
msgstr "Construcciones"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:33
|
||||
msgid "Free document hosting provided by"
|
||||
msgstr "Alojamiento gratuito de documentos proporcionado por"
|
||||
|
BIN
docs/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.mo
vendored
Normal file
152
docs/_themes/sphinx_rtd_theme/locale/nl/LC_MESSAGES/sphinx.po
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
# English translations for sphinx_rtd_theme.
|
||||
# Copyright (C) 2019 ORGANIZATION
|
||||
# This file is distributed under the same license as the sphinx_rtd_theme
|
||||
# project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
|
||||
#
|
||||
# Translators:
|
||||
# Jesse Tan, 2019
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-07-24 23:51-0600\n"
|
||||
"PO-Revision-Date: 2019-07-16 21:44+0000\n"
|
||||
"Last-Translator: Jesse Tan, 2019\n"
|
||||
"Language: nl\n"
|
||||
"Language-Team: Dutch "
|
||||
"(https://www.transifex.com/readthedocs/teams/101354/nl/)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:31
|
||||
msgid "Docs"
|
||||
msgstr "Documentatie"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
|
||||
msgid "Edit on GitHub"
|
||||
msgstr "Bewerk op GitHub"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
|
||||
msgid "Edit on Bitbucket"
|
||||
msgstr "Bewerk op BitBucket"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
|
||||
msgid "Edit on GitLab"
|
||||
msgstr "Bewerk op GitLab"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
|
||||
msgid "View page source"
|
||||
msgstr "Bekijk paginabron"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
|
||||
msgid "Next"
|
||||
msgstr "Volgende"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
|
||||
msgid "Previous"
|
||||
msgstr "Vorige"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
|
||||
#: sphinx_rtd_theme/layout.html:92
|
||||
msgid "Copyright"
|
||||
msgstr "Copyright"
|
||||
|
||||
#. Build is a noun, not a verb
|
||||
#: sphinx_rtd_theme/footer.html:31
|
||||
msgid "Build"
|
||||
msgstr "Bouwsel"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:36
|
||||
msgid "Revision"
|
||||
msgstr "Revisie"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:40
|
||||
#, python-format
|
||||
msgid "Last updated on %(last_updated)s."
|
||||
msgstr "Laatste update op %(last_updated)s."
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "Built with %(sphinx_web)s using a"
|
||||
msgstr "Gebouwd met %(sphinx_web)s met een"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
msgid "theme"
|
||||
msgstr "thema"
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "provided by %(readthedocs_web)s"
|
||||
msgstr "geleverd door %(readthedocs_web)s"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:61
|
||||
#, python-format
|
||||
msgid "Search within %(docstitle)s"
|
||||
msgstr "Zoek binnen %(docstitle)s"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:83
|
||||
msgid "About these documents"
|
||||
msgstr "Over deze documenten"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:86
|
||||
msgid "Index"
|
||||
msgstr "Index"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:89 sphinx_rtd_theme/search.html:11
|
||||
msgid "Search"
|
||||
msgstr "Zoek"
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:124
|
||||
msgid "Logo"
|
||||
msgstr "Logo"
|
||||
|
||||
#: sphinx_rtd_theme/search.html:26
|
||||
msgid "Please activate JavaScript to enable the search functionality."
|
||||
msgstr "Zet JavaScript aan om de zoekfunctie mogelijk te maken."
|
||||
|
||||
#. Search is a noun, not a verb
|
||||
#: sphinx_rtd_theme/search.html:34
|
||||
msgid "Search Results"
|
||||
msgstr "Zoekresultaten"
|
||||
|
||||
#: sphinx_rtd_theme/search.html:36
|
||||
msgid ""
|
||||
"Your search did not match any documents. Please make sure that all words "
|
||||
"are spelled correctly and that you've selected enough categories."
|
||||
msgstr ""
|
||||
"Zoekpoging vond geen documenten. Zorg ervoor dat alle woorden correct "
|
||||
"zijn gespeld en dat voldoende categorieën zijn geselecteerd."
|
||||
|
||||
#: sphinx_rtd_theme/searchbox.html:4
|
||||
msgid "Search docs"
|
||||
msgstr "Zoek in documentatie"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:11
|
||||
msgid "Versions"
|
||||
msgstr "Versies"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:17
|
||||
msgid "Downloads"
|
||||
msgstr "Downloads"
|
||||
|
||||
#. The phrase "Read the Docs" is not translated
|
||||
#: sphinx_rtd_theme/versions.html:24
|
||||
msgid "On Read the Docs"
|
||||
msgstr "Op Read the Docs"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:26
|
||||
msgid "Project Home"
|
||||
msgstr "Project Home"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:29
|
||||
msgid "Builds"
|
||||
msgstr "Bouwsels"
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:33
|
||||
msgid "Free document hosting provided by"
|
||||
msgstr "Gratis hosting voor documentatie verzorgd door"
|
||||
|
BIN
docs/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.mo
vendored
Normal file
148
docs/_themes/sphinx_rtd_theme/locale/ru/LC_MESSAGES/sphinx.po
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
# Russian translations for sphinx_rtd_theme.
|
||||
# Copyright (C) 2019 Read the Docs, Inc
|
||||
# This file is distributed under the same license as the sphinx_rtd_theme
|
||||
# project.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
|
||||
"Report-Msgid-Bugs-To: support@readthedocs.org\n"
|
||||
"POT-Creation-Date: 2019-07-24 23:51-0600\n"
|
||||
"PO-Revision-Date: 2019-07-16 21:44+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: ru\n"
|
||||
"Language-Team: Russian "
|
||||
"(https://www.transifex.com/readthedocs/teams/101354/ru/)\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) "
|
||||
"|| (n%100>=11 && n%100<=14)? 2 : 3)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:31
|
||||
msgid "Docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
|
||||
msgid "Edit on GitHub"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
|
||||
msgid "Edit on Bitbucket"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
|
||||
msgid "Edit on GitLab"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
|
||||
msgid "View page source"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
|
||||
#: sphinx_rtd_theme/layout.html:92
|
||||
msgid "Copyright"
|
||||
msgstr ""
|
||||
|
||||
#. Build is a noun, not a verb
|
||||
#: sphinx_rtd_theme/footer.html:31
|
||||
msgid "Build"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:36
|
||||
msgid "Revision"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:40
|
||||
#, python-format
|
||||
msgid "Last updated on %(last_updated)s."
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "Built with %(sphinx_web)s using a"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
msgid "theme"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "provided by %(readthedocs_web)s"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:61
|
||||
#, python-format
|
||||
msgid "Search within %(docstitle)s"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:83
|
||||
msgid "About these documents"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:86
|
||||
msgid "Index"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:89 sphinx_rtd_theme/search.html:11
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:124
|
||||
msgid "Logo"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/search.html:26
|
||||
msgid "Please activate JavaScript to enable the search functionality."
|
||||
msgstr ""
|
||||
|
||||
#. Search is a noun, not a verb
|
||||
#: sphinx_rtd_theme/search.html:34
|
||||
msgid "Search Results"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/search.html:36
|
||||
msgid ""
|
||||
"Your search did not match any documents. Please make sure that all words "
|
||||
"are spelled correctly and that you've selected enough categories."
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/searchbox.html:4
|
||||
msgid "Search docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:11
|
||||
msgid "Versions"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:17
|
||||
msgid "Downloads"
|
||||
msgstr ""
|
||||
|
||||
#. The phrase "Read the Docs" is not translated
|
||||
#: sphinx_rtd_theme/versions.html:24
|
||||
msgid "On Read the Docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:26
|
||||
msgid "Project Home"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:29
|
||||
msgid "Builds"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:33
|
||||
msgid "Free document hosting provided by"
|
||||
msgstr ""
|
||||
|
146
docs/_themes/sphinx_rtd_theme/locale/sphinx.pot
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
# Translations template for sphinx_rtd_theme.
|
||||
# Copyright (C) 2019 ORGANIZATION
|
||||
# This file is distributed under the same license as the sphinx_rtd_theme
|
||||
# project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: sphinx_rtd_theme 0.4.3.dev0\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2019-07-24 23:51-0600\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.7.0\n"
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:31
|
||||
msgid "Docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:43 sphinx_rtd_theme/breadcrumbs.html:45
|
||||
msgid "Edit on GitHub"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:50 sphinx_rtd_theme/breadcrumbs.html:52
|
||||
msgid "Edit on Bitbucket"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:57 sphinx_rtd_theme/breadcrumbs.html:59
|
||||
msgid "Edit on GitLab"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:62 sphinx_rtd_theme/breadcrumbs.html:64
|
||||
msgid "View page source"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:74 sphinx_rtd_theme/footer.html:5
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/breadcrumbs.html:77 sphinx_rtd_theme/footer.html:8
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:21 sphinx_rtd_theme/footer.html:24
|
||||
#: sphinx_rtd_theme/layout.html:92
|
||||
msgid "Copyright"
|
||||
msgstr ""
|
||||
|
||||
#. Build is a noun, not a verb
|
||||
#: sphinx_rtd_theme/footer.html:31
|
||||
msgid "Build"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:36
|
||||
msgid "Revision"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:40
|
||||
#, python-format
|
||||
msgid "Last updated on %(last_updated)s."
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "Built with %(sphinx_web)s using a"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
msgid "theme"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/footer.html:50
|
||||
#, python-format
|
||||
msgid "provided by %(readthedocs_web)s"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:61
|
||||
#, python-format
|
||||
msgid "Search within %(docstitle)s"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:83
|
||||
msgid "About these documents"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:86
|
||||
msgid "Index"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:89 sphinx_rtd_theme/search.html:11
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/layout.html:124
|
||||
msgid "Logo"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/search.html:26
|
||||
msgid "Please activate JavaScript to enable the search functionality."
|
||||
msgstr ""
|
||||
|
||||
#. Search is a noun, not a verb
|
||||
#: sphinx_rtd_theme/search.html:34
|
||||
msgid "Search Results"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/search.html:36
|
||||
msgid ""
|
||||
"Your search did not match any documents. Please make sure that all words "
|
||||
"are spelled correctly and that you've selected enough categories."
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/searchbox.html:4
|
||||
msgid "Search docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:11
|
||||
msgid "Versions"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:17
|
||||
msgid "Downloads"
|
||||
msgstr ""
|
||||
|
||||
#. The phrase "Read the Docs" is not translated
|
||||
#: sphinx_rtd_theme/versions.html:24
|
||||
msgid "On Read the Docs"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:26
|
||||
msgid "Project Home"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:29
|
||||
msgid "Builds"
|
||||
msgstr ""
|
||||
|
||||
#: sphinx_rtd_theme/versions.html:33
|
||||
msgid "Free document hosting provided by"
|
||||
msgstr ""
|
||||
|
54
docs/_themes/sphinx_rtd_theme/search.html
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
{#
|
||||
basic/search.html
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Template for the search page.
|
||||
|
||||
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
#}
|
||||
{%- extends "layout.html" %}
|
||||
{% set title = _('Search') %}
|
||||
{%- block scripts %}
|
||||
{{ super() }}
|
||||
<script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
|
||||
{%- endblock %}
|
||||
{% block footer %}
|
||||
<script type="text/javascript">
|
||||
jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
|
||||
</script>
|
||||
{# this is used when loading the search index using $.ajax fails,
|
||||
such as on Chrome for documents on localhost #}
|
||||
<script type="text/javascript" id="searchindexloader"></script>
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<noscript>
|
||||
<div id="fallback" class="admonition warning">
|
||||
<p class="last">
|
||||
{% trans trimmed %}Please activate JavaScript to enable the search
|
||||
functionality.{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
{% if search_performed %}
|
||||
{# Translators: Search is a noun, not a verb #}
|
||||
<h2>{{ _('Search Results') }}</h2>
|
||||
{% if not search_results %}
|
||||
<p>{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div id="search-results">
|
||||
{% if search_results %}
|
||||
<ul>
|
||||
{% for href, caption, context in search_results %}
|
||||
<li>
|
||||
<a href="{{ pathto(item.href) }}">{{ caption }}</a>
|
||||
<p class="context">{{ context|e }}</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
9
docs/_themes/sphinx_rtd_theme/searchbox.html
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{%- if builder != 'singlehtml' %}
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
|
||||
<input type="text" name="q" placeholder="{{ _('Search docs') }}" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
{%- endif %}
|
1
docs/_themes/sphinx_rtd_theme/static/css/badge_only.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
|
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Bold.woff2
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/Roboto-Slab-Regular.woff2
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.eot
vendored
Normal file
2671
docs/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.svg
vendored
Normal file
After Width: | Height: | Size: 434 KiB |
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.ttf
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/fontawesome-webfont.woff2
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold-italic.woff2
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-bold.woff2
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal-italic.woff2
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff
vendored
Normal file
BIN
docs/_themes/sphinx_rtd_theme/static/css/fonts/lato-normal.woff2
vendored
Normal file
4
docs/_themes/sphinx_rtd_theme/static/css/theme.css
vendored
Normal file
1
docs/_themes/sphinx_rtd_theme/static/js/badge_only.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
|
1
docs/_themes/sphinx_rtd_theme/static/js/theme.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("<div class='wy-table-responsive'></div>"),n("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),n("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n('<span class="toctree-expand"></span>'),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}t.length>0&&($(".wy-menu-vertical .current").removeClass("current"),t.addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l1").parent().addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l2").addClass("current"),t.closest("li.toctree-l3").addClass("current"),t.closest("li.toctree-l4").addClass("current"),t[0].scrollIntoView())}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[t]+"CancelAnimationFrame"]||window[e[t]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-n)),r=window.setTimeout((function(){e(i+o)}),o);return n=i+o,r}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()}).call(window)},function(n,e){n.exports=jQuery},function(n,e,t){}]);
|
18
docs/_themes/sphinx_rtd_theme/theme.conf
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
[theme]
|
||||
inherit = basic
|
||||
stylesheet = css/theme.css
|
||||
pygments_style = default
|
||||
|
||||
[options]
|
||||
canonical_url =
|
||||
analytics_id =
|
||||
collapse_navigation = True
|
||||
sticky_navigation = True
|
||||
navigation_depth = 4
|
||||
includehidden = True
|
||||
titles_only =
|
||||
logo_only =
|
||||
display_version = True
|
||||
prev_next_buttons_location = bottom
|
||||
style_external_links = False
|
||||
style_nav_header_background =
|
34
docs/_themes/sphinx_rtd_theme/versions.html
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{% if READTHEDOCS %}
|
||||
{# Add rst-badge after rst-versions for small badge style. #}
|
||||
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
<span class="fa fa-book"> Read the Docs</span>
|
||||
v: {{ current_version }}
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</span>
|
||||
<div class="rst-other-versions">
|
||||
<dl>
|
||||
<dt>{{ _('Versions') }}</dt>
|
||||
{% for slug, url in versions %}
|
||||
<dd><a href="{{ url }}">{{ slug }}</a></dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>{{ _('Downloads') }}</dt>
|
||||
{% for type, url in downloads %}
|
||||
<dd><a href="{{ url }}">{{ type }}</a></dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
<dl>
|
||||
{# Translators: The phrase "Read the Docs" is not translated #}
|
||||
<dt>{{ _('On Read the Docs') }}</dt>
|
||||
<dd>
|
||||
<a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">{{ _('Project Home') }}</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">{{ _('Builds') }}</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
146
docs/conf.py
Normal file
@ -0,0 +1,146 @@
|
||||
# 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 subprocess, os, re
|
||||
|
||||
def get_version():
|
||||
try:
|
||||
with open('../src/CMakeLists.txt', 'r') as file:
|
||||
content = file.read()
|
||||
version = re.search(r"project\([^\)]+VERSION (\d+\.\d+\.\d+)[^\)]*\)", content).group(1)
|
||||
return version.strip()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'mp-units'
|
||||
copyright = '2018-present, Mateusz Pusz'
|
||||
author = 'Mateusz Pusz'
|
||||
|
||||
# The major project version, used as the replacement for |version|.
|
||||
version = get_version()
|
||||
|
||||
# The full project version, used as the replacement for |release| and
|
||||
# e.g. in the HTML templates.
|
||||
release = get_version()
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autosectionlabel',
|
||||
'sphinx.ext.githubpages',
|
||||
'sphinx.ext.graphviz',
|
||||
'recommonmark',
|
||||
'breathe'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# If true, Sphinx will warn about all references where the target cannot
|
||||
# be found. Default is False.
|
||||
nitpicky = True
|
||||
|
||||
# A list of (type, target) tuples (by default empty) that should be ignored
|
||||
# when generating warnings in “nitpicky mode”. Note that type should include
|
||||
# the domain name if present. Example entries would be ('py:func', 'int')
|
||||
# or ('envvar', 'LD_LIBRARY_PATH').
|
||||
nitpick_ignore = []
|
||||
|
||||
|
||||
# -- C++ configuration ---------------------------------------------------
|
||||
|
||||
# The name of the default domain. Can also be None to disable a default
|
||||
# domain. The default is 'py'.
|
||||
primary_domain = 'cpp'
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
default_role = 'cpp:any'
|
||||
|
||||
# The default language to highlight source code in. The default is 'python3'.
|
||||
# The value should be a valid Pygments lexer name (https://pygments.org/docs/lexers).
|
||||
highlight_language = 'cpp'
|
||||
|
||||
# The style name to use for Pygments highlighting of source code. If not set,
|
||||
# either the theme’s default style or 'sphinx' is selected for HTML output.
|
||||
pygments_style = 'default'
|
||||
|
||||
# A list of prefixes that will be ignored when sorting C++ objects in the global
|
||||
# index. For example ['awesome_lib::'].
|
||||
cpp_index_common_prefix = ['units::']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
html_theme_path = ["_themes", ]
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If given, this must be the name of an image file (path relative to the
|
||||
# configuration directory) that is the logo of the docs. It is placed at the
|
||||
# top of the sidebar; its width should therefore not exceed 200 pixels.
|
||||
# Default: None.
|
||||
# html_logo =
|
||||
|
||||
# These paths are either relative to html_static_path or fully qualified
|
||||
# paths (eg. https://...)
|
||||
html_css_files = [
|
||||
'css/custom.css'
|
||||
]
|
||||
|
||||
|
||||
# -- Breathe configuration ---------------------------------------------------
|
||||
|
||||
# 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'
|
||||
|
||||
# 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
|
||||
# the directive.
|
||||
breathe_default_project = 'mp-units'
|
||||
|
||||
# Allows you to specify domains for particular files according to their extension.
|
||||
breathe_domain_by_extension = {"h" : "cpp"}
|
||||
|
||||
# Provides the directive flags that should be applied to all directives which
|
||||
# take :members:, :private-members: and :undoc-members: options. By default,
|
||||
# this is set to an empty list, which means no members are displayed.
|
||||
breathe_default_members = ('members', )
|
||||
|
||||
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)
|
BIN
docs/design.png
Normal file
After Width: | Height: | Size: 27 KiB |
13
docs/design.rst
Normal file
@ -0,0 +1,13 @@
|
||||
Design
|
||||
======
|
||||
|
||||
.. note::
|
||||
|
||||
For brevity all the code examples in this documentation will assume::
|
||||
|
||||
using namespace units;
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
design/quantity
|
67
docs/design/quantity.rst
Normal file
@ -0,0 +1,67 @@
|
||||
.. namespace:: units
|
||||
|
||||
quantity
|
||||
========
|
||||
|
||||
Interface
|
||||
---------
|
||||
|
||||
`quantity` class template provides a similar interface to
|
||||
`std::chrono::duration <https://en.cppreference.com/w/cpp/chrono/duration>`_.
|
||||
The difference is that it uses ``double`` as a default representation and has
|
||||
a few additional member types and functions::
|
||||
|
||||
template<Dimension D, UnitOf<D> U, Scalar Rep = double>
|
||||
class quantity {
|
||||
public:
|
||||
using dimension = D;
|
||||
using unit = U;
|
||||
using rep = Rep;
|
||||
|
||||
[[nodiscard]] static constexpr quantity one() noexcept;
|
||||
// ...
|
||||
};
|
||||
|
||||
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2>
|
||||
requires detail::basic_arithmetic<Rep1, Rep2> && equivalent_dim<D1, dim_invert<D2>>
|
||||
[[nodiscard]] constexpr Scalar auto operator*(const quantity<D1, U1, Rep1>& lhs,
|
||||
const quantity<D2, U2, Rep2>& rhs);
|
||||
|
||||
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2>
|
||||
requires detail::basic_arithmetic<Rep1, Rep2> && (!equivalent_dim<D1, dim_invert<D2>>)
|
||||
[[nodiscard]] constexpr Quantity auto operator*(const quantity<D1, U1, Rep1>& lhs,
|
||||
const quantity<D2, U2, Rep2>& rhs);
|
||||
|
||||
template<Scalar Value, typename D, typename U, typename Rep>
|
||||
requires std::magma<std::ranges::divided_by, Value, Rep>
|
||||
[[nodiscard]] constexpr Quantity auto operator/(const Value& v,
|
||||
const quantity<D, U, Rep>& q);
|
||||
|
||||
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2>
|
||||
requires detail::basic_arithmetic<Rep1, Rep2> && equivalent_dim<D1, D2>
|
||||
[[nodiscard]] constexpr Scalar auto operator/(const quantity<D1, U1, Rep1>& lhs,
|
||||
const quantity<D2, U2, Rep2>& rhs);
|
||||
|
||||
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2>
|
||||
requires detail::basic_arithmetic<Rep1, Rep2> && (!equivalent_dim<D1, D2>)
|
||||
[[nodiscard]] constexpr Quantity AUTO operator/(const quantity<D1, U1, Rep1>& lhs,
|
||||
const quantity<D2, U2, Rep2>& rhs);
|
||||
|
||||
Additional functions provide the support for operations that result in a
|
||||
different dimension type than those of their arguments. ``equivalent_dim``
|
||||
constraint requires two dimensions to be either the same or have convertible
|
||||
units of base dimension (with the same reference unit).
|
||||
|
||||
Beside adding new elements a few other changes where applied compared to the
|
||||
`std::chrono::duration <https://en.cppreference.com/w/cpp/chrono/duration>`_
|
||||
class template:
|
||||
|
||||
1. The ``duration`` is using ``std::common_type_t<Rep1, Rep2>`` to find a common
|
||||
representation for a calculation result. Such a design was reported as problematic
|
||||
by SG6 (numerics study group) members as sometimes we want to provide a different
|
||||
type in case of multiplication and different in case of division. ``std::common_type``
|
||||
lacks that additional information. That is why `units::quantity` uses the resulting
|
||||
type of a concrete operator operation.
|
||||
2. `operator %` is constrained with `treat_as_floating_point` type trait to limit the
|
||||
types to integral representations only. Also `operator %(Rep)` takes `Rep` as a
|
||||
template argument to limit implicit conversions.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
8
docs/examples.rst
Normal file
@ -0,0 +1,8 @@
|
||||
Examples
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
examples/hello_units
|
||||
examples/avg_speed
|
8
docs/examples/avg_speed.rst
Normal file
@ -0,0 +1,8 @@
|
||||
avg_speed
|
||||
=========
|
||||
|
||||
.. literalinclude:: ../../example/avg_speed.cpp
|
||||
:caption: avg_speed.cpp
|
||||
:start-at: #include
|
||||
:linenos:
|
||||
:force:
|
7
docs/examples/hello_units.rst
Normal file
@ -0,0 +1,7 @@
|
||||
hello_units
|
||||
===========
|
||||
|
||||
.. literalinclude:: ../../example/hello_units.cpp
|
||||
:caption: hello_units.cpp
|
||||
:start-at: #include
|
||||
:linenos:
|
44
docs/faq.rst
Normal file
@ -0,0 +1,44 @@
|
||||
FAQ
|
||||
===
|
||||
|
||||
General
|
||||
-------
|
||||
|
||||
Why all UDLs are prefixed with ``q_`` instead of just using unit symbol?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Usage of only unit symbols in UDLs would be a preferred approach (less to type,
|
||||
easier to understand and maintain). However, while increasing the coverage for
|
||||
the library we learned that there are a lot unit symbols that conflict with
|
||||
built-in types or numeric extensions. A few of those are: ``F`` (farad),
|
||||
``J`` (joule), ``W`` (watt), ``K`` (kelvin), ``d`` (day),
|
||||
``l`` or ``L`` (litre), ``erg``, ``ergps``. For a while for those we used ``_``
|
||||
prefix to make the library work at all, but at some point we had to unify the
|
||||
naming and we came up with ``q_`` prefix which results in a creation of
|
||||
quantity of a provided unit.
|
||||
|
||||
|
||||
Why dimensions depend on units and not vice versa?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Most of the libraries define units in terms of dimensions and this was also an
|
||||
initial approach for this library. However it turns out that for such a design
|
||||
it is hard to provide support for all the required scenarios.
|
||||
|
||||
The first of them is to support multiple unit systems (like SI, CGS, ...) where
|
||||
each of can have a different base unit for the same dimension. Base quantity of
|
||||
dimension length in SI has to know that it should use ``m`` to print the unit
|
||||
symbol to the text output, while the same dimension for CGS should use ``cm``.
|
||||
Also it helps in conversions among those systems.
|
||||
|
||||
The second one is to support natural units where more than one dimension can be
|
||||
measured with the same unit (i.e. ``GeV``). Also if someone will decide to
|
||||
implement a systems where SI quantities of the same kind are expressed as
|
||||
different dimensions (i.e. height, width, and depth) all of them will just be
|
||||
measured in meters.
|
||||
|
||||
|
||||
Why do we spell ``metre`` instead of ``meter``?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Well, this is how ISO 80000 defines it (British English spelling by default).
|
18
docs/framework.rst
Normal file
@ -0,0 +1,18 @@
|
||||
Framework
|
||||
=========
|
||||
|
||||
.. note::
|
||||
|
||||
For brevity all the code examples in this documentation will assume::
|
||||
|
||||
using namespace units;
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
framework/basic_concepts
|
||||
framework/quantities
|
||||
framework/dimensions
|
||||
framework/units
|
||||
framework/conversions_and_casting
|
||||
framework/text_output
|
22
docs/framework/basic_concepts.rst
Normal file
@ -0,0 +1,22 @@
|
||||
.. namespace:: units
|
||||
|
||||
Basic Concepts
|
||||
==============
|
||||
|
||||
The most important concepts in the library are `Unit`, `Dimension`, and
|
||||
`Quantity`:
|
||||
|
||||
.. image:: /_static/img/design.png
|
||||
:align: center
|
||||
|
||||
`Unit` is a basic building block of the library. Every dimension works with
|
||||
a concrete hierarchy of units. Such hierarchy defines a reference unit and
|
||||
often a few scaled versions of it.
|
||||
|
||||
`Dimension` concept matches a dimension of either a base or derived quantity.
|
||||
`base_dimension` is instantiated with a unique symbol identifier and a base
|
||||
unit. `derived_dimension` is a list of exponents of either base or other
|
||||
derived dimensions.
|
||||
|
||||
`Quantity` is a concrete amount of a unit for a specified dimension with a
|
||||
specific representation.
|
16
docs/framework/conversions_and_casting.rst
Normal file
@ -0,0 +1,16 @@
|
||||
.. namespace:: units
|
||||
|
||||
Conversions and Casting
|
||||
=======================
|
||||
|
||||
Implicit Conversions
|
||||
--------------------
|
||||
|
||||
constructors
|
||||
|
||||
Explicit Casting
|
||||
----------------
|
||||
|
||||
quantity_cast
|
||||
|
||||
Example of casting to a dimension's coherent unit.
|
178
docs/framework/dimensions.rst
Normal file
@ -0,0 +1,178 @@
|
||||
.. namespace:: units
|
||||
|
||||
Dimensions
|
||||
==========
|
||||
|
||||
In the previous chapter we briefly introduced the notion of a physical
|
||||
:term:`dimension`. Now it is time to learn much more about this subject.
|
||||
Length, time, velocity, area, energy are only a few examples of physical
|
||||
dimensions.
|
||||
|
||||
Operations
|
||||
----------
|
||||
|
||||
Quantities of the same dimension can be easily added or subtracted with
|
||||
each other and the result will always be a quantity of the same dimension:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 3-4
|
||||
|
||||
Length auto dist1 = 2q_m;
|
||||
Length auto dist2 = 1q_m;
|
||||
Length auto res1 = dist1 + dist2;
|
||||
Length auto res2 = dist1 - dist2;
|
||||
|
||||
Additionally, we can always multiply or divide a quantity by a
|
||||
:term:`scalar` and in such a case the quantity's dimension will also
|
||||
not change:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 2-4
|
||||
|
||||
Length auto dist = 2q_m;
|
||||
Length auto res1 = dist * 2; // 4 m
|
||||
Length auto res2 = 3 * res1; // 12 m
|
||||
Length auto res3 = res2 / 2; // 6 m
|
||||
|
||||
However, if we try to multiply or divide quantities of the same or
|
||||
different dimensions, or we will divide a scalar by a quantity, we most
|
||||
probably will always end up in a quantity of a yet another dimension:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 4-6
|
||||
|
||||
Length auto dist1 = 2q_m;
|
||||
Length auto dist2 = 3q_m;
|
||||
Time auto dur1 = 2q_s;
|
||||
Area auto res1 = dist1 * dist2; // 6 m²
|
||||
Velocity auto res2 = dist1 / dur1; // 1 m/s
|
||||
Frequency auto res3 = 10 / dur1; // 5 Hz
|
||||
|
||||
However, please note that there is an exception from the above rule.
|
||||
In case we divide the same dimensions, or multiply by the inverted
|
||||
dimension, than we will end up with just a scalar type:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 4-5
|
||||
|
||||
Time auto dur1 = 10q_s;
|
||||
Time auto dur2 = 2q_s;
|
||||
Frequency auto fr1 = 5q_Hz;
|
||||
Scalar auto v1 = dur1 / dur2; // 5
|
||||
Scalar auto v2 = dur1 * fr1; // 50
|
||||
|
||||
|
||||
Base dimensions
|
||||
---------------
|
||||
|
||||
The quantities of base dimensions are called
|
||||
:term:`base quantities <base quantity>` which are the atomic building blocks
|
||||
of a :term:`system of quantities`. For example the The International System
|
||||
of Units (:term:`SI`) defines 7 of them: length, mass, time, electric
|
||||
current, thermodynamic temperature, substance, and luminous intensity.
|
||||
|
||||
To define a new base dimension the `base_dimension` class template is
|
||||
provided. For example the SI base dimension of length can be defined as::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct dim_length : base_dimension<"L", metre> {};
|
||||
|
||||
}
|
||||
|
||||
In the above code sample ``"L"`` is an base dimension's unique identifier
|
||||
and `si::metre` is a :term:`base unit` of this base dimension. We can
|
||||
obtain those back easily with::
|
||||
|
||||
static_assert(si::dim_length::symbol == "L");
|
||||
static_assert(std::is_same_v<si::dim_length::base_unit, si::metre>);
|
||||
|
||||
|
||||
Derived dimensions
|
||||
------------------
|
||||
|
||||
The quantities of derived dimensions are called
|
||||
:term:`derived quantities <derived quantity>` and are derived from base
|
||||
quantities. This means that they are created by multiplying or dividing
|
||||
quantities of other dimensions.
|
||||
|
||||
Looking at the previous code snippets the area, velocity, or frequency are
|
||||
the examples of such quantities. Each derived quantity can be represented
|
||||
as a unique list of exponents of base quantities. For example:
|
||||
|
||||
- an area is a length base quantity raised to the exponent ``2``
|
||||
- a velocity is formed from the length base quantity with exponent ``1``
|
||||
and time base quantity with exponent ``-1``.
|
||||
|
||||
The above dimensions can be defined in the library with the
|
||||
`derived_dimension` class template as follows::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct dim_area : derived_dimension<dim_area, square_metre,
|
||||
exp<dim_length, 2>> {};
|
||||
struct dim_velocity : derived_dimension<dim_velocity, metre_per_second,
|
||||
exp<dim_length, 1>, exp<dim_time, -1>> {};
|
||||
|
||||
}
|
||||
|
||||
In the above code sample `si::square_metre` and `si::metre_per_second`
|
||||
are the :term:`coherent derived units <coherent derived unit>` of those
|
||||
derived dimensions.
|
||||
|
||||
Coherent unit argument is followed by the list of exponents that form this
|
||||
derived dimension. This list is called a :term:`recipe` of this derived
|
||||
dimension and may contain both base and derived dimensions. In the latter
|
||||
case the dimension is being extracted to base dimensions by the framework
|
||||
itself. The order and types of dimensions used in the recipe determine how
|
||||
an dimension's unnamed unit symbol is being printed in the text output.
|
||||
|
||||
.. seealso::
|
||||
|
||||
More information on how the :term:`recipe` affect the printed symbol
|
||||
of unnamed unit can be found in the :ref:`Derived Unnamed Units` chapter.
|
||||
|
||||
It is important to mention here that beside text output the order and
|
||||
the number of elements in the `derived_dimension` definition does not
|
||||
matter. Even if we define the above as:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 4, 6
|
||||
|
||||
namespace si {
|
||||
|
||||
struct dim_area : derived_dimension<dim_area, square_metre,
|
||||
exp<dim_length, 1>, exp<dim_length, 1>> {};
|
||||
struct dim_velocity : derived_dimension<dim_velocity, metre_per_second,
|
||||
exp<dim_time, -1>, exp<dim_length, 1>> {};
|
||||
|
||||
}
|
||||
|
||||
the library will do its magic and will end up with the same
|
||||
:term:`normalized derived dimension` which will allow the dimensional
|
||||
analysis in the library to work as expected.
|
||||
|
||||
.. note::
|
||||
|
||||
The first template argument of `derived_dimension` is the type of the
|
||||
child class inherited from the instantiation of this `derived_dimension`
|
||||
class template. This is called a
|
||||
:abbr:`CRTP (Curiously Recurring Template Parameter)` Idiom and is used
|
||||
in many places in this library to provide :ref:`The Downcasting Facility`.
|
||||
Hopefully if [P0847]_ will land in C++23 the additional CRTP-related
|
||||
template parameter will be removed from this definition.
|
||||
|
||||
|
||||
Obtaining a Unit of the Dimension
|
||||
---------------------------------
|
||||
|
||||
In order to obtain the base/coherent unit of any dimension type a
|
||||
`dimension_unit` helper was introduced::
|
||||
|
||||
static_assert(std::is_same_v<dimension_unit<si::dim_length>, si::metre>);
|
||||
static_assert(std::is_same_v<dimension_unit<si::dim_velocity>, si::metre_per_second>);
|
||||
|
||||
|
||||
.. rubric:: Citations:
|
||||
|
||||
.. [P0847] `"Deducing this" <https://wg21.link/P0847>`_, Programming Language C++ proposal
|
159
docs/framework/quantities.rst
Normal file
@ -0,0 +1,159 @@
|
||||
.. namespace:: units
|
||||
|
||||
Quantities
|
||||
==========
|
||||
|
||||
A :term:`quantity` is a concrete amount of a unit for a specified dimension
|
||||
with a specific representation and is represented in the library with a
|
||||
`quantity` class template.
|
||||
|
||||
|
||||
Construction
|
||||
------------
|
||||
|
||||
To create the quantity object from a :term:`scalar` we just have to pass
|
||||
the value to the `quantity` class template explicit constructor::
|
||||
|
||||
quantity<si::dim_length, si::kilometre, double> d(123);
|
||||
|
||||
.. note::
|
||||
|
||||
As the constructor is explicit, the quantity object can be created from
|
||||
an "unsafe" fundamental type only via
|
||||
`direct initialization <https://en.cppreference.com/w/cpp/language/direct_initialization>`_.
|
||||
This is why the code below using
|
||||
`copy initialization <https://en.cppreference.com/w/cpp/language/copy_initialization>`_
|
||||
**does not compile**::
|
||||
|
||||
quantity<si::dim_length, si::kilometre, double> d = 123; // ERROR
|
||||
|
||||
To simplify `quantity` objects creation the library provides helper aliases for
|
||||
quantities of each :term:`dimension` which additionally set the representation
|
||||
type to ``double`` by default::
|
||||
|
||||
namespace si {
|
||||
|
||||
template<Unit U, Scalar Rep = double>
|
||||
using length = quantity<dim_length, U, Rep>;
|
||||
|
||||
}
|
||||
|
||||
Thanks to that, the above example can be rewritten as follows::
|
||||
|
||||
si::length<si::kilometre> d(123);
|
||||
|
||||
To further simplify construction of quantities with compile-time known
|
||||
values the library provides :abbr:`UDL (User Defined Literal)` s for each
|
||||
:term:`unit` of every :term:`dimension`. Thanks to them the same code can
|
||||
be as simple as::
|
||||
|
||||
using namespace si::literals;
|
||||
constexpr auto d1 = 123q_km; // si::length<si::kilometre, std::int64_t>
|
||||
constexpr auto d2 = 123.q_km; // si::length<si::kilometre, long double>
|
||||
|
||||
``123q_km`` should be read as a quantity of length in kilometers. Initially the
|
||||
library did not use the ``q_`` prefix for UDLs but it turned out that there are
|
||||
a few unit symbols that collide with literals already existing in C and C++
|
||||
language (i.e. ``F`` (farad), ``J`` (joule), ``W`` (watt), ``K`` (kelvin),
|
||||
``d`` (day), ``l`` or ``L`` (litre), ``erg``, ``ergps``). This is why the
|
||||
``q_`` prefix was consistently applied to all the UDLs.
|
||||
|
||||
|
||||
Dimension-specific concepts
|
||||
---------------------------
|
||||
|
||||
In case the user does not care about the specific unit and representation but
|
||||
requires quantity of a concrete dimension than dimension-specific concepts can
|
||||
be used::
|
||||
|
||||
using namespace si::literals;
|
||||
constexpr Length auto d = 123q_km; // si::length<si::kilometre, std::int64_t>
|
||||
|
||||
.. note::
|
||||
|
||||
All instances of `quantity` class always match the `Quantity` concept.
|
||||
All other regular types that are not quantities are called
|
||||
:term:`scalars <scalar>` by the library and match the `Scalar` concept.
|
||||
|
||||
However, the above is not the most important usage of those concepts. Let's
|
||||
assume that the user wants to implement an ``avg_speed`` function that will
|
||||
be calculating the average speed based on provided distance and duration
|
||||
quantities. The usage of such a function can look as follows::
|
||||
|
||||
using namespace si::literals;
|
||||
using namespace international::literals;
|
||||
constexpr Velocity auto v1 = avg_speed(220q_km, 2q_h);
|
||||
constexpr Velocity auto v2 = avg_speed(140q_mi, 2q_h);
|
||||
|
||||
In this and all other physical units libraries such a function can be
|
||||
implemented as::
|
||||
|
||||
constexpr si::velocity<si::metre_per_second> avg_speed(si::length<si::metre> d,
|
||||
si::time<si::second> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
While being correct, this function performs unnecessary intermediate
|
||||
conversions (from kilometers to meters, from hours to seconds,
|
||||
and from meters per second to kilometers per hour) which can affect
|
||||
runtime performance and the precision of the final result. To eliminate
|
||||
all that overhead we have to write a template function::
|
||||
|
||||
template<typename U1, typename R1, typename U2, typename R2>
|
||||
constexpr auto avg_speed(si::length<U1, R1> d, si::time<U2, R2> t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
This function will work for every SI unit and representation without any
|
||||
unnecessary overhead. It is also simple enough to prove its implementation
|
||||
being correct just by a simple inspection. However, it might not always be
|
||||
the case. For more complicated calculations we would like to ensure that we
|
||||
are returning a physical quantity of a correct dimension. For this
|
||||
dimension-specific concepts come handy again and with usage of C++20 generic
|
||||
functions our function can look as simple as::
|
||||
|
||||
constexpr Velocity auto avg_speed(Length auto d, Time auto t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
Now we are sure that the dimension of returned quantity is correct. Also
|
||||
please note that with the above code we implemented a truly generic function
|
||||
that works efficiently not only with SI units but also with other systems of
|
||||
units like CGS.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Please refer to :ref:`avg_speed` example for more information on different
|
||||
kinds of interfaces supported by the library.
|
||||
|
||||
|
||||
Working with constrained deduced quantity types
|
||||
-----------------------------------------------
|
||||
|
||||
It is important to note that when we assign a result from the function to an
|
||||
automatically deduced type, even if it is constrained by a dimension-specific
|
||||
concept, we still do not know what is the exact unit and representation type
|
||||
of such a quantity. In many cases it might be exactly what we want to get,
|
||||
but often we would like to know a specific type too. We have two options here:
|
||||
|
||||
- query the actual dimension, unit, and representation types::
|
||||
|
||||
constexpr Velocity auto v = avg_speed(220q_km, 2q_h);
|
||||
using quantity_type = decltype(v);
|
||||
using dimension_type = quantity_type::dimension;
|
||||
using unit_type = quantity_type::unit;
|
||||
using rep_type = quantity_type::rep;
|
||||
|
||||
- convert or cast to a desired quantity type::
|
||||
|
||||
constexpr Velocity auto v1 = avg_speed(220.q_km, 2q_h);
|
||||
constexpr si::velocity<si::metre_per_second> v2 = v1;
|
||||
constexpr Velocity auto v3 = quantity_cast<si::velocity<si::metre_per_second>(v1);
|
||||
|
||||
.. seealso::
|
||||
|
||||
More information on this subject can be found in :ref:`Conversions and Casting`
|
||||
chapter.
|
45
docs/framework/text_output.rst
Normal file
@ -0,0 +1,45 @@
|
||||
.. namespace:: units
|
||||
|
||||
Text output
|
||||
===========
|
||||
|
||||
Beside providing dimensional analysis and units conversions, the library
|
||||
also tries really hard to print any quantity in the most user friendly way.
|
||||
|
||||
Output streams
|
||||
--------------
|
||||
|
||||
The easiest way to print a quantity is to provide its object to the output
|
||||
stream::
|
||||
|
||||
using namespace si::literals;
|
||||
using namespace international::literals;
|
||||
constexpr Velocity auto v1 = avg_speed(220.q_km, 2q_h);
|
||||
constexpr Velocity auto v2 = avg_speed(140.q_mi, 2q_h);
|
||||
std::cout << v1 << '\n'; // 110 km/h
|
||||
std::cout << v2 << '\n'; // 70 mi/h
|
||||
|
||||
The text output will always print the :term:`value of a quantity` followed
|
||||
by the symbol of a :term:`unit` associated with this quantity. We will learn
|
||||
more about units in the :ref:`Units` chapter, but for now, it is important
|
||||
to remember that it is a good practice to always `quantity_cast()` a quantity
|
||||
of an unknown ``auto`` type before passing it to the text output::
|
||||
|
||||
std::cout << quantity_cast<si::kilometre_per_hour>(v1) << '\n'; // 110 km/h
|
||||
std::cout << quantity_cast<si::metre_per_second>(v1) << '\n'; // 30.5556 m/s
|
||||
|
||||
|
||||
Formatting the output
|
||||
---------------------
|
||||
|
||||
Grammar:
|
||||
|
||||
.. productionlist::
|
||||
units-format-spec: fill-and-align[opt] sign[opt] width[opt] precision[opt] units-specs[opt]
|
||||
units-specs: conversion-spec
|
||||
: units-specs conversion-spec
|
||||
: units-specs literal-char
|
||||
literal-char: any character other than '{' or '}'
|
||||
conversion-spec: '%' modifier[opt] type
|
||||
modifier: one of 'E', 'O'
|
||||
type: one of 'n', 'q', 'Q', 't', '%'
|
319
docs/framework/units.rst
Normal file
@ -0,0 +1,319 @@
|
||||
.. namespace:: units
|
||||
|
||||
Units
|
||||
=====
|
||||
|
||||
Each quantity has a magnitude (a numerical value). In order to be able to
|
||||
compare quantities of the same dimension a notion of a :term:`measurement unit`
|
||||
was introduced. Units are designated by conventionally assigned names and
|
||||
symbols. Thanks to them it is possible to compare two quantities of the
|
||||
same dimension and express the ratio of the second quantity to the first
|
||||
one as a number. For example ``10s`` is ``10`` times more than ``1s``.
|
||||
|
||||
Base quantities are expressed in terms of :term:`base units <base unit>`
|
||||
(i.e. ``m`` (meter), ``s`` (second)), while derived quantities are expressed
|
||||
in terms of :term:`derived units <derived unit>`.
|
||||
|
||||
|
||||
Base Units
|
||||
----------
|
||||
|
||||
:term:`Base units <base unit>` are the units of
|
||||
:term:`base quantities <base quantity>` defined for
|
||||
:term:`base dimensions <base dimension>`. For example in :term:`SI`
|
||||
``m`` (meter) is a base unit of length, ``s`` (second) is a base unit of
|
||||
time. In each :term:`coherent system of units`, there is only one base
|
||||
unit for each base quantity. This is why a base unit type is required by
|
||||
the `base_dimension` definition in this library. For example `si::dim_length`
|
||||
can be defined in the following way::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct dim_length : base_dimension<"L", metre> {};
|
||||
|
||||
}
|
||||
|
||||
where `si::metre` is defined as::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct metre : named_unit<metre, "m", prefix> {};
|
||||
|
||||
}
|
||||
|
||||
In the above definition ``"m"`` is the unit symbol to be used in the text
|
||||
output, and ``si::prefix`` specifies that the library should allow
|
||||
definitions of prefixed units using `si::metre` as a reference (i.e.
|
||||
`si::centimetre`).
|
||||
|
||||
.. seealso::
|
||||
|
||||
For more information on prefixes and scaling please refer to
|
||||
`Scaled Units`_.
|
||||
|
||||
.. note::
|
||||
|
||||
The first template argument of `named_unit` is the type of the
|
||||
child class inherited from the instantiation of this `named_unit`
|
||||
class template. This is called a
|
||||
:abbr:`CRTP (Curiously Recurring Template Parameter)` Idiom and is used
|
||||
in many places in this library to provide :ref:`The Downcasting Facility`.
|
||||
Hopefully if [P0847]_ will land in C++23 the additional CRTP-related
|
||||
template parameter will be removed from this definition.
|
||||
|
||||
|
||||
It is important to notice here that :term:`SI` is not the only system used
|
||||
in the industry and the library has to support other systems too. Also
|
||||
in some cases conversions between such systems should be allowed. The
|
||||
fact that the `base_dimension` takes the base unit in its definition makes
|
||||
it really easy to define other systems of units. For example length in the
|
||||
`CGS <https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units>`_
|
||||
could be defined as::
|
||||
|
||||
namespace cgs {
|
||||
|
||||
struct dim_length : base_dimension<"L", si::centimetre> {};
|
||||
|
||||
}
|
||||
|
||||
The fact that both base dimensions use the same identifier ``"L"`` tells
|
||||
the library that bot definitions refer to the same physical dimension of
|
||||
length. The only difference is the measurement unit used to define their
|
||||
base dimensions. Thanks to using `si::centimetre` in the `cgs::dim_length`
|
||||
definition we also enabled the ability to easily convert between those
|
||||
2 base dimensions (as the library knows how to convert `si::metre` to
|
||||
`si::centimetre` and vice versa).
|
||||
|
||||
|
||||
Derived Units
|
||||
-------------
|
||||
|
||||
Derived units can be either named or unnamed.
|
||||
|
||||
Derived Named Units
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Derived named units have a unique symbol (i.e. ``N`` (newton) or ``Pa``
|
||||
(pascal)) and they are defined in the same way as base units (which
|
||||
always have to be a named unit)::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct newton : named_unit<newton, "N", prefix> {};
|
||||
|
||||
}
|
||||
|
||||
|
||||
Derived Unnamed Units
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Derived unnamed units are the units where the symbol is derived from the
|
||||
base quantities symbols and the expression of the dependence of the derived
|
||||
quantity on the base quantities (i.e. ``m/s`` (metre per second), ``m²``
|
||||
(square metre)). To support such use cases a library introduced a notion of
|
||||
:term:`derived dimension recipe` which stores the information about the
|
||||
order, exponents, and types of dimensions used to defined this particular
|
||||
derived dimension. For example each of the below ``momentum`` definitions
|
||||
will result in a different unnamed unit symbol:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 2-4, 6-8, 10-12
|
||||
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_mass, 1>,
|
||||
exp<si::dim_length, 1>,
|
||||
exp<si::dim_time, -1>> {}; // kg⋅m/s
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_length, 1>,
|
||||
exp<si::dim_mass, 1>,
|
||||
exp<si::dim_time, -1>> {}; // m⋅kg/s
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_time, -1>,
|
||||
exp<si::dim_length, 1>,
|
||||
exp<si::dim_mass, 1>> {}; // 1/s⋅m⋅kg
|
||||
|
||||
where ``kilogram_metre_per_second`` is defined as::
|
||||
|
||||
struct kilogram_metre_per_second : unit<kilogram_metre_per_second> {};
|
||||
|
||||
However, the easiest way to define momentum is just to use the
|
||||
`si::velocity` derived dimension in the recipe:
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 3
|
||||
|
||||
struct dim_momentum : derived_dimension<dim_momentum, kilogram_metre_per_second,
|
||||
exp<si::dim_mass, 1>,
|
||||
exp<si::dim_velocity, 1>> {}; // kg⋅m/s
|
||||
|
||||
In such a case the library will do its magic and will automatically
|
||||
unpack a provided derived dimension to its base dimensions in order to
|
||||
end up with a :term:`normalized derived dimension` for a parent entity.
|
||||
|
||||
|
||||
The need to support a derived dimension in the recipe is not just a
|
||||
syntactic sugar that allows us to do less typing. It is worth to notice
|
||||
here that some of the derived unnamed units are defined in terms of other
|
||||
derived named units (i.e. surface tension quantity is measured in terms
|
||||
of ``N/m``):
|
||||
|
||||
.. code-block::
|
||||
:emphasize-lines: 2
|
||||
|
||||
struct dim_surface_tension : derived_dimension<dim_surface_tension, newton_per_metre,
|
||||
exp<si::dim_force, 1>,
|
||||
exp<si::dim_length, -1>> {}; // N/m
|
||||
|
||||
If we defined the above in terms of base units we would end up with
|
||||
a ``kg/s²`` derived unit symbol.
|
||||
|
||||
|
||||
Scaled Units
|
||||
------------
|
||||
|
||||
Until now we talked mostly about
|
||||
:term:`coherent units <coherent derived unit>` which are units used to
|
||||
define dimensions and thus, in their system of units, have proportionality
|
||||
factor/ratio equals one. However quantities of each dimension can also use
|
||||
other units of measurement to describe their magnitude (numerical value).
|
||||
|
||||
|
||||
Scaled Units
|
||||
^^^^^^^^^^^^
|
||||
|
||||
We are used to use minutes, hours, or days to measure quantities of time.
|
||||
Those units are the scaled versions of a time dimension's base unit,
|
||||
namely second. Those can be defined easily in the library using
|
||||
`named_scaled_unit` class template::
|
||||
|
||||
struct minute : named_scaled_unit<minute, "min", no_prefix, ratio<60>, second> {};
|
||||
struct hour : named_scaled_unit<hour, "h", no_prefix, ratio<60>, minute> {};
|
||||
struct day : named_scaled_unit<hour, "d", no_prefix, ratio<24>, hour> {};
|
||||
|
||||
where `no_prefix` is a special tag type describing that the library should
|
||||
not allow to define a new prefixed unit that would use this unit as a
|
||||
reference ("kilohours" does not have much sense, right?). The `ratio` type
|
||||
used in the definition is really similar to ``std::ratio`` but it takes
|
||||
the third additional argument that defines the exponent of the ratio.
|
||||
Thanks to it we can address nearly infinite scaling factors between units
|
||||
and define units like:
|
||||
|
||||
.. code-block::
|
||||
:force:
|
||||
|
||||
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`,
|
||||
`si::hour`) that is a scaled version of the dimension's base/coherent unit.
|
||||
|
||||
|
||||
Prefixed Unit
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Prefixed units are just scaled units with a standardized ratio. For example
|
||||
:term:`SI` defines prefixes based on the exponent of ``10``. Here is a
|
||||
complete list of all the :term:`SI` prefixes supported by the library::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct prefix : prefix_type {};
|
||||
|
||||
struct yocto : units::prefix<yocto, prefix, "y", ratio<1, 1, -24>> {};
|
||||
struct zepto : units::prefix<zepto, prefix, "z", ratio<1, 1, -21>> {};
|
||||
struct atto : units::prefix<atto, prefix, "a", ratio<1, 1, -18>> {};
|
||||
struct femto : units::prefix<femto, prefix, "f", ratio<1, 1, -15>> {};
|
||||
struct pico : units::prefix<pico, prefix, "p", ratio<1, 1, -12>> {};
|
||||
struct nano : units::prefix<nano, prefix, "n", ratio<1, 1, -9>> {};
|
||||
struct micro : units::prefix<micro, prefix, "µ", ratio<1, 1, -6>> {};
|
||||
struct milli : units::prefix<milli, prefix, "m", ratio<1, 1, -3>> {};
|
||||
struct centi : units::prefix<centi, prefix, "c", ratio<1, 1, -2>> {};
|
||||
struct deci : units::prefix<deci, prefix, "d", ratio<1, 1, -1>> {};
|
||||
struct deca : units::prefix<deca, prefix, "da", ratio<1, 1, 1>> {};
|
||||
struct hecto : units::prefix<hecto, prefix, "h", ratio<1, 1, 2>> {};
|
||||
struct kilo : units::prefix<kilo, prefix, "k", ratio<1, 1, 3>> {};
|
||||
struct mega : units::prefix<mega, prefix, "M", ratio<1, 1, 6>> {};
|
||||
struct giga : units::prefix<giga, prefix, "G", ratio<1, 1, 9>> {};
|
||||
struct tera : units::prefix<tera, prefix, "T", ratio<1, 1, 12>> {};
|
||||
struct peta : units::prefix<peta, prefix, "P", ratio<1, 1, 15>> {};
|
||||
struct exa : units::prefix<exa, prefix, "E", ratio<1, 1, 18>> {};
|
||||
struct zetta : units::prefix<zetta, prefix, "Z", ratio<1, 1, 21>> {};
|
||||
struct yotta : units::prefix<yotta, prefix, "Y", ratio<1, 1, 24>> {};
|
||||
|
||||
}
|
||||
|
||||
Alternative hierarchy of prefixes is the one used in data information
|
||||
domain:
|
||||
|
||||
.. code-block::
|
||||
:force:
|
||||
|
||||
namespace data {
|
||||
|
||||
struct prefix : prefix_type {};
|
||||
|
||||
struct kibi : units::prefix<kibi, prefix, "Ki", ratio< 1'024>> {};
|
||||
struct mebi : units::prefix<mebi, prefix, "Mi", ratio< 1'048'576>> {};
|
||||
struct gibi : units::prefix<gibi, prefix, "Gi", ratio< 1'073'741'824>> {};
|
||||
struct tebi : units::prefix<tebi, prefix, "Ti", ratio< 1'099'511'627'776>> {};
|
||||
struct pebi : units::prefix<pebi, prefix, "Pi", ratio< 1'125'899'906'842'624>> {};
|
||||
struct exbi : units::prefix<exbi, prefix, "Ei", ratio<1'152'921'504'606'846'976>> {};
|
||||
|
||||
}
|
||||
|
||||
With the definitions like above we can easily define prefixed unit. For
|
||||
example we can define `si::kilometre` as::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct kilometre : prefixed_unit<kilometre, kilo, metre> {};
|
||||
|
||||
}
|
||||
|
||||
.. important::
|
||||
|
||||
Prefixed units have to use named units as a reference. For unnamed
|
||||
units we could end up with some strange, misleading, and sometimes
|
||||
wrong definitions ("kilo square metre" seams strange and spelled
|
||||
as ``km²`` would be invalid).
|
||||
|
||||
|
||||
Deduced Units
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
For some units determining of a correct scaling ratio may not be trivial,
|
||||
and even if done correctly, may be a pain to maintain. For a simple example
|
||||
let's take a "kilometre per hour" unit. What is the easiest to maintain
|
||||
ratio in reference to "metre per second":
|
||||
|
||||
- ``1000/3600``
|
||||
- ``10/36``
|
||||
- ``5/18``
|
||||
|
||||
Whichever, we choose there will always be someone not happy with our choice.
|
||||
|
||||
Thanks to a `deduced_unit` class template provided by the library this problem
|
||||
does not exist at all. With it `si::kilometre_per_hour` can be defined as::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct kilometre_per_hour : deduced_unit<kilometre_per_hour, dim_velocity, kilometre, hour> {};
|
||||
|
||||
}
|
||||
|
||||
Please note that this is the only unit-related class template that takes
|
||||
a dimension as its parameter. This derived dimension provides a :term:`recipe`
|
||||
used for its definition. Based on the information stored in the recipe
|
||||
(order, type, and exponents of composite dimensions) and the ratios of units
|
||||
provided in the template parameter list after the derived dimension parameter,
|
||||
the library calculates the final ratio for this unit.
|
||||
|
||||
|
||||
.. rubric:: Citations:
|
||||
|
||||
.. [P0847] `"Deducing this" <https://wg21.link/P0847>`_, Programming Language C++ proposal
|
4
docs/genindex.rst
Normal file
@ -0,0 +1,4 @@
|
||||
.. This file is a placeholder and will be replaced during Sphinx build
|
||||
|
||||
Index
|
||||
#####
|
214
docs/glossary.rst
Normal file
@ -0,0 +1,214 @@
|
||||
.. default-role:: term
|
||||
|
||||
Glossary
|
||||
========
|
||||
|
||||
ISO 80000 [1]_ definitions
|
||||
--------------------------
|
||||
|
||||
.. glossary::
|
||||
|
||||
quantity
|
||||
- Property of a phenomenon, body, or substance, where the property has a magnitude that can
|
||||
be expressed by means of a number and a reference.
|
||||
- A reference can be a measurement unit, a measurement procedure, a reference material, or
|
||||
a combination of such.
|
||||
- A quantity as defined here is a scalar. However, a vector or a tensor, the components of
|
||||
which are quantities, is also considered to be a quantity.
|
||||
- The concept ’quantity’ may be generically divided into, e.g. ‘physical quantity’,
|
||||
‘chemical quantity’, and ‘biological quantity’, or ‘base quantity’ and ‘derived quantity’.
|
||||
- Examples of quantities are: mass, length, density, magnetic field strength, etc.
|
||||
|
||||
kind of quantity
|
||||
kind
|
||||
- Aspect common to mutually comparable `quantities <quantity>`.
|
||||
- The division of the concept ‘quantity’ into several kinds is to some extent arbitrary
|
||||
|
||||
- i.e. the quantities diameter, circumference, and wavelength are generally considered
|
||||
to be quantities of the same kind, namely, of the kind of quantity called length.
|
||||
|
||||
- Quantities of the same kind within a given `system of quantities` have the same quantity
|
||||
`dimension`. However, `quantities <quantity>` of the same `dimension` are not necessarily
|
||||
of the same kind.
|
||||
|
||||
- For example, the absorbed dose and the dose equivalent have the same `dimension`.
|
||||
However, the former measures the absolute amount of radiation one receives whereas
|
||||
the latter is a weighted measurement taking into account the kind of radiation
|
||||
on was exposed to.
|
||||
|
||||
system of quantities
|
||||
system
|
||||
- Set of `quantities <quantity>` together with a set of non-contradictory equations
|
||||
relating those `quantities <quantity>`.
|
||||
- Examples of systems of quantities are: the International System of Quantities,
|
||||
the Imperial System, etc.
|
||||
|
||||
base quantity
|
||||
- `Quantity` in a conventionally chosen subset of a given `system of quantities`, where
|
||||
no `quantity` in the subset can be expressed in terms of the other `quantities <quantity>`
|
||||
within that subset.
|
||||
- Base quantities are referred to as being mutually independent since a base quantity
|
||||
cannot be expressed as a product of powers of the other base quantities.
|
||||
|
||||
derived quantity
|
||||
- `Quantity`, in a `system of quantities`, defined in terms of the base quantities of
|
||||
that system.
|
||||
|
||||
International System of Quantities
|
||||
ISQ
|
||||
- `System of quantities` based on the seven `base quantities <base quantity>`:
|
||||
length, mass, time, electric current, thermodynamic temperature, amount of substance,
|
||||
and luminous intensity.
|
||||
- The International System of Units (SI) is based on the ISQ.
|
||||
|
||||
dimension of a quantity
|
||||
quantity dimension
|
||||
dimension
|
||||
- Expression of the dependence of a `quantity` on the `base quantities <base quantity>`
|
||||
of a `system of quantities` as a product of powers of factors corresponding to the
|
||||
`base quantities <base quantity>`, omitting any numerical factors.
|
||||
- A power of a factor is the factor raised to an exponent. Each factor is the dimension
|
||||
of a `base quantity`.
|
||||
- In deriving the dimension of a quantity, no account is taken of its scalar, vector, or
|
||||
tensor character.
|
||||
- In a given `system of quantities`:
|
||||
|
||||
- `quantities <quantity>` of the same `kind` have the same quantity dimension,
|
||||
- `quantities <quantity>` of different quantity dimensions are always of different `kinds <kind>`,
|
||||
- `quantities <quantity>` having the same quantity dimension are not necessarily of the same `kind`.
|
||||
|
||||
quantity of dimension one
|
||||
dimensionless quantity
|
||||
- `quantity` for which all the exponents of the factors corresponding to the
|
||||
`base quantities <base quantity>` in its `quantity dimension` are zero.
|
||||
- The term “dimensionless quantity” is commonly used and is kept here for historical
|
||||
reasons. It stems from the fact that all exponents are zero in the symbolic
|
||||
representation of the `dimension` for such `quantities <quantity>`. The term “quantity
|
||||
of dimension one” reflects the convention in which the symbolic representation of the
|
||||
`dimension` for such `quantities <quantity>` is the symbol ``1``. This `dimension` is
|
||||
not a number, but the neutral element for multiplication of `dimensions <dimension>`.
|
||||
- The `measurement units <measurement unit>` and values of quantities of dimension one
|
||||
are numbers, but such `quantities <quantity>` convey more information than a number.
|
||||
- Some quantities of dimension one are defined as the ratios of two
|
||||
`quantities of the same kind <kind>`. The `coherent derived unit` is the number one,
|
||||
symbol ``1``.
|
||||
- Numbers of entities are quantities of dimension one.
|
||||
|
||||
unit of measurement
|
||||
measurement unit
|
||||
unit
|
||||
- Real scalar `quantity`, defined and adopted by convention, with which any other
|
||||
`quantity of the same kind <kind>` can be compared to express the ratio of the
|
||||
second `quantity` to the first one as a number.
|
||||
- Measurement units are designated by conventionally assigned names and symbols.
|
||||
- Measurement units of `quantities <quantity>` of the same `quantity dimension` may
|
||||
be designated by the same name and symbol even when the `quantities <quantity>` are
|
||||
not of the same `kind`.
|
||||
|
||||
For example, joule per kelvin and J/K are respectively the name and symbol of both a
|
||||
measurement unit of heat capacity and a measurement unit of entropy, which are generally
|
||||
not considered to be `quantities of the same kind <kind>`. However, in some cases special
|
||||
measurement unit names are restricted to be used with `quantities <quantity>` of specific
|
||||
`kind` only. For example, the measurement unit ‘second to the power minus one’ (``1/s``) is
|
||||
called hertz (``Hz``) when used for frequencies and becquerel (``Bq``) when used for
|
||||
activities of radionuclides. As another example, the joule (``J``) is used as a unit of
|
||||
energy, but never as a unit of moment of force, i.e. the newton metre (``N · m``).
|
||||
- Measurement units of `quantities of dimension one <quantity of dimension one>` are
|
||||
numbers. In some cases, these measurement units are given special names, e.g. radian,
|
||||
steradian, and decibel, or are expressed by quotients such as millimole per mole equal
|
||||
to :math:`10^{−3}` and microgram per kilogram equal to :math:`10^{−9}`.
|
||||
|
||||
base unit
|
||||
- Measurement unit that is adopted by convention for a `base quantity`.
|
||||
- In each `coherent system of units`, there is only one base unit for each `base quantity`.
|
||||
- A base unit may also serve for a `derived quantity` of the same `quantity dimension`.
|
||||
- For example, the `ISQ` has the base units of: metre, kilogram, second, Ampere, Kelvin, mole,
|
||||
and candela.
|
||||
|
||||
derived unit
|
||||
- Measurement unit for a `derived quantity`.
|
||||
- For example, in the `ISQ` Newton, Pascal, and katal are derived units.
|
||||
|
||||
coherent derived unit
|
||||
- `Derived unit` that, for a given `system of quantities` and for a chosen set of
|
||||
`base units <base unit>`, is a product of powers of `base units <base unit>` with no
|
||||
other proportionality factor than one.
|
||||
- A power of a `base unit` is the `base unit` raised to an exponent.
|
||||
- Coherence can be determined only with respect to a particular `system of quantities`
|
||||
and a given set of `base units <base unit>`. That is, if the metre and the second are
|
||||
base units, the metre per second is the coherent derived unit of velocity.
|
||||
|
||||
system of units
|
||||
- Set of `base units <base unit>` and `derived units <derived unit>`, together with
|
||||
their multiples and submultiples, defined in accordance with given rules, for a given
|
||||
`system of quantities`.
|
||||
|
||||
coherent system of units
|
||||
|
||||
- `System of units`, based on a given `system of quantities`, in which the measurement
|
||||
unit for each `derived quantity` is a `coherent derived unit`.
|
||||
- A `system of units` can be coherent only with respect to a `system of quantities` and
|
||||
the adopted `base units <base unit>`.
|
||||
|
||||
off-system measurement unit
|
||||
off-system unit
|
||||
- `Measurement unit` that does not belong to a given `system of units`. For example, the
|
||||
electronvolt (:math:`≈ 1,602 18 × 10^{–19} J`) is an off-system measurement unit of energy with
|
||||
respect to the `SI` or day, hour, minute are off-system measurement units of time with
|
||||
respect to the `SI`.
|
||||
|
||||
International System of Units
|
||||
SI
|
||||
- `System of units`, based on the `International System of Quantities`, their names and
|
||||
symbols, including a series of prefixes and their names and symbols, together with rules
|
||||
for their use, adopted by the General Conference on Weights and Measures (CGPM)
|
||||
|
||||
quantity value
|
||||
value of a quantity
|
||||
value
|
||||
- Number and reference together expressing magnitude of a `quantity`.
|
||||
- A quantity value can be presented in more than one way.
|
||||
|
||||
|
||||
Other definitions
|
||||
-----------------
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
||||
|
||||
base dimension
|
||||
- A `dimension` of a `base quantity`.
|
||||
|
||||
derived dimension
|
||||
- A `dimension` of a `derived quantity`.
|
||||
- Often implemented as a list of exponents of `base dimensions <base dimension>`.
|
||||
|
||||
normalized derived dimension
|
||||
A `derived dimension` in which:
|
||||
|
||||
- `base dimensions <base dimension>` are not repeated in a list (each base dimension is provided at most once),
|
||||
- `base dimensions <base dimension>` are consistently ordered,
|
||||
- `base dimensions <base dimension>` having zero exponent are elided.
|
||||
|
||||
derived dimension recipe
|
||||
recipe
|
||||
- The ordered list of exponents used to define a derived dimension
|
||||
- The list may contain both base and derived dimensions (in the latter case
|
||||
the dimension is being extracted to base dimensions by the framework)
|
||||
- The order and types of dimensions used in the recipe determine how an unnamed
|
||||
dimension's unit symbol is being printed in the text output
|
||||
|
||||
scalar
|
||||
- Not a `quantity`
|
||||
- Can be passed as a representation type to the :class:`units::quantity` type or be used as a factor
|
||||
while multiplying or dividing a `quantity`.
|
||||
|
||||
.. rubric:: Footnotes:
|
||||
|
||||
.. [1] **ISO 80000-1:2009(E) "Quantities and units — Part 1: General"** gives general information
|
||||
and definitions concerning quantities, systems of quantities, units, quantity and unit symbols,
|
||||
and coherent unit systems, especially the International System of Quantities, ISQ, and the
|
||||
International System of Units, SI. The principles laid down in ISO 80000-1:2009 are intended
|
||||
for general use within the various fields of science and technology and as an introduction to
|
||||
other parts of the Quantities and units series. Ordinal quantities and nominal properties are
|
||||
outside the scope of ISO 80000-1:2009.
|
49
docs/index.rst
Normal file
@ -0,0 +1,49 @@
|
||||
Welcome to mp-units!
|
||||
====================
|
||||
|
||||
**mp-units** is a compile-time enabled Modern C++ library that provides compile-time dimensional
|
||||
analysis and unit/quantity manipulation. Source code is hosted on `GitHub <https://github.com/mpusz/units>`_
|
||||
with a permissive `MIT license <https://github.com/mpusz/units/blob/master/LICENSE.md>`_.
|
||||
|
||||
|
||||
.. important::
|
||||
|
||||
The **mp-units** library is the subject of this ISO C++ paper: `P1935 <https://wg21.link/p1935>`_.
|
||||
It is explained in this `CppCon 2019 talk <https://youtu.be/0YW6yxkdhlU>`_ (slightly dated now).
|
||||
We are working towards potentially having it standardized for C++23 and are actively looking
|
||||
for parties interested in field trialing the library.
|
||||
|
||||
.. note::
|
||||
|
||||
As this library targets C++23 and extensively uses C++20 features as of now it compiles correctly
|
||||
only with gcc-9.1 and newer.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Getting Started:
|
||||
|
||||
introduction
|
||||
quick_start
|
||||
usage
|
||||
framework
|
||||
scenarios
|
||||
design
|
||||
examples
|
||||
faq
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Reference:
|
||||
|
||||
reference/concepts
|
||||
reference/types
|
||||
reference/functions
|
||||
reference/systems
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Appendix:
|
||||
|
||||
glossary
|
||||
genindex
|
||||
CHANGELOG
|
47
docs/introduction.rst
Normal file
@ -0,0 +1,47 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
**mp-units** is a compile-time enabled Modern C++ library that provides compile-time
|
||||
dimensional analysis and unit/quantity manipulation. The basic idea and design
|
||||
heavily bases on `std::chrono::duration <https://en.cppreference.com/w/cpp/chrono/duration>`_
|
||||
and extends it to work properly with many dimensions.
|
||||
|
||||
Thanks to compile-time operations no runtime execution cost is introduced,
|
||||
facilitating the use of this library to provide dimension checking in
|
||||
performance-critical code. Support for quantities and units for arbitrary unit
|
||||
system models and arbitrary value types is provided, as is a fine-grained
|
||||
general facility for unit conversions.
|
||||
|
||||
The library architecture has been designed with flexibility and extensibility
|
||||
in mind. The demonstrations of the ease of adding new dimensions, their units,
|
||||
and unit conversions are provided in the :ref:`Examples`.
|
||||
|
||||
Open Source
|
||||
-----------
|
||||
|
||||
**mp-units** is Free and Open Source, with a permissive
|
||||
`MIT license <https://github.com/mpusz/units/blob/master/LICENSE.md>`_. Check
|
||||
out the source code and issue tracking (for questions and support, reporting
|
||||
bugs and suggesting feature requests and improvements) at https://github.com/mpusz/units.
|
||||
|
||||
|
||||
Approach
|
||||
--------
|
||||
|
||||
1. Safety and performance
|
||||
|
||||
- strong types
|
||||
- compile-time safety
|
||||
- ``constexpr`` all the things
|
||||
- as fast or even faster than when working with fundamental types
|
||||
|
||||
2. The best possible user experience
|
||||
|
||||
- compiler errors
|
||||
- debugging
|
||||
|
||||
3. No macros in the user interface
|
||||
4. Easy extensibility
|
||||
5. No external dependencies
|
||||
6. Possibility to be standardized as a freestanding part of the C++ Standard
|
||||
Library
|
62
docs/quick_start.rst
Normal file
@ -0,0 +1,62 @@
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
Here is a small example of possible operations::
|
||||
|
||||
// simple numeric operations
|
||||
static_assert(10q_km / 2 == 5q_km);
|
||||
|
||||
// unit conversions
|
||||
static_assert(1q_h == 3600q_s);
|
||||
static_assert(1q_km + 1q_m == 1001q_m);
|
||||
|
||||
// dimension conversions
|
||||
static_assert(2q_m * 3q_m == 6q_m2);
|
||||
static_assert(10q_km / 5q_km == 2);
|
||||
static_assert(1000 / 1q_s == 1q_kHz);
|
||||
static_assert(1q_km / 1q_s == 1000q_mps);
|
||||
static_assert(2q_kmph * 2q_h == 4q_km);
|
||||
static_assert(2q_km / 2q_kmph == 1q_h);
|
||||
|
||||
.. admonition:: Try it on Compiler Explorer
|
||||
|
||||
`Example #1 <https://godbolt.org/z/BZjWbD>`_
|
||||
|
||||
This library requires some C++20 features (concepts, classes as
|
||||
:abbr:`NTTP (Non-Type Template Parameter)`, ...). Thanks to them the user gets a powerful
|
||||
but still easy to use interface where all unit conversions and dimensional analysis can be
|
||||
performed without sacrificing on accuracy. Please see the below example for a quick preview
|
||||
of basic library features::
|
||||
|
||||
#include <units/physical/si/velocity.h>
|
||||
#include <units/physical/international/velocity.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace units;
|
||||
|
||||
constexpr Velocity auto avg_speed(Length auto d, Time auto t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace si::literals;
|
||||
Velocity auto v1 = avg_speed(220q_km, 2q_h);
|
||||
Velocity auto v2 = avg_speed(si::length<international::mile>(140), si::time<si::hour>(2));
|
||||
Velocity auto v3 = quantity_cast<si::metre_per_second>(v2);
|
||||
Velocity auto v4 = quantity_cast<int>(v3);
|
||||
|
||||
std::cout << v1 << '\n'; // 110 km/h
|
||||
std::cout << v2 << '\n'; // 70 mi/h
|
||||
std::cout << v3 << '\n'; // 31.2928 m/s
|
||||
std::cout << v4 << '\n'; // 31 m/s
|
||||
}
|
||||
|
||||
.. admonition:: Try it on Compiler Explorer
|
||||
|
||||
`Example #2 <https://godbolt.org/z/_Yx6D7>`_
|
||||
|
||||
.. seealso::
|
||||
|
||||
You can find more code examples in the :ref:`Examples` chapter.
|
62
docs/reference/concepts.rst
Normal file
@ -0,0 +1,62 @@
|
||||
Concepts
|
||||
========
|
||||
|
||||
.. namespace:: units
|
||||
|
||||
.. note::
|
||||
|
||||
All names defined in this chapter reside in the :any:`units` namespace unless specified otherwise.
|
||||
|
||||
.. concept:: template<typename T> PrefixType
|
||||
|
||||
Satisfied by all types derived from :class:`prefix_type`.
|
||||
|
||||
.. concept:: template<typename T> Prefix
|
||||
|
||||
Satisfied by all instantiations of :class:`prefix`.
|
||||
|
||||
.. concept:: template<typename T> Ratio
|
||||
|
||||
Satisfied by all instantiations of :class:`ratio`.
|
||||
|
||||
.. concept:: template<typename R> UnitRatio
|
||||
|
||||
Satisfied by all types that satisfy :expr:`Ratio<R>` and for which :expr:`R::num > 0` and :expr:`R::den > 0`.
|
||||
|
||||
.. concept:: template<typename T> BaseDimension
|
||||
|
||||
Satisfied by all dimension types derived from instantiation of :class:`base_dimension`.
|
||||
|
||||
.. concept:: template<typename T> Exponent
|
||||
|
||||
Satisfied by all instantiations of :class:`exp`.
|
||||
|
||||
.. concept:: template<typename T> DerivedDimension
|
||||
|
||||
Satisfied by all dimension types derived from instantiation of :class:`detail::derived_dimension_base`.
|
||||
|
||||
.. concept:: template<typename T> Dimension
|
||||
|
||||
Satisfied by all dimension types for which either :expr:`BaseDimension<T>` or :expr:`DerivedDimension<T>` is ``true``.
|
||||
|
||||
.. concept:: template<typename T> Unit
|
||||
|
||||
Satisfied by all unit types derived from instantiation of :class:`scaled_unit`.
|
||||
|
||||
.. concept:: template<typename U, typename D> UnitOf
|
||||
|
||||
Satisfied by all unit types that satisfy :expr:`Unit<U>`, :expr:`Dimension<D>`, and for which
|
||||
:expr:`U::reference` and :expr:`dimension_unit<D>::reference` denote the same unit type.
|
||||
|
||||
.. concept:: template<typename T> Quantity
|
||||
|
||||
Satisfied by all instantiations of :class:`quantity`.
|
||||
|
||||
.. concept:: template<typename T> WrappedQuantity
|
||||
|
||||
Satisfied by all wrapper types that satisfy :expr:`Quantity<typename T::value_type>` recursively
|
||||
(i.e. :expr:`std::optional<si::length<si::metre>>`).
|
||||
|
||||
.. concept:: template<typename T> Scalar
|
||||
|
||||
Satisfied by types that satisfy :expr:`(!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>`.
|
15
docs/reference/functions.rst
Normal file
@ -0,0 +1,15 @@
|
||||
.. note::
|
||||
|
||||
All names defined in this chapter reside in the :any:`units` namespace unless specified otherwise.
|
||||
|
||||
Functions
|
||||
=========
|
||||
|
||||
.. doxygenfunction:: quantity_cast
|
||||
|
||||
|
||||
|
||||
Metafunctions
|
||||
=============
|
||||
|
||||
.. doxygentypedef:: dimension_unit
|
32
docs/reference/systems.rst
Normal file
@ -0,0 +1,32 @@
|
||||
.. note::
|
||||
|
||||
All names defined in this chapter reside in the :any:`units` namespace unless specified otherwise.
|
||||
|
||||
Systems
|
||||
=======
|
||||
|
||||
SI
|
||||
--
|
||||
|
||||
..
|
||||
doxygennamespace:: units::si
|
||||
:members:
|
||||
:undoc-members:
|
||||
:outline:
|
||||
|
||||
|
||||
File
|
||||
----
|
||||
|
||||
..
|
||||
doxygenfile:: si/length.h
|
||||
|
||||
Group
|
||||
-----
|
||||
|
||||
..
|
||||
doxygengroup:: si_length
|
||||
:content-only:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:outline:
|
51
docs/reference/types.rst
Normal file
@ -0,0 +1,51 @@
|
||||
.. note::
|
||||
|
||||
All names defined in this chapter reside in the :any:`units` namespace unless specified otherwise.
|
||||
|
||||
Types
|
||||
=====
|
||||
|
||||
Quantity
|
||||
--------
|
||||
|
||||
.. doxygenclass:: units::quantity
|
||||
:members:
|
||||
|
||||
..
|
||||
:undoc-members:
|
||||
|
||||
Dimension
|
||||
---------
|
||||
|
||||
.. doxygenstruct:: units::base_dimension
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::derived_dimension
|
||||
:members:
|
||||
|
||||
Unit
|
||||
----
|
||||
|
||||
.. doxygenstruct:: units::scaled_unit
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::unit
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::named_unit
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::named_scaled_unit
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::prefixed_unit
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: units::deduced_unit
|
||||
:members:
|
||||
|
||||
Ratio
|
||||
-----
|
||||
|
||||
.. doxygenstruct:: units::ratio
|
||||
:members:
|
3
docs/requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
sphinx
|
||||
recommonmark
|
||||
breathe
|
15
docs/scenarios.rst
Normal file
@ -0,0 +1,15 @@
|
||||
Scenarios
|
||||
=========
|
||||
|
||||
.. note::
|
||||
|
||||
For brevity all the code examples in this documentation will assume::
|
||||
|
||||
using namespace units;
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
scenarios/unknown_units_and_dimensions
|
||||
scenarios/legacy_interfaces
|
||||
scenarios/extensions
|
19
docs/scenarios/extensions.rst
Normal file
@ -0,0 +1,19 @@
|
||||
.. namespace:: units
|
||||
|
||||
Extending the library
|
||||
=====================
|
||||
|
||||
Custom Units
|
||||
------------
|
||||
|
||||
Custom Dimensions
|
||||
-----------------
|
||||
|
||||
Custom Base Dimensions
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Custom Derived Dimensions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Custom Systems
|
||||
--------------
|
41
docs/scenarios/legacy_interfaces.rst
Normal file
@ -0,0 +1,41 @@
|
||||
.. namespace:: units
|
||||
|
||||
Working with Legacy Interfaces
|
||||
==============================
|
||||
|
||||
In case we are working with a legacy/unsafe interface we may be forced to
|
||||
extract a :term:`value of a quantity` with :func:`quantity::count()` and
|
||||
pass it to the library's output:
|
||||
|
||||
.. code-block::
|
||||
:caption: legacy.h
|
||||
|
||||
namespace legacy {
|
||||
|
||||
void print_eta(double speed_in_mps);
|
||||
|
||||
} // namespace legacy
|
||||
|
||||
.. code-block::
|
||||
|
||||
#include "legacy.h"
|
||||
#include <units/physical/si/velocity.h>
|
||||
|
||||
using namespace units;
|
||||
|
||||
constexpr Velocity auto avg_speed(Length auto d, Time auto t)
|
||||
{
|
||||
return d / t;
|
||||
}
|
||||
|
||||
void print_eta(Length auto d, Time auto t)
|
||||
{
|
||||
Velocity auto v = avg_speed(d, t);
|
||||
legacy::print_eta(quantity_cast<si::metre_per_second>(v).count());
|
||||
}
|
||||
|
||||
.. important::
|
||||
|
||||
When dealing with a quantity of an unknown ``auto`` type please remember
|
||||
to always use `quantity_cast` to cast it to a desired unit before calling
|
||||
`quantity::count()` and passing the raw value to the legacy/unsafe interface.
|
9
docs/scenarios/unknown_units_and_dimensions.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. namespace:: units
|
||||
|
||||
Working with Unknown Units and Dimensions
|
||||
=========================================
|
||||
|
||||
- what is an unknown unit?
|
||||
- what is an unknown dimension?
|
||||
- temporary result
|
||||
- casting to the coherent unit
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
233
docs/usage.rst
Normal file
@ -0,0 +1,233 @@
|
||||
Usage
|
||||
=====
|
||||
|
||||
.. note::
|
||||
|
||||
As this library targets C++23 and extensively uses C++20 features as of now it compiles correctly
|
||||
only with gcc-9.1 and newer.
|
||||
|
||||
Repository structure and dependencies
|
||||
-------------------------------------
|
||||
|
||||
This repository contains three independent CMake-based projects:
|
||||
|
||||
- *./src*
|
||||
|
||||
- header-only project containing whole **mp-units** library
|
||||
- when C++20 support will be fully supported by C++ compilers this library will have
|
||||
no external dependencies but until then it depends on
|
||||
`range-v3 <https://github.com/ericniebler/range-v3>`_ (only for gcc versions < 10.0)
|
||||
and `{fmt} <https://github.com/fmtlib/fmt>`_ libraries.
|
||||
|
||||
- *.*
|
||||
|
||||
- project used as an entry point for library development and CI/CD
|
||||
- it wraps *./src* project together with usage examples and tests
|
||||
- additionally to the dependencies of *./src* project, it uses:
|
||||
|
||||
- `Catch2 <https://github.com/catchorg/Catch2>`_ library as a unit tests framework.
|
||||
- `linear algebra <https://github.com/BobSteagall/wg21/tree/master/linear_algebra/code>`_
|
||||
library based on proposal `P1385 <https://wg21.link/P1385>`_ used in some examples
|
||||
and tests.
|
||||
- `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 recommonmark <https://recommonmark.readthedocs.io>`_.
|
||||
- `Breathe <https://breathe.readthedocs.io/>`_ as a bridge between the Sphinx and Doxygen
|
||||
documentation systems.
|
||||
|
||||
- *./test_package*
|
||||
|
||||
- library installation and Conan package verification
|
||||
|
||||
.. note::
|
||||
|
||||
Please note that **mp-units** repository also depends on a git submodule in the
|
||||
*./cmake/common* subdirectory providing some common CMake utilities.
|
||||
|
||||
|
||||
Obtaining Dependencies
|
||||
----------------------
|
||||
|
||||
This library assumes that most of the dependencies will be provided by the
|
||||
`Conan Package Manager <https://conan.io/>`_. In case you would like to obtain needed
|
||||
dependencies by other means some modifications to library's CMake files will be needed.
|
||||
The rest of the dependencies are provided by :command:`python3-pip`.
|
||||
|
||||
Conan quick intro
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
In case you are not familiar with Conan, to install it (or upgrade) just do:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
pip3 install -U conan
|
||||
|
||||
After that you might need to add a custom profile file for your development environment
|
||||
in *~/.conan/profile* directory. An example profile can look as follows:
|
||||
|
||||
.. code-block:: ini
|
||||
:emphasize-lines: 8
|
||||
|
||||
[settings]
|
||||
os=Linux
|
||||
os_build=Linux
|
||||
arch=x86_64
|
||||
arch_build=x86_64
|
||||
compiler=gcc
|
||||
compiler.version=9
|
||||
compiler.cppstd=20
|
||||
compiler.libcxx=libstdc++11
|
||||
build_type=Release
|
||||
|
||||
[options]
|
||||
[build_requires]
|
||||
|
||||
[env]
|
||||
CC=/usr/bin/gcc-9
|
||||
CXX=/usr/bin/g++-9
|
||||
|
||||
.. 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 rune a Conan command line (as it is suggested below).
|
||||
|
||||
Non-standard Conan remotes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add the following remotes to your local Conan instance:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
conan remote add conan-mpusz https://api.bintray.com/conan/mpusz/conan-mpusz
|
||||
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||
conan remote add linear-algebra https://api.bintray.com/conan/twonington/public-conan
|
||||
|
||||
.. note::
|
||||
|
||||
The last two remotes are needed only if you plan to build all of the code and documentation
|
||||
in **mp-units** repository.
|
||||
|
||||
|
||||
Build options
|
||||
-------------
|
||||
|
||||
Environment variables
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. envvar:: CONAN_RUN_TESTS
|
||||
|
||||
**Defaulted to**: Not defined (``True``/``False`` if defined)
|
||||
|
||||
Enables compilation of all the source code (tests and examples) and building the documentation.
|
||||
To support that it requires some additional Conan build dependencies described in
|
||||
`Repository structure and dependencies`_.
|
||||
It also runs unit tests during Conan build.
|
||||
|
||||
|
||||
Building, Installation, and Reuse
|
||||
---------------------------------
|
||||
|
||||
There are a few different ways of installing/reusing **mp-units** in your project.
|
||||
|
||||
Copy
|
||||
^^^^
|
||||
|
||||
As **mp-units** is a C++ header-only library you can simply copy *src/include* directory to
|
||||
your source tree and use it as regular header files.
|
||||
|
||||
CMake + Conan
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
To use **mp-units** as a CMake imported library the following steps may be performed:
|
||||
|
||||
1. Clone the repository together with its submodules:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone --recurse-submodules https://github.com/mpusz/units.git
|
||||
|
||||
or in case it is already cloned without submodules, initialize, fetch, and checkout them with:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git submodule update --init
|
||||
|
||||
2. Create Conan configuration file (either *conanfile.txt* or *conanfile.py*) in your
|
||||
project's top-level directory and add **mp-units** as a dependency to your Conan configuration
|
||||
file.
|
||||
|
||||
- for example to use **mp-units** testing/prerelease version ``0.5.0`` in case of *conanfile.txt*
|
||||
it is enough for it to just contain the following lines:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[requires]
|
||||
mp-units/0.5.0@mpusz/testing
|
||||
|
||||
3. Import Conan dependencies definitions to the beginning of your top-level *CMakeLists.txt*
|
||||
file in your project:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||
conan_basic_setup(TARGETS)
|
||||
|
||||
4. Link your CMake target with **mp-units**:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_link_libraries(<your_target> PUBLIC|PRIVATE|INTERFACE CONAN_PKG::mp-units)
|
||||
|
||||
5. Download and install Conan dependencies before running CMake configuration step:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd build
|
||||
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -b=outdated -u
|
||||
|
||||
6. Configure your CMake project as usual.
|
||||
|
||||
|
||||
Full **mp-units** build, unit testing, and documentation generation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In case you would like to build all the source code (with unit tests and examples) and documentation
|
||||
in **mp-units** repository, you should use the *CMakeLists.txt* from the top-level directory,
|
||||
obtain Python dependencies, and run Conan with :envvar:`CONAN_RUN_TESTS` = ``True``:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone --recurse-submodules https://github.com/mpusz/units.git && cd units
|
||||
pip3 install -r docs/requirements.txt
|
||||
mkdir build && cd build
|
||||
conan install .. -pr <your_conan_profile> -s compiler.cppstd=20 -e CONAN_RUN_TESTS=True -b outdated
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build .
|
||||
ctest
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Packaging
|
||||
---------
|
||||
|
||||
To test CMake installation and Conan packaging or create a Conan package run:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone --recurse-submodules https://github.com/mpusz/units.git && cd units
|
||||
pip3 install -r docs/requirements.txt
|
||||
conan create . <username>/<channel> -pr <your_conan_profile> -s compiler.cppstd=20 -e CONAN_RUN_TESTS=True -b outdated
|
||||
|
||||
The above will create a Conan package and run tests provided in *./test_package* directory.
|
||||
|
||||
|
||||
Uploading **mp-units** package to the Conan server
|
||||
--------------------------------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
conan upload -r <remote-name> --all mp-units/0.5.0@<user>/<channel>
|