Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document constants #340

Merged
merged 3 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading