diff --git a/geometry/src/algebra.hpp b/geometry/src/algebra.hpp index cbc32c7..36c74f3 100644 --- a/geometry/src/algebra.hpp +++ b/geometry/src/algebra.hpp @@ -12,6 +12,7 @@ #include "geometry/src/detail/type_unique.hpp" #include +#include #include #include #include @@ -280,6 +281,27 @@ struct algebra { return x.coefficient * y.coefficient * e; } + + /// stream insertion + /// + friend auto operator<<(std::ostream& os, blade x) -> std::enable_if_t< + (N < 10), + decltype(os << std::declval(), os)> + { + if (sizeof...(Is) == 0) { + os << x.coefficient; + return os; + } + + if (x.coefficient != scalar_type{1}) { + os << x.coefficient << "*"; + } + + os << "e"; + std::ignore = ((os << Is, true) and ...); + + return os; + } }; template @@ -511,6 +533,22 @@ struct algebra return ((x * get(y)) + ...); } /// @} + + /// stream insertion + /// + friend auto operator<<(std::ostream& os, const multivector& x) + -> decltype(((os << std::declval(), true) and ...), os) + { + auto first = true; + + std::ignore = + ((os << (std::exchange(first, false) ? "" : " + "), + os << get(x), + true) and + ...); + + return os; + } }; }; diff --git a/test/algebra_blade_test.cpp b/test/algebra_blade_test.cpp index 2fe48cd..637bab4 100644 --- a/test/algebra_blade_test.cpp +++ b/test/algebra_blade_test.cpp @@ -2,6 +2,7 @@ #include "skytest/skytest.hpp" #include +#include #include #include @@ -113,4 +114,21 @@ auto main() -> int "geometric product"_ctest = [] { return expect(eq(6, (2 * e<1>)*(3 * e<1>))); }; + + "printable"_test = [] { + static const auto to_string = [](auto blade) { + return (std::stringstream{} << blade).str(); + }; + + return expect( + eq("0*e0", to_string(0 * e<0>)) and // + eq("e1", to_string(1 * e<1>)) and // + eq("2*e2", to_string(2 * e<2>)) and // + eq("3*e01", to_string(3 * e<0, 1>)) and // + eq("4*e12", to_string(4 * e<1, 2>)) and // + eq("5*e02", to_string(5 * e<0, 2>)) and // + eq("6*e012", to_string(6 * e<0, 1, 2>)) and // + eq("7", to_string(7 * e<>)) and // + eq("1", to_string(e<>))); + }; } diff --git a/test/algebra_multivector_test.cpp b/test/algebra_multivector_test.cpp index 465378a..7c3d32d 100644 --- a/test/algebra_multivector_test.cpp +++ b/test/algebra_multivector_test.cpp @@ -1,6 +1,8 @@ #include "geometry/geometry.hpp" #include "skytest/skytest.hpp" +#include +#include #include template @@ -133,4 +135,16 @@ auto main() -> int return expect(eq(z, x * y) and eq(-z, y * x)); }; + + "printable"_test = [] { + static const auto to_string = [](const auto& mvec) { + return (std::stringstream{} << mvec).str(); + }; + + return expect( + eq("1", to_string(multivector(e<>))) and + eq("2*e0 + 3*e1 + 4*e2", to_string(2 * e<0> + 3 * e<1> + 4 * e<2>)) + + ); + }; }