Skip to content

Commit

Permalink
Copy over core units library code (#10)
Browse files Browse the repository at this point in the history
We decomposed this PR into commits for reviewability.

The first commit simply copies the files over, and gets all the targets
to build.

The second commit fixes the bugs we found:

- Can't assume `std::chrono::nanoseconds` uses `int64_t`
- We were missing explicit specializations for cv-qualified `Quantity`
- `isnan()` was never `constexpr`---why did this ever work before?
- template template parameters need to say `class`, not `typename`

The third and final commit clarifies which targets are for public
consumption.
  • Loading branch information
chiphogg authored Nov 17, 2022
1 parent b8dc348 commit 294bdba
Show file tree
Hide file tree
Showing 32 changed files with 8,777 additions and 1 deletion.
322 changes: 321 additions & 1 deletion au/BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,280 @@
# Aurora Innovation, Inc. Proprietary and Confidential. Copyright 2022.

load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_cc//cc:defs.bzl", "cc_library")

################################################################################
# Public libraries and tests

cc_library(
name = "au",
hdrs = ["au.hh"],
visibility = ["//visibility:public"],
deps = [":math"],
)

cc_test(
name = "au_test",
size = "small",
srcs = ["au_test.cc"],
deps = [
":au",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "io",
hdrs = ["io.hh"],
visibility = ["//visibility:public"],
deps = [
":quantity",
":quantity_point",
":zero",
],
)

cc_test(
name = "io_test",
size = "small",
srcs = ["io_test.cc"],
deps = [
":io",
":prefix",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "testing",
testonly = True,
hdrs = ["testing.hh"],
visibility = ["//visibility:public"],
deps = [
":io",
":stdx",
":unit_of_measure",
],
)

cc_test(
name = "testing_test",
size = "small",
srcs = ["testing_test.cc"],
deps = [
":testing",
"@com_google_googletest//:gtest_main",
],
)

################################################################################
# Implementation detail libraries and tests

cc_library(
name = "chrono_policy_validation",
testonly = True,
hdrs = ["chrono_policy_validation.hh"],
deps = [
":dimension",
":quantity",
":stdx",
":unit_of_measure",
"@com_google_googletest//:gtest",
],
)

cc_test(
name = "chrono_policy_validation_test",
size = "small",
srcs = ["chrono_policy_validation_test.cc"],
deps = [
":chrono_policy_validation",
":prefix",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "operators",
hdrs = ["operators.hh"],
)

cc_test(
name = "operators_test",
size = "small",
srcs = ["operators_test.cc"],
deps = [
":operators",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "conversion_policy",
hdrs = ["conversion_policy.hh"],
deps = [
":magnitude",
":stdx",
":unit_of_measure",
],
)

cc_test(
name = "conversion_policy_test",
size = "small",
srcs = ["conversion_policy_test.cc"],
deps = [
":conversion_policy",
":unit_of_measure",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "dimension",
hdrs = ["dimension.hh"],
deps = [":packs"],
)

cc_test(
name = "dimension_test",
size = "small",
srcs = ["dimension_test.cc"],
deps = [
":dimension",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "magnitude",
hdrs = ["magnitude.hh"],
deps = [
":packs",
":stdx",
":utility",
":zero",
],
)

cc_test(
name = "magnitude_test",
size = "small",
srcs = ["magnitude_test.cc"],
deps = [
":magnitude",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "math",
hdrs = ["math.hh"],
deps = [":units"],
)

cc_test(
name = "math_test",
size = "small",
srcs = ["math_test.cc"],
deps = [
":math",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "packs",
hdrs = ["packs.hh"],
deps = [
":stdx",
":utility",
],
)

cc_test(
name = "packs_test",
size = "small",
srcs = ["packs_test.cc"],
deps = [
":packs",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "prefix",
hdrs = ["prefix.hh"],
deps = [
":quantity",
":quantity_point",
":unit_of_measure",
],
)

cc_test(
name = "prefix_test",
size = "small",
srcs = ["prefix_test.cc"],
deps = [
":prefix",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "quantity",
hdrs = ["quantity.hh"],
deps = [
":conversion_policy",
":operators",
":unit_of_measure",
":zero",
],
)

cc_test(
name = "quantity_test",
size = "small",
srcs = [
"quantity_chrono_policy_correspondence_test.cc",
"quantity_test.cc",
],
deps = [
":chrono_policy_validation",
":prefix",
":quantity",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "quantity_point",
hdrs = ["quantity_point.hh"],
deps = [
":quantity",
":stdx",
":utility",
],
)

cc_test(
name = "quantity_point_test",
size = "small",
srcs = ["quantity_point_test.cc"],
deps = [
":prefix",
":quantity_point",
":testing",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "stdx",
Expand All @@ -24,6 +298,52 @@ cc_test(
],
)

cc_library(
name = "unit_of_measure",
hdrs = ["unit_of_measure.hh"],
deps = [
":dimension",
":magnitude",
":stdx",
":utility",
":zero",
],
)

cc_test(
name = "unit_of_measure_test",
size = "small",
srcs = ["unit_of_measure_test.cc"],
deps = [
":prefix",
":testing",
":unit_of_measure",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "units",
hdrs = ["units.hh"],
deps = [
":prefix",
":quantity",
":quantity_point",
":unit_of_measure",
],
)

cc_test(
name = "units_test",
size = "small",
srcs = ["units_test.cc"],
deps = [
":testing",
":units",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "utility",
hdrs = glob(["utility/*.hh"]),
Expand Down
23 changes: 23 additions & 0 deletions au/au.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Aurora Innovation, Inc. Proprietary and Confidential. Copyright 2022.

#pragma once

#include <chrono>

#include "au/math.hh"

namespace au {

// Define 1:1 mapping between duration types of chrono library and our library.
template <typename RepT, typename Period>
struct CorrespondingQuantity<std::chrono::duration<RepT, Period>> {
using Unit = decltype(Seconds{} * (mag<Period::num>() / mag<Period::den>()));
using Rep = RepT;

using ChronoDuration = std::chrono::duration<Rep, Period>;

static constexpr Rep extract_value(ChronoDuration d) { return d.count(); }
static constexpr ChronoDuration construct_from_value(Rep x) { return ChronoDuration{x}; }
};

} // namespace au
37 changes: 37 additions & 0 deletions au/au_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Aurora Innovation, Inc. Proprietary and Confidential. Copyright 2022.

#include "au/au.hh"

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

using ::testing::StaticAssertTypeEq;

using namespace std::chrono_literals;

namespace au {

TEST(DurationQuantity, InterconvertsWithExactlyEquivalentChronoDuration) {
constexpr QuantityD<Seconds> from_chrono = std::chrono::duration<double>{1.23};
EXPECT_THAT(from_chrono, SameTypeAndValue(seconds(1.23)));

constexpr auto val = std::chrono::nanoseconds::rep{456};
constexpr std::chrono::nanoseconds from_au = nano(seconds)(val);
EXPECT_THAT(from_au.count(), SameTypeAndValue(val));
}

TEST(DurationQuantity, InterconvertsWithIndirectlyEquivalentChronoDuration) {
constexpr QuantityD<Seconds> from_chrono = as_quantity(1234ms);
EXPECT_THAT(from_chrono, SameTypeAndValue(seconds(1.234)));
}

TEST(Conversions, SupportIntMHzToU32Hz) {
constexpr QuantityU32<Hertz> freq = mega(hertz)(40);
EXPECT_THAT(freq, SameTypeAndValue(hertz(40'000'000u)));
}

TEST(CommonUnit, HandlesPrefixesReasonably) {
StaticAssertTypeEq<CommonUnitT<Kilo<Meters>, Meters>, Meters>();
}

} // namespace au
Loading

0 comments on commit 294bdba

Please sign in to comment.