mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +02:00
feat: cartesian_vector
added
This commit is contained in:
@ -91,6 +91,7 @@ if(NOT ${projectPrefix}API_FREESTANDING)
|
||||
include/mp-units/bits/fmt.h
|
||||
include/mp-units/bits/requires_hosted.h
|
||||
include/mp-units/ext/format.h
|
||||
include/mp-units/cartesian_vector.h
|
||||
include/mp-units/complex.h
|
||||
include/mp-units/format.h
|
||||
include/mp-units/math.h
|
||||
|
230
src/core/include/mp-units/cartesian_vector.h
Normal file
230
src/core/include/mp-units/cartesian_vector.h
Normal file
@ -0,0 +1,230 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mp-units/bits/requires_hosted.h>
|
||||
//
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/framework/customization_points.h>
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <mp-units/bits/fmt.h>
|
||||
#endif
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#ifdef MP_UNITS_IMPORT_STD
|
||||
import std;
|
||||
#else
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
MP_UNITS_EXPORT template<typename T = double>
|
||||
class cartesian_vector {
|
||||
public:
|
||||
// public members required to satisfy structural type requirements :-(
|
||||
T _coordinates_[3];
|
||||
using value_type = T;
|
||||
|
||||
cartesian_vector() = default;
|
||||
cartesian_vector(const cartesian_vector&) = default;
|
||||
cartesian_vector(cartesian_vector&&) = default;
|
||||
cartesian_vector& operator=(const cartesian_vector&) = default;
|
||||
cartesian_vector& operator=(cartesian_vector&&) = default;
|
||||
|
||||
template<std::convertible_to<T> Arg1, std::convertible_to<T>... Args>
|
||||
constexpr cartesian_vector(Arg1&& arg1, Args&&... args) :
|
||||
_coordinates_(std::forward<Arg1>(arg1), std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template<std::convertible_to<T> U>
|
||||
constexpr cartesian_vector(const cartesian_vector<U>& other) : _coordinates_{other[0], other[1], other[2]}
|
||||
{
|
||||
}
|
||||
|
||||
template<std::convertible_to<T> U>
|
||||
constexpr cartesian_vector(cartesian_vector<U>&& other) :
|
||||
_coordinates_{std::move(other[0]), std::move(other[1]), std::move(other[2])}
|
||||
{
|
||||
}
|
||||
|
||||
template<std::convertible_to<T> U>
|
||||
constexpr cartesian_vector& operator=(const cartesian_vector<U>& other)
|
||||
{
|
||||
_coordinates_[0] = other[0];
|
||||
_coordinates_[1] = other[1];
|
||||
_coordinates_[2] = other[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::convertible_to<T> U>
|
||||
constexpr cartesian_vector& operator=(cartesian_vector<U>&& other)
|
||||
{
|
||||
_coordinates_[0] = std::move(other[0]);
|
||||
_coordinates_[1] = std::move(other[1]);
|
||||
_coordinates_[2] = std::move(other[2]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr T magnitude() const
|
||||
requires treat_as_floating_point<T>
|
||||
{
|
||||
return std::hypot(_coordinates_[0], _coordinates_[1], _coordinates_[2]);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr cartesian_vector unit() const
|
||||
requires treat_as_floating_point<T>
|
||||
{
|
||||
return *this / magnitude();
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t i) { return _coordinates_[i]; }
|
||||
[[nodiscard]] constexpr const T& operator[](std::size_t i) const { return _coordinates_[i]; }
|
||||
|
||||
[[nodiscard]] constexpr cartesian_vector operator+() const { return *this; }
|
||||
[[nodiscard]] constexpr cartesian_vector operator-() const
|
||||
{
|
||||
return {-_coordinates_[0], -_coordinates_[1], -_coordinates_[2]};
|
||||
}
|
||||
|
||||
template<std::same_as<T> U, typename V>
|
||||
requires requires(U u, V v) { u + v; }
|
||||
[[nodiscard]] friend constexpr auto operator+(const cartesian_vector<U>& lhs, const cartesian_vector<V>& rhs)
|
||||
{
|
||||
return ::mp_units::cartesian_vector{lhs._coordinates_[0] + rhs._coordinates_[0],
|
||||
lhs._coordinates_[1] + rhs._coordinates_[1],
|
||||
lhs._coordinates_[2] + rhs._coordinates_[2]};
|
||||
}
|
||||
|
||||
template<std::same_as<T> U, typename V>
|
||||
requires requires(U u, V v) { u - v; }
|
||||
[[nodiscard]] friend constexpr auto operator-(const cartesian_vector<U>& lhs, const cartesian_vector<V>& rhs)
|
||||
{
|
||||
return ::mp_units::cartesian_vector{lhs._coordinates_[0] - rhs._coordinates_[0],
|
||||
lhs._coordinates_[1] - rhs._coordinates_[1],
|
||||
lhs._coordinates_[2] - rhs._coordinates_[2]};
|
||||
}
|
||||
|
||||
template<std::same_as<T> U>
|
||||
requires requires(U u, T t) { u* t; }
|
||||
[[nodiscard]] friend constexpr auto operator*(const cartesian_vector<U>& lhs, const T& rhs)
|
||||
{
|
||||
return ::mp_units::cartesian_vector{lhs._coordinates_[0] * rhs, lhs._coordinates_[1] * rhs,
|
||||
lhs._coordinates_[2] * rhs};
|
||||
}
|
||||
|
||||
template<std::same_as<T> U>
|
||||
requires requires(T t, U u) { t* u; }
|
||||
[[nodiscard]] friend constexpr auto operator*(const T& lhs, const cartesian_vector<U>& rhs)
|
||||
{
|
||||
return rhs * lhs;
|
||||
}
|
||||
|
||||
template<std::same_as<T> U>
|
||||
requires requires(U u, T t) { u / t; }
|
||||
[[nodiscard]] friend constexpr auto operator/(const cartesian_vector<U>& lhs, const T& rhs)
|
||||
{
|
||||
return ::mp_units::cartesian_vector{lhs._coordinates_[0] / rhs, lhs._coordinates_[1] / rhs,
|
||||
lhs._coordinates_[2] / rhs};
|
||||
}
|
||||
|
||||
template<std::same_as<T> U, std::equality_comparable_with<U> V>
|
||||
[[nodiscard]] friend constexpr bool operator==(const cartesian_vector<U>& lhs, const cartesian_vector<V>& rhs)
|
||||
{
|
||||
return lhs._coordinates_[0] == rhs._coordinates_[0] && lhs._coordinates_[1] == rhs._coordinates_[1] &&
|
||||
lhs._coordinates_[2] == rhs._coordinates_[2];
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr T norm(const cartesian_vector& v)
|
||||
requires treat_as_floating_point<T>
|
||||
{
|
||||
return v.magnitude();
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr cartesian_vector unit_vector(const cartesian_vector& v)
|
||||
requires treat_as_floating_point<T>
|
||||
{
|
||||
return v.unit();
|
||||
}
|
||||
|
||||
template<std::same_as<T> U, typename V>
|
||||
requires requires(U u, V v, decltype(u * v) t) {
|
||||
u* v;
|
||||
t + t;
|
||||
}
|
||||
[[nodiscard]] friend constexpr auto scalar_product(const cartesian_vector<U>& lhs, const cartesian_vector<V>& rhs)
|
||||
{
|
||||
return lhs._coordinates_[0] * rhs._coordinates_[0] + lhs._coordinates_[1] * rhs._coordinates_[1] +
|
||||
lhs._coordinates_[2] * rhs._coordinates_[2];
|
||||
}
|
||||
|
||||
template<std::same_as<T> U, typename V>
|
||||
requires requires(U u, V v, decltype(u * v) t) {
|
||||
u* v;
|
||||
t - t;
|
||||
}
|
||||
[[nodiscard]] friend constexpr auto vector_product(const cartesian_vector<U>& lhs, const cartesian_vector<V>& rhs)
|
||||
{
|
||||
return ::mp_units::cartesian_vector{
|
||||
lhs._coordinates_[1] * rhs._coordinates_[2] - lhs._coordinates_[2] * rhs._coordinates_[1],
|
||||
lhs._coordinates_[2] * rhs._coordinates_[0] - lhs._coordinates_[0] * rhs._coordinates_[2],
|
||||
lhs._coordinates_[0] * rhs._coordinates_[1] - lhs._coordinates_[1] * rhs._coordinates_[0]};
|
||||
}
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
friend constexpr std::ostream& operator<<(std::ostream& os, const cartesian_vector& v)
|
||||
{
|
||||
return os << '[' << v[0] << ", " << v[1] << ", " << v[2] << ']';
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename Arg, typename... Args>
|
||||
requires(sizeof...(Args) <= 2) && requires { typename std::common_type_t<Arg, Args...>; }
|
||||
cartesian_vector(Arg, Args...) -> cartesian_vector<std::common_type_t<Arg, Args...>>;
|
||||
|
||||
template<class T>
|
||||
constexpr bool is_vector<cartesian_vector<T>> = true;
|
||||
|
||||
} // namespace mp_units
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
// TODO use parse and use formatter for the underlying type
|
||||
template<typename T, typename Char>
|
||||
struct MP_UNITS_STD_FMT::formatter<mp_units::cartesian_vector<T>, Char> :
|
||||
formatter<std::basic_string_view<Char>, Char> {
|
||||
template<typename FormatContext>
|
||||
auto format(const mp_units::cartesian_vector<T>& v, FormatContext& ctx) const
|
||||
{
|
||||
return format_to(ctx.out(), "[{}, {}, {}]", v[0], v[1], v[2]);
|
||||
}
|
||||
};
|
||||
#endif
|
@ -28,6 +28,7 @@
|
||||
#include <mp-units/framework.h>
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <mp-units/cartesian_vector.h>
|
||||
#include <mp-units/complex.h>
|
||||
#include <mp-units/format.h>
|
||||
#include <mp-units/math.h>
|
||||
|
@ -24,13 +24,14 @@ find_package(Catch2 3 REQUIRED)
|
||||
|
||||
add_executable(
|
||||
unit_tests_runtime
|
||||
atomic_test.cpp
|
||||
cartesian_vector_test.cpp
|
||||
distribution_test.cpp
|
||||
fixed_string_test.cpp
|
||||
fmt_test.cpp
|
||||
math_test.cpp
|
||||
atomic_test.cpp
|
||||
truncation_test.cpp
|
||||
quantity_test.cpp
|
||||
truncation_test.cpp
|
||||
)
|
||||
if(${projectPrefix}BUILD_CXX_MODULES)
|
||||
target_compile_definitions(unit_tests_runtime PUBLIC ${projectPrefix}MODULES)
|
||||
|
374
test/runtime/cartesian_vector_test.cpp
Normal file
374
test/runtime/cartesian_vector_test.cpp
Normal file
@ -0,0 +1,374 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "almost_equals.h"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#ifdef MP_UNITS_MODULES
|
||||
import mp_units;
|
||||
#else
|
||||
#include <mp-units/cartesian_vector.h>
|
||||
#endif
|
||||
|
||||
using namespace mp_units;
|
||||
using namespace Catch::Matchers;
|
||||
|
||||
TEST_CASE("cartesian_vector operations", "[vector]")
|
||||
{
|
||||
SECTION("cartesian_vector initialization and access")
|
||||
{
|
||||
SECTION("one argument")
|
||||
{
|
||||
cartesian_vector v{1.0};
|
||||
REQUIRE(v[0] == 1.0);
|
||||
REQUIRE(v[1] == 0);
|
||||
REQUIRE(v[2] == 0);
|
||||
}
|
||||
|
||||
SECTION("two arguments")
|
||||
{
|
||||
cartesian_vector v{1.0, 2.0};
|
||||
REQUIRE(v[0] == 1.0);
|
||||
REQUIRE(v[1] == 2.0);
|
||||
REQUIRE(v[2] == 0);
|
||||
}
|
||||
|
||||
SECTION("all arguments")
|
||||
{
|
||||
cartesian_vector v{1.0, 2.0, 3.0};
|
||||
REQUIRE(v[0] == 1.0);
|
||||
REQUIRE(v[1] == 2.0);
|
||||
REQUIRE(v[2] == 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("convertibility")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
|
||||
SECTION("construction")
|
||||
{
|
||||
cartesian_vector v2 = v1;
|
||||
REQUIRE(v2[0] == 1.0);
|
||||
REQUIRE(v2[1] == 2.0);
|
||||
REQUIRE(v2[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("assignment")
|
||||
{
|
||||
cartesian_vector v2{3.0, 2.0, 1.0};
|
||||
v2 = v1;
|
||||
REQUIRE(v2[0] == 1.0);
|
||||
REQUIRE(v2[1] == 2.0);
|
||||
REQUIRE(v2[2] == 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector addition")
|
||||
{
|
||||
SECTION("double + double")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{4.0, 5.0, 6.0};
|
||||
cartesian_vector result = v1 + v2;
|
||||
REQUIRE(result[0] == 5.0);
|
||||
REQUIRE(result[1] == 7.0);
|
||||
REQUIRE(result[2] == 9.0);
|
||||
}
|
||||
|
||||
SECTION("double + int")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{4, 5, 6};
|
||||
cartesian_vector result = v1 + v2;
|
||||
REQUIRE(result[0] == 5.0);
|
||||
REQUIRE(result[1] == 7.0);
|
||||
REQUIRE(result[2] == 9.0);
|
||||
}
|
||||
|
||||
SECTION("int + double")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
cartesian_vector v2{4.0, 5.0, 6.0};
|
||||
cartesian_vector result = v1 + v2;
|
||||
REQUIRE(result[0] == 5.0);
|
||||
REQUIRE(result[1] == 7.0);
|
||||
REQUIRE(result[2] == 9.0);
|
||||
}
|
||||
|
||||
SECTION("int + int")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
cartesian_vector v2{4, 5, 6};
|
||||
cartesian_vector result = v1 + v2;
|
||||
REQUIRE(result[0] == 5);
|
||||
REQUIRE(result[1] == 7);
|
||||
REQUIRE(result[2] == 9);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector subtraction")
|
||||
{
|
||||
SECTION("double - double")
|
||||
{
|
||||
cartesian_vector v1{4.0, 5.0, 6.0};
|
||||
cartesian_vector v2{1.0, 2.0, 3.0};
|
||||
cartesian_vector result = v1 - v2;
|
||||
REQUIRE(result[0] == 3.0);
|
||||
REQUIRE(result[1] == 3.0);
|
||||
REQUIRE(result[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("double - int")
|
||||
{
|
||||
cartesian_vector v1{4.0, 5.0, 6.0};
|
||||
cartesian_vector v2{1, 2, 3};
|
||||
cartesian_vector result = v1 - v2;
|
||||
REQUIRE(result[0] == 3.0);
|
||||
REQUIRE(result[1] == 3.0);
|
||||
REQUIRE(result[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("int - double")
|
||||
{
|
||||
cartesian_vector v1{4, 5, 6};
|
||||
cartesian_vector v2{1.0, 2.0, 3.0};
|
||||
cartesian_vector result = v1 - v2;
|
||||
REQUIRE(result[0] == 3.0);
|
||||
REQUIRE(result[1] == 3.0);
|
||||
REQUIRE(result[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("int - int")
|
||||
{
|
||||
cartesian_vector v1{4, 5, 6};
|
||||
cartesian_vector v2{1, 2, 3};
|
||||
cartesian_vector result = v1 - v2;
|
||||
REQUIRE(result[0] == 3);
|
||||
REQUIRE(result[1] == 3);
|
||||
REQUIRE(result[2] == 3);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector scalar multiplication")
|
||||
{
|
||||
SECTION("double * double")
|
||||
{
|
||||
cartesian_vector v{1.0, 2.0, 3.0};
|
||||
cartesian_vector result = v * 2.0;
|
||||
REQUIRE(result[0] == 2.0);
|
||||
REQUIRE(result[1] == 4.0);
|
||||
REQUIRE(result[2] == 6.0);
|
||||
}
|
||||
|
||||
SECTION("double * int")
|
||||
{
|
||||
cartesian_vector v{1.0, 2.0, 3.0};
|
||||
cartesian_vector result = v * 2;
|
||||
REQUIRE(result[0] == 2.0);
|
||||
REQUIRE(result[1] == 4.0);
|
||||
REQUIRE(result[2] == 6.0);
|
||||
}
|
||||
|
||||
SECTION("int * double")
|
||||
{
|
||||
cartesian_vector v{1, 2, 3};
|
||||
cartesian_vector result = v * 2.0;
|
||||
REQUIRE(result[0] == 2.0);
|
||||
REQUIRE(result[1] == 4.0);
|
||||
REQUIRE(result[2] == 6.0);
|
||||
}
|
||||
|
||||
SECTION("int * int")
|
||||
{
|
||||
cartesian_vector v{1, 2, 3};
|
||||
cartesian_vector result = v * 2;
|
||||
REQUIRE(result[0] == 2);
|
||||
REQUIRE(result[1] == 4);
|
||||
REQUIRE(result[2] == 6);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector scalar division")
|
||||
{
|
||||
SECTION("double / double")
|
||||
{
|
||||
cartesian_vector v{2.0, 4.0, 6.0};
|
||||
cartesian_vector result = v / 2.0;
|
||||
REQUIRE(result[0] == 1.0);
|
||||
REQUIRE(result[1] == 2.0);
|
||||
REQUIRE(result[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("double / int")
|
||||
{
|
||||
cartesian_vector v{2.0, 4.0, 6.0};
|
||||
cartesian_vector result = v / 2;
|
||||
REQUIRE(result[0] == 1.0);
|
||||
REQUIRE(result[1] == 2.0);
|
||||
REQUIRE(result[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("int / double")
|
||||
{
|
||||
cartesian_vector v{2, 4, 6};
|
||||
cartesian_vector result = v / 2.0;
|
||||
REQUIRE(result[0] == 1.0);
|
||||
REQUIRE(result[1] == 2.0);
|
||||
REQUIRE(result[2] == 3.0);
|
||||
}
|
||||
|
||||
SECTION("int / int")
|
||||
{
|
||||
cartesian_vector v{2, 4, 6};
|
||||
cartesian_vector result = v / 2;
|
||||
REQUIRE(result[0] == 1);
|
||||
REQUIRE(result[1] == 2);
|
||||
REQUIRE(result[2] == 3);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector magnitude")
|
||||
{
|
||||
cartesian_vector v1{3.0, 4.0, 0.0};
|
||||
cartesian_vector v2{2.0, 3.0, 6.0};
|
||||
REQUIRE(v1.magnitude() == 5.0);
|
||||
REQUIRE(v2.magnitude() == 7.0);
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector unit vector")
|
||||
{
|
||||
cartesian_vector v{3.0, 4.0, 0.0};
|
||||
cartesian_vector unit_v = v.unit();
|
||||
REQUIRE_THAT(unit_v.magnitude(), WithinULP(1.0, 1));
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector equality")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{1, 2, 3};
|
||||
cartesian_vector v3{1.1, 2.0, 3.0};
|
||||
cartesian_vector v4{1.0, 2.1, 3.0};
|
||||
cartesian_vector v5{1.0, 2.0, 3.1};
|
||||
REQUIRE(v1 == v2);
|
||||
REQUIRE(v1 != v3);
|
||||
REQUIRE(v1 != v4);
|
||||
REQUIRE(v1 != v5);
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector scalar product")
|
||||
{
|
||||
SECTION("double * double")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{4.0, 5.0, 6.0};
|
||||
REQUIRE(scalar_product(v1, v2) == 32.0);
|
||||
}
|
||||
|
||||
SECTION("double * int")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{4, 5, 6};
|
||||
REQUIRE(scalar_product(v1, v2) == 32.0);
|
||||
}
|
||||
|
||||
SECTION("int * double")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
cartesian_vector v2{4.0, 5.0, 6.0};
|
||||
REQUIRE(scalar_product(v1, v2) == 32.0);
|
||||
}
|
||||
|
||||
SECTION("int * int")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
cartesian_vector v2{4, 5, 6};
|
||||
REQUIRE(scalar_product(v1, v2) == 32);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("cartesian_vector vector product")
|
||||
{
|
||||
SECTION("double * double")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{4.0, 5.0, 6.0};
|
||||
cartesian_vector result = vector_product(v1, v2);
|
||||
REQUIRE(result[0] == -3.0);
|
||||
REQUIRE(result[1] == 6.0);
|
||||
REQUIRE(result[2] == -3.0);
|
||||
}
|
||||
|
||||
SECTION("double * int")
|
||||
{
|
||||
cartesian_vector v1{1.0, 2.0, 3.0};
|
||||
cartesian_vector v2{4, 5, 6};
|
||||
cartesian_vector result = vector_product(v1, v2);
|
||||
REQUIRE(result[0] == -3.0);
|
||||
REQUIRE(result[1] == 6.0);
|
||||
REQUIRE(result[2] == -3.0);
|
||||
}
|
||||
|
||||
SECTION("int * double")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
cartesian_vector v2{4.0, 5.0, 6.0};
|
||||
cartesian_vector result = vector_product(v1, v2);
|
||||
REQUIRE(result[0] == -3.0);
|
||||
REQUIRE(result[1] == 6.0);
|
||||
REQUIRE(result[2] == -3.0);
|
||||
}
|
||||
|
||||
SECTION("int * int")
|
||||
{
|
||||
cartesian_vector v1{1, 2, 3};
|
||||
cartesian_vector v2{4, 5, 6};
|
||||
cartesian_vector result = vector_product(v1, v2);
|
||||
REQUIRE(result[0] == -3);
|
||||
REQUIRE(result[1] == 6);
|
||||
REQUIRE(result[2] == -3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("cartesian_vector text output", "[vector][fmt][ostream]")
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
SECTION("integral representation")
|
||||
{
|
||||
cartesian_vector v{1, 2, 3};
|
||||
os << v;
|
||||
|
||||
SECTION("iostream") { CHECK(os.str() == "[1, 2, 3]"); }
|
||||
SECTION("fmt with default format {}") { CHECK(MP_UNITS_STD_FMT::format("{}", v) == os.str()); }
|
||||
}
|
||||
|
||||
SECTION("floating-point representation")
|
||||
{
|
||||
cartesian_vector v{1.2, 2.3, 3.4};
|
||||
os << v;
|
||||
|
||||
SECTION("iostream") { CHECK(os.str() == "[1.2, 2.3, 3.4]"); }
|
||||
SECTION("fmt with default format {}") { CHECK(MP_UNITS_STD_FMT::format("{}", v) == os.str()); }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user