diff --git a/develop/cmake/SetupTargets.cmake b/develop/cmake/SetupTargets.cmake index fd5eac3..c1aa6e8 100644 --- a/develop/cmake/SetupTargets.cmake +++ b/develop/cmake/SetupTargets.cmake @@ -1,9 +1,6 @@ add_library(${PROJECT_NAME}.setup_targets INTERFACE) add_library(${PROJECT_NAME}::setup_targets ALIAS ${PROJECT_NAME}.setup_targets) -target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE - vmath.hpp.vendors::doctest) - target_compile_options(${PROJECT_NAME}.setup_targets INTERFACE $<$: /WX /W4> @@ -20,26 +17,13 @@ target_compile_options(${PROJECT_NAME}.setup_targets INTERFACE -Wno-unknown-warning-option >) -if(BUILD_WITH_COVERAGE) - target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE - vmath.hpp::enable_gcov) -endif() - -if(BUILD_WITH_SANITIZERS) - target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE +target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE + $<$: + vmath.hpp::enable_gcov> + $<$: vmath.hpp::enable_asan - vmath.hpp::enable_ubsan) -endif() - -if(BUILD_WITH_NO_EXCEPTIONS) - target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE - vmath.hpp::disable_exceptions) - - target_compile_definitions(${PROJECT_NAME}.setup_targets INTERFACE - DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS) -endif() - -if(BUILD_WITH_NO_RTTI) - target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE - vmath.hpp::disable_rtti) -endif() + vmath.hpp::enable_ubsan> + $<$: + vmath.hpp::disable_exceptions> + $<$: + vmath.hpp::disable_rtti>) diff --git a/develop/singles/CMakeLists.txt b/develop/singles/CMakeLists.txt index 930b461..ea1551e 100644 --- a/develop/singles/CMakeLists.txt +++ b/develop/singles/CMakeLists.txt @@ -13,10 +13,13 @@ set(VMATH_HPP_SINGLES_SCRIPT "${VMATH_HPP_ROOT_DIR}/develop/singles/scripts/buil file(GLOB_RECURSE VMATH_SINGLES_DEPENDS CONFIGURE_DEPENDS "${VMATH_HPP_ROOT_DIR}/headers/*.hpp") add_custom_command(OUTPUT "${VMATH_HPP_SINGLES_OUTPUT}" - COMMAND "${Python3_EXECUTABLE}" "${VMATH_HPP_SINGLES_SCRIPT}" - "${VMATH_HPP_SINGLES_INPUT}" "${VMATH_HPP_SINGLES_OUTPUT}" - DEPENDS ${VMATH_SINGLES_DEPENDS} - WORKING_DIRECTORY "${VMATH_HPP_ROOT_DIR}") + COMMAND + "${Python3_EXECUTABLE}" "${VMATH_HPP_SINGLES_SCRIPT}" + "${VMATH_HPP_SINGLES_INPUT}" "${VMATH_HPP_SINGLES_OUTPUT}" + DEPENDS + "${VMATH_HPP_SINGLES_SCRIPT}" ${VMATH_SINGLES_DEPENDS} + WORKING_DIRECTORY + "${VMATH_HPP_ROOT_DIR}") add_custom_target(${PROJECT_NAME}.generate DEPENDS "${VMATH_HPP_SINGLES_OUTPUT}") diff --git a/develop/singles/headers/vmath.hpp/vmath_all.hpp b/develop/singles/headers/vmath.hpp/vmath_all.hpp index f9265d1..c1d12d9 100644 --- a/develop/singles/headers/vmath.hpp/vmath_all.hpp +++ b/develop/singles/headers/vmath.hpp/vmath_all.hpp @@ -4,6 +4,8 @@ * Copyright (C) 2020-2023, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ +#pragma once + #include #include #include @@ -148,49 +150,49 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - floor(T x) noexcept { + constexpr floor(T x) noexcept { return std::floor(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - trunc(T x) noexcept { + constexpr trunc(T x) noexcept { return std::trunc(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - round(T x) noexcept { + constexpr round(T x) noexcept { return std::round(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - ceil(T x) noexcept { + constexpr ceil(T x) noexcept { return std::ceil(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - fract(T x) noexcept { + constexpr fract(T x) noexcept { return x - floor(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - fmod(T x, T y) noexcept { + constexpr fmod(T x, T y) noexcept { return std::fmod(x, y); } template < typename T > [[nodiscard]] std::enable_if_t, T> - modf(T x, T* y) noexcept { + constexpr modf(T x, T* y) noexcept { return std::modf(x, y); } template < typename T > [[nodiscard]] std::enable_if_t, T> - copysign(T x, T s) noexcept { + constexpr copysign(T x, T s) noexcept { return std::copysign(x, s); } @@ -264,91 +266,91 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - sin(T x) noexcept { + constexpr sin(T x) noexcept { return std::sin(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - cos(T x) noexcept { + constexpr cos(T x) noexcept { return std::cos(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - tan(T x) noexcept { + constexpr tan(T x) noexcept { return std::tan(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - asin(T x) noexcept { + constexpr asin(T x) noexcept { return std::asin(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - acos(T x) noexcept { + constexpr acos(T x) noexcept { return std::acos(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - atan(T x) noexcept { + constexpr atan(T x) noexcept { return std::atan(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - atan2(T y, T x) noexcept { + constexpr atan2(T y, T x) noexcept { return std::atan2(y, x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - sinh(T x) noexcept { + constexpr sinh(T x) noexcept { return std::sinh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - cosh(T x) noexcept { + constexpr cosh(T x) noexcept { return std::cosh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - tanh(T x) noexcept { + constexpr tanh(T x) noexcept { return std::tanh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - asinh(T x) noexcept { + constexpr asinh(T x) noexcept { return std::asinh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - acosh(T x) noexcept { + constexpr acosh(T x) noexcept { return std::acosh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - atanh(T x) noexcept { + constexpr atanh(T x) noexcept { return std::atanh(x); } template < typename T > [[nodiscard]] std::enable_if_t, std::pair> - sincos(T x) noexcept { + constexpr sincos(T x) noexcept { return { sin(x), cos(x) }; } template < typename T > std::enable_if_t, void> - sincos(T x, T* s, T* c) noexcept { + constexpr sincos(T x, T* s, T* c) noexcept { *s = sin(x); *c = cos(x); } @@ -362,43 +364,43 @@ namespace vmath_hpp { template < typename T > [[nodiscard]] std::enable_if_t, T> - pow(T x, T y) noexcept { + constexpr pow(T x, T y) noexcept { return std::pow(x, y); } template < typename T > [[nodiscard]] std::enable_if_t, T> - exp(T x) noexcept { + constexpr exp(T x) noexcept { return std::exp(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - log(T x) noexcept { + constexpr log(T x) noexcept { return std::log(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - exp2(T x) noexcept { + constexpr exp2(T x) noexcept { return std::exp2(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - log2(T x) noexcept { + constexpr log2(T x) noexcept { return std::log2(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - sqrt(T x) noexcept { + constexpr sqrt(T x) noexcept { return std::sqrt(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - rsqrt(T x) noexcept { + constexpr rsqrt(T x) noexcept { return rcp(sqrt(x)); } } @@ -481,7 +483,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - refract(T i, T n, T eta) noexcept { + constexpr refract(T i, T n, T eta) noexcept { const T d = dot(n, i); const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n); @@ -2874,226 +2876,139 @@ namespace vmath_hpp // transpose // - namespace impl - { - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat transpose_2x2_impl( - T a, T c, - T b, T d) - { - return { - a, b, - c, d}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat transpose_3x3_impl( - T a, T d, T g, - T b, T e, T h, - T c, T f, T i) - { - return { - a, b, c, - d, e, f, - g, h, i}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat transpose_4x4_impl( - T a, T e, T i, T m, - T b, T f, T j, T n, - T c, T g, T k, T o, - T d, T h, T l, T p) - { - return { - a, b, c, d, - e, f, g, h, - i, j, k, l, - m, n, o, p}; - } + template < typename T > + [[nodiscard]] constexpr mat transpose(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], + c = _m[1][0], d = _m[1][1]; + return { + a, c, + b, d}; } template < typename T > - [[nodiscard]] constexpr mat transpose(const mat& m) { - return impl::transpose_2x2_impl( - m[0][0], m[0][1], - m[1][0], m[1][1]); + [[nodiscard]] constexpr mat transpose(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], + d = _m[1][0], e = _m[1][1], f = _m[1][2], + g = _m[2][0], h = _m[2][1], i = _m[2][2]; + return { + a, d, g, + b, e, h, + c, f, i}; } template < typename T > - [[nodiscard]] constexpr mat transpose(const mat& m) { - return impl::transpose_3x3_impl( - m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - template < typename T > - [[nodiscard]] constexpr mat transpose(const mat& m) { - return impl::transpose_4x4_impl( - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3]); + [[nodiscard]] constexpr mat transpose(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3], + e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3], + i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3], + m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3]; + return { + a, e, i, m, + b, f, j, n, + c, g, k, o, + d, h, l, p}; } // // adjugate // - namespace impl - { - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat adjugate_2x2_impl( - T a, T b, - T c, T d) - { - return { - +d, -b, - -c, +a}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat adjugate_3x3_impl( - T a, T b, T c, - T d, T e, T f, - T g, T h, T i) - { - return { - e * i - f * h, - c * h - b * i, - b * f - c * e, - f * g - d * i, - a * i - c * g, - c * d - a * f, - d * h - e * g, - b * g - a * h, - a * e - b * d}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat adjugate_4x4_impl( - T a, T b, T c, T d, - T e, T f, T g, T h, - T i, T j, T k, T l, - T m, T n, T o, T p) - { - return { - f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n), - j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n), - n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f), - b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k), - g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p), - k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p), - o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h), - c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k), - h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p), - l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p), - p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h), - d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i), - e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n), - i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n), - m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f), - a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)}; - } + template < typename T > + [[nodiscard]] constexpr mat adjugate(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], + c = _m[1][0], d = _m[1][1]; + return { + +d, + -b, + -c, + +a}; } template < typename T > - [[nodiscard]] constexpr mat adjugate(const mat& m) { - return impl::adjugate_2x2_impl( - m[0][0], m[0][1], - m[1][0], m[1][1]); + [[nodiscard]] constexpr mat adjugate(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], + d = _m[1][0], e = _m[1][1], f = _m[1][2], + g = _m[2][0], h = _m[2][1], i = _m[2][2]; + return { + e * i - f * h, + c * h - b * i, + b * f - c * e, + f * g - d * i, + a * i - c * g, + c * d - a * f, + d * h - e * g, + b * g - a * h, + a * e - b * d}; } template < typename T > - [[nodiscard]] constexpr mat adjugate(const mat& m) { - return impl::adjugate_3x3_impl( - m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - template < typename T > - [[nodiscard]] constexpr mat adjugate(const mat& m) { - return impl::adjugate_4x4_impl( - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3]); + [[nodiscard]] constexpr mat adjugate(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3], + e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3], + i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3], + m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3]; + return { + f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n), + j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n), + n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f), + b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k), + g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p), + k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p), + o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h), + c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k), + h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p), + l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p), + p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h), + d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i), + e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n), + i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n), + m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f), + a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)}; } // // determinant // - namespace impl - { - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - T determinant_2x2_impl( - T a, T b, - T c, T d) - { - return a * d - b * c; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - T determinant_3x3_impl( - T a, T b, T c, - T d, T e, T f, - T g, T h, T i) - { - return - + a * (e * i - f * h) - - b * (d * i - f * g) - + c * (d * h - e * g); - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - T determinant_4x4_impl( - T a, T b, T c, T d, - T e, T f, T g, T h, - T i, T j, T k, T l, - T m, T n, T o, T p) - { - return - + a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k))) - - b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k))) - + c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j))) - - d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j))); - } + template < typename T > + [[nodiscard]] constexpr T determinant(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], + c = _m[1][0], d = _m[1][1]; + return + a * d - b * c; } template < typename T > - [[nodiscard]] constexpr T determinant(const mat& m) { - return impl::determinant_2x2_impl( - m[0][0], m[0][1], - m[1][0], m[1][1]); + [[nodiscard]] constexpr T determinant(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], + d = _m[1][0], e = _m[1][1], f = _m[1][2], + g = _m[2][0], h = _m[2][1], i = _m[2][2]; + return + + a * (e * i - f * h) + - b * (d * i - f * g) + + c * (d * h - e * g); } template < typename T > - [[nodiscard]] constexpr T determinant(const mat& m) { - return impl::determinant_3x3_impl( - m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - template < typename T > - [[nodiscard]] constexpr T determinant(const mat& m) { - return impl::determinant_4x4_impl( - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3]); + [[nodiscard]] constexpr T determinant(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3], + e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3], + i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3], + m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3]; + return + + a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k))) + - b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k))) + + c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j))) + - d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j))); } // @@ -3661,12 +3576,12 @@ namespace vmath_hpp::detail } }; - template < typename T, size_t Size > + template < typename T, std::size_t Size > [[nodiscard]] std::size_t hash(const vec& v) noexcept { return fold_join(hash_combiner{}, std::size_t{}, v); } - template < typename T, size_t Size > + template < typename T, std::size_t Size > [[nodiscard]] std::size_t hash(const mat& m) noexcept { return fold_join(hash_combiner{}, std::size_t{}, m); } diff --git a/develop/singles/scripts/build_singles.py b/develop/singles/scripts/build_singles.py index b3af5f8..a4bff29 100755 --- a/develop/singles/scripts/build_singles.py +++ b/develop/singles/scripts/build_singles.py @@ -5,10 +5,6 @@ import os import re import sys -# -# -# - EMPTY_MATCHER = re.compile(r'^\s*$') C_COMMENT_MATCHER = re.compile(r'^/\*.*\*/', re.S) @@ -19,9 +15,6 @@ USER_INCLUDE_MATCHER = re.compile(r'#\s*include\s*\"(.*)\"') SYSTEM_INCLUDE_MATCHER = re.compile(r'#\s*include\s*<(.*)>') PRAGMA_ONCE_MATCHER = re.compile(r'#\s*pragma\s+once') -# -# -# def CollectLicenseComment(headerPath): with open(headerPath, "r") as headerStream: @@ -29,7 +22,8 @@ def CollectLicenseComment(headerPath): commentMatch = re.match(C_COMMENT_MATCHER, headerContent) return commentMatch.group() if commentMatch else "" -def CollectSystemIncludes(headerPath, parsedHeaders = set()): + +def CollectSystemIncludes(headerPath, parsedHeaders=set()): with open(headerPath, "r") as headerStream: headerContent = headerStream.read().strip() @@ -50,8 +44,10 @@ def CollectSystemIncludes(headerPath, parsedHeaders = set()): includeMatch = USER_INCLUDE_MATCHER.findall(headerLine) if includeMatch and ifdefScopeLevel == 0: - internalHeaderPath = os.path.abspath(os.path.join(os.path.dirname(headerPath), includeMatch[0])) - headerIncludes = headerIncludes.union(CollectSystemIncludes(internalHeaderPath, parsedHeaders)) + internalHeaderPath = os.path.abspath(os.path.join( + os.path.dirname(headerPath), includeMatch[0])) + headerIncludes = headerIncludes.union( + CollectSystemIncludes(internalHeaderPath, parsedHeaders)) includeMatch = SYSTEM_INCLUDE_MATCHER.findall(headerLine) if includeMatch and ifdefScopeLevel == 0: @@ -59,7 +55,8 @@ def CollectSystemIncludes(headerPath, parsedHeaders = set()): return headerIncludes -def ParseHeader(headerPath, parsedHeaders = set()): + +def ParseHeader(headerPath, parsedHeaders=set()): with open(headerPath, "r") as headerStream: headerContent = headerStream.read().strip() headerContent = re.sub(C_COMMENT_MATCHER, '', headerContent) @@ -89,8 +86,10 @@ def ParseHeader(headerPath, parsedHeaders = set()): includeMatch = USER_INCLUDE_MATCHER.findall(headerLine) if includeMatch and ifdefScopeLevel == 0: - internalHeaderPath = os.path.abspath(os.path.join(os.path.dirname(headerPath), includeMatch[0])) - internalHeaderContent = ParseHeader(internalHeaderPath, parsedHeaders) + internalHeaderPath = os.path.abspath(os.path.join( + os.path.dirname(headerPath), includeMatch[0])) + internalHeaderContent = ParseHeader( + internalHeaderPath, parsedHeaders) outputContent += internalHeaderContent shouldSkipNextEmptyLines = True @@ -106,9 +105,6 @@ def ParseHeader(headerPath, parsedHeaders = set()): return "{}\n".format(outputContent) -# -# -# inputHeaderPath = os.path.abspath(sys.argv[1]) outputHeaderPath = os.path.abspath(sys.argv[2]) @@ -118,13 +114,20 @@ os.makedirs(os.path.dirname(outputHeaderPath), exist_ok=True) with open(outputHeaderPath, "w") as outputHeaderStream: licenseComment = CollectLicenseComment(inputHeaderPath) systemIncludes = CollectSystemIncludes(inputHeaderPath) + headersContent = ParseHeader(inputHeaderPath) - outputHeaderStream.write("{}\n".format(licenseComment)) + if licenseComment: + outputHeaderStream.write("{}\n".format(licenseComment)) + outputHeaderStream.write("\n") + + outputHeaderStream.write("#pragma once\n") outputHeaderStream.write("\n") - for systemInclude in sorted(systemIncludes): - outputHeaderStream.write("#include <{}>\n".format(systemInclude)) - outputHeaderStream.write("\n") + if systemIncludes: + for systemInclude in sorted(systemIncludes): + outputHeaderStream.write("#include <{}>\n".format(systemInclude)) + outputHeaderStream.write("\n") - outputHeaderStream.write(ParseHeader(inputHeaderPath).strip()) - outputHeaderStream.write("\n") + if headersContent: + outputHeaderStream.write(headersContent.strip()) + outputHeaderStream.write("\n") diff --git a/develop/untests/CMakeLists.txt b/develop/untests/CMakeLists.txt index af6f006..1cb65c8 100644 --- a/develop/untests/CMakeLists.txt +++ b/develop/untests/CMakeLists.txt @@ -8,11 +8,13 @@ add_executable(${PROJECT_NAME}.singles ${UNTESTS_SOURCES}) target_link_libraries(${PROJECT_NAME} PRIVATE vmath.hpp::vmath.hpp - vmath.hpp::setup_targets) + vmath.hpp::setup_targets + vmath.hpp.vendors::doctest) target_link_libraries(${PROJECT_NAME}.singles PRIVATE vmath.hpp::singles - vmath.hpp::setup_targets) + vmath.hpp::setup_targets + vmath.hpp.vendors::doctest) add_test(${PROJECT_NAME} ${PROJECT_NAME}) add_test(${PROJECT_NAME} ${PROJECT_NAME}.singles) diff --git a/develop/untests/vmath_mat_fun_tests.cpp b/develop/untests/vmath_mat_fun_tests.cpp index 7edc62f..2e5b1bd 100644 --- a/develop/untests/vmath_mat_fun_tests.cpp +++ b/develop/untests/vmath_mat_fun_tests.cpp @@ -322,34 +322,38 @@ TEST_CASE("vmath/mat_fun") { constexpr fmat4 rm1 = inverse(m1); STATIC_CHECK(all(approx( unit4_z * m1 * rm1, - unit4_z))); + unit4_z, + 0.00001f))); } { const fvec3 axis2 = normalize(fvec3(1.f, 2.f, 3.f)); - const fmat4 m2 = fmat4(rotate(0.5f,axis2)); + const fmat4 m2 = perspective_lh(800.f, 600.f, -1.f, 1.f) * translate(fvec3(1.f, 2.f, 3.f)) * scale4(fvec3(2.f, 3.f, 4.f)) * fmat4(rotate(0.5f,axis2)); const fmat4 rm2 = inverse(m2); CHECK(all(approx( unit4_z * m2 * rm2, - unit4_z))); + unit4_z, + 0.00001f))); } { const fvec3 axis3 = normalize(fvec3(1.f, 2.f, 3.f)); - const fmat3 m3 = fmat3(rotate(0.5f,axis3)); + const fmat3 m3 = translate(fvec2(1.f, 2.f)) * scale(fvec3(2.f, 3.f, 4.f)) * fmat3(rotate(0.5f,axis3)); const fmat3 rm3 = inverse(m3); CHECK(all(approx( unit3_z * m3 * rm3, - unit3_z))); + unit3_z, + 0.00001f))); } { const fvec3 axis4 = normalize(fvec3(0.f, 0.f, 3.f)); - const fmat2 m4 = fmat2(rotate(0.5f,axis4)); + const fmat2 m4 = scale(fvec2(2.f, 3.f)) * fmat2(rotate(0.5f,axis4)); const fmat2 rm4 = inverse(m4); CHECK(all(approx( unit2_y * m4 * rm4, - unit2_y))); + unit2_y, + 0.00001f))); } } } diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index f85e8a1..6a41393 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -68,12 +68,12 @@ namespace vmath_hpp::detail } }; - template < typename T, size_t Size > + template < typename T, std::size_t Size > [[nodiscard]] std::size_t hash(const vec& v) noexcept { return fold_join(hash_combiner{}, std::size_t{}, v); } - template < typename T, size_t Size > + template < typename T, std::size_t Size > [[nodiscard]] std::size_t hash(const mat& m) noexcept { return fold_join(hash_combiner{}, std::size_t{}, m); } diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 8c66aac..48a24a5 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -44,49 +44,49 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - floor(T x) noexcept { + constexpr floor(T x) noexcept { return std::floor(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - trunc(T x) noexcept { + constexpr trunc(T x) noexcept { return std::trunc(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - round(T x) noexcept { + constexpr round(T x) noexcept { return std::round(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - ceil(T x) noexcept { + constexpr ceil(T x) noexcept { return std::ceil(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - fract(T x) noexcept { + constexpr fract(T x) noexcept { return x - floor(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - fmod(T x, T y) noexcept { + constexpr fmod(T x, T y) noexcept { return std::fmod(x, y); } template < typename T > [[nodiscard]] std::enable_if_t, T> - modf(T x, T* y) noexcept { + constexpr modf(T x, T* y) noexcept { return std::modf(x, y); } template < typename T > [[nodiscard]] std::enable_if_t, T> - copysign(T x, T s) noexcept { + constexpr copysign(T x, T s) noexcept { return std::copysign(x, s); } @@ -160,91 +160,91 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - sin(T x) noexcept { + constexpr sin(T x) noexcept { return std::sin(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - cos(T x) noexcept { + constexpr cos(T x) noexcept { return std::cos(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - tan(T x) noexcept { + constexpr tan(T x) noexcept { return std::tan(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - asin(T x) noexcept { + constexpr asin(T x) noexcept { return std::asin(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - acos(T x) noexcept { + constexpr acos(T x) noexcept { return std::acos(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - atan(T x) noexcept { + constexpr atan(T x) noexcept { return std::atan(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - atan2(T y, T x) noexcept { + constexpr atan2(T y, T x) noexcept { return std::atan2(y, x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - sinh(T x) noexcept { + constexpr sinh(T x) noexcept { return std::sinh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - cosh(T x) noexcept { + constexpr cosh(T x) noexcept { return std::cosh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - tanh(T x) noexcept { + constexpr tanh(T x) noexcept { return std::tanh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - asinh(T x) noexcept { + constexpr asinh(T x) noexcept { return std::asinh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - acosh(T x) noexcept { + constexpr acosh(T x) noexcept { return std::acosh(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - atanh(T x) noexcept { + constexpr atanh(T x) noexcept { return std::atanh(x); } template < typename T > [[nodiscard]] std::enable_if_t, std::pair> - sincos(T x) noexcept { + constexpr sincos(T x) noexcept { return { sin(x), cos(x) }; } template < typename T > std::enable_if_t, void> - sincos(T x, T* s, T* c) noexcept { + constexpr sincos(T x, T* s, T* c) noexcept { *s = sin(x); *c = cos(x); } @@ -258,43 +258,43 @@ namespace vmath_hpp { template < typename T > [[nodiscard]] std::enable_if_t, T> - pow(T x, T y) noexcept { + constexpr pow(T x, T y) noexcept { return std::pow(x, y); } template < typename T > [[nodiscard]] std::enable_if_t, T> - exp(T x) noexcept { + constexpr exp(T x) noexcept { return std::exp(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - log(T x) noexcept { + constexpr log(T x) noexcept { return std::log(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - exp2(T x) noexcept { + constexpr exp2(T x) noexcept { return std::exp2(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - log2(T x) noexcept { + constexpr log2(T x) noexcept { return std::log2(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - sqrt(T x) noexcept { + constexpr sqrt(T x) noexcept { return std::sqrt(x); } template < typename T > [[nodiscard]] std::enable_if_t, T> - rsqrt(T x) noexcept { + constexpr rsqrt(T x) noexcept { return rcp(sqrt(x)); } } @@ -377,7 +377,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - refract(T i, T n, T eta) noexcept { + constexpr refract(T i, T n, T eta) noexcept { const T d = dot(n, i); const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n); diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 4fcc33a..055a510 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -638,226 +638,139 @@ namespace vmath_hpp // transpose // - namespace impl - { - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat transpose_2x2_impl( - T a, T c, - T b, T d) - { - return { - a, b, - c, d}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat transpose_3x3_impl( - T a, T d, T g, - T b, T e, T h, - T c, T f, T i) - { - return { - a, b, c, - d, e, f, - g, h, i}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat transpose_4x4_impl( - T a, T e, T i, T m, - T b, T f, T j, T n, - T c, T g, T k, T o, - T d, T h, T l, T p) - { - return { - a, b, c, d, - e, f, g, h, - i, j, k, l, - m, n, o, p}; - } + template < typename T > + [[nodiscard]] constexpr mat transpose(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], + c = _m[1][0], d = _m[1][1]; + return { + a, c, + b, d}; } template < typename T > - [[nodiscard]] constexpr mat transpose(const mat& m) { - return impl::transpose_2x2_impl( - m[0][0], m[0][1], - m[1][0], m[1][1]); + [[nodiscard]] constexpr mat transpose(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], + d = _m[1][0], e = _m[1][1], f = _m[1][2], + g = _m[2][0], h = _m[2][1], i = _m[2][2]; + return { + a, d, g, + b, e, h, + c, f, i}; } template < typename T > - [[nodiscard]] constexpr mat transpose(const mat& m) { - return impl::transpose_3x3_impl( - m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - template < typename T > - [[nodiscard]] constexpr mat transpose(const mat& m) { - return impl::transpose_4x4_impl( - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3]); + [[nodiscard]] constexpr mat transpose(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3], + e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3], + i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3], + m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3]; + return { + a, e, i, m, + b, f, j, n, + c, g, k, o, + d, h, l, p}; } // // adjugate // - namespace impl - { - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat adjugate_2x2_impl( - T a, T b, - T c, T d) - { - return { - +d, -b, - -c, +a}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat adjugate_3x3_impl( - T a, T b, T c, - T d, T e, T f, - T g, T h, T i) - { - return { - e * i - f * h, - c * h - b * i, - b * f - c * e, - f * g - d * i, - a * i - c * g, - c * d - a * f, - d * h - e * g, - b * g - a * h, - a * e - b * d}; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - mat adjugate_4x4_impl( - T a, T b, T c, T d, - T e, T f, T g, T h, - T i, T j, T k, T l, - T m, T n, T o, T p) - { - return { - f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n), - j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n), - n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f), - b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k), - g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p), - k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p), - o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h), - c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k), - h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p), - l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p), - p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h), - d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i), - e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n), - i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n), - m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f), - a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)}; - } + template < typename T > + [[nodiscard]] constexpr mat adjugate(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], + c = _m[1][0], d = _m[1][1]; + return { + +d, + -b, + -c, + +a}; } template < typename T > - [[nodiscard]] constexpr mat adjugate(const mat& m) { - return impl::adjugate_2x2_impl( - m[0][0], m[0][1], - m[1][0], m[1][1]); + [[nodiscard]] constexpr mat adjugate(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], + d = _m[1][0], e = _m[1][1], f = _m[1][2], + g = _m[2][0], h = _m[2][1], i = _m[2][2]; + return { + e * i - f * h, + c * h - b * i, + b * f - c * e, + f * g - d * i, + a * i - c * g, + c * d - a * f, + d * h - e * g, + b * g - a * h, + a * e - b * d}; } template < typename T > - [[nodiscard]] constexpr mat adjugate(const mat& m) { - return impl::adjugate_3x3_impl( - m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - template < typename T > - [[nodiscard]] constexpr mat adjugate(const mat& m) { - return impl::adjugate_4x4_impl( - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3]); + [[nodiscard]] constexpr mat adjugate(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3], + e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3], + i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3], + m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3]; + return { + f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n), + j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n), + n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f), + b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k), + g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p), + k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p), + o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h), + c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k), + h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p), + l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p), + p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h), + d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i), + e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n), + i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n), + m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f), + a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)}; } // // determinant // - namespace impl - { - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - T determinant_2x2_impl( - T a, T b, - T c, T d) - { - return a * d - b * c; - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - T determinant_3x3_impl( - T a, T b, T c, - T d, T e, T f, - T g, T h, T i) - { - return - + a * (e * i - f * h) - - b * (d * i - f * g) - + c * (d * h - e * g); - } - - template < typename T > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - T determinant_4x4_impl( - T a, T b, T c, T d, - T e, T f, T g, T h, - T i, T j, T k, T l, - T m, T n, T o, T p) - { - return - + a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k))) - - b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k))) - + c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j))) - - d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j))); - } + template < typename T > + [[nodiscard]] constexpr T determinant(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], + c = _m[1][0], d = _m[1][1]; + return + a * d - b * c; } template < typename T > - [[nodiscard]] constexpr T determinant(const mat& m) { - return impl::determinant_2x2_impl( - m[0][0], m[0][1], - m[1][0], m[1][1]); + [[nodiscard]] constexpr T determinant(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], + d = _m[1][0], e = _m[1][1], f = _m[1][2], + g = _m[2][0], h = _m[2][1], i = _m[2][2]; + return + + a * (e * i - f * h) + - b * (d * i - f * g) + + c * (d * h - e * g); } template < typename T > - [[nodiscard]] constexpr T determinant(const mat& m) { - return impl::determinant_3x3_impl( - m[0][0], m[0][1], m[0][2], - m[1][0], m[1][1], m[1][2], - m[2][0], m[2][1], m[2][2]); - } - - template < typename T > - [[nodiscard]] constexpr T determinant(const mat& m) { - return impl::determinant_4x4_impl( - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3]); + [[nodiscard]] constexpr T determinant(const mat& _m) { + // NOLINTNEXTLINE(*-isolate-declaration) + const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3], + e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3], + i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3], + m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3]; + return + + a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k))) + - b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k))) + + c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j))) + - d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j))); } //