generated from aselimov/cpp_project_template
Add simple Vec3 header file
This commit is contained in:
parent
311a93cdd6
commit
24d7efc977
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
# Builds
|
||||
build/
|
||||
Debug/
|
||||
Testing/
|
||||
|
||||
# Google Tests
|
||||
tests/lib/
|
||||
@ -7,3 +9,6 @@ tests/lib/
|
||||
# Jet Brains
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
|
||||
# Cache dir
|
||||
.cache
|
||||
|
@ -1,35 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.9)
|
||||
project(MyProject LANGUAGES CUDA CXX)
|
||||
project(Vec3)
|
||||
|
||||
enable_testing()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CUDA_ARCHITECTURES 61)
|
||||
set(CUDA_SEPARABLE_COMPILATION ON)
|
||||
|
||||
|
||||
|
||||
include_directories(src)
|
||||
include_directories(kernels)
|
||||
include_directories(/usr/local/cuda-12.8/include)
|
||||
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(kernels)
|
||||
include_directories(include)
|
||||
add_subdirectory(include)
|
||||
add_subdirectory(tests)
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME}_run main.cpp)
|
||||
|
||||
|
||||
|
||||
target_link_libraries(
|
||||
${CMAKE_PROJECT_NAME}_run
|
||||
PRIVATE
|
||||
${CMAKE_PROJECT_NAME}_lib
|
||||
${CMAKE_PROJECT_NAME}_cuda_lib
|
||||
${CUDA_LIBRARIES}
|
||||
)
|
||||
|
||||
# Doxygen Build
|
||||
option(BUILD_DOC "Build Documentation" ON)
|
||||
|
||||
|
32
compile_commands.json
Normal file
32
compile_commands.json
Normal file
@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"directory": "/home/aselimov/projects/Vec3/build/tests/lib/googletest/googlemock",
|
||||
"command": "/usr/bin/c++ -I/home/aselimov/projects/Vec3/include -I/home/aselimov/projects/Vec3/tests/lib/googletest/googlemock/include -I/home/aselimov/projects/Vec3/tests/lib/googletest/googlemock -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest -std=c++17 -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wall -Wextra -Wpedantic -o CMakeFiles/gmock.dir/src/gmock-all.cc.o -c /home/aselimov/projects/Vec3/tests/lib/googletest/googlemock/src/gmock-all.cc",
|
||||
"file": "/home/aselimov/projects/Vec3/tests/lib/googletest/googlemock/src/gmock-all.cc",
|
||||
"output": "tests/lib/googletest/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o"
|
||||
},
|
||||
{
|
||||
"directory": "/home/aselimov/projects/Vec3/build/tests/lib/googletest/googlemock",
|
||||
"command": "/usr/bin/c++ -isystem /home/aselimov/projects/Vec3/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googlemock/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googlemock -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest -std=c++17 -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wall -Wextra -Wpedantic -o CMakeFiles/gmock_main.dir/src/gmock_main.cc.o -c /home/aselimov/projects/Vec3/tests/lib/googletest/googlemock/src/gmock_main.cc",
|
||||
"file": "/home/aselimov/projects/Vec3/tests/lib/googletest/googlemock/src/gmock_main.cc",
|
||||
"output": "tests/lib/googletest/googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o"
|
||||
},
|
||||
{
|
||||
"directory": "/home/aselimov/projects/Vec3/build/tests/lib/googletest/googletest",
|
||||
"command": "/usr/bin/c++ -I/home/aselimov/projects/Vec3/include -I/home/aselimov/projects/Vec3/tests/lib/googletest/googletest/include -I/home/aselimov/projects/Vec3/tests/lib/googletest/googletest -std=c++17 -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wall -Wextra -Wpedantic -o CMakeFiles/gtest.dir/src/gtest-all.cc.o -c /home/aselimov/projects/Vec3/tests/lib/googletest/googletest/src/gtest-all.cc",
|
||||
"file": "/home/aselimov/projects/Vec3/tests/lib/googletest/googletest/src/gtest-all.cc",
|
||||
"output": "tests/lib/googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o"
|
||||
},
|
||||
{
|
||||
"directory": "/home/aselimov/projects/Vec3/build/tests/lib/googletest/googletest",
|
||||
"command": "/usr/bin/c++ -I/home/aselimov/projects/Vec3/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest -std=c++17 -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wall -Wextra -Wpedantic -o CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -c /home/aselimov/projects/Vec3/tests/lib/googletest/googletest/src/gtest_main.cc",
|
||||
"file": "/home/aselimov/projects/Vec3/tests/lib/googletest/googletest/src/gtest_main.cc",
|
||||
"output": "tests/lib/googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o"
|
||||
},
|
||||
{
|
||||
"directory": "/home/aselimov/projects/Vec3/build/tests/unit_tests",
|
||||
"command": "/usr/bin/c++ -I/home/aselimov/projects/Vec3/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest/include -isystem /home/aselimov/projects/Vec3/tests/lib/googletest/googletest -std=gnu++17 -Wall -Wextra -Wpedantic -o CMakeFiles/Unit_Tests_run.dir/vec_test.cpp.o -c /home/aselimov/projects/Vec3/tests/unit_tests/vec_test.cpp",
|
||||
"file": "/home/aselimov/projects/Vec3/tests/unit_tests/vec_test.cpp",
|
||||
"output": "tests/unit_tests/CMakeFiles/Unit_Tests_run.dir/vec_test.cpp.o"
|
||||
}
|
||||
]
|
10
include/CMakeLists.txt
Normal file
10
include/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
project(${CMAKE_PROJECT_NAME}_lib)
|
||||
|
||||
set(HEADER_FILES
|
||||
vec3.h
|
||||
)
|
||||
|
||||
# The library contains header and source files.
|
||||
add_library(${CMAKE_PROJECT_NAME}_lib
|
||||
INTERFACE
|
||||
)
|
33
include/vec3.h
Normal file
33
include/vec3.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef VEC3_H
|
||||
#define VEC3_H
|
||||
|
||||
template <typename T> struct Vec3 {
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
|
||||
inline Vec3<T> operator+(Vec3<T> other) const {
|
||||
return {x + other.x, y + other.y, z + other.z};
|
||||
};
|
||||
|
||||
inline Vec3<T> operator-(Vec3<T> other) const {
|
||||
return {x - other.x, y - other.y, z - other.z};
|
||||
};
|
||||
|
||||
inline void scale(T scalar) {
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
z *= scalar;
|
||||
};
|
||||
|
||||
inline T dot(Vec3<T> other) {
|
||||
return x * other.x + y * other.y + z * other.z;
|
||||
}
|
||||
|
||||
inline Vec3<T> cross(Vec3<T> other) {
|
||||
return {y * other.z - z * other.y, z * other.x - x * other.z,
|
||||
x * other.y - y * other.x};
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -1,18 +0,0 @@
|
||||
project(${CMAKE_PROJECT_NAME}_cuda_lib CUDA CXX)
|
||||
|
||||
set(HEADER_FILES
|
||||
hello_world.h
|
||||
)
|
||||
set(SOURCE_FILES
|
||||
hello_world.cu
|
||||
)
|
||||
|
||||
# The library contains header and source files.
|
||||
add_library(${CMAKE_PROJECT_NAME}_cuda_lib STATIC
|
||||
${SOURCE_FILES}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
target_compile_options(${CMAKE_PROJECT_NAME}_cuda_lib PRIVATE -Wno-gnu-line-marker)
|
||||
endif()
|
@ -1,46 +0,0 @@
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdio.h>
|
||||
|
||||
__global__ void hello_cuda() {
|
||||
printf("Hello CUDA from thread %d\n", threadIdx.x);
|
||||
}
|
||||
|
||||
extern "C" void launch_hello_cuda() {
|
||||
// First check device properties
|
||||
cudaDeviceProp prop;
|
||||
cudaGetDeviceProperties(&prop, 1);
|
||||
printf("Using device: %s with compute capability %d.%d\n", prop.name,
|
||||
prop.major, prop.minor);
|
||||
|
||||
hello_cuda<<<1, 10>>>();
|
||||
cudaDeviceSynchronize();
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
extern "C" void check_cuda() {
|
||||
int deviceCount = 0;
|
||||
cudaError_t error = cudaGetDeviceCount(&deviceCount);
|
||||
|
||||
if (error != cudaSuccess) {
|
||||
printf("CUDA error: %s\n", cudaGetErrorString(error));
|
||||
}
|
||||
|
||||
printf("Found %d CUDA devices\n", deviceCount);
|
||||
|
||||
for (int i = 0; i < deviceCount; i++) {
|
||||
cudaDeviceProp prop;
|
||||
cudaGetDeviceProperties(&prop, i);
|
||||
|
||||
printf("Device %d: %s\n", i, prop.name);
|
||||
printf(" Compute capability: %d.%d\n", prop.major, prop.minor);
|
||||
printf(" Total global memory: %.2f GB\n",
|
||||
static_cast<float>(prop.totalGlobalMem) / (1024 * 1024 * 1024));
|
||||
printf(" Multiprocessors: %d\n", prop.multiProcessorCount);
|
||||
printf(" Max threads per block: %d\n", prop.maxThreadsPerBlock);
|
||||
printf(" Max threads dimensions: (%d, %d, %d)\n", prop.maxThreadsDim[0],
|
||||
prop.maxThreadsDim[1], prop.maxThreadsDim[2]);
|
||||
printf(" Max grid dimensions: (%d, %d, %d)\n", prop.maxGridSize[0],
|
||||
prop.maxGridSize[1], prop.maxGridSize[2]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
#ifndef HELLO_WORLD_CU_H
|
||||
#define HELLO_WORLD_CU_H
|
||||
|
||||
extern "C" {
|
||||
// Declaration of the CUDA function that will be called from C++
|
||||
void launch_hello_cuda();
|
||||
void check_cuda();
|
||||
}
|
||||
|
||||
#endif // HELLO_WORLD_CU_H
|
10
main.cpp
10
main.cpp
@ -1,10 +0,0 @@
|
||||
#include "hello_world.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "Starting CUDA example..." << std::endl; // Using endl to flush
|
||||
check_cuda();
|
||||
launch_hello_cuda();
|
||||
std::cout << "Ending CUDA example" << std::endl; // Using endl to flush
|
||||
return 0;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
project(${CMAKE_PROJECT_NAME}_lib CUDA CXX)
|
||||
|
||||
set(HEADER_FILES
|
||||
./test.h
|
||||
)
|
||||
set(SOURCE_FILES
|
||||
./test.cpp
|
||||
)
|
||||
|
||||
# The library contains header and source files.
|
||||
add_library(${CMAKE_PROJECT_NAME}_lib
|
||||
${SOURCE_FILES}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
|
||||
target_include_directories(${CMAKE_PROJECT_NAME}_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
@ -1,4 +0,0 @@
|
||||
#include "test.h"
|
||||
#include <iostream>
|
||||
|
||||
void test_hello() { std::cout << "Hello!"; }
|
@ -1,2 +0,0 @@
|
||||
#include <iostream>
|
||||
void test_hello();
|
@ -1,8 +1,10 @@
|
||||
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
|
||||
|
||||
add_executable(Unit_Tests_run
|
||||
test_example.cpp
|
||||
vec_test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(Unit_Tests_run gtest gtest_main)
|
||||
target_link_libraries(Unit_Tests_run ${CMAKE_PROJECT_NAME}_lib)
|
||||
target_link_libraries(Unit_Tests_run ${CMAKE_PROJECT_NAME}_lib)
|
||||
|
||||
add_test(NAME Vec3Tests COMMAND ${CMAKE_BINARY_DIR}/tests/unit_tests/Unit_Tests_run)
|
||||
|
@ -1,5 +0,0 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(Example, Equals) {
|
||||
EXPECT_EQ(1, 1);
|
||||
}
|
231
tests/unit_tests/vec_test.cpp
Normal file
231
tests/unit_tests/vec_test.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
#include "vec3.h"
|
||||
#include <cmath>
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
|
||||
// Test fixture for Vec3 tests
|
||||
class Vec3Test : public ::testing::Test {
|
||||
protected:
|
||||
// Test vectors that will be used across multiple tests
|
||||
Vec3<int> intVec1, intVec2;
|
||||
Vec3<float> floatVec1, floatVec2;
|
||||
Vec3<double> doubleVec1, doubleVec2;
|
||||
|
||||
void SetUp() override {
|
||||
// Initialize test vectors
|
||||
intVec1 = {1, 2, 3};
|
||||
intVec2 = {4, 5, 6};
|
||||
|
||||
floatVec1 = {1.5f, 2.5f, 3.5f};
|
||||
floatVec2 = {4.5f, 5.5f, 6.5f};
|
||||
|
||||
doubleVec1 = {1.5, 2.5, 3.5};
|
||||
doubleVec2 = {4.5, 5.5, 6.5};
|
||||
}
|
||||
};
|
||||
|
||||
// Test vector addition
|
||||
TEST_F(Vec3Test, Addition) {
|
||||
// Test integer vectors
|
||||
auto intResult = intVec1 + intVec2;
|
||||
EXPECT_EQ(intResult.x, 5);
|
||||
EXPECT_EQ(intResult.y, 7);
|
||||
EXPECT_EQ(intResult.z, 9);
|
||||
|
||||
// Test float vectors
|
||||
auto floatResult = floatVec1 + floatVec2;
|
||||
EXPECT_FLOAT_EQ(floatResult.x, 6.0f);
|
||||
EXPECT_FLOAT_EQ(floatResult.y, 8.0f);
|
||||
EXPECT_FLOAT_EQ(floatResult.z, 10.0f);
|
||||
|
||||
// Test double vectors
|
||||
auto doubleResult = doubleVec1 + doubleVec2;
|
||||
EXPECT_DOUBLE_EQ(doubleResult.x, 6.0);
|
||||
EXPECT_DOUBLE_EQ(doubleResult.y, 8.0);
|
||||
EXPECT_DOUBLE_EQ(doubleResult.z, 10.0);
|
||||
}
|
||||
|
||||
// Test vector subtraction
|
||||
TEST_F(Vec3Test, Subtraction) {
|
||||
// Test integer vectors
|
||||
auto intResult = intVec2 - intVec1;
|
||||
EXPECT_EQ(intResult.x, 3);
|
||||
EXPECT_EQ(intResult.y, 3);
|
||||
EXPECT_EQ(intResult.z, 3);
|
||||
|
||||
// Test float vectors
|
||||
auto floatResult = floatVec2 - floatVec1;
|
||||
EXPECT_FLOAT_EQ(floatResult.x, 3.0f);
|
||||
EXPECT_FLOAT_EQ(floatResult.y, 3.0f);
|
||||
EXPECT_FLOAT_EQ(floatResult.z, 3.0f);
|
||||
|
||||
// Test double vectors
|
||||
auto doubleResult = doubleVec2 - doubleVec1;
|
||||
EXPECT_DOUBLE_EQ(doubleResult.x, 3.0);
|
||||
EXPECT_DOUBLE_EQ(doubleResult.y, 3.0);
|
||||
EXPECT_DOUBLE_EQ(doubleResult.z, 3.0);
|
||||
}
|
||||
|
||||
// Test vector scaling
|
||||
TEST_F(Vec3Test, Scale) {
|
||||
// Test integer scaling
|
||||
Vec3<int> intVecScaled = intVec1;
|
||||
intVecScaled.scale(2);
|
||||
EXPECT_EQ(intVecScaled.x, 2);
|
||||
EXPECT_EQ(intVecScaled.y, 4);
|
||||
EXPECT_EQ(intVecScaled.z, 6);
|
||||
|
||||
// Test float scaling
|
||||
Vec3<float> floatVecScaled = floatVec1;
|
||||
floatVecScaled.scale(2.0f);
|
||||
EXPECT_FLOAT_EQ(floatVecScaled.x, 3.0f);
|
||||
EXPECT_FLOAT_EQ(floatVecScaled.y, 5.0f);
|
||||
EXPECT_FLOAT_EQ(floatVecScaled.z, 7.0f);
|
||||
|
||||
// Test double scaling
|
||||
Vec3<double> doubleVecScaled = doubleVec1;
|
||||
doubleVecScaled.scale(2.0);
|
||||
EXPECT_DOUBLE_EQ(doubleVecScaled.x, 3.0);
|
||||
EXPECT_DOUBLE_EQ(doubleVecScaled.y, 5.0);
|
||||
EXPECT_DOUBLE_EQ(doubleVecScaled.z, 7.0);
|
||||
|
||||
// Test scaling by zero
|
||||
Vec3<float> zeroScaled = floatVec1;
|
||||
zeroScaled.scale(0.0f);
|
||||
EXPECT_FLOAT_EQ(zeroScaled.x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(zeroScaled.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(zeroScaled.z, 0.0f);
|
||||
|
||||
// Test scaling by negative number
|
||||
Vec3<int> negScaled = intVec1;
|
||||
negScaled.scale(-1);
|
||||
EXPECT_EQ(negScaled.x, -1);
|
||||
EXPECT_EQ(negScaled.y, -2);
|
||||
EXPECT_EQ(negScaled.z, -3);
|
||||
}
|
||||
|
||||
// Test dot product
|
||||
TEST_F(Vec3Test, DotProduct) {
|
||||
// Test integer dot product
|
||||
int intDot = intVec1.dot(intVec2);
|
||||
EXPECT_EQ(intDot, 32); // 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
|
||||
|
||||
// Test float dot product
|
||||
float floatDot = floatVec1.dot(floatVec2);
|
||||
EXPECT_FLOAT_EQ(
|
||||
floatDot,
|
||||
43.25f); // 1.5*4.5 + 2.5*5.5 + 3.5*6.5 = 6.75 + 13.75 + 22.75 = 43.25
|
||||
|
||||
// Test double dot product
|
||||
double doubleDot = doubleVec1.dot(doubleVec2);
|
||||
EXPECT_DOUBLE_EQ(doubleDot, 43.25); // Same calculation as float
|
||||
|
||||
// Test dot product with self (should equal squared length)
|
||||
int selfDot = intVec1.dot(intVec1);
|
||||
EXPECT_EQ(selfDot, 14); // 1*1 + 2*2 + 3*3 = 1 + 4 + 9 = 14
|
||||
|
||||
// Test dot product with zero vector
|
||||
Vec3<int> zeroVec = {0, 0, 0};
|
||||
EXPECT_EQ(intVec1.dot(zeroVec), 0);
|
||||
}
|
||||
|
||||
// Test cross product
|
||||
TEST_F(Vec3Test, CrossProduct) {
|
||||
// Test integer cross product
|
||||
auto intCross = intVec1.cross(intVec2);
|
||||
EXPECT_EQ(intCross.x, -3); // (2*6 - 3*5) = 12 - 15 = -3
|
||||
EXPECT_EQ(intCross.y, 6); // (3*4 - 1*6) = 12 - 6 = 6
|
||||
EXPECT_EQ(intCross.z, -3); // (1*5 - 2*4) = 5 - 8 = -3
|
||||
|
||||
// Test float cross product
|
||||
auto floatCross = floatVec1.cross(floatVec2);
|
||||
EXPECT_FLOAT_EQ(floatCross.x,
|
||||
-3.0f); // (2.5*6.5 - 3.5*5.5) = 16.25 - 19.25 = -3
|
||||
EXPECT_FLOAT_EQ(floatCross.y,
|
||||
6.0f); // (3.5*4.5 - 1.5*6.5) = 15.75 - 9.75 = 6
|
||||
EXPECT_FLOAT_EQ(floatCross.z,
|
||||
-3.0f); // (1.5*5.5 - 2.5*4.5) = 8.25 - 11.25 = -3
|
||||
|
||||
// Test double cross product
|
||||
auto doubleCross = doubleVec1.cross(doubleVec2);
|
||||
EXPECT_DOUBLE_EQ(doubleCross.x, -3.0);
|
||||
EXPECT_DOUBLE_EQ(doubleCross.y, 6.0);
|
||||
EXPECT_DOUBLE_EQ(doubleCross.z, -3.0);
|
||||
|
||||
// Test cross product with self (should be zero)
|
||||
auto selfCross = intVec1.cross(intVec1);
|
||||
EXPECT_EQ(selfCross.x, 0);
|
||||
EXPECT_EQ(selfCross.y, 0);
|
||||
EXPECT_EQ(selfCross.z, 0);
|
||||
|
||||
// Test cross product of standard basis vectors (i × j = k)
|
||||
Vec3<int> i = {1, 0, 0};
|
||||
Vec3<int> j = {0, 1, 0};
|
||||
Vec3<int> k = {0, 0, 1};
|
||||
|
||||
auto i_cross_j = i.cross(j);
|
||||
EXPECT_EQ(i_cross_j.x, 0);
|
||||
EXPECT_EQ(i_cross_j.y, 0);
|
||||
EXPECT_EQ(i_cross_j.z, 1);
|
||||
|
||||
auto j_cross_k = j.cross(k);
|
||||
EXPECT_EQ(j_cross_k.x, 1);
|
||||
EXPECT_EQ(j_cross_k.y, 0);
|
||||
EXPECT_EQ(j_cross_k.z, 0);
|
||||
|
||||
auto k_cross_i = k.cross(i);
|
||||
EXPECT_EQ(k_cross_i.x, 0);
|
||||
EXPECT_EQ(k_cross_i.y, 1);
|
||||
EXPECT_EQ(k_cross_i.z, 0);
|
||||
}
|
||||
|
||||
// Test with edge cases
|
||||
TEST_F(Vec3Test, EdgeCases) {
|
||||
// Test with max values
|
||||
Vec3<int> maxVec = {std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max()};
|
||||
|
||||
// Addition with max values may overflow, but we want to test the operation
|
||||
// works
|
||||
auto maxAddition = maxVec + intVec1;
|
||||
|
||||
// Test with min values
|
||||
Vec3<int> minVec = {std::numeric_limits<int>::min(),
|
||||
std::numeric_limits<int>::min(),
|
||||
std::numeric_limits<int>::min()};
|
||||
|
||||
// Subtraction with min values may underflow, but we want to test the
|
||||
// operation works
|
||||
auto minSubtraction = minVec - intVec1;
|
||||
|
||||
// Test with mixed values
|
||||
Vec3<double> mixedVec1 = {0.0, -1.0, std::numeric_limits<double>::infinity()};
|
||||
Vec3<double> mixedVec2 = {-0.0, 1.0,
|
||||
-std::numeric_limits<double>::infinity()};
|
||||
|
||||
auto mixedAddition = mixedVec1 + mixedVec2;
|
||||
// 0.0 + (-0.0) = 0.0
|
||||
EXPECT_DOUBLE_EQ(mixedAddition.x, 0.0);
|
||||
// -1.0 + 1.0 = 0.0
|
||||
EXPECT_DOUBLE_EQ(mixedAddition.y, 0.0);
|
||||
// inf + (-inf) = NaN
|
||||
EXPECT_TRUE(std::isnan(mixedAddition.z));
|
||||
|
||||
// Test with NaN
|
||||
Vec3<double> nanVec = {std::numeric_limits<double>::quiet_NaN(),
|
||||
std::numeric_limits<double>::quiet_NaN(),
|
||||
std::numeric_limits<double>::quiet_NaN()};
|
||||
|
||||
// Any operation with NaN should result in NaN
|
||||
auto nanResult = doubleVec1 + nanVec;
|
||||
EXPECT_TRUE(std::isnan(nanResult.x));
|
||||
EXPECT_TRUE(std::isnan(nanResult.y));
|
||||
EXPECT_TRUE(std::isnan(nanResult.z));
|
||||
}
|
||||
|
||||
// Main function that runs the tests
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user