diff --git a/au/code/au/CMakeLists.txt b/au/code/au/CMakeLists.txt index 7c518bf4..d9fbcd7b 100644 --- a/au/code/au/CMakeLists.txt +++ b/au/code/au/CMakeLists.txt @@ -59,6 +59,10 @@ header_only_library( stdx/utility.hh units/amperes.hh units/amperes_fwd.hh + units/arcminutes.hh + units/arcminutes_fwd.hh + units/arcseconds.hh + units/arcseconds_fwd.hh units/bars.hh units/bars_fwd.hh units/becquerel.hh @@ -306,6 +310,8 @@ gtest_based_test( NAME units_test SRCS units/test/amperes_test.cc + units/test/arcminutes_test.cc + units/test/arcseconds_test.cc units/test/bars_test.cc units/test/becquerel_test.cc units/test/bits_test.cc diff --git a/au/code/au/au_test.cc b/au/code/au/au_test.cc index d92a7504..b25c229e 100644 --- a/au/code/au/au_test.cc +++ b/au/code/au/au_test.cc @@ -14,8 +14,10 @@ #include "au/au.hh" +#include "au/constants/speed_of_light.hh" #include "au/prefix.hh" #include "au/testing.hh" +#include "au/units/arcminutes.hh" #include "au/units/celsius.hh" #include "au/units/fahrenheit.hh" #include "au/units/fathoms.hh" @@ -26,12 +28,19 @@ #include "au/units/knots.hh" #include "au/units/meters.hh" #include "au/units/miles.hh" +#include "au/units/steradians.hh" #include "au/units/yards.hh" #include "gtest/gtest.h" using ::testing::StaticAssertTypeEq; namespace au { +namespace { +template +auto IsBetween(T lower, U upper) { + return ::testing::AllOf(::testing::Ge(lower), ::testing::Le(upper)); +} +} // namespace TEST(Conversions, SupportIntMHzToU32Hz) { constexpr QuantityU32 freq = mega(hertz)(40); @@ -54,7 +63,7 @@ constexpr auto round_sequentially(Quantity q, FirstUnit first_unit, NextUn return round_sequentially(round_as(first_unit, q), next_units...); } -TEST(RoundAs, ReproducesXkcd2585) { +TEST(Xkcd, RoundAsReproducesXkcd2585) { constexpr auto true_speed = (miles / hour)(17); const auto rounded_speed = round_sequentially(true_speed, @@ -86,6 +95,16 @@ TEST(RoundAs, ReproducesXkcd2585) { EXPECT_EQ((miles / hour)(45), rounded_speed); } +TEST(Xkcd, Xkcd3038GivesReasonableSpeedLimit) { + using symbols::h; + using symbols::mi; + + constexpr auto c = SPEED_OF_LIGHT; + constexpr auto SPEED_LIMIT = make_constant(c * squared(arcminutes) / steradian); + + EXPECT_THAT(SPEED_LIMIT, IsBetween(25.0 * mi / h, 75.0 * mi / h)); +} + TEST(QuantityPoint, DocumentationExampleIsCorrect) { EXPECT_LT(fahrenheit_pt(-40) + celsius_qty(60), kelvins_pt(300)); } diff --git a/au/code/au/units/arcminutes.hh b/au/code/au/units/arcminutes.hh new file mode 100644 index 00000000..87d48f0b --- /dev/null +++ b/au/code/au/units/arcminutes.hh @@ -0,0 +1,44 @@ +// Copyright 2025 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/units/arcminutes_fwd.hh" +// Keep corresponding `_fwd.hh` file on top. + +#include "au/quantity.hh" +#include "au/unit_symbol.hh" +#include "au/units/degrees.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/main/howto/new-units/). +template +struct ArcminutesLabel { + static constexpr const char label[] = "'"; +}; +template +constexpr const char ArcminutesLabel::label[]; +struct Arcminutes : decltype(Degrees{} / mag<60>()), ArcminutesLabel { + using ArcminutesLabel::label; +}; +constexpr auto arcminute = SingularNameFor{}; +constexpr auto arcminutes = QuantityMaker{}; + +namespace symbols { +constexpr auto am = SymbolFor{}; +} + +} // namespace au diff --git a/au/code/au/units/arcminutes_fwd.hh b/au/code/au/units/arcminutes_fwd.hh new file mode 100644 index 00000000..3d411dab --- /dev/null +++ b/au/code/au/units/arcminutes_fwd.hh @@ -0,0 +1,21 @@ +// Copyright 2025 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 + +namespace au { + +struct Arcminutes; + +} // namespace au diff --git a/au/code/au/units/arcseconds.hh b/au/code/au/units/arcseconds.hh new file mode 100644 index 00000000..dc77fa92 --- /dev/null +++ b/au/code/au/units/arcseconds.hh @@ -0,0 +1,44 @@ +// Copyright 2025 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/units/arcseconds_fwd.hh" +// Keep corresponding `_fwd.hh` file on top. + +#include "au/quantity.hh" +#include "au/unit_symbol.hh" +#include "au/units/degrees.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/main/howto/new-units/). +template +struct ArcsecondsLabel { + static constexpr const char label[] = "\""; +}; +template +constexpr const char ArcsecondsLabel::label[]; +struct Arcseconds : decltype(Degrees{} / mag<3600>()), ArcsecondsLabel { + using ArcsecondsLabel::label; +}; +constexpr auto arcsecond = SingularNameFor{}; +constexpr auto arcseconds = QuantityMaker{}; + +namespace symbols { +constexpr auto as = SymbolFor{}; +} + +} // namespace au diff --git a/au/code/au/units/arcseconds_fwd.hh b/au/code/au/units/arcseconds_fwd.hh new file mode 100644 index 00000000..61334839 --- /dev/null +++ b/au/code/au/units/arcseconds_fwd.hh @@ -0,0 +1,21 @@ +// Copyright 2025 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 + +namespace au { + +struct Arcseconds; + +} // namespace au diff --git a/au/code/au/units/test/arcminutes_test.cc b/au/code/au/units/test/arcminutes_test.cc new file mode 100644 index 00000000..6d7f97c4 --- /dev/null +++ b/au/code/au/units/test/arcminutes_test.cc @@ -0,0 +1,34 @@ +// Copyright 2025 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/arcminutes.hh" + +#include "au/testing.hh" +#include "au/units/degrees.hh" +#include "gtest/gtest.h" + +namespace au { + +TEST(Arcseconds, HasExpectedLabel) { expect_label("'"); } + +TEST(Arcseconds, RelatesCorrectlyToDegrees) { + EXPECT_THAT(arcseconds(120.0), QuantityEquivalent(degrees(2.0))); +} + +TEST(Arcseconds, HasExpectedSymbol) { + using symbols::am; + EXPECT_THAT(5.f * am, SameTypeAndValue(arcminutes(5.f))); +} + +} // namespace au diff --git a/au/code/au/units/test/arcseconds_test.cc b/au/code/au/units/test/arcseconds_test.cc new file mode 100644 index 00000000..6eb0d94d --- /dev/null +++ b/au/code/au/units/test/arcseconds_test.cc @@ -0,0 +1,34 @@ +// Copyright 2025 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/arcseconds.hh" + +#include "au/testing.hh" +#include "au/units/degrees.hh" +#include "gtest/gtest.h" + +namespace au { + +TEST(Arcseconds, HasExpectedLabel) { expect_label("\""); } + +TEST(Arcseconds, RelatesCorrectlyToDegrees) { + EXPECT_THAT(arcseconds(7200.0), QuantityEquivalent(degrees(2.0))); +} + +TEST(Arcseconds, HasExpectedSymbol) { + using symbols::as; + EXPECT_THAT(5.f * as, SameTypeAndValue(arcseconds(5.f))); +} + +} // namespace au