diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 8c7b9b92..35be8468 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -7,7 +7,7 @@ else() # otherwise use top-level doxygen setup instead. set(ALL_LIBRARY_TARGETS xo_unit) # todo: automate this from xo-cmake macros - set(ALL_UTEST_TARGETS utest.unit) # todo: automate this from xo-cmake macros + set(ALL_UTEST_TARGETS utest.unit xo_unit_ex1 xo_unit_ex2 xo_unit_ex3 xo_unit_ex4 xo_unit_ex5 xo_unit_ex6) # todo: automate this from xo-cmake macros # look for doxygen executable find_program(DOXYGEN_EXECUTABLE NAMES doxygen REQUIRED) @@ -19,22 +19,27 @@ else() set(DOX_CONFIG_FILE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) - #set(DOX_DEPS ${PROJECT_SOURCE_DIR}/mainpage.dox) # not yet set(DOX_INPUT_DIR ${PROJECT_SOURCE_DIR}) set(DOX_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/dox) set(DOX_INDEX_FILE ${DOX_OUTPUT_DIR}/html/index.html) + # .hpp files reachable from xo-unit/include + # + # REMINDER: for reliability will need to re-run cmake when the set of .hpp files changes + # + file(GLOB_RECURSE DOX_HPP_FILES_GLOB ${PROJECT_SOURCE_DIR}/include *.hpp) + set(SPHINX_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/sphinx/html) set(SPHINX_INDEX_FILE ${SPHINX_OUTPUT_DIR}/index.html) # # sphinx .rst files reachable from cmake-examples/docs # - # REMINDER: will need to re-run cmake when the set of .rst files changes + # REMINDER: for reliability will need to re-run cmake when the set of .rst files changes # file(GLOB_RECURSE SPHINX_RST_FILES_GLOB ${CMAKE_CURRENT_SOURCE_DIR} *.rst) - set(SPHINX_RST_FILES index.rst install.rst examples.rst classes.rst glossary.rst) + set(SPHINX_RST_FILES index.rst install.rst examples.rst unit-quantities.rst quantity-class.rst quantity-factoryfunctions.rst quantity-unitvars.rst unit-reference.rst unit-concept.rst glossary.rst) # TODO: # 1. move Doxyfile.in to xo-cmake project @@ -45,10 +50,12 @@ else() FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE @ONLY) + set(DOX_DEPS ${ALL_LIBRARY_TARGETS} ${ALL_UTEST_TARGETS} ${DOX_HPP_FILES_GLOB}) + file(MAKE_DIRECTORY ${DOX_OUTPUT_DIR}) add_custom_command( OUTPUT ${DOX_INDEX_FILE} - DEPENDS ${DOX_DEPS} ${ALL_LIBRARY_TARGETS} ${ALL_UTEST_TARGETS} + DEPENDS ${DOX_DEPS} COMMAND "${DOXYGEN_EXECUTABLE}" ${DOX_CONFIG_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} MAIN_DEPENDENCY ${DOX_CONFIG_FILE} @@ -62,15 +69,16 @@ else() # add_custom_target( doxygen - DEPENDS ${DOX_INDEX_FILE} + DEPENDS ${DOX_INDEX_FILE} ${DOX_DEPS} ) # root of sphinx doc tree set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}) + set(SPHINX_DEPS doxygen conf.py ${SPHINX_RST_FILES} ${SPHINX_RST_FILES_GLOB} ${DOX_DEPS}) add_custom_command( OUTPUT ${SPHINX_INDEX_FILE} - DEPENDS doxygen conf.py ${SPHINX_RST_FILES} ${SPHINX_RST_FILES_GLOB} + DEPENDS ${SPHINX_DEPS} COMMAND ${SPHINX_EXECUTABLE} -b html -Dbreathe_projects.xodoxxml=${CMAKE_CURRENT_BINARY_DIR}/dox/xml ${SPHINX_SOURCE} ${SPHINX_OUTPUT_DIR} diff --git a/docs/README b/docs/README index 599096ac..078db7c8 100644 --- a/docs/README +++ b/docs/README @@ -3,6 +3,7 @@ map index.rst +- install.rst +- examples.rst + +- unit-quantities.rst +- classes.rst +- glossary.rst diff --git a/docs/classes.rst b/docs/classes.rst deleted file mode 100644 index 1e3ac342..00000000 --- a/docs/classes.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _classes: - -.. toctree - :maxdepth: 2 - -Template Classes -================ - -.. doxygenclass:: xo::unit::quantity - :members: diff --git a/docs/examples.rst b/docs/examples.rst index d9beb387..f9ddda45 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -15,16 +15,17 @@ Compile-time unit inference #include int main() { - namespace u = xo::unit; - namespace qty = u::qty; + namespace u = xo::unit::units; + namespace qty = xo::unit::qty; + using xo::unit::quantity; using namespace std; auto t = qty::milliseconds(10); auto m = qty::kilograms(2.5); auto a = m / (t * t); - static_assert(same_as>); - static_assert(same_as>); + static_assert(same_as>); + static_assert(same_as>); static_assert(sizeof(t) == sizeof(int)); static_assert(sizeof(m) == sizeof(double)); static_assert(sizeof(a) == sizeof(double)); @@ -88,7 +89,7 @@ One way to convert units is by assignment: .. code-block:: cpp :linenos: - :emphasize-lines: 9-10 + :emphasize-lines: 10-11 #include "xo/unit/quantity.hpp" #include @@ -96,6 +97,7 @@ One way to convert units is by assignment: int main() { namespace u = xo::unit; namespace qty = xo::units::qty; + using xo::unit::quantity; using namespace std; quantity t = qty::milliseconds(10); diff --git a/docs/index.rst b/docs/index.rst index 108d97d4..12ffda2e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,11 +24,13 @@ runtime (since we can't construct new c++ types at runtime). .. toctree:: :maxdepth: 2 - :caption: Contents: + :caption: xo-unit contents: install examples - classes + unit-quantities + quantity-reference + unit-reference Indices and Tables ------------------ @@ -36,5 +38,3 @@ Indices and Tables * :ref:`glossary` * :ref:`genindex` * :ref:`search` - -.. toctree:: diff --git a/docs/quantity-class.rst b/docs/quantity-class.rst new file mode 100644 index 00000000..2945026e --- /dev/null +++ b/docs/quantity-class.rst @@ -0,0 +1,70 @@ +.. _quantity-class: + +Quantity +======== + +.. code-block:: cpp + + #include + +The primary data structure for interacting with xo-unit is the +template class ``xo::unit::quantity``. + +.. doxygenclass:: xo::unit::quantity + +Type Traits +----------- + +.. doxygengroup:: quantity-traits + :content-only: + +Constructors +------------ + +.. doxygengroup:: quantity-ctors + :content-only: + +.. doxygengroup:: quantity-named-ctors + :content-only: + +The simplest way to create a quantity instance is to use either + +* factory functions in ``xo::unit::qty``, see :doc:`quantity-factoryfunctions` +* unit variables in ``xo::unit::units``, see :doc:`quantity-unitvars` + +Access Methods +-------------- + +.. doxygengroup:: quantity-access-methods + :content-only: + +Constants +--------- + +.. doxygengroup:: quantity-constants + :content-only: + +Conversion Methods +------------------ + +Amount-preserving conversion to quantities with different units and/or representation. + +.. doxygengroup:: quantity-unit-conversion + :content-only: + +Arithmetic +---------- + +.. doxygengroup:: quantity-arithmetic + :content-only: + +Support methods for arithmetic operations + +.. doxygengroup:: quantity-arithmeticsupport + :content-only: + +Assignment +---------- + +.. doxygengroup:: quantity-assignment + :content-only: diff --git a/docs/quantity-factoryfunctions.rst b/docs/quantity-factoryfunctions.rst new file mode 100644 index 00000000..f73d9745 --- /dev/null +++ b/docs/quantity-factoryfunctions.rst @@ -0,0 +1,27 @@ +.. _quantity_factoryfunctions: + +.. toctree:: + :maxdepth: 2 + +Quantity Factory Functions +========================== + +.. code-block:: cpp + + #include + +.. doxygenfunction:: xo::unit::qty::milligrams +.. doxygenfunction:: xo::unit::qty::grams +.. doxygenfunction:: xo::unit::qty::kilograms + +.. doxygenfunction:: xo::unit::qty::millimeters +.. doxygenfunction:: xo::unit::qty::meters +.. doxygenfunction:: xo::unit::qty::kilometers + +.. doxygenfunction:: xo::unit::qty::nanoseconds +.. doxygenfunction:: xo::unit::qty::microseconds +.. doxygenfunction:: xo::unit::qty::milliseconds +.. doxygenfunction:: xo::unit::qty::seconds +.. doxygenfunction:: xo::unit::qty::minutes +.. doxygenfunction:: xo::unit::qty::hours +.. doxygenfunction:: xo::unit::qty::days diff --git a/docs/quantity-reference.rst b/docs/quantity-reference.rst new file mode 100644 index 00000000..1f3b4496 --- /dev/null +++ b/docs/quantity-reference.rst @@ -0,0 +1,12 @@ +.. _quantity-reference: + +Quantity Reference +================== + +.. toctree:: + :maxdepth: 2 + :caption: Quantity Reference + + quantity-class + quantity-factoryfunctions + quantity-unitvars diff --git a/docs/quantity-unitvars.rst b/docs/quantity-unitvars.rst new file mode 100644 index 00000000..77c09946 --- /dev/null +++ b/docs/quantity-unitvars.rst @@ -0,0 +1,45 @@ +.. _quantity-unitvars: + +.. toctree:: + :maxdepth: 2 + +Quantity Unit Variables +======================= + +.. code-block:: cpp + + #include + +The ``xo::unit::unit_qty`` namespace contains unit quantities in each dimension. +Can use these to request unit conversion involving multiple dimensions, for example: + +.. code-block:: cpp + + namespace qty = xo::unit::qty; + namespace u = xo::unit::unit_qty; + + auto q1 = (qty::kilometers(150.0) / qty::hours(0.5); + auto q2 = q1.with_units_from(u:meter / u:second); + + +Mass +---- +.. doxygenvariable:: xo::unit::unit_qty::milligram +.. doxygenvariable:: xo::unit::unit_qty::gram +.. doxygenvariable:: xo::unit::unit_qty::kilogram + +Distance +-------- +.. doxygenvariable:: xo::unit::unit_qty::millimeter +.. doxygenvariable:: xo::unit::unit_qty::meter +.. doxygenvariable:: xo::unit::unit_qty::kilometer + +Time +---- +.. doxygenvariable:: xo::unit::unit_qty::nanosecond +.. doxygenvariable:: xo::unit::unit_qty::microsecond +.. doxygenvariable:: xo::unit::unit_qty::millisecond +.. doxygenvariable:: xo::unit::unit_qty::second +.. doxygenvariable:: xo::unit::unit_qty::minute +.. doxygenvariable:: xo::unit::unit_qty::hour +.. doxygenvariable:: xo::unit::unit_qty::day diff --git a/docs/unit-concept.rst b/docs/unit-concept.rst new file mode 100644 index 00000000..387289d8 --- /dev/null +++ b/docs/unit-concept.rst @@ -0,0 +1,12 @@ +.. _unit-concept: + +Unit Concepts +============= + +.. code-block:: cpp + + #include + +.. doxygenconcept:: xo::unit::unit_concept + +.. doxygenconcept:: xo::unit::basis_unit_concept diff --git a/docs/unit-quantities.rst b/docs/unit-quantities.rst new file mode 100644 index 00000000..30e57de6 --- /dev/null +++ b/docs/unit-quantities.rst @@ -0,0 +1,93 @@ +.. _unit-quantities: + +.. toctree + :maxdepth: 2 + +Unit Quantities +=============== + +Xo-unit uses the type system to represent units. +This is great for eliminating runtime overhead. + +One place where we face some awkwardness is conversions involving multiple dimensions. +We'd like to write something concise like + +.. code-block:: cpp + + meter / (second * second); + +The difficulty arises because xo-unit represents `meter` and `second` by types +(``xo::unit::units::meter`` and ``xo::unit::units::second``); operators like `*` and `/` +apply to *values*, not types. + +We'll present various ways to express rescaling below + +Converting units +---------------- + +First, xo-unit provides constexpr unit quantities in namespace ``xo::unit::unit_qty``: + +.. code-block:: cpp + :linenos: + + static constexpr auto meter = qty::meters(1); + static constexpr auto kilometer = qty::kilometers(1); + // etc + +Second, a method ``quantity::with_units_from`` that takes units (only) from its argument: +``quantity::with_units_from`` just extracts its argument's unit_type to call ``quantity::with_units``. + +.. code-block:: cpp + :linenos: + + template + template + auto quantity::with_units_from(Quantity q) { + return this->with_units(); + } + +Motivation is that it's easier to express an argument to `with_units_from` +than to express template arguments to `with_units`. + +Prefer + +.. code-block:: cpp + :linenos: + :emphasize-lines: 5 + + namespace u = xo::unit::unit_qty; // u::meter is a value + namespace qty = xo::unit::qty; + + auto q1 = qty::kilometers(150.0) / qty::hours(0.5); + auto q2 = q1.with_units_from(u::meter / u::second); + +instead of the more verbose: + +.. code-block:: cpp + :linenos: + :emphasize-lines: 5-6 + + namespace u = xo::unit::units; // u::meter is a type + + auto q1 = qty::kilometers(150.0) / qty::hours(0.5); + + auto q2 = q1.with_units>>(); + +Using basis units +----------------- + +An alternative way to request multidimensional unit conversion is with basis units + +.. code-block:: cpp + :linenos: + :emphasize-lines: 4-5 + + namespace u = xo::unit::units; // u::meter is a type + + auto q1 = qty::kilometers(150.0) / qty::hours(0.5); + auto q2 = q1.with_basis_unit(); // q2 in km.s^-1 + auto q3 = q2.with_basis_unit(); // q3 in m.s^-1 + +With this technique we don't have to supply the basis dimension's exponent. +Instead we're just giving scale. diff --git a/docs/unit-reference.rst b/docs/unit-reference.rst new file mode 100644 index 00000000..a329f486 --- /dev/null +++ b/docs/unit-reference.rst @@ -0,0 +1,10 @@ +.. _unit-reference: + +Unit Reference +============== + +.. toctree:: + :maxdepth: 2 + :caption: Unit Reference + + unit-concept