Skip to content

Commit

Permalink
Add a concept quantity and use it in Multivector
Browse files Browse the repository at this point in the history
  • Loading branch information
eggrobin committed Mar 23, 2024
1 parent 894ef4f commit d0008af
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 44 deletions.
5 changes: 5 additions & 0 deletions base/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ using internal::all_different_v;
template<template<typename...> typename T, typename U>
inline constexpr bool is_instance_of_v = internal::is_instance_of<T, U>::value;

// Note the argument inversion so that we can use instance_of<T> in a requires
// clause.
template<typename U, template<typename...> typename T>
concept instance_of = is_instance_of_v<T, U>;

// True if and only if T and U are the same template.
template<template<typename...> typename T, template<typename...> typename U>
inline constexpr bool is_same_template_v =
Expand Down
18 changes: 9 additions & 9 deletions geometry/grassmann.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ using namespace principia::quantities::_quantities;
// ⋀ⁿ Scalar³. Do not use this type for |rank == 0| (scalars), use the |Scalar|
// type directly instead.
// |Frame| represents a reference frame together with an orthonormal basis.
template<typename Scalar, typename Frame, int rank>
template<quantity Scalar, typename Frame, int rank>
class Multivector;

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
class Multivector<Scalar, Frame, 1> final {
public:
static constexpr int dimension = 3;
Expand Down Expand Up @@ -66,11 +66,11 @@ class Multivector<Scalar, Frame, 1> final {
private:
R3Element<Scalar> coordinates_;

template<typename S, typename F, int r>
template<quantity S, typename F, int r>
friend class Multivector;
};

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
class Multivector<Scalar, Frame, 2> final {
public:
static constexpr int dimension = 3;
Expand Down Expand Up @@ -103,11 +103,11 @@ class Multivector<Scalar, Frame, 2> final {
private:
R3Element<Scalar> coordinates_;

template<typename S, typename F, int r>
template<quantity S, typename F, int r>
friend class Multivector;
};

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
class Multivector<Scalar, Frame, 3> final {
public:
static constexpr int dimension = 1;
Expand Down Expand Up @@ -137,11 +137,11 @@ class Multivector<Scalar, Frame, 3> final {
Scalar coordinates_;
};

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
using Vector = Multivector<Scalar, Frame, 1>;
template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
using Bivector = Multivector<Scalar, Frame, 2>;
template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
using Trivector = Multivector<Scalar, Frame, 3>;

template<typename LScalar, typename RScalar, typename Frame>
Expand Down
64 changes: 32 additions & 32 deletions geometry/grassmann_body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,149 +17,149 @@ using namespace principia::base::_not_constructible;
using namespace principia::geometry::_sign;
using namespace principia::quantities::_elementary_functions;

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 1>::Multivector(R3Element<Scalar> const& coordinates)
: coordinates_(coordinates) {}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 2>::Multivector(R3Element<Scalar> const& coordinates)
: coordinates_(coordinates) {}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 3>::Multivector(Scalar const& coordinates)
: coordinates_(coordinates) {}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 1>& Multivector<Scalar, Frame, 1>::operator+=(
Multivector const& right) {
coordinates_ += right.coordinates_;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 1>& Multivector<Scalar, Frame, 1>::operator-=(
Multivector const& right) {
coordinates_ -= right.coordinates_;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 1>& Multivector<Scalar, Frame, 1>::operator*=(
double const right) {
coordinates_ *= right;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 1>& Multivector<Scalar, Frame, 1>::operator/=(
double const right) {
coordinates_ /= right;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 2>& Multivector<Scalar, Frame, 2>::operator+=(
Multivector const& right) {
coordinates_ += right.coordinates_;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 2>& Multivector<Scalar, Frame, 2>::operator-=(
Multivector const& right) {
coordinates_ -= right.coordinates_;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 2>& Multivector<Scalar, Frame, 2>::operator*=(
double const right) {
coordinates_ *= right;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 2>& Multivector<Scalar, Frame, 2>::operator/=(
double const right) {
coordinates_ /= right;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 3>& Multivector<Scalar, Frame, 3>::operator+=(
Multivector const& right) {
coordinates_ += right.coordinates_;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 3>& Multivector<Scalar, Frame, 3>::operator-=(
Multivector const& right) {
coordinates_ -= right.coordinates_;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 3>& Multivector<Scalar, Frame, 3>::operator*=(
double const right) {
coordinates_ *= right;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 3>& Multivector<Scalar, Frame, 3>::operator/=(
double const right) {
coordinates_ /= right;
return *this;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
R3Element<Scalar> const& Multivector<Scalar, Frame, 1>::coordinates() const {
return coordinates_;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
R3Element<Scalar> const& Multivector<Scalar, Frame, 2>::coordinates() const {
return coordinates_;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Scalar const& Multivector<Scalar, Frame, 3>::coordinates() const {
return coordinates_;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Scalar Multivector<Scalar, Frame, 1>::Norm() const {
return coordinates_.Norm();
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Scalar Multivector<Scalar, Frame, 2>::Norm() const {
return coordinates_.Norm();
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Scalar Multivector<Scalar, Frame, 3>::Norm() const {
// When |Scalar| is double, ADL will not find |Abs|.
return Abs(coordinates_);
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Square<Scalar> Multivector<Scalar, Frame, 1>::Norm²() const {
return coordinates_.Norm²();
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Square<Scalar> Multivector<Scalar, Frame, 2>::Norm²() const {
return coordinates_.Norm²();
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Square<Scalar> Multivector<Scalar, Frame, 3>::Norm²() const {
return coordinates_ * coordinates_;
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
template<typename S>
Multivector<Scalar, Frame, 1>
Multivector<Scalar, Frame, 1>::OrthogonalizationAgainst(
Expand All @@ -168,7 +168,7 @@ Multivector<Scalar, Frame, 1>::OrthogonalizationAgainst(
coordinates_.OrthogonalizationAgainst(multivector.coordinates_));
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
template<typename S>
Multivector<Scalar, Frame, 2>
Multivector<Scalar, Frame, 2>::OrthogonalizationAgainst(
Expand All @@ -177,28 +177,28 @@ Multivector<Scalar, Frame, 2>::OrthogonalizationAgainst(
coordinates_.OrthogonalizationAgainst(multivector.coordinates_));
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
void Multivector<Scalar, Frame, 1>::WriteToMessage(
not_null<serialization::Multivector*> const message) const {
Frame::WriteToMessage(message->mutable_frame());
coordinates_.WriteToMessage(message->mutable_vector());
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
void Multivector<Scalar, Frame, 2>::WriteToMessage(
not_null<serialization::Multivector*> const message) const {
Frame::WriteToMessage(message->mutable_frame());
coordinates_.WriteToMessage(message->mutable_bivector());
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
void Multivector<Scalar, Frame, 3>::WriteToMessage(
not_null<serialization::Multivector*> const message) const {
Frame::WriteToMessage(message->mutable_frame());
coordinates_.WriteToMessage(message->mutable_trivector());
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 1> Multivector<Scalar, Frame, 1>::ReadFromMessage(
serialization::Multivector const& message)
requires serializable<Frame> {
Expand All @@ -207,7 +207,7 @@ Multivector<Scalar, Frame, 1> Multivector<Scalar, Frame, 1>::ReadFromMessage(
return Multivector(R3Element<Scalar>::ReadFromMessage(message.vector()));
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 2> Multivector<Scalar, Frame, 2>::ReadFromMessage(
serialization::Multivector const& message)
requires serializable<Frame> {
Expand All @@ -216,7 +216,7 @@ Multivector<Scalar, Frame, 2> Multivector<Scalar, Frame, 2>::ReadFromMessage(
return Multivector(R3Element<Scalar>::ReadFromMessage(message.bivector()));
}

template<typename Scalar, typename Frame>
template<quantity Scalar, typename Frame>
Multivector<Scalar, Frame, 3> Multivector<Scalar, Frame, 3>::ReadFromMessage(
serialization::Multivector const& message)
requires serializable<Frame> {
Expand Down
1 change: 1 addition & 0 deletions geometry/grassmann_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class GrassmannTest : public testing::Test {
Inertial,
Handedness::Right,
serialization::Frame::TEST>;
Vector<World, Acceleration> γ;

R3Element<Length> const null_displacement_ = {0 * Metre,
0 * Metre,
Expand Down
Binary file modified ksp_plugin_adapter_stub/ksp_plugin_adapter_stub.dll
Binary file not shown.
Binary file modified ksp_plugin_adapter_stub/ksp_plugin_adapter_stub.pdb
Binary file not shown.
9 changes: 6 additions & 3 deletions quantities/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,21 @@ concept affine_space = requires(A x, A y) {
template<typename V>
concept real_affine_space = affine_space<V, double>;

template<typename T>
concept quantity = instance_of<T, Quantity> || std::same_as<T, double>;

template<typename T>
concept convertible_to_quantity =
std::convertible_to<T, double> ||
is_instance_of_v<Quantity, std::remove_cvref_t<T>>;
std::convertible_to<T, double> || quantity<std::remove_cvref_t<T>>;

} // namespace internal

using internal::additive_group;
using internal::affine_space;
using internal::convertible_to_quantity;
using internal::quantity;
using internal::real_affine_space;
using internal::real_vector_space;
using internal::convertible_to_quantity;
using internal::vector_space;

} // namespace _concepts
Expand Down

0 comments on commit d0008af

Please sign in to comment.