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

Add machinery for built-in constants, such as c #335

Merged
merged 2 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
6 changes: 5 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ BASE_UNIT_STRING = " ".join(BASE_UNITS)

GIT_ID_CMD = "cat bazel-out/stable-status.txt | grep STABLE_GIT_ID | sed 's/STABLE_GIT_ID \\(.*\\)/\\1/' | tr -d '\\n'"

CMD_ROOT = "$(location tools/bin/make-single-file) {extra_opts} {units} --version-id $$({id_cmd}) > $(OUTS)"
CMD_ROOT = "$(location tools/bin/make-single-file) {extra_opts} {units} {all_constants} --version-id $$({id_cmd}) > $(OUTS)"

################################################################################
# Release single-file package `au.hh`
Expand All @@ -86,6 +86,7 @@ genrule(
srcs = ["//au:headers"],
outs = ["docs/au.hh"],
cmd = CMD_ROOT.format(
all_constants = "",
extra_opts = "",
id_cmd = GIT_ID_CMD,
units = "--units " + BASE_UNIT_STRING,
Expand All @@ -108,6 +109,7 @@ genrule(
srcs = ["//au:headers"],
outs = ["docs/au_noio.hh"],
cmd = CMD_ROOT.format(
all_constants = "",
extra_opts = "--noio",
id_cmd = GIT_ID_CMD,
units = "--units " + BASE_UNIT_STRING,
Expand All @@ -131,6 +133,7 @@ genrule(
srcs = ["//au:headers"],
outs = ["docs/au_all_units.hh"],
cmd = CMD_ROOT.format(
all_constants = "--all-constants",
extra_opts = "",
id_cmd = GIT_ID_CMD,
units = "--all-units",
Expand All @@ -153,6 +156,7 @@ genrule(
srcs = ["//au:headers"],
outs = ["docs/au_all_units_noio.hh"],
cmd = CMD_ROOT.format(
all_constants = "--all-constants",
extra_opts = "--noio",
id_cmd = GIT_ID_CMD,
units = "--all-units",
Expand Down
6 changes: 3 additions & 3 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ keep track of the main changes as you go. Use the following categories.

- User-facing library changes
- If the compilation speed has been significantly impacted, mention this here.
- New units
- New units and constants
- Tooling updates
- Documentation updates
- Repo updates
Expand Down Expand Up @@ -78,8 +78,8 @@ Release Notes
User-facing library changes
---------------------------

New units
---------
New units and constants
-----------------------

Tooling updates
---------------
Expand Down
23 changes: 23 additions & 0 deletions au/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ cc_test(
],
)

cc_library(
name = "constants",
hdrs = glob(["code/au/constants/*.hh"]),
includes = ["code"],
visibility = ["//visibility:public"],
deps = [
":constant",
":units",
],
)

cc_test(
name = "constants_test",
size = "small",
srcs = glob(["code/au/constants/test/*.cc"]),
deps = [
":constants",
":testing",
":units",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "fwd",
hdrs = ["code/au/fwd.hh"],
Expand Down
10 changes: 10 additions & 0 deletions au/code/au/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ header_only_library(
unit_symbol.hh
wrapper_operations.hh
zero.hh
constants/speed_of_light.hh
stdx/experimental/is_detected.hh
stdx/functional.hh
stdx/type_traits.hh
Expand Down Expand Up @@ -220,6 +221,15 @@ gtest_based_test(
testing
)

gtest_based_test(
NAME constants_test
SRCS
constants/test/speed_of_light_test.cc
DEPS
au
testing
)

gtest_based_test(
NAME io_test
SRCS
Expand Down
1 change: 0 additions & 1 deletion au/code/au/constant.hh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#include "au/fwd.hh"
#include "au/quantity.hh"
#include "au/quantity_point.hh"
#include "au/stdx/type_traits.hh"
#include "au/unit_of_measure.hh"
#include "au/wrapper_operations.hh"
Expand Down
38 changes: 38 additions & 0 deletions au/code/au/constants/speed_of_light.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2024 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/constant.hh"
#include "au/units/meters.hh"
#include "au/units/seconds.hh"

namespace au {

namespace detail {
// 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 <typename T>
struct SpeedOfLightLabel {
static constexpr const char label[] = "c";
};
template <typename T>
constexpr const char SpeedOfLightLabel<T>::label[];
struct SpeedOfLightUnit : decltype(Meters{} / Seconds{} * mag<299'792'458>()),
SpeedOfLightLabel<void> {
using SpeedOfLightLabel<void>::label;
};
} // namespace detail

constexpr auto SPEED_OF_LIGHT = make_constant(detail::SpeedOfLightUnit{});

} // namespace au
36 changes: 36 additions & 0 deletions au/code/au/constants/test/speed_of_light_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2024 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/constants/speed_of_light.hh"

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

namespace au {
namespace {

using symbols::m;
using symbols::s;
using ::testing::StrEq;

TEST(SpeedOfLight, HasExpectedValue) {
EXPECT_THAT(SPEED_OF_LIGHT.as<int>(m / s), SameTypeAndValue(299'792'458 * m / s));
}

TEST(SpeedOfLight, HasExpectedLabel) { EXPECT_THAT(unit_label(SPEED_OF_LIGHT), StrEq("c")); }

} // namespace
} // namespace au
66 changes: 51 additions & 15 deletions tools/bin/make-single-file
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,32 @@ def main(argv=None):
transitively included files which are within the project, but we leave other
`#include` directives (such as standard library headers) untouched.
"""
args = enumerate_units(parse_command_line_args(argv))
args = enumerate_units_and_constants(parse_command_line_args(argv))
files = parse_files(
filenames=filenames(
main_files=args.main_files, units=args.units, include_io=args.include_io
main_files=args.main_files,
units=args.units,
constants=args.constants,
include_io=args.include_io,
)
)
print_unified_file(files, args=args)

return 0


def filenames(main_files, units, include_io):
def filenames(main_files, units, constants, include_io):
"""Construct the list of project filenames to include.

The script will be sure to include all of these, and will also include any
transitive dependencies from within the project.
"""
names = ["au/au.hh"] + [f"au/units/{unit}.hh" for unit in units] + main_files
names = (
["au/au.hh"]
+ [f"au/units/{u}.hh" for u in units]
+ [f"au/constants/{c.lower()}.hh" for c in constants]
+ main_files
)
if include_io:
names.append("au/io.hh")
return names
Expand All @@ -85,6 +93,16 @@ def parse_command_line_args(argv):
help="Include all units (may slow compilation!)",
)

constant_group = parser.add_mutually_exclusive_group(required=False)
constant_group.add_argument(
"--constants", nargs="*", default=[], help="The constants to include"
)
constant_group.add_argument(
"--all-constants",
action="store_true",
help="Include all constants (may slow compilation!)",
)

parser.add_argument(
"--version-id",
default=git_id_description(),
Expand All @@ -101,17 +119,30 @@ def parse_command_line_args(argv):
return parser.parse_args()


def enumerate_units(args):
def enumerate_units_and_constants(args):
"""
Massage args object so that it's "as if" user had specified all units manually.
Massage args object so that it's "as if" user had specified all units/constants manually.

This means that if `--all-units` is specified, we populate the `units` list
with every existing entry, and then delete `--all-units`.
This means that if `--all-units` is specified, we populate the `units` list with every existing
entry, and then delete `--all-units`, and similarly for `--all-constants`.
"""
if args.all_units:
args.units = [f[:-3] for f in os.listdir("au/code/au/units/") if f.endswith(".hh")]
def looks_like_header(f):
return f.endswith(".hh") and not f.endswith("_fwd.hh")

if args.all_units:
args.units = [
f[:-3] for f in os.listdir("au/code/au/units/") if looks_like_header(f)
]
del args.all_units

if args.all_constants:
args.constants = [
f[:-3].upper()
for f in os.listdir("au/code/au/constants/")
if looks_like_header(f)
]
del args.all_constants

return args


Expand Down Expand Up @@ -247,11 +278,16 @@ def manifest(args):
"""A sequence of lines describing the options that generated this file."""
args = CheckArgs(args)

lines = [
f"Version identifier: {args.version_id}",
f'<iostream> support: {"INCLUDED" if args.include_io else "EXCLUDED"}',
"List of included units:",
] + [f" {u}" for u in sorted(args.units)]
lines = (
[
f"Version identifier: {args.version_id}",
f'<iostream> support: {"INCLUDED" if args.include_io else "EXCLUDED"}',
"List of included units:",
]
+ [f" {u}" for u in sorted(args.units)]
+ ["List of included constants:"]
+ [f" {c}" for c in sorted(args.constants)]
)

if args.main_files:
lines.append("Extra files included:")
Expand Down