diff --git a/.github/workflows/ci.bazelrc b/.github/workflows/ci.bazelrc index 6c7541e..542a28b 100644 --- a/.github/workflows/ci.bazelrc +++ b/.github/workflows/ci.bazelrc @@ -5,7 +5,6 @@ build --show_timestamps build --announce_rc build --color=yes build --terminal_columns=120 -build --remote_download_minimal build --curses=no test --test_output=errors diff --git a/BUILD.bazel b/BUILD.bazel index e7de441..7a39643 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -16,7 +16,9 @@ filegroup( cc_library( name = "geometry", - srcs = [], + srcs = [ + "geometry/src/algebra.hpp", + ], hdrs = ["geometry/geometry.hpp"], visibility = ["//visibility:public"], ) diff --git a/geometry/geometry.hpp b/geometry/geometry.hpp index 9ea2134..27fb55b 100644 --- a/geometry/geometry.hpp +++ b/geometry/geometry.hpp @@ -1,10 +1,3 @@ #pragma once -namespace geometry { - -constexpr auto dummy_function() -{ - return 0; -} - -} // namespace geometry +#include "geometry/src/algebra.hpp" diff --git a/geometry/src/algebra.hpp b/geometry/src/algebra.hpp new file mode 100644 index 0000000..fa79a2d --- /dev/null +++ b/geometry/src/algebra.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include +#include + +namespace geometry { + +template +struct algebra +{ + using scalar_type = S; + + template + struct blade + { + static_assert(sizeof...(Is) <= N + 1, "number of `Is` exceeds rank"); + static_assert(((Is <= N) and ...), "`Is` exceeds rank"); + // TODO check Is.. values are unique + + using algebra_type = algebra; + using scalar_type = typename algebra::scalar_type; + + static constexpr auto grade = sizeof...(Is); + + scalar_type coefficient{}; + + blade() = default; + + template = true> + constexpr blade(scalar_type a) : coefficient{a} + {} + template = true> + constexpr explicit blade(scalar_type a) : coefficient{a} + {} + + [[nodiscard]] + friend constexpr auto + operator==(blade x, blade y) noexcept -> bool + { + return x.coefficient == y.coefficient; + } + [[nodiscard]] + friend constexpr auto + operator!=(blade x, blade y) noexcept -> bool + { + return x.coefficient != y.coefficient; + } + [[nodiscard]] + friend constexpr auto + operator<(blade x, blade y) noexcept -> bool + { + return x.coefficient < y.coefficient; + } + [[nodiscard]] + friend constexpr auto + operator>(blade x, blade y) noexcept -> bool + { + return x.coefficient > y.coefficient; + } + [[nodiscard]] + friend constexpr auto + operator<=(blade x, blade y) noexcept -> bool + { + return x.coefficient <= y.coefficient; + } + [[nodiscard]] + friend constexpr auto + operator>=(blade x, blade y) noexcept -> bool + { + return x.coefficient >= y.coefficient; + } + + [[nodiscard]] + friend constexpr auto + operator-(blade x) -> blade + { + return blade{-x.coefficient}; + } + + [[nodiscard]] + friend constexpr auto + operator*(scalar_type a, blade x) -> blade + { + return blade{a * x.coefficient}; + } + [[nodiscard]] + friend constexpr auto + operator*(blade x, scalar_type a) -> blade + { + return a * x; + } + }; + + template + static constexpr auto e = blade{scalar_type{1}}; +}; + +} // namespace geometry diff --git a/test/BUILD.bazel b/test/BUILD.bazel index 7e5f5eb..7009c30 100644 --- a/test/BUILD.bazel +++ b/test/BUILD.bazel @@ -1,8 +1,8 @@ load("@rules_cc//cc:defs.bzl", "cc_test") cc_test( - name = "dummy_test", - srcs = ["dummy_test.cpp"], + name = "algebra_test", + srcs = ["algebra_test.cpp"], deps = [ "//:geometry", "@skytest", diff --git a/test/algebra_test.cpp b/test/algebra_test.cpp new file mode 100644 index 0000000..8283ea2 --- /dev/null +++ b/test/algebra_test.cpp @@ -0,0 +1,55 @@ +#include "geometry/geometry.hpp" +#include "skytest/skytest.hpp" + +#include +#include +#include + +template +constexpr auto e = ::geometry::algebra::e; + +constexpr auto unit_blades = std::tuple{ + ::geometry::algebra::e<>, + ::geometry::algebra::e<0>, + ::geometry::algebra::e<1>, + ::geometry::algebra::e<2>, + ::geometry::algebra::e<0, 1>, + ::geometry::algebra::e<0, 2>, + ::geometry::algebra::e<1, 2>, + ::geometry::algebra::e<0, 1, 2>}; + +auto main() -> int +{ + using namespace ::skytest::literals; + using ::skytest::eq; + using ::skytest::expect; + using ::skytest::param_ref; + + "0-blade implicitly constructible"_ctest = [] { + return expect( + eq(e<>, e<>) and // + eq(0, 0 * e<>) and // + eq(1, 1 * e<>) and // + eq(-1, -e<>)); + }; + + "grade 1+ blade explicitly constructible"_ctest * param_ref = // + [](auto ei) { + return expect( + ei.grade == 0 or // + not std::is_convertible_v); + }; + + "grade 0+ blades comparable"_ctest * param_ref = // + [](auto ei) { + using namespace ::skytest; + + return expect( + eq(ei, ei) and // + ne(0 * ei, ei) and // + lt(0 * ei, ei) and // + le(0 * ei, ei) and // + gt(ei, 0 * ei) and // + ge(ei, 0 * ei)); + }; +} diff --git a/test/dummy_test.cpp b/test/dummy_test.cpp deleted file mode 100644 index 16b196e..0000000 --- a/test/dummy_test.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "geometry/geometry.hpp" -#include "skytest/skytest.hpp" - -auto main() -> int -{ - using namespace ::skytest::literals; - using ::skytest::eq; - using ::skytest::expect; - - "dummy"_ctest = [] { return expect(eq(0, ::geometry::dummy_function())); }; -} diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel index baa187f..0d0febc 100644 --- a/tools/BUILD.bazel +++ b/tools/BUILD.bazel @@ -49,7 +49,7 @@ sh_binary( ) lcov_attrs = { - "instrumented_targets": ["//:skytest"], + "instrumented_targets": ["//:geometry"], "test_targets": ["//test/..."], "coverage_opts": [ "--combined_report=lcov",