Skip to content

Commit

Permalink
Add almost all core SI units (#157)
Browse files Browse the repository at this point in the history
We get our units from the figure on this NIST page:
https://www.nist.gov/pml/owm/metric-si/si-units

Grammatically, we assume that `becquerel`, `lux`, and `tesla` have the
same plural form as the singular.

We avoid dealing with Sievert for now because I'm worried it would be
too error-prone.  A key goal is to avoid mixing it up with Gray.  A
quantity kind solution, such as the one which mp-units has, would be
ideal here.  Alternatively, we could experiment with defining a brand
new dimension for "absorbed dose equivalent", the same way that the SI
does for luminant quantities.  But in any case I think we should defer
this until we have actual use cases, and even then tread cautiously.

By contrast, I'm not especially worried about mixing up Becquerel,
Hertz, and inverse Seconds; I don't think it's likely to cause problems
in practice.
  • Loading branch information
chiphogg authored Jul 28, 2023
1 parent ae94dcc commit 3fa22a2
Show file tree
Hide file tree
Showing 16 changed files with 536 additions and 0 deletions.
35 changes: 35 additions & 0 deletions au/units/becquerel.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/quantity.hh"
#include "au/units/seconds.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct BecquerelLabel {
static constexpr const char label[] = "Bq";
};
template <typename T>
constexpr const char BecquerelLabel<T>::label[];
struct Becquerel : UnitInverseT<Seconds>, BecquerelLabel<void> {
using BecquerelLabel<void>::label;
};
constexpr auto becquerel = QuantityMaker<Becquerel>{};

} // namespace au
37 changes: 37 additions & 0 deletions au/units/farads.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/quantity.hh"
#include "au/units/coulombs.hh"
#include "au/units/volts.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct FaradsLabel {
static constexpr const char label[] = "F";
};
template <typename T>
constexpr const char FaradsLabel<T>::label[];
struct Farads : decltype(Coulombs{} / Volts{}), FaradsLabel<void> {
using FaradsLabel<void>::label;
};
constexpr auto farad = SingularNameFor<Farads>{};
constexpr auto farads = QuantityMaker<Farads>{};

} // namespace au
38 changes: 38 additions & 0 deletions au/units/grays.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/prefix.hh"
#include "au/quantity.hh"
#include "au/units/grams.hh"
#include "au/units/joules.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct GraysLabel {
static constexpr const char label[] = "Gy";
};
template <typename T>
constexpr const char GraysLabel<T>::label[];
struct Grays : decltype(Joules{} / Kilo<Grams>{}), GraysLabel<void> {
using GraysLabel<void>::label;
};
constexpr auto gray = SingularNameFor<Grays>{};
constexpr auto grays = QuantityMaker<Grays>{};

} // namespace au
37 changes: 37 additions & 0 deletions au/units/henries.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/quantity.hh"
#include "au/units/amperes.hh"
#include "au/units/webers.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct HenriesLabel {
static constexpr const char label[] = "H";
};
template <typename T>
constexpr const char HenriesLabel<T>::label[];
struct Henries : decltype(Webers{} / Amperes{}), HenriesLabel<void> {
using HenriesLabel<void>::label;
};
constexpr auto henry = SingularNameFor<Henries>{};
constexpr auto henries = QuantityMaker<Henries>{};

} // namespace au
36 changes: 36 additions & 0 deletions au/units/lux.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/quantity.hh"
#include "au/units/lumens.hh"
#include "au/units/meters.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct LuxLabel {
static constexpr const char label[] = "lx";
};
template <typename T>
constexpr const char LuxLabel<T>::label[];
struct Lux : decltype(Lumens{} / squared(Meters{})), LuxLabel<void> {
using LuxLabel<void>::label;
};
constexpr auto lux = QuantityMaker<Lux>{};

} // namespace au
36 changes: 36 additions & 0 deletions au/units/siemens.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/quantity.hh"
#include "au/units/ohms.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct SiemensLabel {
static constexpr const char label[] = "S";
};
template <typename T>
constexpr const char SiemensLabel<T>::label[];
struct Siemens : UnitInverseT<Ohms>, SiemensLabel<void> {
using SiemensLabel<void>::label;
};
constexpr auto siemen = SingularNameFor<Siemens>{};
constexpr auto siemens = QuantityMaker<Siemens>{};

} // namespace au
36 changes: 36 additions & 0 deletions au/units/tesla.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2022 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/quantity.hh"
#include "au/units/meters.hh"
#include "au/units/webers.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/howto/new-units).
template <typename T>
struct TeslaLabel {
static constexpr const char label[] = "T";
};
template <typename T>
constexpr const char TeslaLabel<T>::label[];
struct Tesla : decltype(Webers{} / squared(Meters{})), TeslaLabel<void> {
using TeslaLabel<void>::label;
};
constexpr auto tesla = QuantityMaker<Tesla>{};

} // namespace au
29 changes: 29 additions & 0 deletions au/units/test/becquerel_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "au/units/becquerel.hh"

#include "au/testing.hh"
#include "au/units/seconds.hh"
#include "gtest/gtest.h"

namespace au {

TEST(Becquerel, HasExpectedLabel) { expect_label<Becquerel>("Bq"); }

TEST(Becquerel, EquivalentToInverseSeconds) {
EXPECT_THAT(becquerel(4.0), QuantityEquivalent(inverse(seconds)(4.0)));
}

} // namespace au
30 changes: 30 additions & 0 deletions au/units/test/farads_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "au/units/farads.hh"

#include "au/testing.hh"
#include "au/units/coulombs.hh"
#include "au/units/volts.hh"
#include "gtest/gtest.h"

namespace au {

TEST(Farads, HasExpectedLabel) { expect_label<Farads>("F"); }

TEST(Farads, EquivalentToCoulombsPerVolt) {
EXPECT_THAT(farads(4.0), QuantityEquivalent(coulombs(8.0) / volts(2.0)));
}

} // namespace au
30 changes: 30 additions & 0 deletions au/units/test/grays_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "au/units/grays.hh"

#include "au/testing.hh"
#include "au/units/grams.hh"
#include "au/units/joules.hh"
#include "gtest/gtest.h"

namespace au {

TEST(Grays, HasExpectedLabel) { expect_label<Grays>("Gy"); }

TEST(Grays, EquivalentToJoulesPerKilogram) {
EXPECT_THAT(grays(4.0), QuantityEquivalent(joules(8.0) / kilo(grams)(2.0)));
}

} // namespace au
30 changes: 30 additions & 0 deletions au/units/test/henries_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "au/units/henries.hh"

#include "au/testing.hh"
#include "au/units/amperes.hh"
#include "au/units/webers.hh"
#include "gtest/gtest.h"

namespace au {

TEST(Henries, HasExpectedLabel) { expect_label<Henries>("H"); }

TEST(Henries, EquivalentToWebersPerAmpere) {
EXPECT_THAT(henries(4.0), QuantityEquivalent(webers(8.0) / amperes(2.0)));
}

} // namespace au
Loading

0 comments on commit 3fa22a2

Please sign in to comment.