Skip to content

Commit

Permalink
Document constants (#340)
Browse files Browse the repository at this point in the history
We update the installation guide, both to point users to the headers for
the constants, and to tell them how to include constants in the
single-file script.  This made me realize that we had forgotten to make
constants available in `@au//au`, so I updated the BUILD file.

On the constant reference page, we now list the built-in constants.  I
like the way the table looks!

On the monovalue types page, constants are a great example of monovalue
types, so I add them as an example.

We also add a how-to guide for making new constants.

Finally, now that we include built-in constants with the library, I
think Au's constant support is now best-in-class, so I am updating our
Alternatives page to list us as such.

Fixes #90.
  • Loading branch information
chiphogg authored Dec 2, 2024
1 parent 72c2d06 commit d5bbc6f
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 8 deletions.
2 changes: 2 additions & 0 deletions au/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ cc_library(
deps = [
":chrono_interop",
":constant",
":constants",
":math",
":units",
],
)

Expand Down
7 changes: 2 additions & 5 deletions docs/alternatives/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -908,15 +908,12 @@ features.
href="https://mpusz.github.io/mp-units/2.0/users_guide/framework_basics/faster_than_lightspeed_constants/">"Faster
than lightspeed" constants</a>
</td>
<td class="good">
<td class="best">
<ul>
<li class="check">Constants as types</li>
<li class="check">Perfect conversion policy</li>
<li class="check">Implicit Quantity conversion</li>
<li class="x">
No built-in values yet (see <a
href="https://github.com/aurora-opensource/au/issues/90">#90</a>)
</li>
<li class="check"><a href="https://aurora-opensource.github.io/au/main/reference/constant/#built-in">Includes</a> exact constants from SI 2019</li>
</ul>
</td>
</tr>
Expand Down
2 changes: 2 additions & 0 deletions docs/howto/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ using the library. Here's a summary of what you'll find.
- **[New units](./new-units.md).** How to add a new unit of measure that the library doesn't
include.

- **[New constants](./new-constants.md).** How to add a custom physical constant.

- **[New dimensions](./new-dimensions.md).** How to add a new, independent base dimension.

- **[Inter-library Interoperation](./interop/index.md).** How to set up automatic correspondence
Expand Down
83 changes: 83 additions & 0 deletions docs/howto/new-constants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Defining new constants

This page explains how to define new constants that aren't [included in the
library](../reference/constant.md#built-in).

!!! tip
If you think it _should_ be included in the library, feel free to [file an
issue](https://github.com/aurora-opensource/au/issues): there's no harm in asking.

In order for us to consider it, it should be relatively widely used. It also needs to have an
_exact_ value: we don't have a great way to deal with values that can change over time.

If these conditions don't apply, then follow the directions in this guide to define a _custom_
constant for your project.

## Methods of definition

There are two ways to define a new constant. The only difference is _whether you need a label_ for
your constant. In either case, you create a constant by calling `make_constant(...)`. The argument
is a [unit slot](../discussion/idioms/unit-slots.md), so you can pass it anything that goes into
a unit slot.

### Ad hoc (no special label)

Pass any ad hoc unit expression to the unit slot. The constant will produce correct results in
code, in every situation. It will even have _a_ label, which will identify it exactly. The label
will simply be cumbersome.

!!! example "Example: speed of light in an ad hoc manner"
Here's how to create a constant for the speed of light, without giving it a special symbol.

```cpp
constexpr auto c = make_constant(meters / second * mag<299'792'458>());
```

Here's an example use case, in user code:

```cpp
std::cout << (0.8 * c) << std::endl;
```

The above prints `"0.8 [299792458 m/s]"`. Notice how the unit label, `"[299792458 m/s]"`, is
_correct_, but _cumbersome_.

### Full unit definition (includes custom label)

First, follow a stripped down version of the [new unit instructions](./new-units.md) to define
a _unit_ for the constant. The only thing you need to give it is a _label_; you can omit the
instructions for quantity makers and so on.

Next, pass an instance of this custom unit to `make_constant`.

!!! example "Example: speed of light with full unit definition"
Here's how to create a constant for the speed of light using a full custom unit, with label.

=== "C++14"
```cpp
// In `.hh` file:
struct SpeedOfLightUnit : decltype(Meters{} / Seconds{} * mag<299'792'458>()) {
static constexpr const char label[] = "c";
};
constexpr auto c = make_constant(SpeedOfLightUnit{});

// In `.cc` file:
constexpr const char SpeedOfLightUnit::label[];
```

=== "C++17"
```cpp
// In `.hh` file:
struct SpeedOfLightUnit : decltype(Meters{} / Seconds{} * mag<299'792'458>()) {
static constexpr inline const char label[] = "c";
};
constexpr auto c = make_constant(SpeedOfLightUnit{});
```

Here's an example use case, in user code:

```cpp
std::cout << (0.8 * c) << std::endl;
```

The above prints `"0.8 c"`.
9 changes: 6 additions & 3 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ to your `deps` attribute, and include the appropriate files.
| Dependency | Headers provided | Notes |
|------------|------------------|-------|
| `@au//au` | `"au/au.hh"`<br>`"au/fwd.hh"`<br>`"au/units/*.hh"`<br>`"au/units/*_fwd.hh"` | Core library functionality. See [all available units](https://github.com/aurora-opensource/au/tree/main/au/units) |
| `@au//au` | `"au/au.hh"`<br>`"au/fwd.hh"`<br>`"au/units/*.hh"`<br>`"au/units/*_fwd.hh"`<br>`"au/constants/*.hh"` | Core library functionality. See [all available units](https://github.com/aurora-opensource/au/tree/main/au/units) and [constants](./reference/constant.md#built-in) |
| `@au//au:io` | `"au/io.hh"` | `operator<<` support |
| `@au//au:testing` | `"au/testing.hh"` | Utilities for writing googletest tests<br>_Note:_ `testonly = True` |
Expand All @@ -141,7 +141,7 @@ In either case, here are the main targets and include files provided by the Au l
| Target | Headers provided | Notes |
|--------|------------------|-------|
| `Au::au` | `"au/au.hh"`<br>`"au/fwd.hh"`<br>`"au/io.hh"`<br>`"au/units/*.hh"`<br>`"au/units/*_fwd.hh"` | Core library functionality. See [all available units](https://github.com/aurora-opensource/au/tree/main/au/units) |
| `Au::au` | `"au/au.hh"`<br>`"au/fwd.hh"`<br>`"au/io.hh"`<br>`"au/units/*.hh"`<br>`"au/units/*_fwd.hh"`<br>`"au/constants/*.hh"` | Core library functionality. See [all available units](https://github.com/aurora-opensource/au/tree/main/au/units) |
| `Au::testing` | `"au/testing.hh"` | Utilities for writing googletest tests |
!!! note
Expand Down Expand Up @@ -336,7 +336,10 @@ Here's how:
creates a file, `~/au.hh`, which packages the entire library in a single file with these three
units.
- To see the full list of available units, search the `.hh` files in the `au/units/` folder. For
example, `meters` will include the contents of `au/units/meters.hh`.
example, `meters` will include the contents of `"au/units/meters.hh"`.
- Similarly, to see the full list of available constants, search the `.hh` files in the
`au/constants/` folder. For example, `speed_of_light` will include the contents of
`"au/constants/speed_of_light.hh"`, which provides the constant `au::SPEED_OF_LIGHT`.
- Provide the `--noio` flag if you prefer to avoid the expense of the `<iostream>` library.
Now you have a file, `~/au.hh`, which you can add to your `third_party` folder.
39 changes: 39 additions & 0 deletions docs/reference/constant.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,45 @@ still store `5` under the hood.
This approach means that if subsequent operations cancel out the constant, this cancellation is both
_exact_ and has _zero runtime cost_.

## Built-in constants included with Au {#built-in}

Au includes a number of built-in constants. Each constant is in its own include file, in the folder
`"au/constant"` --- for example, `"au/constant/speed_of_light.hh"`.

The constant object itself is in the top-level `au::` namespace, and uses an UPPERCASE naming
convention, as with all other constants in the library --- for example, `au::SPEED_OF_LIGHT`.

We spell out the constant name in full to avoid ambiguity. However, this can be overly verbose. We
encourage users to define their own copy of each constant, with a more usable name --- for example:

```cpp
constexpr auto c = au::SPEED_OF_LIGHT;
```

This "copy" is essentially free, because the constant is a [monovalue
type](./detail/monovalue_types.md), and therefore empty.

Here are the constants that we include with Au:

| Name | Symbol | Value | Include (under `"au/constants/"`) | Object name (under `au::` namespace) |
| ---- | ------ | ----- | ------- | ----------- |
| Avogadro constant | $N_A$ | $6.022\,140\,76 \times 10^{23}\,\, \text{mol}^{-1}$ | `avogadro_constant.hh` | `AVOGADRO_CONSTANT` |
| Boltzmann constant | $k_B$ | $1.380\,649 \times 10^{-23}\,\, \text{J} / \text{K}$ | `boltzmann_constant.hh` | `BOLTZMANN_CONSTANT` |
| Cesium hyperfine transition frequency | $\Delta \nu_{Cs}$ | $9\,192\,631\,770\,\, \text{Hz}$ | `cesium_hyperfine_transition_frequency.hh` | `CESIUM_HYPERFINE_TRANSITION_FREQUENCY` |
| Elementary charge | $e$ | $1.602\,176\,634 \times 10^{-19}\,\, \text{C}$ | `elementary_charge.hh` | `ELEMENTARY_CHARGE` |
| Luminous efficacy of light at $540\,\, \text{THz}$ | $K_{cd}$ | $683\,\, \text{lm} / \text{W}$ | `luminous_efficacy_540_terahertz.hh` | `LUMINOUS_EFFICACY_540_TERAHERTZ` |
| Planck constant | $h$ | $6.626\,070\,15 \times 10^{-34}\,\, \text{J} \cdot \text{s}$ | `planck_constant.hh` | `PLANCK_CONSTANT` |
| Reduced Planck constant | $\hbar$ | $1.054\,571\,817 \times 10^{-34}\,\, \text{J} \cdot \text{s}$ | `reduced_planck_constant.hh` | `REDUCED_PLANCK_CONSTANT` |
| Speed of light | $c$ | $299\,792\,458\,\, \text{m} / \text{s}$ | `speed_of_light.hh` | `SPEED_OF_LIGHT` |

Our policy is to include only exactly defined constants with the library. This rules out many
useful constants, such as the universal gravitational constant $G$, the _new_ (post-2019) permeability
of free space $\mu_0$, and so on. For these, we can't reasonably provide values that will satisfy
all users at all times. However, defining custom constants for your own project is straightforward,
as we explain in the next section, and in our [how-to guide for custom
constants](../howto/new-constants.md).


## Constructing `Constant`

`Constant` encodes all information about the value in its type. Moreover, it has only a single
Expand Down
1 change: 1 addition & 0 deletions docs/reference/detail/monovalue_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Here are some canonical examples in Au.
| `Zero` | `ZERO` | Comparing to any `Quantity` |
| `Magnitude<>` | `ONE` | <ul><li>Equality comparison with other Magnitudes</li><li>`get_value<T>(ONE)`</li></ul> |
| `Radians` (and other units) | `Radians{}` (no special pre-formed instance) | Arithmetic with other units, such as `Radians{} / Meters{}` |
| `Constant<...>` | `SPEED_OF_LIGHT` | <ul><li>Comparing to any same-dimension `Quantity`</li><li>`Quantity` construction with exact conversion policy</li><li>zero-cost multiplying to change units/dimensions of numbers and `Quantity` instances</li></ul> |

## Switching between types and values {#switching}

Expand Down

0 comments on commit d5bbc6f

Please sign in to comment.