Skip to content

Commit

Permalink
Add mp-units units library
Browse files Browse the repository at this point in the history
Add a units library [0] to allow compile-time dimensional analysis. This
commit adds the README example as a unit test.

[0] https://github.com/mpusz/mp-units

Change-Id: I74eb111e2df7c65881e0ba893a3de58b2ebc8512
  • Loading branch information
oliverlee committed Jul 24, 2023
1 parent 4536c8a commit 9f4cab9
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ Checks: >
# https://reviews.llvm.org/D95714?id=320393,
-modernize-use-nullptr,
# segfaults with mp-units,
-modernize-use-trailing-return-type,
# disable common aliases,
-cppcoreguidelines-avoid-c-arrays,
-cppcoreguidelines-avoid-magic-numbers,
Expand Down
64 changes: 64 additions & 0 deletions WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,70 @@ cc_library(
url = "https://github.com/kokkos/stdblas/archive/%s.tar.gz" % LINALG_VERSION,
)

GSL_LITE_VERSION = "a8c7e5bbbd08841836f9b92d72747fb8769dbec4"

http_archive(
name = "gsl_lite",
build_file_content = """
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "gsl_lite",
hdrs = ["include/gsl/gsl-lite.hpp"],
includes = ["include"],
visibility = ["//visibility:public"],
)
""",
sha256 = "f9edeec2b517dbb57c5688150db56c90f5c4922ef8aa8d15cfe532fa42058792",
strip_prefix = "gsl-lite-%s" % GSL_LITE_VERSION,
url = "https://github.com/gsl-lite/gsl-lite/archive/%s.tar.gz" % GSL_LITE_VERSION,
)

MP_UNITS_VERSION = "60a564a86700804e306f0d73a1521ea6e4abe377"

http_archive(
name = "mp_units",
build_file_content = """
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "mp_units",
hdrs = glob(["src/**"]),
includes = [
"src/core-fmt/include",
"src/core-io/include",
"src/core/include",
"src/systems/angular/include",
"src/systems/cgs/include",
"src/systems/hep/include",
"src/systems/iau/include",
"src/systems/iec80000/include",
"src/systems/imperial/include",
"src/systems/international/include",
"src/systems/isq/include",
"src/systems/isq_angle/include",
"src/systems/natural/include",
"src/systems/si/include",
"src/systems/typographic/include",
"src/systems/usc/include",
"src/utility/include",
],
deps = [
"@gsl_lite",
],
visibility = ["//visibility:public"],
)
""",
# Fix Clang builds by defining constructor as public
# https://github.com/mpusz/mp-units/issues/473
#
patch_args = ["-p1"],
patches = ["//third_party:mp-units-clang-priv-ctor.patch"],
sha256 = "2c48171815909da836300d50a40e396412cb4881794b4cb5d13dcef858c46da1",
strip_prefix = "mp-units-%s" % MP_UNITS_VERSION,
url = "https://github.com/mpusz/mp-units/archive/%s.tar.gz" % MP_UNITS_VERSION,
)

BOOST_UT_VERSION = "e53a47d37bc594e80bd5f1b8dc1ade8dce4429d3"

http_archive(
Expand Down
11 changes: 11 additions & 0 deletions test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,14 @@ cc_test(
"@mdspan",
],
)

cc_test(
name = "units_test",
timeout = "short",
srcs = ["units_test.cpp"],
deps = [
"@boost_ut",
"@fmt",
"@mp_units",
],
)
51 changes: 51 additions & 0 deletions test/units_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <boost/ut.hpp>

#include <fmt/core.h>
#include <mp-units/format.h>
#include <mp-units/ostream.h>
#include <mp-units/systems/international/international.h>
#include <mp-units/systems/isq/space_and_time.h>
#include <mp-units/systems/si/si.h>
#include <sstream>

using namespace mp_units;

constexpr QuantityOf<isq::speed> auto
avg_speed(QuantityOf<isq::length> auto d, QuantityOf<isq::time> auto t)
{
return d / t;
}

constexpr auto to_string(const auto& value)
{
auto ss = std::stringstream{};
ss << value;
return ss.str();
}

auto main() -> int
{
using ::boost::ut::expect;
using ::boost::ut::test;

test("units example") = [] {
using namespace mp_units::si::unit_symbols;
using namespace mp_units::international::unit_symbols;

constexpr auto v1 = 110 * (km / h);
constexpr auto v2 = 70 * mph;
constexpr auto v3 = avg_speed(220. * isq::distance[km], 2 * h);
constexpr auto v4 = avg_speed(isq::distance(140. * mi), 2 * h);
constexpr auto v5 = v3[m / s];
constexpr auto v6 = value_cast<m / s>(v4);
constexpr auto v7 = value_cast<int>(v6);

expect("110 km/h" == to_string(v1));
expect("70 mi/h" == to_string(v2));
expect("110 km/h" == fmt::format("{}", v3));
expect("***70 mi/h****" == fmt::format("{:*^14}", v4));
expect("30.5556 in m/s" == fmt::format("{:%Q in %q}", v5));
expect("31.2928 in m/s" == fmt::format("{0:%Q} in {0:%q}", v6));
expect("31" == fmt::format("{:%Q}", v7));
};
}
1 change: 1 addition & 0 deletions third_party/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports_files(["mp-units-clang-priv-ctor.patch"])
12 changes: 12 additions & 0 deletions third_party/mp-units-clang-priv-ctor.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/src/core/include/mp-units/quantity.h b/src/core/include/mp-units/quantity.h
index 3d3642b3..5e16eff4 100644
--- a/src/core/include/mp-units/quantity.h
+++ b/src/core/include/mp-units/quantity.h
@@ -321,6 +321,7 @@ private:
requires quantity<R2, std::remove_cvref_t<Rep2>>::_rep_safe_constructible_
friend constexpr quantity<R2, std::remove_cvref_t<Rep2>> make_quantity(Rep2&&);

+public:
template<typename Value>
requires detail::RepSafeConstructibleFrom<rep, Value&&, unit>
constexpr explicit quantity(Value&& v) : number_(std::forward<Value>(v))

0 comments on commit 9f4cab9

Please sign in to comment.