Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/test-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
CTEST_OUTPUT_ON_FAILURE: 1
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm_modules
Expand Down Expand Up @@ -53,3 +56,37 @@ jobs:
run: |
cd build
ctest --build-config ${{ matrix.build-type }}

sanitizers:
name: sanitizers (clang, asan+ubsan)

runs-on: ubuntu-latest

env:
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
ASAN_OPTIONS: detect_stack_use_after_return=1

steps:
- uses: actions/checkout@v4

- uses: actions/cache@v4
with:
path: "**/cpm_modules"
key: ${{ github.workflow }}-cpm-modules-sanitizers-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}

# clang doubles as a second front-end next to GCC 14 and MSVC, so this
# job is also where -Werror is enforced.
- name: Configure
run: >
cmake -Stest -Bbuild -DCMAKE_BUILD_TYPE=Debug
-DHYPERJET_SANITIZE=ON -DHYPERJET_WERROR=ON
env:
CXX: clang++

- name: Build
run: cmake --build build -j4

- name: Test
run: |
cd build
ctest
14 changes: 5 additions & 9 deletions include/hyperjet/hyperjet.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#pragma once

#include <array> // array
#include <assert.h> // assert
#include <algorithm> // copy, fill
#include <array> // array
#include <assert.h> // assert
#include <cmath> // acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, hypot, log, log2, log10, pow, sin, sinh, sqrt, tan, tanh
#include <cstddef> // ptrdiff_t
#include <initializer_list> // initializer_list
#include <ostream> // ostream
#include <sstream> // stringstream
#include <stdexcept> // runtime_error
#include <string> // string
#include <type_traits> // conditional
#include <unordered_map> // unordered_map
Expand Down Expand Up @@ -301,7 +303,7 @@ class DDScalar {
static_assert(!is_dynamic());
}

DDScalar(const Data &data, const index size) : m_data(data), m_size(size) {
DDScalar(const Data &data, const index size) : m_size(size), m_data(data) {
static_assert(0 < order() && order() <= 2);

static_assert(is_dynamic());
Expand Down Expand Up @@ -2089,7 +2091,6 @@ template <typename TScalar> class SScalar {
using std::hypot;

const auto f = hypot(a.m_f, b.m_f);
const auto f3 = f * f * f;
const auto da = a.m_f / f;
const auto db = b.m_f / f;

Expand All @@ -2101,11 +2102,6 @@ template <typename TScalar> class SScalar {

const auto f = hypot(a.m_f, b.m_f, c.m_f);

const auto f3 = f * f * f;
const auto a2 = a.m_f * a.m_f;
const auto b2 = b.m_f * b.m_f;
const auto c2 = c.m_f * c.m_f;

const auto da = a.m_f / f;
const auto db = b.m_f / f;
const auto dc = c.m_f / f;
Expand Down
35 changes: 34 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CPMAddPackage(

if(Eigen_ADDED)
add_library(Eigen INTERFACE IMPORTED)
target_include_directories(Eigen INTERFACE ${Eigen_SOURCE_DIR})
target_include_directories(Eigen SYSTEM INTERFACE ${Eigen_SOURCE_DIR})
endif()

if(TEST_INSTALLED_VERSION)
Expand All @@ -33,6 +33,39 @@ add_executable(HyperJetTest ${sources})
target_link_libraries(HyperJetTest doctest::doctest hyperjet::hyperjet Eigen)
set_target_properties(HyperJetTest PROPERTIES CXX_STANDARD 23)

# --- Warnings

# HYPERJET_WERROR is enabled by a single CI job. Warnings differ between
# compilers, so promoting them to errors everywhere would let an unrelated
# toolchain block every build.
option(HYPERJET_WERROR "Treat compiler warnings as errors" OFF)

if(MSVC)
target_compile_options(HyperJetTest PRIVATE /W4)

if(HYPERJET_WERROR)
target_compile_options(HyperJetTest PRIVATE /WX)
endif()
else()
target_compile_options(HyperJetTest PRIVATE -Wall -Wextra -Wpedantic)

if(HYPERJET_WERROR)
target_compile_options(HyperJetTest PRIVATE -Werror)
endif()
endif()

# --- Sanitizers

option(HYPERJET_SANITIZE "Build the tests with the address and undefined behavior sanitizers" OFF)

if(HYPERJET_SANITIZE)
target_compile_options(
HyperJetTest PRIVATE -fsanitize=address,undefined -fno-sanitize-recover=all
-fno-omit-frame-pointer -g
)
target_link_options(HyperJetTest PRIVATE -fsanitize=address,undefined)
endif()

# --- Add HyperJetTest

enable_testing()
Expand Down
21 changes: 20 additions & 1 deletion test/src/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,4 +746,23 @@ TEST_CASE("SScalar Tan") {
REQUIRE(r1.d("x") == doctest::Approx(1.02031951694242680));
REQUIRE(r1.d("y") == doctest::Approx(6.12191710165456100));
REQUIRE(r1.d("z") == doctest::Approx(4.08127806776970700));
}
}
TEST_CASE("SScalar Hypot") {
using std::hypot;

const auto r1 = hypot(s1, s2);

REQUIRE(r1.size() == 3);
REQUIRE(r1.f() == doctest::Approx(5.0));
REQUIRE(r1.d("x") == doctest::Approx(6.2000000000000000));
REQUIRE(r1.d("y") == doctest::Approx(4.4000000000000000));
REQUIRE(r1.d("z") == doctest::Approx(2.4000000000000000));

const auto r2 = hypot(s1, s2, s3);

REQUIRE(r2.size() == 3);
REQUIRE(r2.f() == doctest::Approx(5.0089919145472770));
REQUIRE(r2.d("x") == doctest::Approx(6.1948592709606240));
REQUIRE(r2.d("y") == doctest::Approx(4.4400151526317840));
REQUIRE(r2.d("z") == doctest::Approx(2.4076700872634590));
}
Loading